I don´t manage to get a responsive result keeping the same HTML layout.
I need :
two different block orders if the screen width is before or after 1024px,
=> 1024px, I have to display items organized in two columns and make sure blocks 1, 2, 3 are inside the left column and blocks 4, 5 are inside the right column (the height of the wrapper has to fit of the content ),
< 1024px, all blocks are inside unique column but the order is different.
Like this...
1024px and more
1023px and less
Current CSS
#media screen and (max-width: 1023px) {
.production-container{
display: grid;
grid-template-columns: repeat(1, 1fr);
padding: 0 var(--standard-margin) 0 var(--standard-margin);
justify-content: stretch;
min-height: 200px;
}
aside.production-block{
max-width: 100vw;
width: 100%;
display: flex;
flex: 1;
flex-direction: column;
margin: 24px 0;
display: grid;
grid-template-rows: 1fr auto;
break-inside: avoid;
}
.production-container > .production-block-4 {
order: 1;
}
.production-container > .production-block-1 {
order: 2;
}
.production-container > .production-block-2 {
order: 3;
}
.production-container > .production-block-5 {
order: 4;
}
.production-container > .production-block-3 {
order: 5;
}
}
#media screen and (min-width: 1024px) {
.production-container{
column-count: 2;
column-gap: 50px;
max-width: 1024px;
background: linear-gradient( var(--text-light-color), var(--text-light-color) ) no-repeat center/1px 100%; /* vertical line in the center */
}
.production-block {
margin: 0 0 10px 0;
break-inside: avoid;
max-width: 520px;
}
}
The most important problem is, in the biggest resolution, I don´t manage to force each block to be on the first or second column, they place thereself naturally based on height content. Maybe, I should change of css strategy compatible with the smallest resolution but when I used "grid", each row got a height that made big blank spaces.
Someone has got an idea ?
You can switch from a grid layout to a column CSS layout (untill masonry CSS grid layout is widely avalaible https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Masonry_Layout , here is an example https://codepen.io/gc-nomade/pen/ExXNXdd For FF at this time if activated)
Demo from your HTML code in the snippet lower below withouth blank space
How does it work ?
1 - < 1024px grid for the single column to use order (grid creates a single column if no template is set)
2 - > 1023px column-count and display:block for a 2 column layout . break-after:always & break-before: column will be avalaible for browsers using the chrome engine (see CSS Fragmentation ).
3 - For firefox & >1023px a hudge margin-bottom on the third element, so there can be only 3 on the first column. This margin won't be applied inside the container, npr will be overflowing it, it will only push the fourth on the next column.
Firefox can be filtered via (untill it understands break-after:always with Column CSS) to apply the margin trick only for Firefox browsers use :
#-moz-document url-prefix() {
.grid > div:nth-child(3) {
margin-bottom:100%;
}
}
Live Example where the main container takes only the height needed to wrap the 2 columns, no matter the height of the children, you will notice that on the second example, where col 2 is taller, Chrome(s) seem follows the breaking rules, the first column do not need to be the tallest one.
.grid {
display: grid;
gap: 1em;
border:solid;
background:gray;
}
.grid > div:nth-child(1) {
order: 1;
}
.grid > div:nth-child(2) {
order: 2;
}
.grid > div:nth-child(3) {
order: 4;
}
.grid > div:nth-child(4) {
order: 0;
}
.grid > div:nth-child(5) {
order: 3;
}
#media (min-width: 1024px) {
.grid {
display: block;
column-count: 2;
}
.grid > div {
margin-bottom: 1em;
}
.grid > div:nth-child(3) {
break-after:always;
}
.grid> div:nth-child(4) {
break-before: column;
}
#-moz-document url-prefix() {
.grid > div:nth-child(3) {
margin-bottom:100%;/* trick for FF that won't show that margin if the last inside a column but not in the last column */
}
}
}
/* demo */
.grid {
counter-reset: divs;
}
.grid > div {
display: grid;
}
.grid > div::before {
counter-increment: divs;
content: counter(divs);
color: white;
margin: auto;
font-size: clamp(10px, 5vmin, 30px);
}
.grid > div:nth-child(1) {
background: #fa9917;
height: 100px;
}
.grid > div:nth-child(2) {
background: #33e0fe;
height: 160px;
}
.grid > div:nth-child(3) {
background: #ff3366;
height: 80px;
}
.grid > div:nth-child(4) {
background: #2bc940;
height: 80px;
}
.grid > div:nth-child(5) {
background: #3399fe;
height: 160px;
}
<div class=grid>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Hello the world
<hr>
Make second column taller to see where the fourth stands before you test or ask ;)
<div class=grid>
<div></div>
<div></div>
<div></div>
<div></div>
<div style="height:600px"></div>
</div>
Finally, i would advise to use a tiny bit of javascript, or the well known and solid masonry library to avoid that FF CSS tricks. Tricks can become obsolete anytime ;)
No idea about Safari behavior about CSS Fragmentation.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fragmentation
CSS Fragmentation is a module of CSS that defines how content is displayed when it is broken (fragmented) across multiple pages, regions, or columns.
Fragmentation occurs when an inline box wraps onto multiple lines. It also occurs when a block spans more than one column inside a column layout container, or spans a page break when printed. Each piece of the rendering for the element is called a fragment.
about the native CSS grid masonry, you can see & read : https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/
I found a solution with grid-template-areas.
#media screen and (min-width: 1024px) {
.production-container{
height: 100%;
display: grid;
grid-template-areas: "zone-row1-column1 zone-row1-column2" "zone-row2-column1 zone-row2-column2" "zone-row3-column1 zone-row3-column2";
grid-template-rows: minmax(290px, auto) 1fr;
grid-template-columns: 1fr 1fr;
grid-gap: 50px;
max-width: 1024px;
background: linear-gradient( var(--text-light-color), var(--text-light-color) ) no-repeat center/1px 100%; /* vertical line in the center */
}
.production-container > .production-block-4 {
grid-area: zone-row1-column2;
}
.production-container > .production-block-1 {
grid-area: zone-row1-column1;
}
.production-container > .production-block-2 {
grid-area: zone-row2-column1;
}
.production-container > .production-block-5 {
grid-area: zone-row2-column2;
}
.production-container > .production-block-3 {
grid-area: zone-row3-column1;
}
}
You must add "zone-row3-column2" even if it does not use inside grid-template-areas because there are 2 columns anyway.
#media screen and (min-width: 1024px) {
.production-container{
padding: 0 var(--standard-margin) 0 var(--standard-margin);
min-height: 200px;
}
.production-block {
border: 1px solid blue;
width:50%;
}
.production-block-1{
float: left;
clear:left
}
.production-block-2{
float: left;
clear:left
}
.production-block-3{
float: left;
clear:left
}
.production-block-4{
margin-left:50%
}
.production-block-5{
margin-left:50%
}
}
Actually it works, you're almost done.
Just add the orders to:
#media screen and (min-width: 1024px) {
.production-container{
column-count: 2;
column-gap: 50px;
max-width: 1024px;
background: linear-gradient( var(--text-light-color), var(--text-light-color) ) no-repeat center/1px 100%; /* vertical line in the center */
}
.production-block {
margin: 0 0 10px 0;
break-inside: avoid;
max-width: 520px;
border: 1px solid red;
}
.production-container > .production-block-4 {
order: 1;
}
.production-container > .production-block-1 {
order: 2;
}
.production-container > .production-block-2 {
order: 3;
}
.production-container > .production-block-5 {
order: 4;
}
.production-container > .production-block-3 {
order: 5;
}
}
I don´t manage to force each block to be on the first or second
column, they place thereself naturally based on height content.
In that case, you can manage the grid with grid-row-start and grid-row-end
when I used "grid", each row got a height that made big blank spaces.
For this solution you try to set height with height: min-content. If the block doesn't have any contents it's collapse. But, should be remember about padding, they give extra height without the content.
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
:root {
--bg1: hsl(34, 96%, 54%);
--bg2: hsl(189, 99%, 60%);
--bg3: hsl(345, 100%, 60%);
--bg4: hsl(128, 65%, 48%);
--bg5: hsl(210, 99%, 60%);
--standard-margin: 1rem;
}
.production-block-1,
.production-block-2,
.production-block-3,
.production-block-4,
.production-block-5 {
height: min-content;
display: flex;
justify-content: center;
align-items: center;
color: white;
padding: 1rem;
}
.production-block-1 {
grid-row-start: 2;
background-color: var(--bg1);
}
.production-block-2 {
grid-row-start: 3;
background-color: var(--bg2);
}
.production-block-3 {
grid-row-start: 5;
background-color: var(--bg3);
}
.production-block-4 {
grid-row-start: 1;
background-color: var(--bg4);
}
.production-block-5 {
grid-row-start: 4;
background-color: var(--bg5);
}
.production-container {
display: grid;
gap: 1rem;
}
#media screen and (max-width: 1023px) {
.production-container {
grid-template-columns: repeat(1, 1fr);
padding: 0 var(--standard-margin) 0 var(--standard-margin);
}
}
#media screen and (min-width: 1024px) {
.production-container {
grid-template-columns: repeat(2, 1fr);
}
.production-block-1 {
grid-row-start: 1;
}
.production-block-2 {
grid-row-start: 2;
}
.production-block-3 {
grid-row-start: 3;
}
.production-block-4 {
grid-row-start: 1;
}
.production-block-5 {
grid-row-start: 2;
}
}
<div class="production-container">
<div class="production-block-1">1</div>
<div class="production-block-2">2</div>
<div class="production-block-3">3</div>
<div class="production-block-4">4</div>
<div class="production-block-5">5</div>
</div>
I found a better solution that used grid to make two columns.
Notice : when you use grid, that forces the template to be aligned with columns and rows as well that can make blank space when blocks on the same row have not a similar height...
Template that makes blank spaces
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
:root {
--bg1: hsl(34, 96%, 54%);
--bg2: hsl(189, 99%, 60%);
--bg3: hsl(345, 100%, 60%);
--bg4: hsl(128, 65%, 48%);
--bg5: hsl(210, 99%, 60%);
--standard-margin: 1rem;
}
.production-block-1,
.production-block-2,
.production-block-3,
.production-block-4,
.production-block-5 {
height: min-content;
display: flex;
justify-content: center;
align-items: center;
color: white;
padding: 1rem;
}
.production-block-1 {
grid-row-start: 2;
background-color: var(--bg1);
}
.production-block-2 {
grid-row-start: 3;
background-color: var(--bg2);
}
.production-block-3 {
grid-row-start: 5;
background-color: var(--bg3);
}
.production-block-4 {
grid-row-start: 1;
background-color: var(--bg4);
}
.production-block-5 {
grid-row-start: 4;
background-color: var(--bg5);
}
.production-container {
display: grid;
gap: 1rem;
}
#media screen and (max-width: 1023px) {
.production-container {
grid-template-columns: repeat(1, 1fr);
padding: 0 var(--standard-margin) 0 var(--standard-margin);
}
}
#media screen and (min-width: 1024px) {
.production-container {
grid-template-columns: repeat(2, 1fr);
}
.production-block-1 {
grid-row-start: 1;
height: 150px;
}
.production-block-2 {
grid-row-start: 2;
height: 200px;
}
.production-block-3 {
grid-row-start: 3;
}
.production-block-4 {
grid-row-start: 1;
height: 300px;
}
.production-block-5 {
grid-row-start: 2;
height: 250px;
}
}
<h1>Grid template with blank spaces</h1>
<div class="production-container">
<div class="production-block-1">1</div>
<div class="production-block-2">2</div>
<div class="production-block-3">3</div>
<div class="production-block-4">4</div>
<div class="production-block-5">5</div>
</div>
My Solution (Masonry + break column)
To avoid blank spaces, you have a solution based on Masonry with flexbox and add a break column inside the HTML template.
Notice : That solution needs :
add a html tag with break-column class
use height: 100%; on wrappers html tags.
The orders of the biggest resolution is the order in the html template, it is for the smallest resolution, you change the order.
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
:root {
--bg1: hsl(34, 96%, 54%);
--bg2: hsl(189, 99%, 60%);
--bg3: hsl(345, 100%, 60%);
--bg4: hsl(128, 65%, 48%);
--bg5: hsl(210, 99%, 60%);
--standard-margin: 1rem;
}
body, html{
height: 100%;
}
.production-block-1,
.production-block-2,
.production-block-3,
.production-block-4,
.production-block-5 {
height: min-content;
display: flex;
justify-content: center;
align-items: center;
color: white;
padding: 1rem;
}
.production-block-1 {
grid-row-start: 2;
background-color: var(--bg1);
}
.production-block-2 {
grid-row-start: 3;
background-color: var(--bg2);
}
.production-block-3 {
grid-row-start: 5;
background-color: var(--bg3);
}
.production-block-4 {
grid-row-start: 1;
background-color: var(--bg4);
}
.production-block-5 {
grid-row-start: 4;
background-color: var(--bg5);
}
.production-container {
display: grid;
gap: 1rem;
}
#media screen and (max-width: 1023px) {
.production-container {
grid-template-columns: repeat(1, 1fr);
padding: 0 var(--standard-margin) 0 var(--standard-margin);
}
}
#media screen and (min-width: 1024px) {
.production-container {
display: flex;
flex-flow: column wrap;
max-width: 1024px;
height: 100%;
background: linear-gradient( var(--text-light-color), var(--text-light-color) ) no-repeat center/1px 100%;
}
/* Force new columns */
.production-container::before,
.production-container::after {
content: "";
flex-basis: 100%;
width: 0;
order: 2;
}
.break-column {
flex-basis: 100%;
width: 0 !important;
}
.production-container > .production-block{
width: 500px;
}
.production-block-1 {
height: 150px;
}
.production-block-2 {
height: 200px;
}
.production-block-4 {
height: 300px;
}
.production-block-5 {
height: 250px;
}
}
<h1>Masonry solution without blank space</h1>
<div class="production-container">
<div class="production-block production-block-1">1</div>
<div class="production-block production-block-2">2</div>
<div class="production-block production-block-3">3</div>
<div class="break-column"></div>
<div class="production-block production-block-4">4</div>
<div class="production-block production-block-5">5</div>
</div>
I'm new to CSS Grid and trying to learn how it works. I've found a layout that I've been playing around with but I can't seem to figure out how to get the article to span the entire width of the footer/header. I've tried changing the grid-template-columns but and get pretty close to spanning it but not all the way.
Any tips would be greatly appreciated!
.grid {
display: grid;
grid-template-columns: 150px auto 0px;
grid-gap: 1em;
}
header,
footer {
grid-column: 1 / 4;
}
#media all and (max-width: 800px) {
aside,
article {
grid-column: 1 / 4;
}
}
/* Demo Specific Styles */
body {
margin: 0 auto;
max-width: 56em;
padding: 1em 0;
}
header,
aside,
article,
footer {
background: #eaeaea;
display: flex;
align-items: center;
justify-content: center;
height: 25vh;
}
header {
height: 250px;
}
<div class="grid">
<header>
Header
</header>
<aside class="sidebar-left">
Left Sidebar
</aside>
<article>
Article
</article>
<footer>
Footer
</footer>
</div>
I can't seem to figure out how to get the article to span the entire width of the footer/header.
You have created a 3-column grid:
grid-template-columns: 150px auto 0px
You've set the header and footer to span across all three columns:
header, footer {
grid-column: 1 / 4;
}
However, the article has no such instruction. It simply expands across column two, because that's the default setting (i.e., grid-column { 2 / auto }).
Therefore, you need to tell the article to expand across the third column. Add this to your code:
article {
grid-column: 2 / 4;
}
.grid {
display: grid;
grid-template-columns: 150px auto 0px;
grid-gap: 1em;
}
header,
footer {
grid-column: 1 / 4;
}
/* new */
article {
grid-column: 2 / 4;
}
#media all and (max-width: 800px) {
aside,
article {
grid-column: 1 / 4;
}
}
/* Demo Specific Styles */
body {
margin: 0 auto;
max-width: 56em;
padding: 1em 0;
}
header,
aside,
article,
footer {
background: #eaeaea;
display: flex;
align-items: center;
justify-content: center;
height: 25vh;
}
header {
height: 250px;
}
<div class="grid">
<header>Header</header>
<aside class="sidebar-left">Left Sidebar</aside>
<article>Article</article>
<footer>Footer</footer>
</div>
I am currently creating some pages as part of the Free Code Camp CSS challenges.
For some reason my tags are not properly centering once I collapse the grid upon the #media activation. They keep slightly drifting to the right side.
The link for the complete pen is here:
https://codepen.io/alioshr/pen/KKPBPMr
I have already tried using inline-block display, justify-self to center, etc.
<html>
<header id="header">
<figure>
<img id="header-img"src="https://cdn.shopify.com/s/files/1/0866/9666/files/checkout_logo_4_1024x2_37df55d3-8344-46fb-8913-ea64de22f564_500x.png?v=1509363172">
</figure>
<div>
<h1>Doce Meliponicultura</h1>
<p>Reconnect with Mother-nature</p>
</div>
<nav id="nav-bar">
<ul>
<li>Top Features</li>
<li>Products</li>
<li>Social</li>
</ul>
</nav>
</header>
</html>
<style>
a {text-decoration: none; display: inline-block;}
#header {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
background: gold;
align-items: center;
justify-self: center;
position: fixed;
top: 0;
left:0;
width: 100%;
z-index: 99;
}
#media (max-width: 600px) {
#header {grid-template-areas: "title" "logo" "nav-bar";}
#header > figure {grid-area: logo;}
#header > div {grid-area: title;}
#header > nav {grid-area: nav-bar;}
}
#header > figure {
justify-self: start;
align-self: center;
display: relative;
max-height: 140px;
}
#media (max-width: 600px) {
#header > figure {
justify-self: center;
}
}
#header > nav {
justify-self: end;
}
#media (max-width: 600px) {
#header > nav {
justify-self: center;
}
}
</style>
You can add below CSS in your #media (max-width: 600px)
#header > nav > ul{
padding: 0px;
}
It will fix your issue.
I'll add my answer as well, to give a bit more info about Flexbox set up. Basically I removed all the CSS Grid syntax in favor of Flexbox. I'm not sure what exactly you're going for, but this will give you an idea of how to get it working at a minimum.
#header {
display: flex;
background: gold;
align-items: center;
justify-content: space-around;
width: 100%;
}
#media (max-width: 600px) {
#header {
flex-direction: column;
}
}
#header>figure {
justify-self: flex-start;
align-self: center;
max-height: 140px;
}
#media (max-width: 600px) {
#header>figure {
justify-self: center;
}
}
#header>nav {
justify-self: flex-end;
}
#media (max-width: 600px) {
#header>nav {
justify-self: center;
}
}
Here is my working fiddle (the codepen link you supplied never loaded for me).
Here is a really great resource on learning what all the Flexbox rules do, etc
A Complete Guide to Flexbox
I am trying to achieve a simple clean minimalistic responsive layout in CSS3 Flex, where:
A) in the desktop mode the body contains three vertical elements side by side "all in one row", and;
B) an alternative vertical oriented mobile version mode where the body contains the elements as rows on top of eachother, "all in one column".
But my code is broken somewhere as I dont see the mobile version kicking in when resizing the the window to narrow vertical orientation. What am I missing?
*{
margin: 0;
padding: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
display: flex;
min-height: 100vh;
flex-direction: row;
flex: 1;
background: yellow;
}
main {
flex: 2;
background: tomato;
}
nav {
flex: 1;
background: tan;
}
aside {
flex:1;
background: thistle;
}
/* FOR MOBILE PHONES */
#media only screen and (orientation: vertical) and (max-width: 768px) {
body{
flex-direction: column;
}
main {
background: crimson; /* test to see if mobile mode is activated */
}
}
<body>
<main>content</main>
<nav>nav</nav>
<aside>aside</aside>
</body>
orientation: can be portrait or landscape:
body {
display: flex;
min-height: 100vh;
flex-direction: row;
flex: 1;
background: yellow;
}
main {
flex: 2;
background: tomato;
}
nav {
flex: 1;
background: tan;
}
aside {
flex: 1;
background: thistle;
}
/* FOR MOBILE PHONES */
#media only screen and (orientation: portrait) {
body {
flex-direction: column;
}
main {
background: crimson;
}
}
<body>
<main>content</main>
<nav>nav</nav>
<aside>aside</aside>
</body>
I've got a form with a couple areas to it and I've been trying to figure out how to get flexbox to lay something out like this:
If possible, how could I do this while using the least amount of parent containers? (Or, why might I not want to do that?)
Stumped enough by not having achieved this that I think asking is the right move. Still wrapping my head around it all.
.wrapper {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
flex: 1 100%;
}
.header {
background: tomato;
}
.footer {
background: lightgreen;
}
.main {
text-align: left;
background: deepskyblue;
}
.aside-1 {
background: gold;
}
.aside-2 {
background: hotpink;
}
#media all and (min-width: 600px) {
.aside { flex: 1 auto; }
}
#media all and (min-width: 800px) {
.main { flex: 3 0px; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}
body {
padding: 2em;
}
<div class="wrapper">
<header class="header">Header</header>
<aside class="aside aside-1">Aside 1</aside>
<aside class="aside aside-2">Aside 2</aside>
<footer class="footer">Footer</footer>
</div>
Modified from an example found here. Full credit to css-tricks.
Edit: highly recommend that css-tricks article. Very helpful resource for all things flexbox
you can build this layout from body with a few CSS lines:
html,
body {
height: 100%;/* or 100vw just for body */
margin:0 /* reset */
}
body,
section {
display: flex;
}
/* eventually : section {overflow:auto} if you want to keep footer down the screen no matter how much content */
body {
flex-flow: column;
}
section,
article {
flex: 1;/* use whole space avalaible if only child or share it evenly when multiple children */
}
/* add borders to see elements */
header,
footer,
article {
border: solid;
padding: 1em;
}
/* break point without mediaqueries ?
uncomment this below */
/* article {
min-width:320px;/* 2 articles make break point at average 640px */
}*/
<header>
header any height
</header>
<section>
<article>Side</article>
<article>Side</article>
</section>
<footer>
footer any height
</footer>
http://codepen.io/gc-nomade/pen/WGazGX to play with (or download code samples)