skip to Main Content

I am developing an reusable component that has a banner which should be fixed to the top of its parent component.

I am struggling to get the banner to stay fixed reletive to its parent rather than fixing itself to the top of the entire app.

My basic app structure is as follows:

.header {
  display: flex;
  -webkit-box-flex: 1;
  flex-grow: 1;
  margin: 0px 25px;
  height: 64px;
  background-color: blue;
  position: fixed;
  top: 0px;
  z-index: 999;
  width: 100%;
}

.content {
  width: inherit;
  box-sizing: border-box;
}

.banner {
  position: sticky;
  top: 0px;
  width: inherit;
  z-index: 100;
  box-sizing: border-box;
  background-color: red;
  width: 100%;
}

.form {
  padding-top: 15px;
  padding-left: 24px;
  padding-right: 24px;
  display: flex;
  flex-flow: wrap;
  width: 100%;
  height: 1000px;
  background-color: green;
  z-index: -9;
}
<div class="App">
  <div class="header"></div>
  <div class="content">
    <div class="banner">HEllo</div>
    <div class="form"></div>
  </div>
</div>

The content section of this is being abstracted into its own component so I can’t change top:0

Sandbox

2

Answers


  1. In the banner CSS rule, remove the position declaration.

    .banner {
      /* position: sticky; */
      top: 0px;
      width: inherit;
      z-index: 100;
      box-sizing: border-box;
      background-color: red;
      width: 100%;
    }
    
    Login or Signup to reply.
  2. I modified your CSS code and added comments to explain what and why I included. Here are a few useful readings. It’s worth being familiar with each type of position.

    .header {
      display: flex;
      -webkit-box-flex: 1;
      flex-grow: 1;
      margin: 0px 25px;
      height: 64px;
      background-color: blue;
      /* position: fixed; */ /* the issue with 'fixed' is that it doesn't interact with the rest of the page's elements */
      position: sticky; /* in contrast, 'sticky' will keep it at the top of the page, but only when scrolling downwards */
      top: 0px;
      z-index: 999;
      width: 100%;
    }
    
    .content {
      position: relative; /* for relative elements, you can position children with absolute alignment */
      width: inherit;
      box-sizing: border-box;
    }
    
    .banner {
      position: absolute; /* so instead of 'sticky', you can align it to the relative parent with 'absolute' */
      top: 0px;
      width: inherit;
      z-index: 100;
      box-sizing: border-box;
      background-color: red;
      width: 100%;
    }
    
    .form {
      padding-top: 15px;
      padding-left: 24px;
      padding-right: 24px;
      display: flex;
      flex-flow: wrap;
      width: 100%;
      height: 1000px;
      background-color: green;
      z-index: -9;
    }
    <div class="App">
      <div class="header"></div>
      <div class="content">
        <div class="banner">Hello</div>
        <div class="form"></div>
      </div>
    </div>

    It’s not clear what you want, as you didn’t provide a screenshot. If the goal is to always display the header and then the banner below it and then the content below that, then you just need to tweak the top pixels a little.

    .header {
      display: flex;
      -webkit-box-flex: 1;
      flex-grow: 1;
      margin: 0px 25px;
      height: 64px;
      background-color: blue;
      /* position: fixed; */ /* the issue with 'fixed' is that it doesn't interact with the rest of the page's elements */
      position: sticky; /* in contrast, 'sticky' will keep it at the top of the page, but only when scrolling downwards */
      top: 0px;
      z-index: 999;
      width: 100%;
    }
    
    .content {
      width: inherit;
      box-sizing: border-box;
      background: yellow; /* highlighted it in yellow
                             so you can see that the .banner actually starts from the top of the .content,
                             it's just that the .form doesn't start from the top of the .content
                             because the .banner is there */
    }
    
    .banner {
      position: sticky;
      top: 64px; /* instead of 0, place it so that it starts below the height of the header. */
      width: inherit;
      z-index: 100;
      box-sizing: border-box;
      background-color: red;
      width: 100%;
    }
    
    .form {
      padding-top: 15px;
      padding-left: 24px;
      padding-right: 24px;
      display: flex;
      flex-flow: wrap;
      width: 100%;
      height: 1000px;
      background-color: green;
      z-index: -9;
    }
    <div class="App">
      <div class="header"></div>
      <div class="content">
        <div class="banner">Hello</div>
        <div class="form"></div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search