为什么flexbox会影响其包含列表项的标记?

时间:2019-01-31 17:33:47

标签: css css3 flexbox listitem

知道了a list-item element cannot be display: flex at the same time之后,我用容器包装了内容,然后将容器放入<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来这样做,以使用户不要复制标记的文本。但是我不知道它是否好。)

2 个答案:

答案 0 :(得分:4)

我不确定您要使用元素内部的flexbox尝试做什么,但是display flex内部的空元素会折叠下来,因此会产生奇怪的影响。您可以通过使用flex: numberflex-basis: 50px

为元素赋予“大小”来解决此问题

我会避免使用::marker属性,因为它具有exporting,而只是使用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>

答案 1 :(得分:2)

要解决该问题简单地调整对齐为基线: (末尾的另一解决方案)

.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>

在空元件,因为默认取向拉伸,然后在numerotation与其底部对齐。

如果增加/减小高度,您会更好地注意到这一点

.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>

基本上,加注法试图与第一个项目的基线对齐。如果您增加第一项的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的容器内的伪元件,这将是我们的第一挠性项因而我们避免与任何交互提供了元素。

诀窍是不要使该元素为空,但至少要包含一个内容。我使用了零宽度空格字符\200B

.flex {
  display: flex;
}
.flex:before {
  content:"\200B"; /*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>