grid cell gets pushed down to the next row - css

So I just started trying out the grid display, but for some reason with this basic of a code.
div{
padding: 50px;
margin: 10px;
border: 5px solid black;
}
.grid{
display: grid;
grid-template-columns: auto auto auto;
}
.grid-header{grid-column: 1 / span 3;}
.grid-main{grid-column: 1 / span 2;}
I keep getting this as a result though.
Result
but what I want is for it to look like this
Intended
Here's the full code if it helps.
<html>
<head>
<style>
div {
padding: 50px;
margin: 10px;
border: 5px solid black;
}
.grid {
display: grid;
grid-template-columns: auto auto auto;
}
.grid-header {
grid-column: 1 / span 3;
}
.grid-main {
grid-column: 1 / span 2;
}
</style>
</head>
<body>
<div class="grid">
<div class="grid-header"></div>
<div></div>
<div class="grid-main"></div>
<div class="grid-main"></div>
<div></div>
</div>
</body>
</html>

I have changed one div's class grid-main to grid-main2. Let me know if face any issue
<html>
<head>
<style>
div {
padding: 50px;
margin: 10px;
border: 5px solid black;
}
.grid {
display: grid;
grid-template-columns: auto auto auto;
}
.grid-header {
grid-column: 1 / span 3;
}
.grid-main {
grid-column: 2 / span 2;
}
.grid-main2 {
grid-column: 1 / span 2;
}
</style>
</head>
<body>
<div class="grid">
<div class="grid-header"></div>
<div></div>
<div class="grid-main"></div>
<div class="grid-main2"></div>
<div></div>
</div>
</body>
</html>
One more solution is possible with your existing html without changing class.
Here is the css:
div {
padding: 50px;
margin: 10px;
border: 5px solid black;
}
.grid {
display: grid;
grid-template-columns: auto auto auto;
}
.grid-header {
grid-column: 1 / span 3;
}
.grid-main:nth-child(3) {
grid-column: 2 / span 2;
}
.grid-main:nth-child(4) {
grid-column: 1 / span 2;
}

Related

How to make my grid cell same size after spanding it over the next cell?

enter image description here
How do I make my grid cell same size after spanning it over the next cell? This is what I have tried so far
.factory {
display: grid;
grid-template-columns: 1fr 1fr 2fr;
height: 600px;
gap: 10px;
margin-top: 100px;
padding: 10px;
}
.factory>div {
background-color: gray;
border: 1px green solid;
}
.image-1 {
width: 100%;
height: auto;
}
.div-3 {
grid-column: 3 / span 5;
}
.div-5 {
grid-column: 1 / span 2;
}
<div class="factory">
<div class="div-1">box1</div>
<div class="div-2">box2</div>
<div class="div-3">box3</div>
<div class="div-5">box5</div>
<div class="div-6">box6</div>
</div>
As you can see box6 is smaller than the rest of the boxes.
Your issue is that on div-3 you try to span 5 columns after it has started at column 3 which will make the browser attempt to add 5 more columns to the grid.
.div-3 {
grid-column: 3 / span 5;
}
You can either remove this section completely because you have already specified in your grid-template-columns: 1fr 1fr 2fr; that the third column should be double the space of the first two.
Another option would be to span 1
.div-3 {
grid-column: 3 / span 1;
}
You can see this clearly by using the inspection tools.
.factory {
display: grid;
grid-template-columns: 1fr 1fr 2fr;
height: 600px;
gap: 10px;
margin-top: 100px;
padding: 10px;
}
.factory>div {
background-color: gray;
border: 1px green solid;
}
.image-1 {
width: 100%;
height: auto;
}
/*.div-3 {
grid-column: 3 / span 5;
}*/
.div-5 {
grid-column: 1 / span 2;
}
<div class="factory">
<div class="div-1">box1</div>
<div class="div-2">box2</div>
<div class="div-3">box3</div>
<div class="div-5">box5</div>
<div class="div-6">box6</div>
</div>

CSS grid with sticky first row/column? [duplicate]

I've looked at other examples of this on here but can't find one that makes this work. I want the sidebar (section) to be sticky while the page scrolls. the position: sticky works if I put it on the nav, so my browser def supports it.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
position: sticky;
top: 0;
left: 0;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
<main>
<nav></nav>
<section>
hi
</section>
<article>
<p>hi</p>
</article>
</main>
the problem you are facing here is, that your section block consumes the full height. so it won't stick, since it is too large to do so. you would need to put a child element inside your section and give that your sticky attributes, to make it work. based on your example, i simply wrapped your 'hi' inside a div.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
}
section div {
position: sticky;
top: 0;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
<main>
<nav></nav>
<section>
<div>
<p>one</p>
</div>
</section>
<article>
<p>two</p>
</article>
</main>
You need to use align-self: start on the thing you want to be sticky.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
background: grey;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
position: sticky;
top: 0;
left: 0;
align-self: start;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
<main>
<nav></nav>
<section>
hi
</section>
<article>
<p>hi</p>
</article>
</main>
Update with complete code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
top: 0;
left: 0;
}
.fixed-section {
position: fixed;
z-index: 1;
overflow-x: hidden;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
</style>
</head>
<body>
<main>
<nav></nav>
<section>
<div class='fixed-section'>
Hi 1
<div>
</section>
<article>
<p>hi</p>
</article>
</main>
</body>
</html>

Css-grid: Bleed background outside container

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

Drawing column/rows in incomplete css3 grid

I'm using css-grid to generate a grid like display. But this display does not contain an element for every cell.
Is it possible to draw the outline of every lines/rows using CSS without adding the missing elements?
Example of grid:
.grid {
display: grid;
grid-template-columns: 15px 25px 35px;
grid-template-rows: 30px 20px 10px;
grid-gap: 5px 5px;
}
.cell1 {
grid-area: 1 / 1 / span 1 / span 1;
background: green;
}
.cell2 {
grid-area: 3 / 3 / span 1 / span 1;
background : blue;
}
<div class="grid">
<div class="cell1"></div>
<div class="cell2"></div>
</div>
As I said in the comment, you can use background linear gradients, without css-grid
.grid {
display: grid;
grid-template-columns: 25px 25px 25px;
grid-template-rows: 25px 25px 25px;
grid-gap: 5px 5px;
background-image: repeating-linear-gradient(0deg,transparent,transparent 25px,#CCC 25px,#CCC 30px),repeating-linear-gradient(-90deg,transparent,transparent 25px,#CCC 25px,#CCC 30px);
background-size: 30px 30px;
background-position: -5px -5px;
width: 85px;
height: 85px;
}
.cell1 {
grid-area: 1 / 1 / span 1 / span 1;
background: green;
}
.cell2 {
grid-area: 3 / 3 / span 1 / span 1;
background : blue;
}
<div class="grid">
<div class="cell1"></div>
<div class="cell2"></div>
</div>
Seems like you have to add the remaining cells but just dont add a class.
I think you need the DOM element to render css without sth like canvas.
.grid {
display: grid;
grid-template-columns: 25px 25px 25px;
grid-template-rows: 25px 25px 25px;
grid-gap: 0;
}
.grid > * {
border: 1px solid rgb(137,153,175);
}
.cell1 {
grid-area: 1 / 1 / span 1 / span 1;
background: green;
}
.cell2 {
grid-area: 3 / 3 / span 1 / span 1;
background : blue;
}
<div class="grid">
<div class="cell1"></div>
<div class="cell2"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

Is it possible to split a grid item to allow different spans?

I have an article and an aside (sidebar) element - easy, except the title and sub-heading of the article need to span the entire row. If I take the title/sub-heading out of the article, the article element is no longer semantically complete.
Is there a way, using CSS Grid, to have the format below, where Title, Sub and Content are all a part of an "Article" element, and "Aside" is the second in a 2 column grid?
From my research so far, it seems this is not possible.
You can hack your way through using nested CSS grid if you know:
The width of the aside section
The height of the title and sub heading sections
(in many layouts, these dimensions are fixed)
You can use a pseudo element that create a space for the aside element and then sneak it inside the outer grid container - check out the demo below:
body {
margin: 0;
}
* {
box-sizing: border-box;
}
article,
aside {
border: 1px solid;
display: flex;
align-items: center;
justify-content: center;
}
div {
display: grid;
grid-template-areas: "section aside";
}
section {
grid-area: section;
display: grid;
grid-template-areas: "header header" "subhead subhead" "content empty";
grid-template-rows: 50px 50px auto;
grid-template-columns: 80vw auto;
height: 100vh;
width: 100vw;
}
section article:first-child {
grid-area: header;
}
section article:nth-child(2) {
grid-area: subhead;
}
section article:last-child {
grid-area: content;
}
section:after {
content: '';
display: block;
grid-area: empty;
}
aside {
grid-area: aside;
height: calc(100vh - 100px);
width: 20vw;
align-self: flex-end;
position:relative;
transform: translateX(-100%);
}
<div>
<section>
<article>Article title</article>
<article>Article sub-heading</article>
<article>Article content</article>
</section>
<aside>Aside</aside>
</div>
You can use something like this.
* {box-sizing: border-box;}
.wrapper {
max-width: 940px;
margin: 0 auto;
}
.wrapper > div {
border: 2px solid rgb(233,171,88);
border-radius: 5px;
background-color: rgba(233,171,88,.5);
padding: 10px;
color: #d9480f;
}.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
grid-auto-rows: minmax(100px, auto);
}
.one {
grid-column: 1 / 4;
grid-row: 1;
}
.two {
grid-column: 1 / 4;
grid-row: 2;
}
.three {
grid-column: 1 / 3;
grid-row: 3;
min-height:200px;
}
.four {
grid-column: 3;
grid-row: 3;
min-height:200px;
}
<div class="wrapper">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
Also check Fiddle.
And for more details please visit https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
You can achieve that by simply floating all the cells, as long as the article doesn't float - https://jsfiddle.net/yxbckzcq/1/
<div class="wrapper">
<article>
<div style="float:left;width:100%" class="one">One</div>
<div style="float:left;width:100%" class="two">Two</div>
<div style="float:left;width:70%" class="three">Three</div>
</article>
<div style="float:left;width:30%" class="four">Four</div>
</div>

Resources