skip to Main Content

I have a layout including Header section which is fixed on top, Body section, and Side Menu which is on the right side(please refer to image below). It seems that margin-top not working with position:absolute properly. Could anybody explain why?

It works as expected when

  • removing position: relative; from .container css class or
  • changing margin-top to padding-top in .container .body css class

Expected layout

expected result

Actual layout

actual result

issue code

html

<div className={styles.container}>
  <div className={styles.header}>Header Section</div>
  <div className={styles.body}>Body Section</div>
  <div className={styles.menu}>Side Menu</div>
</div>

css

.container {
  position: relative;
}

.container .header {
  height: 40px;
  position: fixed;
  top: 0;
  width: 100%;
  background-color: lightgoldenrodyellow;
}

.container .body {
  margin-top: 40px;
}

.container .menu {
  position: absolute;
  right: 0;
  top: 0;
  background-color: lightcoral;
}

3

Answers


  1. It’s not working because you are using position: fixed for the .header element. That makes your Header section fixed on top and your container element starts below it.

    FIX: remove position: fixed from your .header class

    Login or Signup to reply.
  2. So there are a few things going on here.

    1. The reason it works when you remove position: relative; from .container is that then the absolute positioning is set to the viewport, not an element.
    2. It does work if you removed the position: fixed; from the .header element. I’d want to know why this is fixed, and if the menu element is always going to be in the header. If it is, I would consider changing the mark up (see below). If the menu isn’t always going to be in the header, I would consider using position: sticky; on the .header element if you need it to stay at the top. Though you could still have some issues positioning the menu on top without putting it in the header.
    3. If you removed the margin-top on the .body element the .menu item will move to the correct space, but now the .body content is below the .header. If you added padding-top to the .container it would offset the height of the header and allow you to position the .menu (shown in first snippet). This is still going to cause a problem when the page scrolls.

    The real issue is that you’re mixing fixed and absolute positioning. Using position: fixed; fixes an element to the viewport, not to an ancestor. So you’re .header won’t scroll, but the .menu will. Even if you got it to line up with one of these methods, you’d still watch the .menu fly off the header when the page scrolls.

    .container {
      position: relative;
      padding-top: 40px;
    }
    
    .container .header {
      height: 40px;
      position: fixed;
      top: 0;
      width: 100%;
      background-color: lightgoldenrodyellow;
    }
    
    .container .menu {
      position: absolute;
      right: 0;
      top: 0;
      background-color: lightcoral;
    }
    <div class="container">
      <div class="header">Header Section</div>
      <div class="menu">Side Menu</div>
      <div class="body">Body Section</div>
    </div>

    I think you should consider updating the mark up. If you did, you wouldn’t have to be fighting positioning like this. If you want the header to be fixed, sticky, or static (scroll) then it would just work and the menu would be where you needed it to be. Then you could use something like flexbox to layout the header element while leaving the .body to scroll as needed. It would look something like this:

    /* make it a little easier to work with widths */
    *, *::before, *::after {
        box-sizing: border-box;
    }
    
    body {
      margin: 0;
      padding-top: 40px;
      /* fix for initial load to be below fixed header */
    }
    
    .container {
      position: relative;
    }
    
    .container .header {
      background-color: lightgoldenrodyellow;
      display: flex;
      /* use flexbox to layout the header */
      height: 40px;
      justify-content: space-between;
      /* content on the left / menu on the right */
      padding: 8px;
      position: fixed;
      top: 0;
      width: 100%;
    }
    
    .container .menu {
      background-color: lightcoral;
    }
    
    .container .body {
      padding: 0 1rem;
    }
    <div class="container">
      <div class="header">Header Section
        <div class="menu">Side Menu</div>
      </div>
      <div class="body">
        <h1>Body Section</h1>
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugiat nobis eaque provident ullam vel sapiente soluta repellat, fugit est, itaque, molestiae culpa reprehenderit autem optio! Dolore cupiditate rerum odio voluptate. Sed nesciunt quod est
          voluptas optio velit. Provident, soluta quaerat praesentium commodi, quia expedita laudantium esse veniam, hic iusto voluptates?</p>
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugiat nobis eaque provident ullam vel sapiente soluta repellat, fugit est, itaque, molestiae culpa reprehenderit autem optio! Dolore cupiditate rerum odio voluptate. Sed nesciunt quod est
          voluptas optio velit. Provident, soluta quaerat praesentium commodi, quia expedita laudantium esse veniam, hic iusto voluptates?</p>
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugiat nobis eaque provident ullam vel sapiente soluta repellat, fugit est, itaque, molestiae culpa reprehenderit autem optio! Dolore cupiditate rerum odio voluptate. Sed nesciunt quod est
          voluptas optio velit. Provident, soluta quaerat praesentium commodi, quia expedita laudantium esse veniam, hic iusto voluptates?</p>
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugiat nobis eaque provident ullam vel sapiente soluta repellat, fugit est, itaque, molestiae culpa reprehenderit autem optio! Dolore cupiditate rerum odio voluptate. Sed nesciunt quod est
          voluptas optio velit. Provident, soluta quaerat praesentium commodi, quia expedita laudantium esse veniam, hic iusto voluptates?</p>
        <h2>This Page Scrolls</h2>
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugiat nobis eaque provident ullam vel sapiente soluta repellat, fugit est, itaque, molestiae culpa reprehenderit autem optio! Dolore cupiditate rerum odio voluptate. Sed nesciunt quod est
          voluptas optio velit. Provident, soluta quaerat praesentium commodi, quia expedita laudantium esse veniam, hic iusto voluptates?</p>
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugiat nobis eaque provident ullam vel sapiente soluta repellat, fugit est, itaque, molestiae culpa reprehenderit autem optio! Dolore cupiditate rerum odio voluptate. Sed nesciunt quod est
          voluptas optio velit. Provident, soluta quaerat praesentium commodi, quia expedita laudantium esse veniam, hic iusto voluptates?</p>
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugiat nobis eaque provident ullam vel sapiente soluta repellat, fugit est, itaque, molestiae culpa reprehenderit autem optio! Dolore cupiditate rerum odio voluptate. Sed nesciunt quod est
          voluptas optio velit. Provident, soluta quaerat praesentium commodi, quia expedita laudantium esse veniam, hic iusto voluptates?</p>
      </div>
    </div>
    Login or Signup to reply.
  3. If margin-top doesn’t work, then try top property.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search