vertical-align and inline-block behaving annoyingl

2020-06-23 02:25发布

I am currently trying to wrap my brain around a problem, but i can't seem to grasp it.

In an unordered list for a navigation, i want to add an icon before every list item via css before pseudo class.

<ul class="list">
    <li class="list-item"><a href="#">one</a></li>
    <li class="list-item"><a href="#">two</a></li>
    <li class="list-item"><a href="#">three</a></li>
    <li class="list-item"><a href="#">four</a></li>
</ul>​

My first thought was to give both elements (the icon and the a-tag) display:inline-block and align the icon with vertical-align:middle. With just little adjustments (margin-bottom), this works well in chrome:

.list-item {
    display: block;
    font-weight: bold;
    text-transform: uppercase;
    margin: 10px 0;
    padding-bottom: 10px;
    border-bottom: 1px solid #F3F3F3;
    height:1.5em;
    overflow:hidden;
}

.list-item:before {
    display: inline-block;
    content: '';
    vertical-align: middle;
    background-color: red;
    width: 5px;
    height: 7px;
    margin: 0 4px 0.125em 5px;
}

.list-item a {
    display: inline-block;
    overflow: hidden;
    line-height: 1.5;
    height:1.5em;
}

But when you load the page in firefox, the icon is way off at the bottom. http://jsfiddle.net/pUhPB/4/

I tried what seems to me every possible combination of display, vertical-align and margin-values to get it right in both browsers, and finally, if i give the a-tag vertical-align:middle and the icon vertical-align:baseline, it seems to work:

.list-item {
    display: block;
    font-weight: bold;
    text-transform: uppercase;
    margin: 10px 0;
    padding-bottom: 10px;
    border-bottom: 1px solid #F3F3F3;
    height:1.5em;
    overflow:hidden;
}

.list-item:before {
    display: inline-block;
    content: '';
    vertical-align: baseline;
    background-color: red;
    width: 5px;
    height: 7px;
    margin: 0 4px 0 5px;
}

.list-item a {
    display: inline-block;
    vertical-align:middle;
    overflow: hidden;
    line-height: 1.5;
    height:1.5em;
}

http://jsfiddle.net/L3N3f/

But i just don't get it. Why does the first version not work? To me, it seems way more logical than the version that actually works. And which one of both browsers doesn't render the elements the right way?

I already found a solution that seems to work for me, so it's not a very urgent question, but it bugs me that i don't understand the core of my problem (and the solution), so i would be really thankful if someone could enlighten me on this.

thanks

3条回答
ゆ 、 Hurt°
2楼-- · 2020-06-23 03:03

Try this: http://jsfiddle.net/pUhPB/6/

The first thing I do in these situations is to open the code in both browsers. Then I start removing CSS code until I can see the problem. Removing the margins and the vertical-align, both browsers have rendered the code differently. So I keep removing code until they're both the same. Once they were the same in both browsers, I then changed what I could to get the desired effect.

Here's the new CSS:

.list-item:before 
{
    content: '';
    background-color: red;
    width: 5px;
    height: 7px;
    margin: 5px 4px 0 5px;
    float:left;
}
查看更多
Rolldiameter
3楼-- · 2020-06-23 03:04

According to web standard only inline elements can be "vertically aligned" in spite that some browsers, like chrome, still align them. Note that it is the element that is aligned and not its contents! So if you apply it to a <span> the <span> becomes aligned with the surrounding text and not whatever is inside it within in.

ispo lorem <span> text </span> due carpe diem

adding span {vertical-align:top; border: 1px solid black} makes <span> text </span> (whole box) become higher than the rest of the text and not push the text to the ceiling of the box <span>.

The core issue here is that Firefox is very literal when it comes to web standard whilst Chrome adds a few implicit features like this one.

For more details click here.

EDIT: apparently if you use vertical-align:top ONLY on the <a> it also works.

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2020-06-23 03:24

Your problem is that per spec setting overflow:hidden changes the baseline position of an inline-block. Firefox implements what the spec says. Chrome does not.

So as long as your .list-item a is baseline-aligned, it will render differently in the two browsers. The only way to make the renderings the same is to make sure you don't baseline-align any inline-blocks with non-visible overflow, which is what your second code paste does (it's using vertical-align: middle on the inline-block).

查看更多
登录 后发表回答