I've been trying to make a few layouts for specific sizes.
As shown in the picture above, I tried to create two layouts, PC and mobile.
Making a PC was easy. SectionA and SectionB were configured through the flex layout, and SectionC was configured below it.
The problem was with Mobile. SectionA and SectionB are tied together in a flex layout, so I couldn't think of a way to put SectionC between A and B.
This is because, in the html structure, sectionC already exists below. Is it possible to configure only with CSS without using Javascript?
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
/*only for ilustration*/
background-color: #d7d7d7;
}
.bottom {
display: flex;
flex-direction: row;
/*only for ilustration*/
background-color: #ffd5d5;
}
#media screen and (max-width: 760px) {
.header {
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.bottom {
flex-direction: column;
border: none;
}
}
<div>
<div class="header">
<div>
SectionA
</div>
<div>
SectionB
</div>
</div>
<div class="bottom">
SectionC
</div>
</div>
I have just made a change in your HTML.
So I wrapped all div inside of .header.
Then, to give 50% width for first to direct child I have just added class .hlalf and set this class CSS to flex:1 0 50%, which means take 50% width of flexbox.
Now to achieve bottom div in center in responsive we use order property of flexbox. and for that I have just added class to all 3 div according to their order. I have used sm keyword just for understanding as small screens.
#media screen and (max-width: 560px) {
.order-sm-1 {
order: 1;
}
.order-sm-2 {
order: 2;
}
.order-sm-3 {
order: 3;
}
}
.header {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.header>div {
flex: 1;
}
.header>div.half {
/*This css tells all the direct div of header class to take 50% of the space*/
flex: 1 0 50%;
}
.bggreen {
background: green;
}
.bgblue {
background: blue;
}
.bottom {
background-color: #ffd5d5;
}
#media screen and (max-width: 760px) {
/*This will change flex-direction to column which is by default row*/
.header {
flex-direction: column;
}
.order-sm-1 {
order: 1;
}
.order-sm-2 {
order: 2;
}
.order-sm-3 {
order: 3;
}
}
<div>
<div class="header">
<div class="bggreen half order-sm-1">
SectionA
</div>
<div class="bgblue half order-sm-3">
SectionB
</div>
<div class="bottom order-sm-2">
SectionC
</div>
</div>
You can wrap all your section in a flex container and play with the flex-order properties
I'm late to the party with this one but Grid's the way to go in my opinion as you get complete control over where you put items. It's much more versatile than flexbox but it is a steep learning curve initially as there are so many options. Kevin Powell has a good introductory video to grid and this is also a good, clearly-written resource from css tricks.
.container {
display: grid;
grid-template-columns: 3fr 1fr;
grid-template-areas: "a b" "c c";
border: 2px solid #285DBB;
row-gap: 0.25rem;
column-gap: 2rem;
padding: 0.35rem;
}
.container>div {
background-color: #92D050;
color: white;
display: grid;
place-content: center;
padding: 0.75rem 2rem;
}
.zoneA {
grid-area: a;
text-decoration: underline wavy red;
}
.zoneB {
grid-area: b;
}
.zoneC {
grid-area: c;
}
.footer {
margin-top: 1.5rem;
font-size: 1.25rem;
text-align: center;
}
.mobile {
display: none;
}
.pc {
display: block;
}
#media only screen and (max-width:760px) {
.container {
grid-template-columns: 1fr;
grid-template-rows: 1fr 3fr 1fr;
grid-template-areas: "a" "c" "b";
}
.mobile {
display: block;
}
.pc {
display: none;
}
.zoneB {
text-decoration: underline wavy red;
}
.zoneC {
text-decoration: underline wavy red;
}
}
<div class="container">
<div class="zoneA">
SectionA
</div>
<div class="zoneB">
SectionB
</div>
<div class="zoneC">
SectionC
</div>
</div>
<div class="pc footer">PC</div>
<div class="mobile footer">Mobile</div>
<meta content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/>
Related
:root {
--min-screen-height:100px;
}
.App {
display: grid;
grid-template-columns: 0.7fr 0.9fr 1.5fr 0.9fr;
grid-template-rows: 2.75rem 3fr;
grid-template-areas:
'nav nav nav nav'
'sidebar leftmenu content rightmenu';
gap: 0.75rem 0.4rem;
}
.navigation {
grid-area: nav;
background-color: yellow;
}
.sidebar {
min-height: var(--min-screen-height);
grid-area: sidebar;
background-color: aliceblue;
}
.leftmenu {
grid-area: leftmenu;
background-color: skyblue;
}
.content {
min-height: var(--min-screen-height);
grid-area: content;
background-color: blanchedalmond;
padding: 0.5em 0.75em 0.5em 0.75em;
}
.rightmenu {
grid-area: rightmenu;
background-color: coral;
}
#media screen and (max-width: 768px) {
.App {
grid-template-columns: 1fr;
grid-template-areas:
'nav'
'content';
}
}
<div class="App">
<div class="navigation">Nav</div>
<div class="sidebar">Side bar</div>
<div class="leftmenu">Left Menu</div>
<main class="content">Main</main>
<div class="rightmenu">Right Menu</div>
</div>
In responsive until 768px I am only showing the nav and container. But still in the 768 I could see the rightmenu.
what is wrong here? or how to fix this? Please check in full page with by resizing it.
https://www.w3.org/TR/css-grid-2/#explicit-grids
The three properties grid-template-rows, grid-template-columns, and grid-template-areas together define the explicit grid of a grid container by specifying its explicit grid tracks. The final grid may end up larger due to grid items placed outside the explicit grid; in this case implicit tracks will be created, these implicit tracks will be sized by the grid-auto-rows and grid-auto-columns properties.
The grid-auto-flow property controls auto-placement of grid items without an explicit position. Once the explicit grid is filled (or if there is no explicit grid) auto-placement will also cause the generation of implicit grid tracks.
So grid-template-areas defines explicit grid. Remaining areas are put in implicit grid.
To get rid of those elements you may use:
#media screen and (max-width: 768px) {
.App {
grid-template-columns: 1fr;
grid-template-areas: "nav" "content";
}
.App :not(.navigation, .content) {
display: none;
}
}
All the divs are still there so the grid does its best to accommodate them although they say they are in grid-areas which are not defined.
To completely get rid of them you will need to set them to display none in the media query.
:root {
--min-screen-height: 100px;
}
.App {
display: grid;
grid-template-columns: 0.7fr 0.9fr 1.5fr 0.9fr;
grid-template-rows: 2.75rem 3fr;
grid-template-areas: 'nav nav nav nav' 'sidebar leftmenu content rightmenu';
gap: 0.75rem 0.4rem;
}
.navigation {
grid-area: nav;
background-color: yellow;
}
.sidebar {
min-height: var(--min-screen-height);
grid-area: sidebar;
background-color: aliceblue;
}
.leftmenu {
grid-area: leftmenu;
background-color: skyblue;
}
.content {
min-height: var(--min-screen-height);
grid-area: content;
background-color: blanchedalmond;
padding: 0.5em 0.75em 0.5em 0.75em;
}
.rightmenu {
grid-area: rightmenu;
background-color: coral;
}
#media screen and (max-width: 768px) {
.App {
grid-template-columns: 1fr;
grid-template-areas: 'nav' 'content';
}
.sidebar,
.rightmenu,
.leftmenu {
display: none;
}
}
<div class="App">
<div class="navigation">Nav</div>
<div class="sidebar">Side bar</div>
<div class="leftmenu">Left Menu</div>
<main class="content">Main</main>
<div class="rightmenu">Right Menu</div>
</div>
First off I am very new to CSS and following an online course.
I am trying to create a navigation bar that changes from row to column when going into mobile. I am using flexbox and #media queries for that however, it seems like my code does not make any change to the navigation direction when going to mobile. Please help! ]
.container {
display: flex;
color: white;
justify-content: flex-end;
}
.box {
width: 90px;
height: 3rem;
margin: 0.5rem;
background-color: black;
text-align: center;
}
.box-four {
width: 100px;
}
#media screen and (max-width: 600px) {
.container {
flex-direction: row;
justify-content: center;
flex-grow: 2rem;
flex-wrap: wrap;
flex-basis: 10%;
}
}
Can't say exactly what problems you are having without seeing some example HTML to work with but at first glance it seems you should be using flex-direction:column for your mobile view.
Note well: What is in the media query is your mobile styles in this case. You can tell because you have specified max-width which means that it will apply to all screen sizes below the width provided (600px).
See the below as an example which incorporates your provided CSS with some basic HTML I made. (Resize the browser window to test).
.container {
display: flex;
color: white;
}
.box {
width: 90px;
height: 3rem;
margin: 0.5rem;
background-color: black;
text-align: center;
}
.box-four {
width: 100px;
}
#media screen and (max-width: 600px) {
.container {
flex-direction: column;
justify-content: center;
flex-grow: 2rem;
flex-wrap: wrap;
flex-basis: 10%;
}
}
<div class="container">
<div class="box">Entry 1</div>
<div class="box">Entry 2</div>
<div class="box">Entry 3</div>
<div class="box">Entry 4</div>
</div>
You can also read more about flex-direction at the MDN Web Docs
I'd like to have responsive version to this code.
body {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-areas:
"navigation-bar content content content";
margin: 0; padding: 0;
}
.navigation-bar {
grid-area: navigation-bar;
height: 100vh;
background-color: #1a1b20;
}
.content {
grid-area: content;
background-color: #202127;
}
<body>
<div class="navigation-bar"></div>
<div class="content"></div>
</body>
What I have:
#media only screen and (max-width: 600px) {
body {
}
.navigation-bar {
}
.content {
}
}
I'd like to have navigation-bar on the top of the website and content below it.
It means:
grid-template-columns should be 1fr
height of navigation-bar should be about 25vh
But I don't know, what grid-template-rows should be.
It depends on content, but if there is no content in content, it should fill whole screen (navigation-bar and content is a rest).
May you help me with responsive desige, please?
EDIT:
On mobile phone:
I would write the base styles using columnar flex and then a use grid when the screen is larger than 600px. Note that in mobile, .content uses flex-grow: 1, which means it will fill all the remaining vertical space.
.navigation-bar {
height: 15vh;
background-color: #1a1b20;
}
.content {
flex-grow: 1;
background-color: #202127;
}
body {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
color: white;
}
#media only screen and (min-width: 600px) {
body {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-areas:
"navigation-bar content content content";
}
.navigation-bar {
grid-area: navigation-bar;
height: 100vh;
}
.content {
grid-area: content;
}
}
<div class="navigation-bar">navbar</div>
<div class="content">content</div>
jsFiddle
I'm trying to understand grid-template-areas.
I've this HTML
<div class="wrapper">
<div class="d">D</div>
<div class="b">B</div>
<div class="c">C</div>
<div class="a">A</div>
</div>
and this CSS
.wrapper {
grid-template-areas: "areaA areaB areaC areaD"
}
.A { grid-area: areaA; }
.B { grid-area: areaB; }
.C { grid-area: areaC; }
.D { grid-area: areaD; }
I get the (expected) following result
A B C D
now if I add a media query, and wanted to hide column B, C and D
#media (min-width: 500px) {
.wrapper {
grid-template-areas: "areaA";
}
.B {
display: none;
}
.C {
display: none;
}
.D {
display: none;
}
}
this also works :
A
now, I then removed the display:none entries, hoping that because there was no mention of the elements in grid-template-areas that they would not show. I was wrong ;)
Is it possible to specify just using css-grid that elements not specified are hidden by default ? I can't seem to find anything that mentions this
The grid-template-areas property cannot hide grid items. It is designed to create grid areas.
But your media query can still be very simple.
This is all you need:
#media (max-width: 500px) {
section:not(.a) { display: none; }
}
jsFiddle demo
article {
display: grid;
grid-template-areas: "areaA areaB areaC areaD";
}
#media (max-width: 500px) {
section:not(.a) { display: none; }
}
.a { grid-area: areaA; }
.b { grid-area: areaB; }
.c { grid-area: areaC; }
.d { grid-area: areaD; }
/* non-essential demo styles */
section {
height: 50px;
width: 75px;
background-color: lightgreen;
border: 1px solid #ccc;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2em;
}
<article>
<section class="d">D</section>
<section class="b">B</section>
<section class="c">C</section>
<section class="a">A</section>
</article>
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)