Responsive relocate sparse element in sidebar with only css - css

I want to make a responsive layout with one column on mobile and two columns on desktop.
In very old article on web the author uses javascript, but I guess with modern browsers you can only do this with css.
Responsive layout
The best result I've been able to achieve so far is with the following code, but in desktop mode I can't place the sidebar items one behind the other.
I think grid layout is not the right approach.
.container {
display: grid;
grid-template-columns: auto auto;
}
.main {
background-color: blue;
grid-column: 1;
}
.sidebar {
background-color: green;
grid-column: 2;
}
#media screen and (max-width: 600px) {
.container {
grid-template-columns: auto;
}
.main, .sidebar {
grid-column: 1;
}
}
<div class="container">
<div class="main"><span>A1</span></div>
<div class="sidebar"><span>B1</span></div>
<div class="main"><span>A2</span></div>
<div class="main"><span>A3</span></div>
<div class="sidebar"><span>B2</span></div>
<div class="main"><span>C1</span></div>
</div>
Thanks to #vineet-tyagi suggestion I add below the solution which works well for me:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
display: grid;
grid-template-columns: auto auto;
grid-auto-flow: dense;
}
.main {
background-color: blue;
grid-column: 1;
}
.sidebar {
background-color: green;
grid-column: 2;
height: fit-content;
}
#media screen and (max-width: 600px) {
.container {
grid-template-columns: auto;
}
.main, .sidebar {
grid-column: 1;
}
}
</style>
</head>
<body>
<div class="container">
<div class="main">
A1
</div>
<div class="sidebar">
B1
</div>
<div class="main">
A2<br>A2<br>A2<br>A2
</div>
<div class="main">
A3
</div>
<div class="sidebar">
B2
</div>
<div class="main">
C1
</div>
</div>
</body>
</html>

Add "grid-auto-flow: dense;" also to the container class.

.container {
display: grid;
grid-template-columns: repeat(1, 1fr);
gap: 10px;
grid-auto-rows: 100px;
}
.container .main,
.container .sidebar {
border: 1px solid black;
}
.container .sidebar {
background:red;
}
#media screen and (min-width: 600px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
.container .sidebar {
grid-column: 2 / 3;
}
.container .sidebar:nth-child(3) {
grid-row: 2 / 1;
background: red;
}
.container .main {
grid-column: 1 / 2;
}
.container .main:nth-last-child(1) {
grid-row: 1 / 1;
}
.container .main:nth-last-child(2) {
grid-row: 2 / 2;
}
}
<div class="container">
<div class="sidebar"><span>sidebar - B2</span></div>
<div class="main"><span>main - A1</span></div>
<div class="sidebar"><span>sidebar - B1</span></div>
<div class="main"><span>main - C1</span></div>
<div class="main"><span>main - A2 </span></div>
<div class="main"><span>main - A3</span></div>
</div>

Related

How can i give space from grids

when i try to display blocks in grid then there is space at the end of grid item on right side and there is no space at the start of the grid i.e at the left side . You can see screenshot and code. i cannot figure it out what is the problem. I hope you can figure it out.
<html lang="en">
<head>
<meta charset="utf-8">
<title>Projects</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.gird-section{
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
margin-top: 40px;
background-color: yellow;
}
.grid-item{
background-color: red;
width: 500px;
height: 100px;
}
</style>
</head>
<body>
<h1>Grid</h1>
<div class="gird-section">
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
</body>
</html>
You can use Css Grid Layout
I have edited your code so you can have yellow space left and right. I added width in the first section in order for the parent to have more with then the child . For more editing I suggest to watch the link above.
<head>
<meta charset="utf-8" />
<title>Projects</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#grid {
display: grid;
height: 100px;
grid-template-columns: repeat(5, 1fr);
}
#item1 {
background-color: yellow;
grid-column: 1/2;
}
#item2 {
background-color: red;
grid-column: 2/4;
}
#item3 {
background-color: yellow;
grid-column: 4/5;
}
</style>
</head>
<body>
<h1>Grid</h1>
<div id="grid">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
</div>
</body>
</html>

Responsive Website that makes divs fullscreen and user scroll down to see others

hello i want to make my site responsive.I have divide body in 4 divs. Every 2 divs has the 100% of the screen and the other two has margin-top : 50%;. Now i want everytime max-width = 800px, I want every div to has the fullscreen and the user scroll down to see the other divs. My site is https://frontjim.github.io if you want to see it. thanks is advance and sorry for my bad english.
i have used this but it didnt work
#media screen and (max-width: 800px) {
body,
html {
margin: 0;
padding: 0;
height: 100%;
max-height: 100vh;
display: flex;
flex-direction: row;
flex: 1 1 auto;
min-height: 0;
}
}
.back {
display: flex;
flex-direction: column;
}
.navbar {
width: 100vw;
height: 100vh;
}
.mater {
width: 100vw;
height: 100vh;
}
.cb {
width: 100vw;
height: 100vh;
}
.scroll {
width: 100vw;
height: 100vh;
}
You can have a general container that has child elements. This container has width: 100vw and height: 100vh, and display: flex. You don't need to add flex-direction: row since it's the default.
The children will have width: 100%.
Snippet:
* {
margin: 0;
padding: 0;
}
.flex {
width: 100vw;
height: 100vh;
display: flex;
}
.div1 {
background-color: red;
width: 100%;
}
.div2 {
background-color: blue;
width: 100%;
}
.div3 {
background-color: green;
width: 100%;
}
.div4 {
background-color: grey;
width: 100%;
}
<div class="flex">
<div class="div1"></div>
<div class="div2"></div>
</div>
<div class="flex">
<div class="div3"></div>
<div class="div4"></div>
</div>
Use CSS Grid, it can get the job done easily
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Responsive Grid</title>
</head>
<body>
<div class="main">
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
<div class="div4"></div>
</div>
</body>
</html>
CSS:
* {
margin: 0;
padding: 0;
}
.main {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 100vh 100vh;
}
.div1 {
background-color: lightgreen;
}
.div2 {
background-color: lightseagreen;
}
.div3 {
background-color: coral;
}
.div4 {
background-color: lightblue;
}
#media screen and (max-width: 800px) {
.main {
grid-template-columns: 1fr;
grid-template-rows: 100vh 100vh 100vh 100vh;
}
}
Live view: https://codepen.io/zgheibali/pen/ZEWWVvr
I hope that my answer was helpful :)
change the design.use like this:
in html::
<div class='flexyy'>
<div class='div1'>....</div>
<div class='div2'>....</div>
<div class='div3'>....</div>
<div class='div4'>....</div>
</div>
in css::
div1{
width:100%;
}
div2{
width:100%;
}
div3{
width:100%;
}
div4{
width:100%;
}
#media(min-width:800px){
.div1,.div2,.div3,.div4{
width:auto;
}
.flexyy{
display:flex;
flex-direction:row;
flex: 0.5 1 auto;
flex-wrap:wrap;
}
}

Add new fitted rows based on column width?

I have this code where there is simply one column with three different rows fitted to the viewport. Each row will contain an image that is fit by height. I want to make it so that if the browser is resized horizontally, and the width of that column(viewport) falls below a certain point, additional rows are then inserted on the page THAT ALSO FIT the viewport. So it would snap from fitting three rows, to fitting four rows, then five and so on, depending on the width of the one column/viewport:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TEST SITE ONE</title>
<meta name="description" content="Test Site">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="main.css">
<style>
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
* {
margin: 0px;
padding: 0px;
}
body{
display: block;
}
#page1{
background-color: aquamarine;
display: block;
width: 100vw;
height: 100vh;
max-width: 100%;
max-height: 100%;
}
.grid-container{
display: grid;
height: 100%;
grid-template-rows: repeat(3, 1fr);
}
.grid-items{
display: flex;
justify-content: center;
align-items: center;
border: 2px solid black;
}
.slot-image{
height: auto;
width:auto;
max-height: 100%;
max-width: 100%;
}
</style>
</head>
<body>
<section id="page1">
<div class="grid-container">
<div class=grid-items>
<img class="slot-image" src="WC%20Sov%20edit.png" alt="sov">
</div>
<div class=grid-items>image</div>
<div class=grid-items>image</div>
</div>
<div class="grid-container">
<div class=grid-items>
<img class="slot-image" src="WC%20Sov%20edit.png" alt="sov">
</div>
<div class=grid-items>image</div>
<div class=grid-items>image</div>
</div>
</section>
</body>
</html>
I would wrap the grid-template-rows: repeat(3, 1fr); definition within #media queries. Where you can define the min and max breakpoints.
For example:
#media only screen and (max-width: 480px) { // Small Devices
.grid-container{
grid-template-rows: repeat(3, 1fr); // 3 columns
}
}
#media only screen and (min-width: 481px) and (max-width: 768px) { // Medium Devices
.grid-container{
grid-template-rows: repeat(4, 1fr); // 4 columns
}
}
#media only screen and (min-width: 769px) { // Large Devices
.grid-container{
grid-template-rows: repeat(5, 1fr); // 5 columns
}
}

How do I use flexbox to contain the contents inside a grid?

I want using flexbox to contain everything within the second div of the grid. In this case the picture overflows and I don't know why. I would like it to be resized by height and maintain aspect ratio.
body {
height: 100%;
margin: 0;
}
.wrapper {
display: grid;
grid-template: repeat(2, 50vh) / repeat(3, 1fr);
background-color: #A9A9A9;
}
.wrapper>div:nth-child(even) {
background-color: #D3D3D3;
}
.pic2 {
display: flex;
flex-direction: column;
}
button {
flex: 1;
min-height: 40px;
background: green;
}
img {
flex: 1;
max-height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="wrapper">
<div class="pic1">Div2</div>
<div class="pic2">
<button>Div2</button>
<img src="https://i.imgur.com/VHtXwib.jpg">
</div>
<div class="pic3">Div3</div>
<div class="pic4">Div4</div>
<div class="pic5">Div5</div>
<div class="pic6">Div6</div>
</div>
</body>
</html>
You cannot set min-height for the button in terms you must use div.
Unless it will cause strange overflow problem when you resize the picture. Take I try to resize the window, see if this the effect you want.
body {
height: 100%;
margin: 0;
}
.wrapper {
display: grid;
grid-template: repeat(2, 50vh) / repeat(3, 1fr);
background-color: #A9A9A9;
}
.wrapper div{
width:100%;
height:100%;
}
.wrapper > div:nth-child(even) {
background-color: #D3D3D3;
}
.pic2 {
display: flex;
flex-direction: column;
}
button {
flex: 1;
height:30%;
background: green;
}
img {
flex : 1;
max-height: 100%;
}
.custom-img{
display:block;
max-height:70%;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="wrapper">
<div class="pic1">Div2</div>
<div class="pic2">
<button>Div2</button>
<div class="custom-img">
<img src="https://i.imgur.com/VHtXwib.jpg">
</div>
</div>
<div class="pic3">Div3</div>
<div class="pic4">Div4</div>
<div class="pic5">Div5</div>
<div class="pic6">Div6</div>
</div>
</body>
</html>
As you have set your button min-height: 40px when CSS applies the img max-height:100% it is actually getting the parent size, not decreasing the button 40px.
You can set max-height: calc(100% - 40px);, which will apply the parent 100% height minus 40px of the button.
body {
height: 100%;
margin: 0;
}
.wrapper {
display: grid;
grid-template: repeat(2, 50vh) / repeat(3, 1fr);
background-color: #A9A9A9;
}
.wrapper>div:nth-child(even) {
background-color: #D3D3D3;
}
.pic2 {
display: flex;
flex-direction: column;
}
button {
flex: 1;
min-height: 40px;
background: green;
}
img {
flex: 1;
max-height: calc(100% - 40px);
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="wrapper">
<div class="pic1">Div2</div>
<div class="pic2">
<button>Div2</button>
<img src="https://i.imgur.com/VHtXwib.jpg">
</div>
<div class="pic3">Div3</div>
<div class="pic4">Div4</div>
<div class="pic5">Div5</div>
<div class="pic6">Div6</div>
</div>
</body>
</html>

How do I fill a cell in a grid layout with an image?

I'm trying to insert a picture within a div within a grid layout and I want the height of the picture to always match exactly the height of the div. However I can't get the image to respect the boundaries of it's parent div. Most of the times it overlaps the grid and if I use overflow:hidden it just crops the image. I want it to maintain the aspect ratio.
body {
margin: 0;
}
.wrapper {
display: grid;
grid-template: repeat(2, 50vh) / repeat(3, 1fr);
}
.wrapper {
background-color: #A9A9A9;
}
.wrapper > div:nth-child(even) {
background-color: #D3D3D3;
}
.img_div {
position:relative;
display: inline-block;
height: 100%;
width: 100%
}
.img_div > img {
position: absolute;
width: auto;
height: auto;
margin: auto;
min-height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="wrapper">
<div class="pic1">Div1</div>
<div class="pic2">Div2
<div class="img_div">
<img src="https://i.imgur.com/VHtXwib.jpg">
</div>
</div>
<div class="pic3">Div3</div>
<div class="pic4">Div4</div>
<div class="pic5">Div5</div>
<div class="pic6">Div6</div>
</div>
</body>
</html>
The extra child .img_div is probably not needed, but to keep same structure, I updated your css to make it display: inline and changed the .img_div > img styles, removing display: absolute; and changed min-height: 100%; to max-height: 100%; adding max-width: 100%; as well.
body {
margin: 0;
}
.wrapper {
display: grid;
grid-template: repeat(2, 50vh) / repeat(3, 1fr);
}
.wrapper {
background-color: #A9A9A9;
}
.wrapper > div:nth-child(even) {
background-color: #D3D3D3;
}
.img_div {
position:relative;
display: inline;
height: 100%;
width: 100%
}
.img_div > img {
width: auto;
height: auto;
margin: auto;
max-height: 100%;
max-width: 100%;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="wrapper">
<div class="pic1">Div1</div>
<div class="pic2">Div2
<div class="img_div">
<img src="https://i.imgur.com/VHtXwib.jpg">
</div>
</div>
<div class="pic3">Div3</div>
<div class="pic4">Div4</div>
<div class="pic5">Div5</div>
<div class="pic6">Div6</div>
</div>
</body>
</html>
You could also leave .img_div as display: inline-block if you'd prefer, but would need to remove its width: 100%;
Also, you may need to adjust vertical alignment depending on your use case.
I think I found the solution based on this article here.
https://www.whitebyte.info/programming/css/how-to-make-a-div-take-the-remaining-height
Basically setting every div to display:table and then putting every container inside that div as a table-row. That will fill the rest of the height of the gris
body {
margin: 0;
}
.wrapper {
display: grid;
grid-template: repeat(2, 50vh) / repeat(3, 1fr);
}
.wrapper {
background-color: #A9A9A9;
}
.wrapper > div {
text-align: center;
display: table;
height: 100%;
}
.wrapper > div:nth-child(even) {
background-color: #D3D3D3;
}
.img_div {
display: table-row;
height: 100%;
width: 100%;
}
.img_div > img {
height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="wrapper">
<div class="pic1">Div1</div>
<div class="pic2">Div2
<div class="img_div">
<img src="https://i.imgur.com/VHtXwib.jpg">
</div>
</div>
<div class="pic3">Div3</div>
<div class="pic4">Div4</div>
<div class="pic5">Div5</div>
<div class="pic6">Div6</div>
</div>
</body>
</html>

Resources