CSS网格:容器外部的出血背景

时间:2018-11-30 03:33:43

标签: css background-color css-grid

考虑以下三列网格布局,该布局在容器上具有最大宽度约束:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 56px minmax(56px, auto) 56px;
  max-width: 300px;
  margin: auto;
}

header {
  background-color: grey;
  grid-column: 1 / span 3;
  grid-row: 1 / 2;
}

main {
  background-color: #2E64FE;
  grid-column: 1 / span 2;
  grid-row: 2 / 3;
}

aside {
  background-color: #FF0040;
  grid-column: 3 / span 1;
  grid-row: 2 / 3;
}

footer {
  background-color: grey;
  grid-column: 1 / span 3;
  grid-row: 3 / 4;
}

header, main, aside, footer {
  line-height: 56px;
  text-align: center;
  vertical-align: middle;
}
<html>
  <body>
    <div class='container'>
      <header>Header</header>
      <main>Main</main>
      <aside>Sidebar</aside>
      <footer>Footer </footer>
    </div>
  </body>
</html>

理想情况下,我想在视口宽度大于max-width时在容器外部散放页眉和页脚的背景,但请像示例中那样将网格及其结构保持在max-width之内(包括内部页眉和页脚的内容。

我已经考虑过以下方法:

  • 忘记最大宽度的容器,请使用具有minmax的全宽容器,并在页眉和页脚(https://codepen.io/anon/pen/OaryXj)下方将全跨度div放置在背景颜色下。我不喜欢这种方法,因为它纯粹是为样式添加了额外的元素,并且因为它添加了两个额外的列(我可以使用命名列来使用这一列)
  • 使用与上述相同的方法,但不要添加额外的div,而应使用全跨度页眉和页脚以及“填充:0 calc((100%-900px)/ 2);” (https://codepen.io/anon/pen/BGvoxx)。我也不喜欢这种方法,因为我不理解为什么当100%<900px(为什么不添加负填充)并且它还在网格中又增加了两列时,它根本无法工作。

还有其他想法吗?某些calc()魔术具有负边距和页眉/页脚填充?

2 个答案:

答案 0 :(得分:2)

如果仅涉及背景和颜色,则可以使用伪元素来产生溢出效果:

body {
 overflow-x:hidden;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 56px minmax(56px, auto) 56px;
  max-width: 300px;
  margin: auto;
}

header {
  background-color: grey;
  grid-column: 1 / span 3;
  grid-row: 1 / 2;
  position:relative;
}
header:before,
footer:before{
  content:"";
  z-index:-1;
  position:absolute;
  top:0;
  bottom:0;
  left:-100vw;
  right:-100vw;
  background:inherit;
}

main {
  background-color: #2E64FE;
  grid-column: 1 / span 2;
  grid-row: 2 / 3;
}

aside {
  background-color: #FF0040;
  grid-column: 3 / span 1;
  grid-row: 2 / 3;
}

footer {
  background-color: grey;
  grid-column: 1 / span 3;
  grid-row: 3 / 4;
  position:relative;
}

header, main, aside, footer {
  line-height: 56px;
  text-align: center;
  vertical-align: middle;
}
<html>
  <body>
    <div class='container'>
      <header>Header</header>
      <main>Main</main>
      <aside>Sidebar</aside>
      <footer>Footer </footer>
    </div>
  </body>
</html>

答案 1 :(得分:0)

可接受的答案很棒,但是您可以通过稍微更改标记来解决问题。通过更改div的顺序并将容器类的关注点与网格的关注点分开,您将得到相同的结果:

body { 
 margin: 0;
 overflow-x:hidden;
}

.container {
  max-width: 300px;
  margin: auto;
}

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: minmax(56px, auto);
}

header, footer {
  background-color: grey;
  height: 56px;
}

main {
  background-color: #2E64FE;
  grid-column: 1 / span 2;
}

aside {
  background-color: #FF0040;
  grid-column: 3 / span 1;
}

header, main, aside, footer {
  line-height: 56px;
  text-align: center;
  vertical-align: middle;
}
<html>
  <body>
    <header>
      <div class="container">Header</div>
    </header>
    <div class="container grid">
      <main>Main</main>
      <aside>Sidebar</aside>
    </div>
    <footer>
      <div class="container">Footer</div>
    </footer>
  </body>
</html>

我看到一个公认的答案真正有用的用例是,当您有多列并且不想破坏网格,而是将其中一列的背景色扩展到浏览器的边缘时...

body {
 overflow-x:hidden;
 margin: 0;
}

.container {
  max-width: 300px;
  margin: auto;
}

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: minmax(56px, auto);
}

header, footer {
  background-color: grey;
  height: 56px;
}

aside {
  background-color: #FF0040;
  grid-column: 1 / span 1;
}

main {
  background-color: #2E64FE;
  grid-column: 2 / span 2;

}

.extend-right {
  position: relative;
}

.extend-right:after {
  content: '';
  position: absolute;
  height: 100%;
  left: 100%;
  right: -100vw;
  background-color: inherit;
}

header, main, aside, footer {
  line-height: 56px;
  text-align: center;
  vertical-align: middle;
}
<html>
  <body>
    <header>
      <div class="container">Header</div>
    </header>
    <div class="container grid">
      <aside>Sidebar</aside>
      <main class="extend-right">Main</main>
    </div>
    <footer>
      <div class="container">Footer</div>
    </footer>
  </body>
</html>