I'm playing with "grid layout" and I have a "section" with 100% width. This is display: grid.
Inside it there are 4 other divs that I would like to appear on the right side instead of the left side.
Here is my code:
.fullWidth {
display: grid;
grid-template: "it01 it02 it03 it04 it05";
grid-template-rows: 40px;
grid-template-columns: 40px 40px 40px 200px 40px;
background: orange;
}
.item01 {
grid-area: it01;
background: lime;
}
.item02 {
grid-area: it02;
background: blue;
}
.item03 {
grid-area: it03;
background: red;
}
.item04 {
grid-area: it04;
background: yellow;
}
.item05 {
grid-area: it05;
background: tomato;
}
<section class="fullWidth">
<div class="item01"> </div>
<div class="item02"> </div>
<div class="item03"> </div>
<div class="item04"> </div>
<div class="item05"> </div>
</section>
Here's the fiddle:
https://jsfiddle.net/2mpsuc7c/
Just add:
.fullWidth {
justify-content: end;
}
Updated snippet:
.fullWidth {
display: grid;
grid-template: "it01 it02 it03 it04 it05";
grid-template-rows: 40px;
grid-template-columns: 40px 40px 40px 200px 40px;
background: orange;
justify-content: end;
}
.item01 {
grid-area: it01;
background: lime;
}
.item02 {
grid-area: it02;
background: blue;
}
.item03 {
grid-area: it03;
background: red;
}
.item04 {
grid-area: it04;
background: yellow;
}
.item05 {
grid-area: it05;
background: tomato;
}
<section class="fullWidth">
<div class="item01"> </div>
<div class="item02"> </div>
<div class="item03"> </div>
<div class="item04"> </div>
<div class="item05"> </div>
</section>
Updated Fiddle
You can make use of the direction property with direction: rtl:
.fullWidth {
display: grid;
grid-template: "it01 it02 it03 it04 it05";
grid-template-rows: 40px;
grid-template-columns: 40px 40px 40px 200px 40px;
background: orange;
direction: rtl;
}
.item01 {
grid-area: it01;
background: lime;
}
.item02 {
grid-area: it02;
background: blue;
}
.item03 {
grid-area: it03;
background: red;
}
.item04 {
grid-area: it04;
background: yellow;
}
.item05 {
grid-area: it05;
background: tomato;
}
<section class="fullWidth">
<div class="item01"></div>
<div class="item02"></div>
<div class="item03"></div>
<div class="item04"></div>
<div class="item05"></div>
</section>
Hope this helps! :)
Related
I have a grid (containers) to display a navbar, a main-container and a footer. In the main-container, it is also a grid to display 3 children elements in a custom disposition using grid-area. Everything works properly.
Now, I would like to display an overlay div (overlay) which has to fit the whole main-container. To do so, I just add an additional div in the main-container with the property height: 100%; width: 100%; and play with the position property without success. Indeed, position: absolute or position: fixed make it too big and I don't want to set a fixed width or height since the layout can be responsive. And with position: relative, it is not working neither.
Do you have any idea, how I could make the overlay display above the main-container while keeping the properties width: 100%; height: 100%;?
#containers {
display: grid;
grid-template-areas: "navbar main" "navbar footer";
grid-template-rows: calc(100% - 32px) 32px;
grid-template-columns: 56px calc(100% - 56px);
}
#navbar-container {
grid-area: navbar;
background-color: blue;
}
#main-container {
grid-area: main;
height: 100%;
width: 100%;
display: grid;
grid-template-areas:
'child1 child2'
'child1 child3';
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
#footer-container {
grid-area: footer;
background-color: black;
}
#child1,
#child2,
#child3 {
padding: 10px;
}
#child1 {
grid-area: child1;
background-color: red;
}
#child2 {
grid-area: child2;
background-color: purple;
}
#child3 {
grid-area: child3;
background-color: pink;
}
#footer-container {
grid-area: footer;
}
.modal {
width: 100%;
height: 100%;
background-color: grey;
opacity: 0.5;
position: absolute;
}
<div id="containers">
<div id="navbar-container"></div>
<div id="main-container">
<div id="child1">
<span>CHILD 1</span>
</div>
<div id="child2">
<span>CHILD 2</span>
</div>
<div id="child3">
<span>CHILD 3</span>
</div>
<div class="modal">
MODAL
</div>
</div>
<div id="footer-container"></div>
</div>
Just needed to make the parent relative and the modal absolute.
#containers {
display: grid;
grid-template-areas: "navbar main" "navbar footer";
grid-template-rows: calc(100% - 32px) 32px;
grid-template-columns: 56px calc(100% - 56px);
}
#navbar-container {
grid-area: navbar;
background-color: blue;
}
#main-container {
grid-area: main;
height: 100%;
width: 100%;
display: grid;
grid-template-areas:
'child1 child2'
'child1 child3';
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
position: relative;
}
#footer-container {
grid-area: footer;
background-color: black;
}
#child1,
#child2,
#child3 {
padding: 10px;
}
#child1 {
grid-area: child1;
background-color: red;
}
#child2 {
grid-area: child2;
background-color: purple;
}
#child3 {
grid-area: child3;
background-color: pink;
}
#footer-container {
grid-area: footer;
}
.modal {
width: 100%;
height: 100%;
background-color: grey;
opacity: 0.5;
position: absolute;
}
<div id="containers">
<div id="navbar-container"></div>
<div id="main-container">
<div id="child1">
<span>CHILD 1</span>
</div>
<div id="child2">
<span>CHILD 2</span>
</div>
<div id="child3">
<span>CHILD 3</span>
</div>
<div class="modal">
MODAL
</div>
</div>
<div id="footer-container"></div>
</div>
Try to make this:
Article and Aside are the same width
I don't know if the floating is wrong, or other. even I make the margin to 0, the Article box will drop below to Aside. And I don't why after I float the box, some of the borderlines will overlap but the footer won't. And there are some requirements.
The border is 3px.
The height of each box is 200px. Article and Aside are the same width
header,main,aside,article,footer{
background-color: lightblue;
border: 3px solid red;
height: 200px;
margin: 0;
}
header {
}
main {
width: 60%;
float: left;
}
aside{
width: 20%;
float: left;
}
article {
width: 20%;
float: right;
}
footer{
clear: both;
}
<header>
<h2>Header</h2>
</header >
<main>
<h2>Main</h2>
</main>
<aside>
<h2>Aside</h2>
</aside>
<article>
<h2>Article</h2>
</article>
<footer>
<h2>Footer</h2>
</footer>
A way is using grid:
.container {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(3, 100px);
grid-gap: 20px;
}
.container div {
background-color: green;
border: solid red 1px;
}
.header {
grid-column: 1 / 6;
}
.main {
grid-column: 1 / 4;
}
.asid {
grid-column: 4 / 5;
}
.article {
grid-column: 5 / 6;
}
.footer {
grid-column: 1 / 6;
}
<div class="container">
<div class="header">header</div>
<div class="main">main</div>
<div class="asid">asid</div>
<div class="article">article</div>
<div class="footer">footer</div>
</div>
I would wrap the .main, .aside, .article blocks with a flex container.
.content {
display: flex;
gap: 10px;
}
.content {
display: flex;
gap: 10px;
}
.header,.main,.aside,.article,.footer{
background-color: lightblue;
border: 3px solid red;
height: 200px;
margin: 1em;
}
.main {
width: 60%;
}
.aside {
width: 20%;
}
.article {
width: 20%;
}
<div class="container">
<div class="header">HEADER</div>
<div class="content">
<div class="main">MAIN</div>
<div class="aside">ASIDE</div>
<div class="article">ARTICLE</div>
</div>
<div class="footer">FOOTER</div>
</div>
Try using flex
section{
display: flex;
}
main, aside, article{
height: 60px;
}
main{
flex-grow: 3;
background: red;
}
aside{
flex-grow: 1;
background: green;
}
article{
flex-grow: 1;
background: blue;
}
<section>
<main>main</main>
<aside>aside</aside>
<article>article</article>
</section>
I have the following layout with 2 headers and 3 footers:
.my-grid {
display: grid;
grid-template-areas:
"header1"
"header2"
"mainAreaExpandMePlease"
"footer1"
"footer2"
"footer3"
;
grid-template-rows: 27px 27px 1fr 28px 28px 28px;
height: 100%;
}
The main area will expand to fill the gap left after showing the headers and footers.
I want to be able to toggle footers on and off (show / hide them) such that they collapse. With the code above, a gap will be left in place of the footer when we hide it.
How should I go about:
Having a main area that always expands
Having optional headers and footers which collapse, when hidden
Examples:
If header1 collapses, then header2 should take its place and mainAreaExpandMePlease should expand to where header2 used to be
If header2 collapses, then mainAreaExpandMePlease should expand up by another 27px
If footer3 collapses, then footer2 takes place of footer3, footer1 takes the place of footer2 and mainAreaExpandMePlease will stretch down another 28px
Thank you!
Fiddle: https://jsfiddle.net/jg6ho4wu/1/
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.my-grid {
display: grid;
grid-template-areas:
"header1"
"header2"
"mainAreaExpandMePlease"
"footer1"
"footer2"
"footer3";
grid-template-rows: 27px 27px 1fr 28px 28px 28px;
height: 100%;
}
.header1 {
grid-area: header1;
background-color: yellow;
}
.header2 {
grid-area: header2;
background-color: magenta;
}
.mainAreaExpandMePlease {
grid-area: mainAreaExpandMePlease;
background-color: cyan;
}
.footer1 {
grid-area: footer1;
background-color: green;
}
.footer2 {
grid-area: footer2;
background-color: red;
}
.footer3 {
grid-area: footer3;
background-color: blue;
}
<div class="my-grid">
<div class="header1"></div>
<div class="header2"></div>
<div class="mainAreaExpandMePlease"></div>
<div class="footer1"></div>
<div class="footer2" style="display:none"></div>
<div class="footer3"></div>
</div>
Don't set the height of the header and footer rows at the container level.
Set their heights on the items, and set their container heights to auto.
.my-grid {
display: grid;
height: 100vh;
grid-template-rows: auto auto 1fr auto auto auto;
grid-template-areas: "header1"
"header2"
"mainAreaExpandMePlease"
"footer1"
"footer2"
"footer3";
}
.header1 {
height: 27px;
grid-area: header1;
background-color: yellow;
}
.header2 {
height: 27px;
grid-area: header2;
background-color: magenta;
}
.mainAreaExpandMePlease {
grid-area: mainAreaExpandMePlease;
background-color: cyan;
}
.footer1 {
height: 28px;
grid-area: footer1;
background-color: green;
}
.footer2 {
height: 28px;
grid-area: footer2;
background-color: red;
}
.footer3 {
height: 28px;
grid-area: footer3;
background-color: blue;
}
body {
margin: 0;
padding: 0;
}
<div class="my-grid">
<div class="header1"></div>
<div class="header2"></div>
<div class="mainAreaExpandMePlease"></div>
<div class="footer1"></div>
<div class="footer2" style="display:none"></div>
<div class="footer3"></div>
</div>
I've got some problems when I'am trying to make my section with Grid layout. Where exactly I make mistake? Can someone explaine me, please?
HTML
<body>
<header>
<div class="grid-wrapper">
<div class="item1"><span>Item 1</span></div>
<div class="item2"><span>Item 2</span></div>
<div class="item3"><span>Item 3</span></div>
<div class="item4"><span>Item 4</span></div>
<div class="item5"><span>Item 5</span></div>
</div>
</header>
</body>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #969d9f;
}
header {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background-color: #969d9f;
}
.grid-wrapper {
border: 1px solid red;
width: 1200px;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(2, 1fr);
}
.item1, .item2, .item3, .item4, .item5 {
border: 1px solid grey;
background-color: #636564;
height: 360px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 40px;
}
.item1 { width: 750px; }
.item2 { width: 360px; }
.item3 { width: 555px; }
.item4 { width: 555px; }
.item5 { width: 1200px; }
So the main question is how can I correctly display my blocks and where is my main mistake that I make?
Here is some pics:
Thank you for your attention!
its my opinion
HTML
<body>
<header>
<div class="grid-wrapper">
<div class="item1"><span>Item 1</span></div>
<div class="item2"><span>Item 2</span></div>
<div class="item3"><span>Item 3</span></div>
<div class="item4"><span>Item 4</span></div>
<div class="item5"><span>Item 5</span></div>
</div>
</header>
</body>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #969d9f;
}
header {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
background-color: #969d9f;
}
.grid-wrapper {
border: 1px solid red;
width: 1200px;
display: grid;
grid-gap: 20px;
grid-template-areas: "item1 item1 item2" /* make grid area */
"item3 item4 item4"
"item5 item5 item5";
grid-template-columns:(1fr, 1fr, 1fr); /* set width of colums */
}
.item1, .item2, .item3, .item4, .item5 {
border: 1px solid grey;
background-color: #636564;
height: 360px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 40px;
}
.item1 {grid-area: item1} /* connect items with grid area */
.item2 {grid-area: item2}
.item3 {grid-area: item3}
.item4 {grid-area: item4}
.item5 {grid-area: item5}
Your layout isn't a "normal" grid (your rows 1 & 2 have cells with different widths from each other), so to resolve it, a solution could be to create more columns (3/4/5 columns: it depends by cells width and if the biggests [1&4] are equals or not) and play, for example, with grid-template-areas to create items that can... "fill more than 1 cell": in background there is a grid, but with this "trick" you can transform it as your layout.
This is a useful guide for more informations about CSS grid: https://css-tricks.com/snippets/css/complete-guide-grid/
Another solution is to use flexbox also for those rows :-)
Try it:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #969d9f;
}
header {
width: 100%;
/*height: 100vh;*/
display: flex;
justify-content: center;
background-color: #969d9f;
}
.grid-wrapper {
border: 1px solid red;
width: 100%;
max-width:1200px;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(4, 1fr);
grid-template-areas:
"item1 item1 item1 item2"
"item3 item4 item4 item4"
"item5 item5 item5 item5";
}
.item1, .item2, .item3, .item4, .item5 {
border: 1px solid grey;
background-color: #636564;
height: 360px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 40px;
}
/*.item1 { width: 750px; }
.item2 { width: 360px; }
.item3 { width: 555px; }
.item4 { width: 555px; }
.item5 { width: 1200px; }*/
.item1 {
grid-area: item1;
}
.item2 {
grid-area: item2;
}
.item3 {
grid-area: item3;
}
.item4 {
grid-area: item4;
}
.item5 {
grid-area: item5;
}
<header>
<div class="grid-wrapper">
<div class="item1"><span>Item 1</span></div>
<div class="item2"><span>Item 2</span></div>
<div class="item3"><span>Item 3</span></div>
<div class="item4"><span>Item 4</span></div>
<div class="item5"><span>Item 5</span></div>
</div>
</header>
P.S. Maybe it is better don't use a fixed widths in a world of mobile device, so I changed your witdh:1200px with a max-width:1200px, but well you can change it
if you do not care about it ;-)
Essentially what I need to happen is to set up a grid, but if one of the elements is missing, another element stretches to fill the space.
This is an example Pen of where I'm currently at:
https://codepen.io/Rockster160/pen/JMLaXY
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto 50px;
grid-template-areas: "sidebar header"
"sidebar content"
"sidebar footer";
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
.footer {
grid-area: footer;
background: orange;
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<!-- <div class="footer"></div> -->
</div>
footer is an optional element, so when it doesn't exist (commented out as in the code) then content should stretch and line up with the bottom of sidebar.
I've tried a variety of different combinations using min/max content and different auto placements, but no luck. I thought if I had multiple elements named content it might work as well, but no luck there either.
Any help is greatly appreciated!
You are forcing the 3rd row to be 50px in the grid style.
Change it to be adapted to the content, and set the 50px as height in the footer itself:
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto max-content; /* changed last 50px to max-content*/
grid-template-areas: "sidebar header"
"sidebar content"
"sidebar footer";
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
.footer {
grid-area: footer;
background: orange;
height: 50px; /* added */
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<!-- <div class="footer"></div> -->
</div>
And another posibility, thanks to Michael_B. The sintax of grid-template-rows is clearer:
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px 1fr auto;
grid-template-areas: "sidebar header"
"sidebar content"
"sidebar footer";
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
.footer {
grid-area: footer;
background: orange;
height: 50px; /* added */
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
The easiest way to do this is to use the :last-child selector:
.content:last-child {
grid-row: content / footer;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto 50px;
grid-template-areas: "sidebar header" "sidebar content" "sidebar footer";
margin-bottom: 2rem;
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
.content:last-child {
grid-row: content / footer;
}
.footer {
grid-area: footer;
background: orange;
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<!-- <div class="footer"></div> -->
</div>
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
Or, alternatively, we could reverse the order of the .content and .footer elements in the HTML (as below) and use the CSS negation operator (:not()) to determine that the .content element should take up extra space if it is not preceded by a .footer element:
:not(.footer) + .content {
grid-row: content/footer;
}
which styles a .content element that is not immediately preceded by a .footer sibling in such a way that it starts in the grid-row identified by content and ends in the grid-row identified by footer:
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto 50px;
grid-template-areas: "sidebar header" "sidebar content" "sidebar footer";
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
:not(.footer)+.content {
grid-row: content/footer;
}
.footer {
grid-area: footer;
background: orange;
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<!-- <div class="footer"></div> -->
</div>
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
References:
grid-row.
:last-child.
Negation pseudo-class:not().
Sometimes things are simpler with flexbox.
Since your container has a defined height (the viewport), you can use flex-flow: column wrap to create both columns.
Then use flex: 1 on the content item, which tells it to consume free space.
When the footer is present, the content makes space for it. When the footer is not present, the content consumes all space.
.grid {
display: flex;
flex-flow: column wrap;
height: 100vh;
background: white;
border: 2px solid red;
}
.sidebar {
flex: 0 0 100%;
width: 250px;
background: green;
}
.header {
flex: 0 0 100px;
width: calc(100% - 250px);
background: lightblue;
}
.content {
flex: 1;
width: calc(100% - 250px);
border: 5px solid black;
background: blue;
}
.footer {
flex: 0 0 50px;
width: calc(100% - 250px);
background: orange;
}
body { margin: 0; }
div { box-sizing: border-box; }
<!-- WITH FOOTER -->
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
<hr>
<!-- WITHOUT FOOTER -->
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
</div>
Change your .grid class to
.grid {
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto 50px;
grid-template-areas:
"sidebar header"
"sidebar content"
"sidebar content";
}
when you comment your footer tag as in your pen, grid is still waiting to have a footer element there, so it's kinda "saving space" for this element there