Martin AJ Martin AJ - 3 months ago 11
CSS Question

How can I set margin top/bottom to a li?

Here is my code:



li {
padding: 5px 4px 6px 7px;
margin-top: 3px;
margin-bottom: 3px;
list-style: none;
}
li + li {
border-top: 1px solid #eff0f1;
}
li:hover {
background-color: #f7f8f8;
}

<ul>
<li>something</li>
<li>something else</li>
<li>something else again</li>
</ul>





As you see, there isn't any white space in the top of those rows. In other word,
margin-top: 3px;
doesn't work. Why? And how can I fix it?




Current output:

enter image description here

Expected output:

enter image description here




Note: I can wrap everything which is into
<li>
to a
<div>
. And then set all those
li
's properties to that
<div>
. But I want to know how can I do that with my current HTML structure?

Answer

Your problem is due to collapsing margins - from https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing:

Top and bottom margins of blocks are sometimes combined (collapsed) into a single margin whose size is the largest of the margins combined into it, a behavior known as margin collapsing.

To get around this, I would wrap the content of the li in a span or div and put your original li padding on that, and then put the 3px margin as padding on your li instead:

li {
  list-style: none;
  padding: 3px 0; /* this is in place of your margin */
}
li + li {
  border-top: 1px solid #eff0f1;
}
li > span {
  display: block;
  padding: 5px 4px 6px 7px; /* this is you original li padding */
}
li:hover > span {
  background-color: #f7f8f8;
}
<ul>
  <li><span>something</span></li>
  <li><span>something else</span></li>
  <li><span>something else again</span></li>
</ul>

UPDATE

If you cannot change your html then you will need something like this:

li {
  list-style: none;
  padding: 5px 4px 6px 7px;
  margin-bottom:7px; /* 3px margin plus 1px for the border */
  position:relative;
}
li + li:before {        /* this is a pseudo element to create the border */
  content:'';
  display:block; 
  height:1px;
  background: #eff0f1;
  position:absolute;
  top:-4px;
  left:0;
  right:0;
}
li:hover {
  background-color: #f7f8f8;
}
<ul>
  <li>something</li>
  <li>something else</li>
  <li>something else again</li>
</ul>