定位 div 中 uls 的高度之谜:它是如何工作的?
mystery of the height of uls in positioned divs: How does it even work?
我对css、盒模型和一般定位有一定的了解。
但是有一个谜团我从来没有摸索过,我也无法google理解它,很多时候它减慢了我的布局实现速度:
The mystery of the ul inside a positioned div
为什么我必须将 ul
font-size
设置为 0,将 line-height
设置为 1,然后将它们重置为我希望它们在 li
为了使 ul
成为正确的高度并且(似乎)包含在 div
?
如果我将ul
line-height
设置为我想要的标称行高,神秘的额外高度从何而来?为什么这个额外的高度在每个浏览器上都不一样?
还有很多其他方法可以得到神秘的高度和偏移量,但我觉得如果我理解这些情况,我就会有一个足够的模型。
有没有人拥有可以让我预测这些行为的心智模型? (因此希望记住它们,这样我就不会浪费时间每 6 个月重新计算一次)?
Here is a playground demonstrating what I seek to understand.
section {
background-color: gray;
width: 500px;
height: 700px;
padding-top: 10px;
font-size: 12px;
line-height: 25px;
}
.reference {
background-color: aquamarine;
height: 25px;
width: 75px;
float: left;
padding: 0;
margin: 0;
}
.container {
padding: 0;
margin: 0;
background-color: white;
height: 25px;
width: 423px;
}
ul {
list-style-type: none;
background-color: rgba(255, 50, 50, 0.25);
}
li {
display: inline;
}
.case-one {
display: inline-block;
}
.reference-two {
position: absolute;
top: 130px;
}
.reference-two-b {
position: absolute;
top: 200px;
}
.case-two {
position: absolute;
left: 85px;
}
.case-two-a {
top: 130px;
}
.case-two-b {
top: 200px;
}
.case-two ul {
position: relative;
font-size: 0px;
}
.case-two-a ul {
line-height: 1;
}
.case-two-b ul {
line-height: 25px;
}
.case-two li {
display: inline;
font-size: 12px;
line-height: 25px;
}
<section>
<div class="container case-one">this I fully understand</div>
<div class="reference">case one</div>
<br/>
<br/>
<div class="container case-one">
<div style="background-color: rgba(50,50,200,0.4); width:8px;height: 12px; position: absolute;"></div>
<ul>
<li>but</li>
<li>not this.</li>
<li>why is the ul offset?</li>
<li>why by font-size, not line-height?</li>
</ul>
</div>
<div class="reference">case one b</div>
<div class="container case-two case-two-a">
<ul>
<li>why does</li>
<li>setting the ul font-size to 0 work?</li>
</ul>
<div style="line-height: 1.2;">also, why does the ul line-height have to be set to 1? If it is set to 25px, the ul grows, see below</div>
</div>
<div class="reference reference-two">case two</div>
<div class="container case-two case-two-b">
<div style="background-color: rgba(50,50,200,0.4);left:4px;width:8px; height: 30px; position: absolute;"></div>
<div style="background-color: rgba(50,200,50,0.4);width:8px; height: 29px; position: absolute;left:16px;"></div>
<div style="background-color: rgba(200,50,50,0.4);width:8px; height: 28px; position: absolute;left:28px;"></div>
<ul>
<li>why does</li>
<li>setting the ul line-height to 25px result in it being 30px high?</li>
</ul>
<div style="line-height: 1.4;margin-top: 8px;">where does the 5px come from?? Why is it 4px on chrome? Why is it 3px on firefox? Anyone else get any other heights, lol?</div>
</div>
<div class="reference reference-two-b">case two</div>
</section>
是不是因为要去掉默认的margin
?
ul{
margin:0;
}
看到这个Fiddle
是的。您需要的心智模型是 strut。这似乎是 CSS 最好的秘密,这很不幸,因为它对于理解案例二和许多类似行为至关重要。找出支柱的位置和高度,许多布局行为开始变得有意义。
首先,案例一。浏览器将 ul 元素的默认顶部(和底部)边距定义为字体大小的比例。不同的浏览器可以自由设置他们想要的任何比例,因此某种重置或规范化是司空见惯的。
现在案例二,回到支柱。仅包含行内级元素的块盒由一堆行盒组成。每个行框都以一个零宽度的虚拟内联元素开始——strut。现在,行高只影响行内元素。但是当您设置块元素的行高时,每个子元素(包括支柱)都会继承该行高。您可以覆盖真正的子元素的行高,但不能覆盖 strut。
所以当你说 ul { font-size:0; line-height:1; }
时,这意味着支柱的高度将是 0px 乘以系数 1 = 0px,所以无论支柱在哪里,它都不会占用 space .
但是,当您说 ul { line-height:24px; }
时,这意味着支柱的有效高度将为 24px。内联元素的行高通过在元素字符的上方和下方添加 space 来影响它们所在文本行的高度。因此,如果字符高 18px,行高为 24px,则要添加的额外 space 为 6px。这叫做leading。行距的一半添加在元素上方,一半添加在元素下方。这些被称为 half-leading.
因此,如果您有 ul { font-size:0; line-height:24px; }
,每行文本的支柱的字符大小为 0,但上下半行距为 12px。但是其他元素的字符大小不为零。如果他们的字体 em 大小是 12px,这可能取决于字体,给使用的字符高度 16px(比如基线以上 13px 和基线以下 3px)。所以他们将领先一半 (24px - 16px) / 2 = 4px
.
但除了他们的高度,您还必须考虑他们的垂直对齐方式。支柱始终是“vertical-align:baseline”,并在此基础上与该行文本上的其他内联元素对齐。
为简单起见,我们假设其他文本元素也是 vertical-align:baseline
。
那么文本行的总行高是基线以上的最大高度 max(13px + 4px (character), 12px (strut)
加上基线以下的最大高度 max(3px + 4px (character), 12px (strut)
。这是 17px + 12px = 29px
,因此超过了指定的 24px 行高。
Lister 先生在 an answer to a related question
中提供了一些有用的图表
我对css、盒模型和一般定位有一定的了解。
但是有一个谜团我从来没有摸索过,我也无法google理解它,很多时候它减慢了我的布局实现速度:
The mystery of the ul inside a positioned div
为什么我必须将 ul
font-size
设置为 0,将 line-height
设置为 1,然后将它们重置为我希望它们在 li
为了使 ul
成为正确的高度并且(似乎)包含在 div
?
如果我将ul
line-height
设置为我想要的标称行高,神秘的额外高度从何而来?为什么这个额外的高度在每个浏览器上都不一样?
还有很多其他方法可以得到神秘的高度和偏移量,但我觉得如果我理解这些情况,我就会有一个足够的模型。
有没有人拥有可以让我预测这些行为的心智模型? (因此希望记住它们,这样我就不会浪费时间每 6 个月重新计算一次)?
Here is a playground demonstrating what I seek to understand.
section {
background-color: gray;
width: 500px;
height: 700px;
padding-top: 10px;
font-size: 12px;
line-height: 25px;
}
.reference {
background-color: aquamarine;
height: 25px;
width: 75px;
float: left;
padding: 0;
margin: 0;
}
.container {
padding: 0;
margin: 0;
background-color: white;
height: 25px;
width: 423px;
}
ul {
list-style-type: none;
background-color: rgba(255, 50, 50, 0.25);
}
li {
display: inline;
}
.case-one {
display: inline-block;
}
.reference-two {
position: absolute;
top: 130px;
}
.reference-two-b {
position: absolute;
top: 200px;
}
.case-two {
position: absolute;
left: 85px;
}
.case-two-a {
top: 130px;
}
.case-two-b {
top: 200px;
}
.case-two ul {
position: relative;
font-size: 0px;
}
.case-two-a ul {
line-height: 1;
}
.case-two-b ul {
line-height: 25px;
}
.case-two li {
display: inline;
font-size: 12px;
line-height: 25px;
}
<section>
<div class="container case-one">this I fully understand</div>
<div class="reference">case one</div>
<br/>
<br/>
<div class="container case-one">
<div style="background-color: rgba(50,50,200,0.4); width:8px;height: 12px; position: absolute;"></div>
<ul>
<li>but</li>
<li>not this.</li>
<li>why is the ul offset?</li>
<li>why by font-size, not line-height?</li>
</ul>
</div>
<div class="reference">case one b</div>
<div class="container case-two case-two-a">
<ul>
<li>why does</li>
<li>setting the ul font-size to 0 work?</li>
</ul>
<div style="line-height: 1.2;">also, why does the ul line-height have to be set to 1? If it is set to 25px, the ul grows, see below</div>
</div>
<div class="reference reference-two">case two</div>
<div class="container case-two case-two-b">
<div style="background-color: rgba(50,50,200,0.4);left:4px;width:8px; height: 30px; position: absolute;"></div>
<div style="background-color: rgba(50,200,50,0.4);width:8px; height: 29px; position: absolute;left:16px;"></div>
<div style="background-color: rgba(200,50,50,0.4);width:8px; height: 28px; position: absolute;left:28px;"></div>
<ul>
<li>why does</li>
<li>setting the ul line-height to 25px result in it being 30px high?</li>
</ul>
<div style="line-height: 1.4;margin-top: 8px;">where does the 5px come from?? Why is it 4px on chrome? Why is it 3px on firefox? Anyone else get any other heights, lol?</div>
</div>
<div class="reference reference-two-b">case two</div>
</section>
是不是因为要去掉默认的margin
?
ul{
margin:0;
}
看到这个Fiddle
是的。您需要的心智模型是 strut。这似乎是 CSS 最好的秘密,这很不幸,因为它对于理解案例二和许多类似行为至关重要。找出支柱的位置和高度,许多布局行为开始变得有意义。
首先,案例一。浏览器将 ul 元素的默认顶部(和底部)边距定义为字体大小的比例。不同的浏览器可以自由设置他们想要的任何比例,因此某种重置或规范化是司空见惯的。
现在案例二,回到支柱。仅包含行内级元素的块盒由一堆行盒组成。每个行框都以一个零宽度的虚拟内联元素开始——strut。现在,行高只影响行内元素。但是当您设置块元素的行高时,每个子元素(包括支柱)都会继承该行高。您可以覆盖真正的子元素的行高,但不能覆盖 strut。
所以当你说 ul { font-size:0; line-height:1; }
时,这意味着支柱的高度将是 0px 乘以系数 1 = 0px,所以无论支柱在哪里,它都不会占用 space .
但是,当您说 ul { line-height:24px; }
时,这意味着支柱的有效高度将为 24px。内联元素的行高通过在元素字符的上方和下方添加 space 来影响它们所在文本行的高度。因此,如果字符高 18px,行高为 24px,则要添加的额外 space 为 6px。这叫做leading。行距的一半添加在元素上方,一半添加在元素下方。这些被称为 half-leading.
因此,如果您有 ul { font-size:0; line-height:24px; }
,每行文本的支柱的字符大小为 0,但上下半行距为 12px。但是其他元素的字符大小不为零。如果他们的字体 em 大小是 12px,这可能取决于字体,给使用的字符高度 16px(比如基线以上 13px 和基线以下 3px)。所以他们将领先一半 (24px - 16px) / 2 = 4px
.
但除了他们的高度,您还必须考虑他们的垂直对齐方式。支柱始终是“vertical-align:baseline”,并在此基础上与该行文本上的其他内联元素对齐。
为简单起见,我们假设其他文本元素也是 vertical-align:baseline
。
那么文本行的总行高是基线以上的最大高度 max(13px + 4px (character), 12px (strut)
加上基线以下的最大高度 max(3px + 4px (character), 12px (strut)
。这是 17px + 12px = 29px
,因此超过了指定的 24px 行高。
Lister 先生在 an answer to a related question
中提供了一些有用的图表