Hi Guys I need help displaying layout in CSS. Here is i want the layout to display like.
Here is what i have so far in CSS but can't get the menu zone to fully expand down height. Any suggestions? i'm using display grid as layout.
.page{
display: grid;
grid-template-columns:29% 71%;
justify-content: flex-start;
align-content: start;
}
.section-header{
grid-column: 1/3;
display:grid
grid-row:row;
background-color:blue;
color:#fff;
}
.zone-menu-wrapper{
grid-row:1/3;
background-color:#286dc5;
}
.zone-topper-wrapper{
grid-row:1/3;
}
.section-main{
grid-column:2/3;
background-color:orange;
}
.section-footer{
grid-column: 2/3;
background-color:yellow;
}
.zone-branding-wrapper{
grid-column:2/3;
}
.zone-menu{
width:29%;
display:inline-block;
}
<div class="page">
<header class="section-header">
<div class="zone-topper-wrapper">Top Zone</div>
<div class="zone-menu-wrapper">Menu Zone</div>
</header>
<main class="section-main">
<div class="zone-branding-wrapper">Branding Zone</div>
<div class="zone-content-wrapper">Content Zone</div>
</main>
<footer class="section-footer">
<div class="zone-footer-wrapper">Footer Zone</div>
</footer>
</div>
</pre>
Here's a flexbox solution that will give you greater support than grid columns. If you don't like flexbox you can always use a float based solution which would have even greater support.
I won't go into a lot of detail but the key takeaways are:
flex-grow, tells the element to take up the remaining space of it's parent element. Very handy for stretching elements out to unknown widths, also flexible.
min-height: 100vh in body, this allows the layout to take up the full viewport if their is not enough content to fill it. This also provides a context in which flex-grow can grow into. Without min-height: 100vh; flex-grow doesn't have any space to stretch elements out in.
100vh for min-height, uses viewport units to establish the minimum height the body element can be. 100vh, says use 100% of vertical height (vh) of viewport.
body {
display: flex;
flex-direction: column;
margin: 0;
min-height: 100vh;
}
.wrap {
display: flex;
flex-direction: row;
flex-grow: 1;
background-color: indianred;
}
.content {
display: flex;
flex-direction: column;
flex-grow: 1;
}
header {
background-color: darkseagreen;
}
aside {
background-color: skyblue;
}
main {
flex-grow: 1;
background-color: gold;
}
<header>
Header
</header>
<div class="wrap">
<aside>
Sidebar
</aside>
<div class="content">
<main>
Main
</main>
<footer>
Footer
</footer>
</div>
</div>
with grid, you may use just the minimal semantic markup needed:
body {
display: grid;
grid-template-columns: 29% 71%;
grid-template-rows: auto 1fr auto;
grid-template-areas: "header header" "nav main" "nav footer";
height: 100vh
}
header {
grid-area: header ;
}
nav {
grid-area: nav ;
grid-column: 1;
}
main,
footer {
grid-column: 2;/* or grid-area for each of them */
}
/*makup*/
header,
nav {
background: tomato;
}
main {
background: turquoise
}
footer {
background: orange;
}
body>* {
padding:1em;
box-shadow:0 0 1px
}
<header>header</header>
<nav> nav </nav>
<main> main</main>
<footer>footer</footer>
<div class="page">
<header class="section-header">
<div class="zone-topper-wrapper">Top Zone</div>
</header>
<div class="zone-menu-wrapper">Menu Zone</div>
<main class="section-main">
<div class="zone-branding-wrapper">Branding Zone</div>
<div class="zone-content-wrapper">Content Zone</div>
</main>
<footer class="section-footer">
<div class="zone-footer-wrapper">Footer<br> Zone</div>
</footer>
</div>
CSS
.page{
display: grid;
grid-template-columns:29% 71%;
justify-content: flex-start;
align-content: start;
}
.section-header{
grid-column: 1/3;
display:grid
grid-row:row;
background-color:blue;
color:#fff;
}
.zone-menu-wrapper{
grid-row:2/4;
background-color:#286dc5;
}
.zone-topper-wrapper{
grid-row:1/3;
}
.section-main{
grid-column:2/3;
background-color:orange;
}
.section-footer{
grid-column: 2/3;
background-color:yellow;
}
.zone-branding-wrapper{
grid-column:2/3;
}
.zone-menu{
width:29%;
display:inline-block;
}
https://codepen.io/ak472526/pen/dvLaGX
Related
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.
I have two divs (div1 and div2) side by side and I would like to place a third div (div3) under div2.
I've tried adding a margin to div3 to try and line it up, but div1 width is dynamic. I've also tried floating div3 to the right but then the content is too far and doesn't line up with the start of div2 like in the image above
.row {
display: flex;
}
.div1 {
margin-right: 1em;
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
</div>
<div class="div3">
<p> some content that should be under div2 </p>
</div>
The default behaviour is div3 being under div1. I am trying to put div3 below div 2
You can do this with below:
.wrapper {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
}
.div {
flex-basis: 50%;
min-height: 100px;
}
.div1 {
background: red;
}
.div2 {
background: blue;
}
.div3 {
background: aqua;
}
<div class="wrapper">
<div class="div div1">div1</div>
<div class="div div2">div2</div>
<div class="div div3">div3</div>
</div>
And here is a codepan
Use float and inline-block:
[class*="div"] {
display:inline-block;
border:2px solid;
}
.div1 {
float:left;
margin-right: 1em;
margin-bottom:10px; /*mandatory margin to push the div3*/
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
</div>
<div class="div3">
<p> some content that should be under div2 </p>
</div>
You can make use of the CSS Grid structure. In this way you can have all child elements inside a single parent container.
.row {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
grid-column-gap: 5px;
grid-row-gap: 5px;
}
.div1 {
grid-area: 1 / 1 / 2 / 2;
}
.div2 {
grid-area: 1 / 2 / 2 / 3;
}
.div3 {
grid-area: 2 / 2 / 3 / 3;
}
/* Snippet styling */
.row > div {
background: #6A67CE;
color: white;
text-align: center;
text-transform: capitalize;
font-family: sans-serif;
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
<div class="div3">
<p> some content under div2 </p>
</div>
</div>
Here is a flex solution, you can use the slider to change the width of the left box to see that the width doesn't matter.
In case you are not familiar with flex, here is what happens.
display: flex; tells the container to act as a flex container, flex is just another display behavior just like float.
flex-flow: row wrap;, now that the container is flex, tells the children to display in a row, and wrap if necessary, not in this case.
That is all, after adding two boxes in the right div, and set some demo width and height, we are done.
window.addEventListener('DOMContentLoaded', e => {
let left = document.querySelector('.left')
let range = document.querySelector('.range')
range.addEventListener('input', e => {
left.style.width = e.target.value + 'px'
})
})
div {
border: 3px solid green;
}
.container,
.right {
border: none;
}
.container {
display: flex;
flex-flow: row wrap;
}
.left,
.one,
.two {
min-width: 50px;
min-height: 50px;
}
.left {
margin-right: 1em;
}
.one {
min-width: 80px;
}
.two {
margin-top: 1em;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="one"></div>
<div class="two"></div>
</div>
</div>
<input class="range" type="range" min="50" max="300"></input>
Since div do not share the same parent , you could use display:contents and set a grid-layout one level upper , unfortunately, display:contents is not yet supported every where .
here is an example (body is the wrapper and .row not seen anymore)
body {
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 10px;
}
.row {
display: contents;
/* removed from the tree */
}
div {
border: solid;
/* show me */
grid-column: 2;
/* make it the defaut column position */
width: max-content;
}
.div1 {
grid-column: 1;
/*a single reset enough here */
}
#supports (display:grid) {
.disclaimer {
display: none;
}
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
</div>
<div class="div3">
<p> some content that should be under div2 </p>
</div>
<p class="disclaimer">Your browser do not support <code>display:contents</code>.</p>
Another possibility is the table-layout algorythm
example with display:table (widely supported) , but every cell of each columns are of the same width.
body {
display: table;
border-spacing: 10px;
}
.div3,
.row {
display: table-row;
}
.row>div,
.div3>p,
.div3::before {
display: table-cell;
border: solid;
}
.div3::before {/* it stands in column 1 */
content: '';
border: none;
}
<div class="row">
<div class="div1">
<p> some content with unknown width</p>
</div>
<div class="div2">
<p> some content </p>
</div>
</div>
<div class="div3">
<p> some content that should be under div2 </p>
</div>
Nothing is perfect ;)
hi i coded this if that helps
.first-container {
display: flex;
flex-direction: row;
}
.first-container div{
margin: 10px;
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<div class="container">
<div class="first-container">
<div class="first">first</div>
<div class="second">second</div>
</div>
<div class="third">third</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)
I'm trying to accomplish this design by using flexbox:
It's supposed to be a one page website.
.container {
display: flex;
}
.big {
flex: 2;
height: 70vh;
background: gray;
}
.small {
flex: 1;
height: 70vh;
background: gray;
}
<div class="container">
<div class="small">
</div>
<div class="smallest">
</div>
<div class="big">
</div>
</div>
I have no idea how to implement the "smallest" div to be 25% of the big, let alone make the "small" 75% of the big one.
Also the height really confuses me, I need them to always have the same height.
With flexbox you can wrap the small and the smallest into a separate div and use column flexbox on the left section.
I have no idea how to implement the "smallest" div to be 25% of the big
25% to 75% ratio means 1:3 ratio - and in flexbox language that is flex: 1 to the small element and flex: 3 to the big element.
Also the height really confuses me, I need them to always have the same height.
You can set the height of the container to the container element - your flexbox will fill to this height.
See demo below:
.container {
display: flex;
height: 70vh;
}
.big {
flex: 3;
background: gray;
margin-left: 5px;
}
.left {
flex: 1;
display: flex;
flex-direction: column;
}
.left .small {
background: gray;
flex: 3;
}
.left .smallest {
margin-top: 5px;
background: gray;
flex: 1;
}
<div class="container">
<div class="left">
<div class="small">
</div>
<div class="smallest">
</div>
</div>
<div class="big">
</div>
</div>
https://codepen.io/masm/pen/MxWBEB
Hello there,
I am trying to create a basic, responsive layout using CSS Grid and Flexbox. However I'm coming across some issues with the header. I don't full understand why the logo and nav aren't spanning across the 960px width.
HTML:
<div id="hd">
<div class="container">
<div class"ct">
<div class="logo">
Logo
</div>
<div class="nav">
one
two
three
four
five
</div>
</div>
</div>
CSS:
.container {
width: 960px;
margin: 0 auto;
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-areas: "top top"
"main side"
}
.ct {
grid-area: top;
}
.logo {
background: #ddd;
}
.nav {
background: #ddf;
}
Secondly, I am trying to make it so that the logo and nav are side by side. My idea was to set .ct to display:flex, however it does not work.
.ct {
grid-area: top;
display: flex;
flex-direction: column;
}
Lastly, I want the background colors of the header to span the full width of the page, and the content (logo, nav, main, side) to take up no more than the 960px width, which is why I added a container in between the #hd and #main divs. My question here is, is this a good approach?
Issues I have noted in your code are the following,
you forgot to add "=" before the class name. ie " "
then you put "flex-direction: column;"
Please check the following fiddle. Hope that's what you are looking for
Try this fiddle
.ct {
grid-area: top;
display: flex;
flex-direction: row;
}
For side by side, you need to place them row-wise and in the center align the content of the div vertically, Also give some predefined height to it:
.ct{
height: 80px;
display: flex;
justify-content: flex-start;
align-items:center;
flex-flow: row;
}
Remove flex-direction: column; and there is no = after class ct
<div class="ct">
#hd {
background: #444;
}
.container {
width: 960px;
margin: 0 auto;
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-areas: "top top"
"main side"
}
.ct {
grid-area: top;
display: flex;
flex-direction: column;
}
.logo {
background: #ddd;
}
.nav {
background: #ddf;
}
.main {
background: #ee0099;
grid-area: main;
}
.side {
background: #efefef;
grid-area: side;
}
.ct {
grid-area: top;
display: flex;
flex-direction: column;
}
<div id="hd">
<div class="container">
<div class="ct">
<div class="logo">
Logo
</div>
<div class="nav">
one
two
three
four
five
</div>
</div>
</div>
</div>
<div id="mn">
<div class="container">
<div class="main">
<p>hello</p>
</div>
<div class="side">
<p>hello</p>
</div>
</div>
</div>