跨越 higher-level 个容器的边界

Make a border span across higher-level containers

我想在我的标题上有一个打破网格的底部边框。有 3 列,左、中、右,我的标题和内容在中间。我想让底部边框一直延伸到左栏的左侧。有没有比我在下面想出的更好的方法来做到这一点? CSS 网格是否提供了 built-in 机制来执行此类操作?我将不胜感激任何建议。

.grid-container {
  padding: 10px;
  display: grid;
  grid-template-columns:  [start] 1fr  [middle] 4fr  [end] 1fr ;
  
  grid-gap: 1rem;
  background-color: #fff;
  color: #444;
}

.start {
  grid-column: start;
  background-color: #ccc;
}

.middle {
  grid-column: middle;
}
.title {
  
 }
.title:after {
  content: '';
  display: block;
  border-bottom: 1px solid red;
  margin-left: calc(-25% - 1rem);
}
 
 .end {
   grid-column: end;
   background-color: #ccc;
 }
<div class="grid-container">
    <div class="start">Start</div>
    <div class="middle">
      <h2 class="title">My Title</h2>
      <div class="content">Some text lorem ipsum, whatever.</div>
    </div>
    <div class="end">End</div>
</div>

您的负边距方法似乎有效。有点笨拙,但似乎仍然有效。

您还可以使用绝对定位 将边框对齐到标题下方。容器将是边界框(即 position: relative)。但这也有点笨拙。

如果您想要纯网格解决方案,那也是可以的。我想出的方法干净有效。有些人可能认为它对于一个简单的边框来说有点矫枉过正,但您的需求有些独特,所以这可能会有用。

基本概念如下:

  • 将容器分成 100 小行 (1px)。
  • 让您现有的网格项目从上到下跨越这些行。
  • 现在您回到了原来的布局,但内部进行了升级。
  • 您现在有 100 个边界线位置。
  • 创建一个新的网格项(DOM 或 pseudo-element)。
  • 将项目横跨您标题下的行。
  • 瞧! :-)

.grid-container {
  padding: 10px;
  display: grid;
  grid-template-columns:  [start] 1fr  [middle] 4fr  [end] 1fr ;
  grid-template-rows: repeat(100, 1px);        /* new */
  grid-column-gap: 1rem;                       /* adjusted; removed grid-row-gap */
  background-color: #fff;
  color: #444;
}

.start {
  grid-column: start;
  background-color: #ccc;
  grid-row: 1 / -1;                            /* new */
}

.middle {
  grid-column: middle;
  grid-row: 1 / -1;                            /* new */
}
 
 .end {
   grid-column: end;
   background-color: #ccc;
   grid-row: 1 / -1;                           /* new */   
 }
 
.grid-container::after {                       /* new */
   content: "";
   background-color: red;
   grid-row-start: 47;
   grid-column: 1 / 3;
}
<div class="grid-container">
    <div class="start">Start</div>
    <div class="middle">
      <h2 class="title">My Title</h2>
      <div class="content">Some text lorem ipsum, whatever.</div>
    </div>
    <div class="end">End</div>
    <div class="border"></div>
</div>

jsFiddle demo

另一种方法,基于与 Micheael_B 相同的想法,"you need more rows"。

你可以做的是将中间部分分成三部分。标题、边框、内容。 您可以按顺序给每个人自己的grid-row。

请参阅 fiddle,它仅适用于 Firefox,因为我没有展开 3 个标签,而是使用显示 属性 contents https://jsfiddle.net/npddveag/2/

显示 属性 内容是一种使包装器 div 消失而不实际标记消失的神奇方法。(继承的样式仍然适用,因此还有更多内容) . 如果您需要它在其他浏览器中工作,您可以解开 3 个标签。

这是对上面 Michael_B 的回答的修改。似乎工作相同,但没有向原始 html 添加标记。

.grid-container {
  padding: 10px;
  display: grid;
  grid-template-columns:  [start] 1fr  [middle] 4fr  [end] 1fr ;
  grid-template-rows: repeat(100, 1px);        /* new */
  grid-column-gap: 1rem;                       /* adjusted; removed grid-row-gap */
  background-color: #fff;
  color: #444;
}

.start {
  grid-column: start;
  background-color: #ccc;
  grid-row: 1 / -1;                            /* new */
}

.middle {
  grid-column: middle;
  grid-row: 1 / -1;                            /* new */
}
 
 .end {
   grid-column: end;
   background-color: #ccc;
   grid-row: 1 / -1;                           /* new */   
 }
 
.grid-container:after {                                      /* new */
  content: '';
  background-color: red;
  grid-row-start: 47;
  grid-column: 1 / 3;
}
<div class="grid-container">
    <div class="start">Start</div>
        <div class="middle">
            <h2 class="title">My Title</h2>
            <div class="content">Some text lorem ipsum, whatever.</div>
        </div>
    <div class="end">End</div>
</div>