51

I would like to set an element's position to absolute and have a margin-bottom, but it seems that the margin-bottom doesn't have an effect.

HTML:

<div id='container'></div>

CSS:

#container {
  border: 1px solid red;
  position: absolute; 
  top: 0px;
  right: 0px;
  width: 300px;
  margin-bottom: 50px; // this line isn't working
}
alexmac
  • 19,087
  • 7
  • 58
  • 69
kirby
  • 3,981
  • 14
  • 41
  • 54

10 Answers10

60

I know this isn't a very timely answer but there is a way to solve this. You could add a "spacer" element inside the element positioned absolutely with a negative bottom margin and a height that is the same size as the negative bottom margin.

HTML:

<div id="container">
    <div class="spacer"></div>
</div>

CSS:

// same container code, but you should remove the margin-bottom as it has no effect

// spacer code, made it a class as you may need to use it often
.spacer {
    height: 50px;
    margin: 0 0 -50px 0;
    /* margin: 20px 0 -50px 0; use this if you want #container to have a 'bottom padding', in this case of 20px */
    background: transparent; /* you'll need this if #container's parent element has a different background from #container itself */
}
Joey
  • 623
  • 1
  • 7
  • 7
  • 3
    Or add a wrapper div with the padding. – Felix Eve Aug 08 '14 at 05:59
  • I tried both the main solution and the comment solution and they worked! Thank you! However, I propose that setting the height rather than the padding on the wrapper div as that makes more sense than margin-bottom when you read it. – 11th Hour Worker Jan 25 '18 at 05:48
  • I suggest to use a pseudo element, no extra HTML necessary: `.container:after { content: " "; display: block; height: 200px; width: 100px; }`. Adjust the height and width to your needs. – Avatar May 03 '22 at 09:43
38

Building upon Joey's answer, for a cleaner markup, use the CSS :after-selector to add a spacer for the desired bottom margin.

CSS

#container:after {
    position: absolute;
    content: "";
    bottom: -40px;
    height: 40px;
    width: 1px;
}
Community
  • 1
  • 1
nik
  • 543
  • 5
  • 7
26

What are you expecting margin-bottom to do when your element is positioned by its top side?

margin-bottom will only do anything to an absolutely-positioned element if the element has no top property.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 3
    i have elements below `container` that overlapping the `container`. if margin-bottom was working, these elements would move down. these elements don't have a `position` attribute – kirby Feb 19 '12 at 16:23
  • 3
    No, you can't do that. Once an element has `position: absolute`, it's like it were never there in the flow. Kind of like if you set `display: none` on it. Either put a `padding-top` on whatever `#container` is in, or use `position: relative` instead. – Niet the Dark Absol Feb 19 '12 at 16:50
6

You need to set the position to relative in order to set its margin.

The margin-bottom, margin-left and margin-right will NOT work when the element is in position: absolute.

Example: HTML:

<img src="whatever.png"/>

CSS:

img {
   position: relative;
   margin: 0 auto;
}
Notlaw
  • 69
  • 1
  • 4
4

I have an absolute position and need to set a margin in right side. here the way i come up with:

position:absolute;
  top:0px;
  left:10px;  
  width: calc(99% - 10px);
  height:80%;
morteza
  • 718
  • 1
  • 9
  • 14
0

For some use cases, changing position: absolute to position: relative solves this problem as well. If you can change your positioning, it will be the simplest way to solve the problem. Otherwise, the spacer of Joey does the trick.

Liglo App
  • 3,719
  • 4
  • 30
  • 54
0

I have found the solution!!!

set a min-height of the container, the position will need to be changed from absolute to inherit, set the top property to a value of your choice and the display will need to be inline-block.

This worked for me when I tried using position absolute, moving the element with top property and try to add a margin.

min-height: 42px;
display: inline-block;
top: 6px;
position: inherit;
Tom McDonough
  • 1,176
  • 15
  • 18
0

Since I don't know the height in advance, I instead added an invisible element at the end of the absolutely positioned with a height that I wanted the margin to be.

In my case, the absolutely positioned element is a table, so I added an extra empty row with a height of 100px. Then the border that was supposed to be at the bottom of the table went on "tr:nth-last-of-type(2) td" instead.

Hope this helps.

Dovev Hefetz
  • 1,346
  • 14
  • 21
0

Put it in other element and set margin to that:

.nav-item {
  margin: 0;
  margin-right: 10px;
  margin-left: 10px;
  display: inline;
  padding: 0 20px;
}

.nav-link {
  position: absolute;
  color: #000;
  transition: all 0.5s ease;
  text-decoration: none;

}

.nav-link:hover {
  color: #14aae6;
  transform: translateY(-.35em) scale(1.1);
}
<ul>
  <li class="nav-item">
    <a class="nav-link" href="#"> Item 1 </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#"> Item 2 </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#"> Item 3 </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#"> Item 4 </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#"> Item 5 </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#"> Item 6 </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#"> Item 7 </a>
  </li>
</ul>
Bambier
  • 586
  • 10
  • 16
0

If it's okay to use padding.

Try :after pseudo class.

#parent {
  padding-bottom: 10px;
  background: gray;
  width: 300px;
  height: 100px;
}

#child {
  position: relative;
  width: 100%;
  height: 100%;
}

#child:after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: yellow;
}
<div id='parent'>
  <div id='child'></div>
</div>
junho
  • 3,603
  • 3
  • 18
  • 25