htmlcsscss-position

CSS fixed element to not overflow parent


I have a full page of content (.page-content) with a sticky footer at the bottom. I need a vertical separator (the white line) that takes 100% of the .page-content height. This works.

I also need a fixed position separator (the red line) that takes 50% of the content height. This works too.

When scrolling to the bottom of the page, I'd like the red separator to not overflow the .page-content element. In other words, I need it to not be visible further down, just like the white line. But I need it to be fixed position at the top (as it is now).

I have tried many different things such as placing that fixed element within another absolute positioned element, setting overflow: hidden; on the .page-content element, but nothing helped, the red line always overflows.

Is there a way I can achieve that with pure HTML/CSS?

body,
html {
  padding: 0;
  margin: 0;
  font-family: sans-serif;
}

.page-content {
  position: relative;
  min-height: 100vh;
  background: #eee;
  z-index: 1;
}

.content {
  padding: 2em;
}

.vertical-separator {
  position: absolute;
  top: 0;
  left: 50%;
  width: 3px;
  height: 100%;
  background-color: #fff;
  z-index: 2;
}

.half-vertical-separator {
  position: fixed;
  top: 0;
  left: 50%;
  width: 3px;
  height: 50%;
  background-color: red;
  z-index: 3;
}

.page-footer {
  background: #444;
  color: #eee;
  position: sticky;
  bottom: 0;
  height: 100vh;
}
<div class="page-content">
  <div class="vertical-separator"></div>
  <div class="half-vertical-separator"></div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
  <div class="content">Some content</div>
</div>
<div class="page-footer">
  <div class="content">Footer</div>
</div>


Solution

  • This can be achieved with a combination of position sticky and a negative margin to hide the initial space the element would take up.

    body,
    html {
      padding: 0;
      margin: 0;
      font-family: sans-serif;
    }
    
    .page-content {
      position: relative;
      min-height: 100vh;
      background: #eee;
      z-index: 1;
    }
    
    .content {
      padding: 2em;
    }
    
    .vertical-separator {
      position: absolute;
      top: 0;
      left: 50%;
      width: 3px;
      height: 100%;
      background-color: #fff;
      z-index: 2;
    }
    
    .half-vertical-separator {
      position: sticky; /* This has changed to sticky */
      top: 0;
      left: 50%;
      width: 3px;
      height: 50vh; /* This has changed to using vh units to keep it proportional to the window */
      background-color: red;
      z-index: 3;
      margin-top: -50vh; /* This negates the original space taken up by a sticky element */
    }
    
    .page-footer {
      background: #444;
      color: #eee;
      position: sticky;
      bottom: 0;
      height: 100vh;
    }
    <div class="page-content">
      <div class="vertical-separator"></div>
      <div class="half-vertical-separator"></div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
      <div class="content">Some content</div>
    </div>
    <div class="page-footer">
      <div class="content">Footer</div>
    </div>