【问题标题】:Align child elements at inner grid lines在内部网格线对齐子元素
【发布时间】:2019-12-15 11:28:49
【问题描述】:

我有一个简单的三列 CSS 网格布局。我需要让第一行的背景延伸到整个轨道,但将子元素对齐内部网格线,就像标准导航栏与它后面的内容对齐一样。我正在使用以下代码,但一次只能完成我的一个要求(要么让背景颜色伸展,将子元素向左移动,要么让子元素位于正确的位置,但未能背景颜色穿过):

body {
  display: grid;
  grid-template: 
           "nav   nav   nav" 
           " .  content  . "
}

nav {
  background-color: lightblue;
  grid-area: nav;
}

nav ul {
  display: flex;
  list-style: none;
}

main {
  grid-area: content;
}
<nav>
  <ul>
    <li>item 1</li>
    <li>item 2</li>
  </ul>
</nav>

<main>
  <h1>content</h1>
</main>

据我了解,在使用 CSS 网格布局时,我只能放置网格容器的直接子元素。换句话说,我可以放置nav,但不能放置nav ul。想必,CSS Grid Layout Module Level 2 会解除这个限制,让这件事变得微不足道。但我需要一个适用于今天的解决方案。

鉴于以下限制,我将如何处理:

  • 解决方案必须是纯 CSS(无 JavaScript 或框架)。
  • 它必须是可维护的,例如如果我决定更改第一列的宽度,我不想更改两段(或更多段)代码。
  • 解决方案不必是通用的;我真的只需要在一行中使用一种纯色,以防万一。

更新:

阅读我意识到的答案,我的措辞太草率了。我问的和我想问的不一致。我正在寻找一个基于 CSS 网格布局的解决方案,复制以下“传统”实现:

nav {
  background-color: lightblue;
}

.container {
  margin: auto;
  width: 80vw;
}
<nav>
  <div class="container">
    <a>item</a>
    <a>item</a>
  </div>
</nav>

<main>
  <div class="container">
    <p>content</p>
  </div>
</main>

我需要导航栏的背景颜色覆盖父元素的整个宽度,但&lt;nav&gt;&lt;main&gt;的实际内容在同一水平位置左对齐。

【问题讨论】:

  • 类似这样的东西:stackoverflow.com/a/53554204/8620333?
  • @tem:这似乎总是覆盖整个视口宽度,所以这只有在布局也用完整个视口宽度时才有效。我现在将使用它,但它并没有完全涵盖我的用例。

标签: css css-grid


【解决方案1】:

请注意您的 main 元素是一个具有 HTML5 语义意义的容器,它消除了对 HTML5 之前常见的 div 容器的需求。

<!-- valid and efficient structure -->
<main>
  <h1>content</h1>
</main>

<!-- valid but inefficient structure -->
<main>
  <div>
     <h1>content</h1>
  </div>
</main>

您为什么不在导航栏上应用同样的原则?

有了 HTML5 nav 标签可用,为什么要使用列表项?

而不是这个:

<nav>
   <ul>
      <li>item 1</li>
      <li>item 2</li>
   </ul>
</nav>

这样做:

<nav>
   <a>item 1</a>
   <a>item 2</a>
</nav>

这为您提供了至少三个好处:

  1. 一个干净且具有语义意义的元素,
  2. 属于 Grid 父子关系范围的 HTML 结构,以及
  3. 使用一个嵌套网格,占用与父网格相同的空间,您可以沿网格线对齐您的项目。

body {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-areas: " nav nav nav " 
                       " . content . "
}

nav {
  grid-area: nav;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background-color: lightblue;
}

main {
  grid-area: content;
}
<nav>
  <a>item 1</a>
  <a>item 2</a>
  <a>item 3</a>
</nav>

<main>
  <h1>content</h1>
</main>

还有其他方法可以实现您的布局,上面的代码概念可以应用于您的原始 HTML 结构(只需添加另一个嵌套网格)。我只是把它作为一种希望有用的方法提出来。

【讨论】:

  • 这很有见地,谢谢。我没有意识到,我可以将&lt;nav&gt; 本身用作容器。我几天前刚开始学习 HTML/CSS,有很多历史背景需要介绍。这种方法虽然有用,但我试图避免。事实上,这就是第二个要求所要防范的。
  • 那么你可能需要等待subgrid feature的执行。
【解决方案2】:

您的问题来自于您的 grid 样式在 body 标记上。将它们向下移动到您要格式化的各个部分:

main,
header ul.menu {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

main .content {
  grid-column: 2/3;
}

header ul.menu {
  list-style: none;
  padding: 0;
  margin: 0;
  background-color: lightblue;
}

header ul.menu li {
   margin: 1em;
}

header ul.menu li:not(:first-child){
   margin-left: 0;
}
<header>
  <nav>
    <ul class="menu">
      <li>item 1</li>
      <li>item 2</li>
    </ul>
  </nav>
</header>

<main>
  <div class="content">
    <h1>content</h1>
  </div>
</main>

【讨论】:

  • 这不会按照指定的方式沿内部网格线对齐项目。它只是将它们分散到整个行中。
  • 是的。这与我的回答中的概念相同:将网格移近项目。除了我没有删除顶级网格,因为我不知道它是否需要用于其他目的。
  • @Michael_B 很接近了。如果你再看看你的,你会嵌套两个网格,这会导致你的项目不完全对齐。
  • 感谢您指出这一点。问题不在于嵌套网格。它是顶级网格列(默认)设置为auto,嵌套网格列(由我设置)为1fr。我修好了它。现在都排好了。
  • @Michael_B 不客气。我仍然不建议使用相同的布局嵌套网格,因为这样做会产生望远镜效果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-24
  • 2014-04-01
  • 2020-06-27
相关资源
最近更新 更多