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
topadding-top
in.container .body
css class
Expected layout
Actual layout
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
It’s not working because you are using
position: fixed
for the.header
element. That makes your Header section fixed on top and yourcontainer
element starts below it.FIX: remove
position: fixed
from your.header
classSo there are a few things going on here.
position: relative;
from.container
is that then the absolute positioning is set to the viewport, not an element.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 usingposition: 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.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 addedpadding-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
andabsolute
positioning. Usingposition: 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.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:If margin-top doesn’t work, then try top property.