为什么 flexbox 会影响其包含列表项的标记?
Why does flexbox affect its containing list-item's marker?
知道后,我用容器包裹我的内容,然后将容器放入<li />
。
有内容的元素一切顺利。
但是,如果容器中的第一个元素没有子节点,<li />
的标记意外位于底部。
虽然在我的情况下我可以简单地添加一个 display: none
来解决问题,但我仍然感到困惑:
flexbox中的内容如何影响它的祖父节点?
示例:(标记 1.
位于 <li />
的右下角)
.flex { display: flex; }
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
相关问题:
CSS伪元素::marker
在流行的浏览器中没有实现,只有Firefox支持@counter-style。目前建议在 <ol />
中实现用户定义的标记是什么? (我看到有些人使用 ::before
这样做,目的是让用户不要复制标记的文本。但我不知道它是否好。)
我不确定您要在元素内使用 flexbox 来完成什么,但是 display flex 内的空元素会塌陷,因此会产生奇怪的影响。您可以通过使用 flex: number
或 flex-basis: 50px
给元素一个 "size" 来解决这个问题
我会避免使用 ::marker
属性,因为它有 horrific support 并且只需使用 css 计数器创建您自己的属性。
这是一个例子:
ol {
display:block;
width: 30em;
list-style: none;
counter-reset: counterName;
}
li {
padding-left: 2em;
padding-bottom: 1em;
border-bottom: 1px solid #ccc;
margin-bottom: 1em;
position: relative;
counter-increment: counterName;
}
li:before {
content:'#' counter(counterName);
position: absolute;
left:0;
top:0;
}
.flex {
display:flex;
justify-content: space-between;
flex-wrap:no-wrap;
}
.flex > * {
flex: 1;
}
<ol>
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
要解决这个问题,只需将对齐方式调整为基线:(最后的另一个解决方案)
.flex {
display: flex;
align-items:baseline;
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
为了更好地理解正在发生的事情(基于我自己的解释)让我们为空元素添加一些宽度和背景:
.flex {
display: flex;
}
div:empty {
width:30px;
background:red;
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
由于默认对齐,空元素被拉伸,然后数字旋转与其底部对齐。
如果你increase/decrease身高你会更好地注意到这个
.flex {
display: flex;
}
div:empty {
width:30px;
background:red;
animation:change 5s linear infinite alternate;
}
@keyframes change {
from {
height:5px;
}
to {
height:80px;
}
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
如果您将第一个弹性项目中的 inline-block
元素设置为 overlow:hidden
(使其基线成为底部边框)
,也会发生这种情况
.flex {
display: flex;
}
div:empty {
width:30px;
background:red;
}
.inline-block {
display:inline-block;
height:50px;
background:green;
width:50px;
overflow:hidden;
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div><div class="inline-block">some text </div></div>
<div>TITLE</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
基本上,numerotation 试图与第一项的基线对齐。如果你增加第一项的 font-size
我们也可以注意到这一点:
.flex {
display: flex;
}
.size {
animation:change 5s linear infinite alternate;
}
@keyframes change {
from {
font-size:5px;
}
to {
font-size:30px;
}
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div class="size">TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
正如您已经注意到的,只有当它是关于第一个项目时才会发生这种情况,这使得它有点复杂并且不容易解释:
.flex {
display: flex;
}
div:empty {
width:30px;
background:red;
}
.inline-block {
display:inline-block;
height:50px;
background:green;
width:50px;
overflow:hidden;
}
<ol style="width: 15em">
<li>
<div class="flex">
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
<div></div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div><div class="inline-block">some text </div></div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
除了更改对齐方式之外的另一个解决方法是考虑在 flexbox 容器内使用一个伪元素,它将成为我们的第一个 flex 项目,从而避免与我们的 real 元素进行任何交互。
诀窍是不要让该元素为空,但至少要有一个内容。我使用了零宽度 space 字符 0B
:
.flex {
display: flex;
}
.flex:before {
content:"0B"; /*a non collapsible white space*/
}
div:empty {
width:30px;
background:red;
animation:change 5s linear infinite alternate;
}
@keyframes change {
from {
height:5px;
}
to {
height:80px;
}
}
.size {
color:green;
animation:size 5s linear infinite alternate;
}
@keyframes size {
from {
font-size:5px;
}
to {
font-size:20px;
}
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div class="size">TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
知道<li />
。
有内容的元素一切顺利。
但是,如果容器中的第一个元素没有子节点,<li />
的标记意外位于底部。
虽然在我的情况下我可以简单地添加一个 display: none
来解决问题,但我仍然感到困惑:
flexbox中的内容如何影响它的祖父节点?
示例:(标记 1.
位于 <li />
的右下角)
.flex { display: flex; }
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
相关问题:
CSS伪元素::marker
在流行的浏览器中没有实现,只有Firefox支持@counter-style。目前建议在 <ol />
中实现用户定义的标记是什么? (我看到有些人使用 ::before
这样做,目的是让用户不要复制标记的文本。但我不知道它是否好。)
我不确定您要在元素内使用 flexbox 来完成什么,但是 display flex 内的空元素会塌陷,因此会产生奇怪的影响。您可以通过使用 flex: number
或 flex-basis: 50px
我会避免使用 ::marker
属性,因为它有 horrific support 并且只需使用 css 计数器创建您自己的属性。
这是一个例子:
ol {
display:block;
width: 30em;
list-style: none;
counter-reset: counterName;
}
li {
padding-left: 2em;
padding-bottom: 1em;
border-bottom: 1px solid #ccc;
margin-bottom: 1em;
position: relative;
counter-increment: counterName;
}
li:before {
content:'#' counter(counterName);
position: absolute;
left:0;
top:0;
}
.flex {
display:flex;
justify-content: space-between;
flex-wrap:no-wrap;
}
.flex > * {
flex: 1;
}
<ol>
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
要解决这个问题,只需将对齐方式调整为基线:(最后的另一个解决方案)
.flex {
display: flex;
align-items:baseline;
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
为了更好地理解正在发生的事情(基于我自己的解释)让我们为空元素添加一些宽度和背景:
.flex {
display: flex;
}
div:empty {
width:30px;
background:red;
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
由于默认对齐,空元素被拉伸,然后数字旋转与其底部对齐。
如果你increase/decrease身高你会更好地注意到这个
.flex {
display: flex;
}
div:empty {
width:30px;
background:red;
animation:change 5s linear infinite alternate;
}
@keyframes change {
from {
height:5px;
}
to {
height:80px;
}
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
如果您将第一个弹性项目中的 inline-block
元素设置为 overlow:hidden
(使其基线成为底部边框)
.flex {
display: flex;
}
div:empty {
width:30px;
background:red;
}
.inline-block {
display:inline-block;
height:50px;
background:green;
width:50px;
overflow:hidden;
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div><div class="inline-block">some text </div></div>
<div>TITLE</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
基本上,numerotation 试图与第一项的基线对齐。如果你增加第一项的 font-size
我们也可以注意到这一点:
.flex {
display: flex;
}
.size {
animation:change 5s linear infinite alternate;
}
@keyframes change {
from {
font-size:5px;
}
to {
font-size:30px;
}
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div class="size">TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
正如您已经注意到的,只有当它是关于第一个项目时才会发生这种情况,这使得它有点复杂并且不容易解释:
.flex {
display: flex;
}
div:empty {
width:30px;
background:red;
}
.inline-block {
display:inline-block;
height:50px;
background:green;
width:50px;
overflow:hidden;
}
<ol style="width: 15em">
<li>
<div class="flex">
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
<div></div>
</div>
</li>
<li>
<div class="flex">
<div>TITLE</div>
<div><div class="inline-block">some text </div></div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>
除了更改对齐方式之外的另一个解决方法是考虑在 flexbox 容器内使用一个伪元素,它将成为我们的第一个 flex 项目,从而避免与我们的 real 元素进行任何交互。
诀窍是不要让该元素为空,但至少要有一个内容。我使用了零宽度 space 字符 0B
:
.flex {
display: flex;
}
.flex:before {
content:"0B"; /*a non collapsible white space*/
}
div:empty {
width:30px;
background:red;
animation:change 5s linear infinite alternate;
}
@keyframes change {
from {
height:5px;
}
to {
height:80px;
}
}
.size {
color:green;
animation:size 5s linear infinite alternate;
}
@keyframes size {
from {
font-size:5px;
}
to {
font-size:20px;
}
}
<ol style="width: 15em">
<li>
<div class="flex">
<div></div>
<div>When an element without content is preceding, the ::marker of the list-item is located at the bottom.</div>
</div>
</li>
<li>
<div class="flex">
<div class="size">TITLE</div>
<div>If there's content in the first element, then it goes as expected.</div>
</div>
</li>
<li>
<div class="flex">
<div>It's also fine if there's only one child here.</div>
</div>
</li>
</ol>