Css-grid: Bleed background outside container

ぐ巨炮叔叔 提交于 2020-06-22 04:02:49

问题


Consider the following 3-column grid layout with max-width constraint on container:

.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>

Ideally, I would like to bleed background of header and footer outside the container when viewport width is above max-width, but keep grid and its structure within max-width as in example (including inner content of header and footer).

I have considered these approaches:

  • Forget max-width container, use full width container with minmax'es and position full-span divs with background-color underneath header and footer(https://codepen.io/anon/pen/OaryXj). I don't like this approach because it adds extra elements purely for styling and because it adds two extra columns (I can live with this one probably, using named columns)
  • Use same approach as above, but instead of adding extra divs, use full-span header and footer with "padding: 0 calc((100% - 900px)/2);" (https://codepen.io/anon/pen/BGvoxx). I don't like this approach either, because I don't understand why it works at all when 100% < 900px (why negative padding is not added) and it adds two extra columns to the grid as well.

Any other ideas? Some calc() magic with negative margins and padding on header / footer?


回答1:


if it's only about background and coloration you can use pseudo element to have the overflow effect:

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>



回答2:


the accepted answer is amazing, but you can solve your problem by changing your markup a little bit. by changing the order of your divs and splitting the concerns of your container class with that of the grid you get the same result:

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>

the use-case where I see the accepted answer really shine is when you have multiple columns and you don't want to break the grid but extend the background color of one of the columns to the edges of the browser...

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>


来源:https://stackoverflow.com/questions/53550846/css-grid-bleed-background-outside-container

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!