【问题标题】:Children don't inherit style despite declaration on ancestor尽管声明了祖先,但孩子们不会继承风格
【发布时间】:2022-12-26 04:53:57
【问题描述】:

我在 body 上声明了 display: inline,但元素仍然以块方式显示。请帮助我理解这个概念。

直接在li 上声明display: inline 有效:它们将以内联方式显示。但是为什么在 body 上声明时内联不应用于它们?

body {display: inline}
<body>
  <ul>
    <li>1234</li>
    <li>5678</li>
  </ul>
</body>

我也尝试在li 上使用display: inherit,但它仍然以块方式显示,并且还删除了我不想要的标记:

body {display: inline}
li {display: inherit}
<body>
  <ul>
    <li>1234</li>
    <li>5678</li>
  </ul>
</body>

【问题讨论】:

  • display 未继承:将 &lt;BODY&gt; 设置为 display: inline 不会影响其子项的 display 值。
  • 如果我想内联显示所有孩子的显示值都可以继承,那么代码是什么?我试过 <style> body { display: inline; } li { 显示:继承; } </style> 但它仍然显示在 BLOCK 中

标签: html css


【解决方案1】:

继承display

在元素上设置 display将不会让它的孩子继承价值:

.wrapper {display: inline}
<div class="wrapper">
  <div>First text.</div>
  <div>Second text.</div>
</div>

虽然您可以声明元素从其祖先那里继承display我不推荐这(通常):

  • 声明要继承display 的元素与声明特定的display 值一样需要声明。
  • 如果选择器太不明确,具有合理默认值的元素将丢失这些值。

为您的用例选择好的选择器很重要。对于您的简短示例,使用 universal selector *descendant combinator 是很好的通用选择器,例如 body *(换句话说:“BODY 的所有后代”)。

笔记:通常使用组合器不是选择“子选择”本身,例如选择器body *BODY不是被选中。另请注意后代组合子不如child combinator &gt;具体。

这是一个类似的例子:

.wrapper * {display: inline}
<div class="wrapper">
  <div>First text.</div>
  <div>Second text.</div>
</div>

但是,如果您仍想将元素声明为继承display,这是一个例子:

.wrapper {display: inline} /*Set the value to inherit*/
.wrapper * {display: inherit}
<div class="wrapper">
  <div>First text.</div>
  <div>Second text.</div>
</div>

列表和display

列表的默认display值为block,其子项的值为 (LI) 是list-item。如果您只是想摆脱标记,请声明列表list-style-type: none

ul {list-style-type: none}
<ul>
  <li>First item.
  <li>Second item.
</ul>

但您也可以将列表及其子列表 (ul, ul&gt;*) 声明为 display: inline。请注意,删除填充需要另一个声明。

ul, ul&gt;* {display: inline}
<ul>
  <li>First item.
  <li>Second item.
</ul>

带标记的内联列表

如果你想用标记内联列表项,有几种可能性:

您可以通过声明 list as display: inline-flex 来保留 ::markers 个内联列表项。

边注:::markers 默认为 outside 列表项的 principal box,这意味着它们可以阻挡其他框的视图。将列表(或其项)声明为 list-style-position: inside 以将标记保留在列表项的框中以防止此类溢出。

笔记flex-wrap: nowrap 是它的默认值,这与常规文本流不同。使用 flex-wrap: wrap 让列表项(及其内容)像常规文本一样流动:

// Ignore; for handling radio inputs
const form = document.querySelector("form");
const list = document.querySelector("ol");
form.addEventListener("input", evt => {
  const className = evt.target.name === "position" ? "inside" : "wrap";
  // Classes for applying non-default values are named after the values
  const state = evt.target.value === className;
  
  list.classList.toggle(className, state);
});
ol {display: inline-flex}
.inside {list-style-position: inside}
.wrap {flex-wrap: wrap}

/*Ignore; for presentational purposes*/
ol {margin: 0; padding: 0}
li {border: 1px solid darkgray}
section {margin-block: 1.2rem}
<form>
  <div>
    List type:
    <label for="i-outside">
      <input id="i-outside" name="position" type="radio" value="outside" checked> Outside
    </label>
    <label for="i-inside">
      <input id="i-inside" name="position" type="radio" value="inside"> Inside
    </label>
  </div>
  <div>
    Wrapping:
    <label for="i-nowrap">
      <input id="i-nowrap" name="wrap" type="radio" value="nowrap" checked> No-wrap
    </label>
    <label for="i-wrap">
      <input id="i-wrap" name="wrap" type="radio" value="wrap"> Wrap
    </label>
  </div>
</form>

<ol>
  <li>A very long named item that hopefully overflows its box, and
  <li>An item, and
  <li>Another short item, and
  <li>another very long named item that too should overflow its box.
</ol>

您还可以通过::beforepseudo-element使用自定义“标记”。

边注:使用custom-styledCSS counter,您可以重新创建例如list-style-type: georgian专柜:

ol {counter-reset: li-counter}
li {counter-increment: li-counter}
li::before {content: counter(li-counter)". "}

/*Ignore; for presentational purposes*/
ol, li {padding: 0; display: inline}
A list consisting of
<ol>
  <li>one item and
  <li>another item.
</ol>

列表项不继承display

您问为什么以下没有导致 LIs 继承 BODYdisplay 值:

body {display: inline}
li {display: inherit}
<body>
  <ul>
    <li>First item.
    <li>Second item.
  </ul>
</body>

那是因为——BODY声明为display: inline——中间列表的默认display值为block。由于继承是从元素的直接祖先发生的,因此列表项将从列表中继承值block

Accessibility concern

列表是语义元素,默认情况下由浏览器解释。但是改变它们的样式可能会改变浏览器解释它们的方式,可能会将它们的语义减少到一个通用的包含文本的元素。

因此,通过ARIA-attributerole分别将列表及其项目声明为listlistitem,通常可以确保列表被解释为列表。这个否决浏览器决定将元素解释为列表,即使浏览器会因为某些 CSS 而决定不将其解释为列表。

另一点是伪元素(例如::marker::before)在技术上不是文档的一部分,因此不能与之交互(例如selecting or copying)。如果您需要将它们作为文档的一部分,则将它们直接包含在文档中。

【讨论】:

  • 如果我需要标记和内联方法,我该如何编码?参考 ul,ul * {display: inline;列表样式类型:乔治亚; } <ul> <li>第一项。 <li>第二项。 </ul>
  • @JamesC 有关更多详细信息,请参阅我的编辑:您可以使用display: inline-flex,或带有伪元素的模拟标记,如::before
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 2022-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
相关资源
最近更新 更多