内容列表项中的Flexbox未与列表项的顶部对齐

max*_*son 19 html css css3 flexbox

将flexbox放在列表项中会导致内容被看起来是整行高度推下来.

我一直在玩不同的CSS属性,比如给flexbox margin-top: 0,它的孩子margin-top:0,添加flex-wrap到flexbox等等.没有骰子!

.wrapper {
  display: flex;
}
li {
  background: #ccc;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <div class="wrapper">
      <div>hello</div>
      <div>world</div>
    </div>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

codepen

Ori*_*iol 14

这似乎是由于::marker伪元素.

我不确切知道应该发生什么,因为这是各种规格的重叠

这是有问题的,因为它们是尚未准备好实施的提案.例如,请参阅CSS列表3 - 定位标记中的警告,这也与此问题相关:

本节尚未准备好实施.这是一个未经审查的草稿,甚至没有经过适当的Web兼容性检查.随意发送反馈,但不要使用该规范的这一部分.

以下是我对Chrome如何处理标记的猜测.

首先,让我们list-style-position: inside在列表项上使用simpler ,并让它包含一个块:

ul {
  list-style-position: inside;
}
li {
  border: 1px solid blue;
}
div {
  border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <div>Hello<br />world</div>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

Chrome会像这样显示:

在此输入图像描述

请注意,标记与div重叠,但缩小其第一个行框.这种行为是典型的花车!

float不应与格式化上下文根重叠.例如,display: inline-block建立块格式化上下文.

ul {
  list-style-position: inside;
}
li {
  border: 1px solid blue;
}
div {
  display: inline-block;
  border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <div>Hello<br />world</div>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

所以像浮子一样,标记将其推向右侧,以防止重叠.

但请注意标记是垂直对齐的.并且建立块格式化上下文overflow: hidden不会阻止重叠.

ul {
  list-style-position: inside;
}
li {
  border: 1px solid blue;
}
div {
  overflow: hidden;
  border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <div>Hello<br />world</div>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

所以它有一些类似浮动的行为,但它不是浮动的.

我的猜测是Chrome不断迭代列表项中的第一个框,然后是其中的第一个框,依此类推,直到第一个框不再是一个块.然后它在它之前插入标记,显示内联级别(可能inline-block).像这样的东西:

var deepestFirstBlock,
    child = listItem;
do {
  deepestFirstBlock = child;
  child = deepestFirstBlock.firstBoxChild;
} while (child.style.display == 'block');
deepestFirstBlock.insertBefore(marker, deepestFirstBlock.firstBoxChild);
Run Code Online (Sandbox Code Playgroud)

事实并非如此,因为如果direction最深的第一个块是从右到左,则标记将插入第一行的最后一个框之后.

因此,正如Michael_B所注意到的那样,当你设置内部容器的样式时,display: inline-flex没有空的空间.这是因为标记在它之前插入,并且因为它们都是内联级别,所以它们并排显示.

ul {
  list-style-position: inside;
}
li {
  border: 1px solid blue;
}
div {
  display: inline-flex;
  border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <div>Hello<br />world</div>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是display: flex容器是块级的.所以它被迫转到下一行.然后空的空间是标记,它占据第一个线框.

ul {
  list-style-position: inside;
}
li {
  border: 1px solid blue;
}
div {
  display: flex;
  border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <div>Hello<br />world</div>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这不会发生display: block,也是块级,因为标记插入其中.我想标记没有插入块级flex容器中,因为它会成为一个flex项目,它可能会产生一个奇怪的布局.

当您使用初始值时list-style-position: outside,Chrome似乎只对标记应用某种负水平边距,以便下面的框(插入标记之前的第一个框)在容器的左侧对齐,就像插入标记之前一样.也许标记也会浮动,因为列表项中的浮动内容不再能够出现在其左侧.

但是,这个负边距将不允许块级flex容器上升.这就是为什么空间仍然存在,即使标记不再存在.

请注意,这与当前未经审查的粗略草案相矛盾,该草案尚未准备好实施,其中标记list-style-position: outside应该具有position: marker,和

position: marker计数绝对定位的元素.

绝对定位的元素被取出流动并与元素重叠,因此我应该将flex容器移到顶部.

Firefox似乎做了一些更简单的事情.使用list-style-position: inside,它只是将标记作为列表项的第一个(内联级别)框插入.它不会尝试迭代块以在尽可能深的水平插入标记.

然而,list-style-position: outside就像草案所说的那样,它可能会使标记流出.这就是为什么你没有在Firefox中看到空间的原因.

  • 我认为考虑到现有信息,这是最好的解释.谢谢.(我将让赏金继续运行,但如果得到更好的答案,将会非常惊讶.) (4认同)

Mic*_*l_B 8

解决方案

如果您切换.wrapperdisplay: flexinline-flex,问题得到解决(演示).

如果设置list-style-typenone,则问题已解决(评论中为@Ricky_Ruiz)(演示).

浏览器行为

Chrome,Edge和IE11中存在此问题.原始代码在Firefox和Safari中运行良好.

说明

我目前还不确定导致这种行为的原因.

出于某种原因(显然是标记),顶部li是禁区.父母不允许孩子进入该区域.

(更新: 另一个答案中提供了详细解释.)

在测试中......

  • 我删除padding,并marginul和后代.它没有帮助.
  • 我玩过line-heightvertical-align.也没有帮助.

通过为所有元素设置相等的高度,很明显有些东西迫使Flex容器渲染低于预期,并溢出父级.

ul {
  padding: 0;
  margin: 0;
  height: 100px;
  border: 1px solid black;
}
li {
  padding: 0;
  margin: 0;
  background: #ccc;
  height: 100%;
}
.wrapper {
  display: flex;
  padding: 0;
  margin: 0;
  height: 100%;
  border: 1px dashed red;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>
    <div class="wrapper">
      <div>hello</div>
      <div>world</div>
    </div>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

修改后的codepen