在CSS Grid中定位伪元素

3
我正在尝试在网格上定位伪元素,根据规范应该是可能的。对于我设置在<body>上的外部布局来说,这非常有效,但对于<header>本身作为网格时则不起作用。
如何将标题nav:after元素定位在网格的右侧列?为什么在我的示例中无法正常工作?
我感激任何帮助!以下是代码:

body {
  display: grid;
  grid-template-columns: 1fr 800px 1fr;
}
header {
  grid-column: 1 / 4;
  grid-row: 1;

  display: grid;
  grid-template-columns: 1fr 800px 1fr;
}

/* Works great */
header:before {
  content: 'Left';
  grid-column: 1 / 2;
}

/* Doesn't work, treated as a child element */
header nav:after {
  content: 'Right';
  grid-column: 3 / 4;
}
header nav {
  grid-column: 2 / 3;
}
<body>
  <header>
    <nav>
    <ul>
      <li><a href='#'>Link</a></li>
      <li><a href='#'>Link</a></li>
      <li><a href='#'>Link</a></li>
    </ul>
    </nav>
  </header>
</body>    

谢谢!
2个回答

3

nav:afternav的一个子元素。所以你也需要将nav设为网格布局——目前它还不是。

或者你可以使用header:after代替nav:after——请参见下面的演示:

body {
  display: grid;
  grid-template-columns: 1fr 800px 1fr;
}

header {
  grid-column: 1 / 4;
  grid-row: 1;
  display: grid;
  grid-template-columns: 1fr 800px 1fr;
}


/* Works great */

header:before {
  content: 'Left';
  grid-column: 1 / 2;
}


/* CHANGED THIS*/

header:after {
  content: 'Right';
  grid-column: 3 / 4;
}

header nav {
  grid-column: 2 / 3;
}
<header>
  <nav>
    <ul>
      <li><a href='#'>Link</a></li>
      <li><a href='#'>Link</a></li>
      <li><a href='#'>Link</a></li>
    </ul>
  </nav>
</header>


你好kukkuz,感谢你的回答!从我在标题示例中看到的内容来看,header:before元素实际上是body的子元素,否则我就无法将其定位在左侧,对吗?我正在尝试实现相同的效果,我需要ul元素具有:before或:after伪元素,但需要将其定位在右侧。然而,我看不出这种情况有什么不同?为什么它不能以同样的方式工作? - Sebastian
1
"header: before" 是 "header" 的子元素...":after" 和 ":before" 伪元素是应用于元素的子元素... - kukkuz
请纠正我,如果我错了的话。看下面的简单示例。如果我可以将 :before 定位在 body 的网格上,header:before 现在必须是 body 的子元素,也是 header 的同级元素。我认为这也是以下规范所说的:https://developer.mozilla.org/zh-CN/docs/Web/CSS/:before。body { display: grid; grid-template-columns: 1fr 800px 1fr; } header { grid-column: 1 / 4; grid-row: 1; } header:before { content: 'Left'; grid-column: 1 / 2; }
- Sebastian
我的问题是,为什么导航栏的工作方式也是一样的呢? - Sebastian
2
@Sebastian,很抱歉,你的猜测是错误的。如果你尝试将headerheader:before放置在body的网格的不同行中,就可以证明这一点。你的示例“看起来像”headerheader:before共享相同的body网格区域,因为header:beforeheader的“内容”的一部分。你可以使用Firefox Devtools中的Grid Inspector工具查看它。你提供的文档不是规范,而是旧版Firefox的发布说明,与网格无关。事实上,:before是元素的子元素。 - Ilya Streltsyn

1

网格容器中的伪元素被视为容器的子元素。参考资料:

因此,除非伪元素是绝对定位的,否则它是一个网格项。参考资料:

这是基于您的代码的演示:

body {
  display: grid;
  grid-template-columns: 1fr 300px 1fr;
  text-align: center;
  border: 1px solid black;
}

body::before {
  content: "pseudo - \a left sibling \a of header";
  white-space: pre;
  grid-column: 1 / 2;
  background-color: salmon;
}

body::after {
  content: "pseudo - \a right sibling \a of header";
  white-space: pre;
  grid-column: 3 / 4;
  background-color: lightgreen;
}

header {
  grid-column: 2 / 3;
  background-color: yellow;
  padding: 5px;
  display: grid;
  grid-template-columns: 1fr 100px 1fr;
  grid-gap: 5px;
}

header nav {
  grid-column: 2 / 3;
  border: 1px dashed red;
}

header::before {
  content: "pseudo - \a left sibling \a of nav";
  white-space: pre;
  grid-column: 1 / 2;
  border: 1px dashed red;
}

header::after {
  content: "pseudo - \a right sibling \a of nav";
  white-space: pre;
  grid-column: 3 / 4;
  border: 1px dashed red;
}
<body>
  <header>
    <nav>
      <ul>
        <li><a href='#'>Link</a></li>
        <li><a href='#'>Link</a></li>
        <li><a href='#'>Link</a></li>
      </ul>
    </nav>
  </header>
</body>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接