I'm trying to make a simple layout as I'm learning CSS Grid.
The layout should be as follows:
"header header header"
"adv content content"
"adv footer footer"
What I'm getting is this:
"header header header"
"adv content content"
". footer footer"
The div "adv" never takes the vertical space, doesn't matter if I do it using template-areas as above or using grid-row and columns as the code below.
In fact, I'm not able to manipulate any of my divs vertically. I cannot make them span several rows. Can somebody maybe tell me what I'm doing wrong?
body {
background: dimgray;
}
div {
height: 200px;
font-size: 50px;
font-family: sans-serif;
color: floralwhite;
}
.header {
background-color: lightcoral;
grid-column: 1 / 4;
}
/*Div having the issue below*/
.adv {
background-color: blue;
grid-row: 2/4;
/*Expecting to span from row 2 to 4, but not happening.*/
}
/*Div having the issue above*/
.content {
background: pink;
grid-column: 2/4;
}
.footer {
background-color: salmon;
grid-column: 2/4;
}
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
<body>
<div class="container">
<div class="header">header
</div>
<div class="adv">adv
<!--Div with the issue-->
</div>
<div class="content">content
</div>
<div class="footer">footer</div>
</div>
</body>
Your grid layout is fine, the problem is with: div {height: 200}, remove the height and it will work as expected.
You forced the height of all divs to be the same. This of course means adv can't be as big as two divs. So try this, if you still need the a minimum height on all divs (or just remove hight all together):
div {
min-height: 200px; /* min/max-height is preferred to `height` for flexible layouts like grid and flex-box. */
font-size: 50px;
font-family: sans-serif;
color: floralwhite;
}
body {
background: dimgray;
}
div {
min-height: 200px; /* height means that all divs will be the same hieght which prevents the layout you want. Min-height is more correct here. */
font-size: 50px;
font-family: sans-serif;
color: floralwhite;
}
.header {
background-color: lightcoral;
grid-column: 1 / 4;
}
/*Div having the issue below*/
.adv {
background-color: blue;
grid-row: 2/4;
/*Expecting to span from row 2 to 4, but not happening.*/
}
/*Div having the issue above*/
.content {
background: pink;
grid-column: 2/4;
}
.footer {
background-color: salmon;
grid-column: 2/4;
}
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
<body>
<div class="container">
<div class="header">header
</div>
<div class="adv">adv
<!--Div with the issue-->
</div>
<div class="content">content
</div>
<div class="footer">footer</div>
</div>
</body>
try:
div.container {
display: grid;
grid-template-areas: 'h h h' 'a c c' 'a f f';
}
.header { grid-area: h; }
...
templates columns and rows can only draw simples tables.
template-area permitt to customise the display.
Related
I was trying to use the code below, but it did not work. I wanted to use the grid to define the whole webpage layout on every page I make. It seems like it is not that simple, because it seems like the grid accepts only a simpler flow of elements like this one:
The layout that the grid won't accept:
header just row one and column one
"right div element" row 2/3 and column 2/3
that is what I wanted.
I wanted to achieve that with this code:
<html>
<head>
<style>
body,
html {
margin: 0;
height: 100%;
width: 100%;
}
.main {
width: 100%;
height: 100%;
display: grid;
grid-template-rows: 120px 1fr 120px;
grid-template-columns: 200px 1fr auto;
}
.main footer {
grid-column: 1/3;
grid-row-start: 3;
background: #949994;
}
.main .header {
grid-column-start: 1;
grid-row-start: 1;
background: #034f84;
}
.main .right {
grid-row: 1/2;
grid-column: 2/3;
text-align: center;
background-color: aquamarine;
}
</style>
</head>
<body>
<div class="main">
<header>
</header>
<div class="right">
</div>
<footer>
</footer>
</div>
</body>
</html>
My goal is to break my screen in four different blocks that are not the same size, just like in the picture (block one and two should be the same size). I tried using bootstrap which kinda works but it makes it scrollable and I want to avoid that. Is there a way to make it not scrollable and have each block in a fixed size? Any tips would be appreciated. I'm using bootstrap and angularjs.
This is what I have so far, but I want to make full screen.
https://codepen.io/BrunoTrax/pen/XWWVNgL
<style>
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: [col1-start] 100px [col2-start] 100px [col3-start] 100px [col3-end];
grid-template-rows: [row1-start] auto [row2-start] auto [row2-end];
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.a {
grid-column: col1-start / col3-start;
grid-row: row2-start ;
}
.b {
grid-column: col3-start ;
grid-row: row1-start / row2-end;
}
.c {
grid-column: col1-start;
grid-row: row1-start ;
}
.d {
grid-column: col2-start ;
grid-row: row1-start ;
}
</style>
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
</div>
You should check out CSS "Grid's". Basically, you can declare a grid inside your css and use the grid-template-columns property to display your blocks in various arrangements. Here is a good resource that shows you how to create a custom layout.
The grid property also allows you to declare a height and width which will fix your scrolling problem.
Check this out and start experamenting.
CSS
.grid {
display: grid;
width: 100%;
height: 250px;
grid-template-areas: "head head"
"nav main"
"nav foot";
grid-template-rows: 50px 1fr 30px;
grid-template-columns: 150px 1fr;
}
.grid > header {
grid-area: head;
background: #eee;
}
.grid > navLeft {
grid-area: nav;
background-color: #a072;
}
.grid > main {
grid-area: main;
background-color: #8510ff;
}
.grid > footer {
grid-area: foot;
background-color: #8cffa0;
}
HTML
<header> Hello</header>
<navLeft> Hello</navLeft>
<main> Hello</main>
<p> Hello</p>
<p> Hello</p>
</div> ```
I have the following grid layout:
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<div class="index-view"></div>
</div>
and I am trying to insert a new div between sidebar and index such that the resulting layout will be like:
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<div class="profile-pane"></div>
<div class="index-view"></div>
</div>
My attempt so far has been:
.main-page {
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: 72px 1fr;
height: 100%;
}
.main-page > .side-bar {
display: grid;
grid-row: 1/4;
width: 80px;
}
.main-page > .profile-pane {
width: 260px;
position: relative;
grid-row: 2/4;
}
.main-page > .index-view {
grid-row: 2/4;
}
This renders a huge space between profile and index and compresses index to the right. I've been trying different values for the grid-row property but to no avail. However, if I remove either one of profile and index, the remaining div will render nicely and right beside the sidebar. How do I achieve the second layout?
You can consider different values based on the existance of the profile element:
.main-page {
display: grid;
grid-template-columns: 80px 1fr 4fr;
grid-template-rows: 72px 1fr;
height: 200px;
margin:20px;
}
.side-bar {
grid-row: span 2;
}
.nav-bar,
.index-view {
grid-column:span 2;
}
/* Take only one clumn if profile exist*/
.profile-pane + .index-view {
grid-column:span 1;
}
/* Irrelevant code */
.main-page > * {
border:1px solid;
}
.main-page > *:before {
content:attr(class);
}
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<!--<div class="profile-pane"></div>-->
<div class="index-view"></div>
</div>
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<div class="profile-pane"></div>
<div class="index-view"></div>
</div>
You can achieve the desired result by setting the "grid-row: span 2" property in the sidebar to increase its height by two lines. And for the navigation bar, the "grid-column: span 2" property is to expand it into two columns
Oh yes, and do not forget to set the columns of the required width for the grid container grid-template-columns: 10% 15% 70%;
Result:
.main-page {
display: grid;
grid-template-columns: 10% 15% 70%;
}
.main-page>* {
padding: 20px;
border: 1px solid #000;
}
.side-bar {
grid-row: span 2;
}
.nav-bar {
grid-column: span 2;
}
.index-view {
min-height: 500px;
}
<div class="main-page">
<div class="side-bar">side-bar</div>
<div class="nav-bar">nav-bar</div>
<div class="profile-pane">profile-pane</div>
<div class="index-view">index-view</div>
</div>
I'm trying to display two columns with the CSS Grid stretched to the bottom of the screen. I used flexbox to achieve it:
html, body {
height: 100%;
}
#root {
display: flex;
flex-direction: column;
min-height: 100%;
color: #fff;
}
#wrapper {
flex: 1;
display: grid;
grid:
"title title" min-content
"divider divider" min-content
"part1 part2" 1fr
/ calc(50% - 5px) calc(50% - 5px);
background-color: #003300;
grid-gap: 10px;
}
#title {
grid-area: title;
}
#divider {
grid-area: divider;
}
#part1 {
grid-area: part1;
}
#part2 {
grid-area: part2;
}
#part1, #part2 {
background-color: #ff0000;
}
<section id="root">
<section id="wrapper">
<div id="title">Title</div>
<div id="divider"><hr></div>
<div id="part1">Part 1</div>
<div id="part2">Part 2</div>
</section>
</section>
If you run this code in Firefox, you can see properly stretching red columns that reach the bottom of the screen. But in the Chrome they do not stretch properly and leave as small as possible. Is there some way to avoid this issue? I would like to save the flexbox-direction: column.
Maybe there is also a link to the chromium bug?
Looks like a bug in Chrome.
Flex and Grid properties don't play nice in this particular scenario.
I know you said you would like to keep flex-direction: column.
But you can get the same behavior with flex-direction: row when you add wrap to the container and make each item width: 100%.
And in this case, that switch in flex-direction solves your problem.
#root {
display: flex;
min-height: 100vh;
color: #fff;
}
#wrapper {
flex: 1;
display: grid;
grid:
"title title" min-content
"divider divider" min-content
"part1 part2" 1fr
/ 1fr 1fr ; /* calc(50% - 5px) calc(50% - 5px) why the added complexity? */
background-color: #003300;
grid-gap: 10px;
}
#title { grid-area: title; }
#divider { grid-area: divider; }
#part1 { grid-area: part1; }
#part2 { grid-area: part2; }
#part1,
#part2 { background-color: #ff0000; }
body { margin: 0; }
<section id="root">
<section id="wrapper">
<div id="title">Title</div>
<div id="divider"><hr></div>
<div id="part1">Part 1</div>
<div id="part2">Part 2</div>
</section>
</section>
jsFiddle demo
More information: Force flex item to span full row width
If you really can't switch from flex-direction: column, here are two options you can try:
move the min-height from #root to #wrapper (jsfiddle demo)
make the overall parent (body, in this case) a flex container (jsfiddle demo)
This question already has answers here:
Make a div span two rows in a grid
(2 answers)
Closed 2 years ago.
I'm facing an issue where I need to make several adjacent div to position a certain way:
Their html layout positions are right next to each other:
<div class="parent">
<div class="div1">....</div>
<div class="div2">....</div>
<div class="div3">....</div>
<div class="div4">....</div>
</div>
I've tried with flex boxes and floating out Div1 and Div4 out but it's not working. I also need Div1 and Div4's height to all be vertically aligned to its correct dynamic height depending on the contents of Div2 and Div3.
CSS grid may help you solve it easily.
.parent {
display: grid;
grid-gap: 10px;
grid-template-columns: [col1-start] 100px [col2-start] 100px [col3-start] 100px [col3-end];
grid-template-rows: [row1-start] auto [row2-start] auto [row2-end];
}
.div1, .div2, .div3, .div4 {
background-color: #444;
color: #fff;
padding: 20px;
}
.div1 {
grid-column: col1-start;
grid-row: row1-start / row2-end ;
}
.div2 {
grid-column: col2-start ;
grid-row: row1-start;
}
.div3 {
grid-column: col2-start;
grid-row: row2-start ;
}
.div4 {
grid-column: col3-start ;
grid-row: row1-start / row2-end ;
}
<div class="parent">
<div class="div1">....</div>
<div class="div2">....</div>
<div class="div3">....</div>
<div class="div4">....</div>
</div>
Some more examples could be found HERE.
I would do it this way:
*{
margin: 0;
border: 0;
padding: 0;
box-sizing: border-box;
}
.parent{
display: flex;
padding: 15px;
}
.a, .b{
background: #ddd;
margin: 10px;
flex-basis: 20%;
}
.container{
width: 60%;
}
.container div{
background: #ddd;
margin: 10px;
}
<div class="parent">
<div class="a">div1</div>
<div class="container">
<div>div</div>
<div>div</div>
</div>
<div class="b">div2</div>
</div>