I have to achieve below three layout - in a responsive way.
1st layout - default layout
2nd Layout - with "min-width:600px"
3rd Layout - with "min-width:700px"
Above three layout I have already achieved.
I have mentioned height "200px" for dark-blue and red colored divs, which is actually somewhat fixed. If at a later stage, content in it increases (hypothetically) - the design layout will fail I think.
Is there any better way of doing it dynamically and my design doesn't fail if content increases.
I tried to think of it but couldn't get any.
Just Asked this question for better learning.
I wanted to achieve it by using flexbox. Any other way is also appreciated.
Can someone point in right direction?
I have added my HTML and css code.
/* default color of background */
.red {
background: red;
}
.dark-blue {
background: darkblue;
}
.light-blue {
background: lightblue;
}
.green {
background: green;
}
/* Container properties */
.container {
/* mentioned 100% so that element inside takes full width i.e with id = container2 */
width: 100%;
display: flex;
flex-wrap: wrap;
}
.box {
width: 100%;
height: 100px;
}
/* Responsive design proprties */
#media screen and (min-width: 600px) {
.dark-blue {
width: 50%;
height: 200px;
}
#container2 {
width: 50%;
height: 50%;
}
}
#media screen and (min-width: 700px) {
.dark-blue,
.red {
height: 200px;
}
.dark-blue {
width: 25%;
order: 2;
}
#container2 {
width: 50%;
flex-wrap: wrap;
}
.red {
width: 25%;
order: -1;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Layout shifter</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="container">
<div class="box dark-blue"></div>
<div class="container" id="container2">
<div class="box light-blue"></div>
<div class="box green"></div>
</div>
<div class="box red"></div>
</div>
</body>
</html>
Flexbox has some advanatges and some downsides. one of the downsides is, that it is only good in controlling either height or width. Not both.
If you need to control both, CSS-Grid is the way to go.
Use grid-template-areas to place the divs. Its the equivalent to flex order.
body {
margin: 0;
width: 100vw;
min-height: 100vh;
box-sizing: border-box;
display: grid;
}
.dark-blue {
grid-area: dark-blue;
background-color: darkblue;
}
.light-blue {
grid-area: light-blue;
background-color: lightblue;
}
.green {
grid-area: green;
background-color: green;
}
.red {
grid-area: red;
background-color: red;
}
#media only screen
and (max-width: 600px) {
body {
grid-template-areas:
"dark-blue"
"light-blue"
"green"
"red"
}
}
#media only screen
and (max-width: 600px) {
body {
grid-template-areas:
"dark-blue"
"light-blue"
"green"
"red";
}
}
#media only screen
and (min-width: 601px)
and (max-width: 700px) {
body {
grid-template-areas:
"dark-blue light-blue"
"dark-blue green"
"red red";
}
}
#media only screen
and (min-width: 701px) {
body {
grid-template-areas:
"red light-blue light-blue dark-blue"
"red green green dark-blue"
}
}
<div class="dark-blue"></div>
<div class="light-blue"></div>
<div class="green"></div>
<div class="red"></div>
Related
I have div container in which two divs with background pictures.I style div container display grid and fix one div bigger than other. I want divs to stack on top (or take width 100%)for small screen size. Want to make it responsive.But not working. In original code I more divs. Here i just included two.
#main {
height: 300px;
display: grid;
grid-template-columns: auto auto auto;
}
.sub {
background-color: cadetblue;
margin: 10px;
}
#one {
grid-column-start: 1;
grid-column-end: 3;
background-image: url("https://image.shutterstock.com/image-
vector/floral-seamless-pattern-leaves-cordelia-600w- 1142315438.jpg");
}
#two {
background-image: url(https://image.shutterstock.com/image-
photo/colorful-flower-on-dark-tropical-600w-721703848.jpg)
}
#media screen and (max-width: 600px) {
#one,
#two {
width: 100%;
}
}
<div id="main">
<div class="sub" id="one">1</div>
<div class="sub" id="two">2</div>
Try to modify the media query to below:
#media screen and (max-width: 600px) {
#main {
grid-template-columns: auto;
}
#one {
grid-column-end: 2;
}
}
I would just use flex-box it's a lot easier to work with in my opinion. Just add a media query and change the flex-direction to row if you don't want them stacked on bigger screen sizes.
body {
margin: 0;
padding: 0;
}
.sub{
width: 100%;
height: 500px; /** can be whatever height you want **/
background-color: blue;
margin-top: 20px;
background-image: url("https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/suburban-house-royalty-free-image-1584972559.jpg?resize=980:*");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<div class="main">
<div class="sub" id="1"></div>
<div class="sub" id="2"></div>
</div>
How to make side parts of web page reduce they width with reducing width of whole page by degrees?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.container {
display: grid;
grid-template-columns: 10% 80% 10%;
min-height: 100vh;
}
.side-right {
background: red;
}
.side-left {
background: blue;
}
.main {
background: green;
}
#media screen and (max-width: 1000px) {
.container {
grid-template-columns: 0 100% 0;
}
}
</style>
</head>
<body>
<div class="container">
<div class="side-right">
</div>
<div class="main">
</div>
<div class="side-left">
</div>
</div>
</body>
</html>
In example below after max-width = 1000px side elements are dissapearing instantly, but I want to make them reducing they width reacting by every pixel changed on max-width. How to make it?
If I understand your requirement correctly...change the initial grid-template-columns to
grid-template-columns: 1fr minmax(1000px, 8fr) 1fr;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::before,
::after {
box-sizing: inherit;
}
.container {
display: grid;
grid-template-columns: 1fr minmax(1000px, 8fr) 1fr;
min-height: 100vh;
}
.side-right {
background: red;
}
.side-left {
background: blue;
}
.main {
background: green;
}
#media screen and (max-width: 1000px) {
.container {
grid-template-columns: 0 1fr 0;
}
}
<div class="container">
<div class="side-right">
</div>
<div class="main">
</div>
<div class="side-left">
</div>
</div>
You can animate all with flex-box and just by changing some of your css.
.container {
display: flex;
min-height: 100vh;
flex-direction: row-reverse;
}
.side-right {
background: red;
width: 100%;
}
.side-left {
background: blue;
width: 100%;
}
.main {
background: green;
min-width: 600px;
}
Thats just a basic example. Consider reading more about flex-box.
Try to add min-with: 50px; to .side-right and .side-left
And then give them both an z-index: 1;
So they wont lay under your main
Hope that helps
I have a container with four boxes. The container all together should be the width of the window.
Above 720px, there should be one row of four boxes.
Below 720px, there should be two rows of two boxes.
Below 600px, there should be four rows of one box.
I'm confused what I should put in the media queries.
html,
body {
width: 100%;
height: 100%;
}
.container {
border: 1px solid black;
display: flex;
height: 100%;
width: 100%;
}
.column {
border: 1px solid red;
flex: 1;
}
#media (max-width: 720px) {
.container {
?
}
}
#media (max-width: 600px) {
.container {
?
}
}
<div class="container">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
Set the flex items to wrap at your breakpoints.
Here's a fiddle demo.
.container {
display: flex;
flex-wrap: wrap;
height: 100vh;
}
.column {
flex: 1;
border: 1px solid black;
background-color: lightgray;
}
#media (max-width: 720px) {
.column {
flex-basis: 34%;
background-color: orange;
}
}
#media (max-width: 600px) {
.column {
flex-basis: 51%;
background-color: lightgreen;
}
}
body {
margin: 0;
}
<div class="container">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
Note that with flex-grow: 1 defined in the flex shorthand, there's no need for flex-basis to be exact (25%, 50%, 100%), which can result in unequal wrapping if you were to add margin space.
Since flex-grow will consume free space on the row, flex-basis only needs to be large enough to enforce a wrap. This will ensure plenty of space for margins, but not enough space for an extra item.
You could use grids to achieve this. If you name them like I did in the snippet, it is easy to alter the sequence of the columns.
.container {
display: grid;
grid-auto-rows: 200px;
grid-auto-columns: auto;
grid-template-areas:
"column1 column2 column3 column4";
border: 1px solid black;
width: 100%;
height: 100%;
}
.column {
display: flex;
}
.column1 {
grid-area: column1;
background-color: red;
}
.column2 {
grid-area: column2;
background-color: yellow;
}
.column3 {
grid-area: column3;
background-color: green;
}
.column4 {
grid-area: column4;
background-color: blue;
}
#media (max-width: 720px) {
.container {
grid-template-areas:
"column1 column2"
"column3 column4";
}
}
#media (max-width: 600px) {
.container {
grid-template-areas:
"column1"
"column2"
"column3"
"column4";
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div class="column column1"></div>
<div class="column column2"></div>
<div class="column column3"></div>
<div class="column column4"></div>
</div>
</body>
</html>
More info about grids in CSS here
I created a responsive four-column layout by using a mobile-first approach. The smallest screen shows 1 column, the larger screen 2 columns, and the largest screen 4 columns.
It seems to work so far, but I'd like you to take a look at my code and tell me if there's anything wrong with my approach. I would be grateful for your opinions.
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FlexBox Test</title>
<style>
:root {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
/* mobile phone */
.flex-container {
display: flex;
flex-wrap: wrap;
max-width: 1400px;
margin: 0 auto;
border: 1px solid red;
padding: 1em;
}
.flex-item-1 {
background: indianred;
}
.flex-item-2 {
background: blue;
}
.flex-item-3 {
background: tomato;
}
.flex-item-4 {
background: coral;
}
.flex-item {
flex: 100%;
height: 100px;
}
/* tablet */
#media screen and (min-width: 640px) {
.flex-item {
flex: calc(50% - 1em);
}
.flex-item:nth-child(2n) {
margin-left: 1em;
}
}
/* desktop */
#media screen and (min-width: 960px) {
.flex-item {
flex: calc(25% - 1em);
}
.flex-container > * + * {
margin-left: 1em;
}
}
</style>
</head>
<body>
<div class="flex-container">
<div class="flex-item flex-item-1">
1
</div>
<div class="flex-item flex-item-2">
2
</div>
<div class="flex-item flex-item-3">
3
</div>
<div class="flex-item flex-item-4">
4
</div>
</div>
</body>
</html>
If you want remove calc from the css you can do something like that.
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FlexBox Test</title>
<style>
:root {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
/* mobile phone */
.flex-container {
display: flex;
flex-wrap: wrap;
max-width: 1400px;
margin: 0 auto;
border: 1px solid red;
padding: 1em;
}
.flex-item-1 {
background: indianred;
}
.flex-item-2 {
background: blue;
}
.flex-item-3 {
background: tomato;
}
.flex-item-4 {
background: coral;
}
.flex-item {
flex: 100%;
height: 100px;
}
/* tablet */
#media screen and (min-width: 675px) and (max-width: 960px) {
.flex-item {
flex: 1 0 19em;
}
.flex-item:nth-child(2n) {
margin-left: 1em;
}
}
/* desktop */
#media screen and (min-width: 960px) {
.flex-item {
flex: 1 0;
}
.flex-container > * + * {
margin-left: 1em;
}
}
</style>
</head>
<body>
<div class="flex-container">
<div class="flex-item flex-item-1">
1
</div>
<div class="flex-item flex-item-2">
2
</div>
<div class="flex-item flex-item-3">
3
</div>
<div class="flex-item flex-item-4">
4
</div>
</div>
</body>
</html>
However to keep the margin as you have on your initial example, I have to change #media screen and (min-width: 675px) and (max-width: 960px) for tablet screen. If not, three block appears on the first line for specific browser width (not the same behaviour as you want).
What do you think about that ?
I used to work with responsive design. Now I have a feeling, but not sure, that it is possible to manage the position of each div by its id or class. For example:
<div id='first'></div>
<div id='second'></div>
<div id='third'></div>
In CSS you might be able to say:
#media (max-width: 600px) {
// pseudo code
#second: after #third
}
#media (max-width: 300px) {
// pseudo code
#first: after #third
}
Is it possible to manage the element that way without giving the position a value, left or right a value?
You can do this with flexbox using the order property.
FIDDLE (Resize browser window)
.container {
display: flex;
}
.container div {
display: inline-block;
margin: 40px;
width: 100px;
height: 100px;
}
.first {
background: gold;
}
.second {
background: tomato;
}
.third {
background: aqua;
}
#media (max-width: 900px) {
.second {
order: 3;
}
}
#media (max-width: 600px) {
.second {
order: 1;
}
}
.first {
order: 3;
}
}
<div class="container">
<div class="first">first</div>
<div class="second">second</div>
<div class="third">third</div>
</div>
Check out this css-tricks article for an overview of flexbox.