This question already has an answer here:
Using flex order property to re-arrange items for desktop and mobile views
(1 answer)
Closed 6 years ago.
I've learned that display flex help me reduce working hours for publishing.
However I've got a problem that the layout didn't display what I want.
All I want to display like grid layout like below :
But unfortunately I cannot fix this issue by myself.
Could you give me an advice how can I fix this issue with flex tag?
You can see my problem like below too :
Here is my code :
.item_wrap {
display: flex;
justify-content: space-between;
flex-flow: row-wrap;
}
.item_0 {
width: 500px;
height: 500px;
background: #ff0;
}
.item_1 {
width: 490px;
height: 160px;
background: #00f;
}
.item_2 {
width: 240px;
height: 160px;
background: #ff00e4;
}
.item_3 {
width: 240px;
height: 160px;
background: #ff00e4;
}
.item_4 {
width: 240px;
height: 160px;
background: #1cc600;
}
.item_5 {
width: 240px;
height: 160px;
background: #1cc600;
}
You will need to change HTML structure.
All blocks on the right side should be wrapped in a <div>.
HTML:
<div class="item-wrap">
<div class="item_0">0</div>
<div class="inner-wrap">
<div class="item_1">1</div>
<div class="item_2">2</div>
<div class="item_3">3</div>
<div class="item_4">4</div>
<div class="item_5">5</div>
</div>
</div>
CSS:
.item-wrap {
justify-content: space-between;
display: flex;
}
.inner-wrap {
justify-content: space-between;
flex-wrap: wrap;
display: flex;
}
.item_0,
.inner-wrap {
flex-basis: calc(50% - 5px);
}
.inner-wrap > div {
flex-basis: calc(50% - 5px);
}
.inner-wrap > .item_1 {
flex-basis: 100%;
}
* {box-sizing: border-box;}
body {
margin: 0;
}
.item-wrap {
justify-content: space-between;
height: 100vh;
display: flex;
}
.inner-wrap {
justify-content: space-between;
flex-wrap: wrap;
display: flex;
}
.item_0,
.inner-wrap {
flex-basis: calc(50% - 5px);
}
.inner-wrap > div {
flex-basis: calc(50% - 5px);
padding: 10px;
}
.inner-wrap > div + div {
margin-top: 10px;
}
.inner-wrap > .item_1 {
flex-basis: 100%;
}
.item_0{background:#ff0; padding: 10px;}
.item_1{background:#00f;}
.item_2{background:#ff00e4;}
.item_3{background:#ff00e4;}
.item_4{background:#1cc600;}
.item_5{background:#1cc600;}
<div class="item-wrap">
<div class="item_0">0</div>
<div class="inner-wrap">
<div class="item_1">1</div>
<div class="item_2">2</div>
<div class="item_3">3</div>
<div class="item_4">4</div>
<div class="item_5">5</div>
</div>
</div>
Hi! Please checkout this code
HTML5, CSS3
.item_wrap {
width: 800px;
display: flex;
margin: 0 auto;
}
.item_0 {
height: 500px;
background: red;
flex: 1;
margin: 5px;
}
.item_1 {
height: 500px;
background: yellow;
flex: 1;
margin: 5px;
}
.headbar {
}
.head_column {
height: 200px;
background: green;
flex: 1;
}
.headbar2 {
display: flex;
}
.pinkone {
background: #000;
flex: 1;
height: 150px;
}
.pinktwo {
background: pink;
flex: 1;
height: 150px;
}
.headbar3 {
display: flex;
}
.grayone {
background: gray;
flex: 1;
height: 150px;
}
.graytwo {
background: blue;
flex: 1;
height: 150px;
}
<div class="item_wrap">
<div class="item_0"></div>
<div class="item_1">
<div class="headbar">
<div class="head_column"></div>
</div>
<div class="headbar2">
<div class="pinkone"></div>
<div class="pinktwo"></div>
</div>
<div class="headbar3">
<div class="grayone"></div>
<div class="graytwo"></div>
</div>
</div>
</div>
Moreover you can follow YouTube Channel- LearnWebCode
Related
I want to make a website that would consist of 4 boxes each 50% height and width. I found code that does that, but now I struggle to add images into each box. I want each of the four divs to have a different image, and they should scale according to window size. Any help is appreciated.
Here's my codepen: https://codepen.io/alanvkarlik/pen/OJRdyRR
Here's what I would like to achieve: https://i.imgur.com/7CR7sW8.jpg
HTML:
<div class="container">
<div class="column"><img src="https://f4.bcbits.com/img/a0846297992_16.jpg"></div>
<div class="column">IMG 2</div>
<div class="column">IMG 3</div>
<div class="column">IMG 4</div>
</div>
CSS:
html, body {
height: 100%;
margin: 0;
}
.container {
height: 100%;
}
.column {
height: 25%;
display: flex;
justify-content: center;
align-items: center;
}
#media screen and (min-width: 600px) {
.container {
display: flex;
flex-wrap: wrap;
}
.column {
flex-basis: 50%;
height: 50%;
}
}
/* general styles */
body {
font-family: 'Lato', sans-serif;
font-size: 1.3em;
color: #ccc;
background: #000;
/*margin-bottom: 70px;*/
}
.column {
padding: 15px;
/*border: 1px solid #666;*/
box-sizing: border-box;
}
.column:nth-child(1) {
background: #5c9;
}
.column:nth-child(2) {
background: #fb0;
}
.column:nth-child(3) {
background: #39f;
}
.column:nth-child(4) {
background: #f33;
}
main {
max-width: 1200px;
margin: 0 auto;
}
h1,
h2 {
text-align: center;
}
Not sure if this is what you're trying to achieve but I'd do it with by setting object-fit: contain on images. I also changed a bit the way (css) you're defining the divs.
body {
margin: 0;
}
.container {
display: flex;
flex-wrap: wrap;
}
.column {
height: 50vh;
width: 50vw;
display: flex;
justify-content: center;
align-items: center;
padding: 15px;
box-sizing: border-box;
}
.column img {
height: 100%;
width: 100%;
object-fit: contain;
}
.column:nth-child(1) {
background: #5c9;
}
.column:nth-child(2) {
background: #fb0;
}
.column:nth-child(3) {
background: #39f;
}
.column:nth-child(4) {
background: #f33;
}
<div class="container">
<div class="column"><img src="https://f4.bcbits.com/img/a0846297992_16.jpg"></div>
<div class="column">IMG 2</div>
<div class="column">IMG 3</div>
<div class="column">IMG 4</div>
</div>
I think this is what you are looking for.
Your column img class is set to 100% width and height. I set the height to 50% and the width to auto so it detects the image size and displays it noramlly.
And i simply removed the "object-fit: cover;".
If you change your .colum img {} to the following it should be exactly what you want.
.column img {
height: 50%;
width: auto;
}
I added a snippet so you can see it working.
body {
margin: 0;
}
.container {
display: flex;
flex-wrap: wrap;
}
.column {
height: 50vh;
width: 50vw;
display: flex;
justify-content: center;
align-items: center;
padding: 15px;
box-sizing: border-box;
}
.column img {
height: 50%;
width: auto;
}
.column:nth-child(1) {
background: #5c9;
}
.column:nth-child(2) {
background: #fb0;
}
.column:nth-child(3) {
background: #39f;
}
.column:nth-child(4) {
background: #f33;
}
<div class="container">
<div class="column"><img src="https://f4.bcbits.com/img/a0846297992_16.jpg"></div>
<div class="column">IMG 2</div>
<div class="column">IMG 3</div>
<div class="column">IMG 4</div>
</div>
I posted a question here that was answered and worked for me at the time. I had to re-write my code with flex box and now the overlay scrolling doesn't work. I tried adding position:sticky; to the behind div that fixed it in the first question I posted, but doesn't work for my current code. Using my current code, how can I get the overlay scrolling to work again? What am I missing?
Edit:
using only css and html, is it possible to scroll away the front div (overlay div ontop of the image) completely before scrolling down the rest of the page? Essentially, wondering if overlay scrolling while freezing the behind div is possible in only css? Then once the front div is gone, unfreeze the background scrolling and continue on. Similar to this site here: https://humaan.com/ .
html,
body {
margin: 0;
height: 100%;
width: 100%;
}
#container {
height: 100%;
}
#front {
background-color: pink;
height: 91%;
display: flex;
position: relative;
z-index: 2;
}
#left {
width: 50%;
background-color: lightgreen;
display: flex;
flex-direction: column;
}
#left>* {
flex: 1;
}
#leftnav {
height: 8%;
width: 100%;
background-color: green;
display: flex;
}
#logotext {
display: flex;
}
#right {
width: 50%;
background-color: lightgreen;
display: flex;
flex-direction: column;
}
#right>* {
flex: 1;
}
#logo {
width: 100%;
max-width: calc(80vh - 25px);
background-color: blue;
}
#logo:before {
content: "";
display: flex;
padding-top: 100%;
}
#llogo {
width: 100%;
max-width: calc(80vh - 25px);
background-color: lightblue;
margin: 0;
}
#llogo:before {
content: "";
display: flex;
padding-top: 100%;
}
#rightsidetop {
background-color: lightgrey;
}
#leftsidetop {
background-color: lightgrey;
}
ul {
display: flex;
text-align: center;
justify-content: space-between;
width: 85%;
text-decoration: none;
}
li {
display: block;
font-size: 17px;
text-decoration: none;
}
#rightsideright {
background-color: lightgreen;
flex: 1;
}
#leftsideright {
background-color: lightgreen;
flex: 1;
}
#rightsidebottom {
background-color: pink;
}
#leftsidebottom {
background-color: pink;
}
.wrapper {
display: flex;
}
.video {
background: url(https://picsum.photos/id/107/800/800) center/cover;
height: 100%;
margin-top: -100%;
position: sticky;
top: 0;
}
<div id="container">
<div id="front">
<div id="left">
<div id="leftsidetop">
<p>logo</p>
</div>
<div class="wrapper">
<div id="leftsideright"></div>
<div id="llogo"></div>
</div>
<div id="leftsidebottom"></div>
</div>
<div id="right">
<div id="rightsidetop">
<ul>
<li>About</li>
<li>Services</li>
<li>Clients</li>
<li>Contact</li>
</ul>
</div>
<div class="wrapper">
<div id="logo"></div>
<div id="rightsideright"></div>
</div>
<div id="rightsidebottom"></div>
</div>
</div>
</div>
<div class="video"></div>
<div style="height:150vh"> more content later </div>
just add to element you want to be scrollable an overflow: auto;
e.g :
#right {
overflow: auto;
}
I am trying to have 4 little squares inside one big square. Those small squares need to be position at the bottom inside a big square, so far my code looks like this
.date-grid button {
position: relative;
border: 0;
width: 7.5ch;
height: 7.5ch;
background-color: #A1A100;
margin-bottom: 2px;
}
.smallHolder {
display: flex;
align-items: flex-end;
}
.small1 {
border: 0;
width: 2.5ch;
height: 2.5ch;
background-color: gray;
}
.small2 {
width: 2.5ch;
height: 2.5ch;
background-color: red;
}
.small3 {
border: 0;
width: 2.5ch;
height: 2.5ch;
background-color: green;
}
.small4 {
border: 0;
width: 2.5ch;
height: 2.5ch;
background-color: blue;
}
<div class="date-grid">
<button class="vrs22">
<time>3</time>
<div class="smallHolder">
<div class="small1"></div>
<div class="small2"></div>
<div class="small3"></div>
<div class="small4"></div>
</div>
</button>
</div>
What I am trying to achieve is this:
Idea is to have this flexible so if I have 2 small squares, results should be like this:
Can anybody try to help me with this?
This could be a solution. It uses your unaltered HTML, but with completely different CSS. Changing the height and width of the outer container will still result in 4 small squares, as long as width and height of the outer container are equal.
* {
box-sizing: border-box;
}
.date-grid {
width: 100px;
height: 100px;
background: #eee;
display: flex;
flex-direction: column;
}
.vrs22 {
width: 100%;
height: 100%;
background: green;
border: none;
padding: 0;
}
time {
display: block;
height: 75%;
font-size: 24px;
display: flex;
flex-direction: column;
justify-content: center;
}
.smallHolder {
width: 100%;
height: 25%;
display: flex;
}
.smallHolder>div {
width: 25%;
height: 100%;
flex-shrink: 0;
flex-grow: 1;
}
.small1 {
background: #fb0;
}
.small2 {
background: #bf0;
}
.small3 {
background: #f07;
}
.small4 {
background: #ba0;
}
<div class="date-grid">
<button class="vrs22">
<time>3</time>
<div class="smallHolder">
<div class="small1"></div>
<div class="small2"></div>
<div class="small3"></div>
<div class="small4"></div>
</div>
</button>
</div>
With different container size:
* {
box-sizing: border-box;
}
.date-grid {
width: 150px;
height: 150px;
background: #eee;
display: flex;
flex-direction: column;
}
.vrs22 {
width: 100%;
height: 100%;
background: green;
border: none;
padding: 0;
}
time {
display: block;
height: 75%;
font-size: 24px;
display: flex;
flex-direction: column;
justify-content: center;
}
.smallHolder {
width: 100%;
height: 25%;
display: flex;
}
.smallHolder>div {
width: 25%;
height: 100%;
flex-shrink: 0;
flex-grow: 1;
}
.small1 {
background: #fb0;
}
.small2 {
background: #bf0;
}
.small3 {
background: #f07;
}
.small4 {
background: #ba0;
}
<div class="date-grid">
<button class="vrs22">
<time>3</time>
<div class="smallHolder">
<div class="small1"></div>
<div class="small2"></div>
<div class="small3"></div>
<div class="small4"></div>
</div>
</button>
</div>
And a variation with only two squares at the bottom:
* {
box-sizing: border-box;
}
.date-grid {
width: 100px;
height: 100px;
background: #eee;
display: flex;
flex-direction: column;
}
.vrs22 {
width: 100%;
height: 100%;
background: green;
border: none;
padding: 0;
}
time {
display: block;
height: 50%;
font-size: 24px;
display: flex;
flex-direction: column;
justify-content: center;
}
.smallHolder {
width: 100%;
height: 50%;
display: flex;
}
.smallHolder>div {
width: 25%;
height: 100%;
flex-shrink: 0;
flex-grow: 1;
}
.small1 {
background: #fb0;
}
.small2 {
background: #bf0;
}
<div class="date-grid">
<button class="vrs22">
<time>3</time>
<div class="smallHolder">
<div class="small1"></div>
<div class="small2"></div>
</div>
</button>
</div>
I am trying to fit 4 divs within the view bounds of a non-scrolling column flexbox but I can't seem to get it working.
What I want:
What I experience:
I have no idea what I am doing and just randomly permutating flex-related CSS fields to try and fix it haha. If someone could point out what is wrong I would love you forever.
Here is the gist of my code:
body {
overflow: hidden;
margin: 0;
width: 100%;
height: 100%;
}
#flexcontent {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
#header #firstContent #secondContent {
flex: 1 1 auto;
}
#header {
background-color: green;
font-weight: 700;
align-content: center;
font-size: 7rem;
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
#picture {
background-color: blue;
flex: 0 1 auto;
}
<body>
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg"/></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
</body>
Try this below. And use object-fit if image doesn't expand or shrink as expected or aspect ratio changes.
#flexcontainer {
display: flex;
flex-direction: column;
height: 100vh;
}
#picture {
flex: 1;
min-height: 0;
}
body {
margin: 0;
}
img {
object-fit: contain;
height: 100%;
width: auto;
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
Please check your container div id
<div id="flexcontainer">
change
#flexcontent {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
to
#flexcontainer {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
try object-fit for img
img {
object-fit: contain;
height: 100%;
}
there is a few thing to fix in your CSS, typo and value used
html, /* to inherit height */
body {
margin: 0;
width: 100%;
height: 100%;
}
#flexcontainer {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
min-height: 0; /* force size calculation*/
}
#header,/* you meant each one of them */
#firstContent,
#secondContent {
flex: 1;
margin: 2px 5vw;/* for demo */
}
#header {
background-color: green;
font-weight: 700;
/* align-content: center; or did you forget display:flex here */
font-size: calc(1rem + 2vw);
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
#picture {
display: flex;
min-height: 0; /* force size calculation*/
}
img {
max-height: 90%;/* whatever */
margin: auto;/* or align-content + justify-content : center on flex parent*/
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
Allow the item holding the image to shrink below its content size.
Define the parameters of the image.
(Tested in Chrome, Firefox and Edge.)
#flexcontainer {
display: flex;
flex-direction: column;
height: 100vh;
}
#picture {
min-height: 0;
background-color: blue;
}
#picture>img {
width: 100%;
max-height: 100%;
object-fit: contain;
}
#header {
background-color: green;
font-weight: 700;
font-size: 7rem;
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
body {
margin: 0;
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
jsFiddle demo
I've tidied up your html a little and simplified the CSS. You want to take the overflow: hidden off of the body tag, and give each of your elements a class instead of an id. Finally, simplify the image section by making the image tag itself a flexbox item:
html,
body {
height: 100%
}
body {
/*overflow: hidden;*/
margin: 0;
}
.flexContainer {
display: flex;
flex-direction: column;
height: 100%;
}
.flexContainer__header,
.flexContainer__firstContent,
.flexContainer__secondContent {
flex: 1 1 auto;
}
.flexContainer__header {
background-color: green;
font-weight: 700;
align-content: center;
font-size: 7rem;
}
.flexContainer__firstContent {
background-color: red;
}
.flexContainer__secondContent {
background-color: yellow;
}
.flexContainer__picture {
display: block;
width: 100%;
}
<div class="flexContainer">
<div class="flexContainer__header">Title</div>
<img class="flexContainer__picture" src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" />
<div class="flexContainer__firstContent">first</div>
<div class="flexContainer__secondContent">second</div>
</div>
My use case is the following:
I've got a center-aligned layout with a max-width of say 360px.
Part of that layout is a container with two adjacent boxes. The right one contains an image that fills 33% width of the window. Left to it should be a text container. This text container should be aligned with the left border of the remaining center-aligned layout.
Here's a sketch of it:
body {
display: flex;
flex-direction: column;
}
.col {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.items-center {
align-items: center;
}
.items-end {
align-items: flex-end;
}
.items-start {
align-items: flex-start;
}
.top {
max-width: 360px;
width: 100%;
height: 50px;
background: tomato
}
.width-2-3 {
width: 66.666%;
}
.width-1-3 {
width: 33.3333%
}
.left-content,
.right-content {
width: 100%;
height: 50px;
}
.left-content {
max-width: 240px;
background: rebeccapurple;
color: white;
}
.right-content {
background: pink;
}
<div class="col items-center">
<div class="top"></div>
</div>
<div class="row">
<div class="width-2-3 col items-end">
<div class="left-content">text</div>
</div>
<div class="width-1-3 col items-start">
<div class="right-content">[img]</div>
</div>
</div>
So basically my goal is to left align those two rows, no matter how big the window width. But after trying for some time I just can't get the math right! So any help would be greatly appreciated :)
You can consider negative margin left:
body {
display: flex;
flex-direction: column;
margin:0;
}
.col {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.items-center {
align-items: center;
}
.top {
max-width: 360px;
width: 100%;
height: 50px;
background: tomato
}
.width-2-3 {
width: 66.666%;
}
.width-1-3 {
width: 33.3333%
}
.left-content,
.right-content {
width: 100%;
height: 50px;
}
.left-content {
max-width: 240px;
background: rebeccapurple;
color: white;
}
.right-content {
background: pink;
}
#media (min-width:360px) {
.left-content {
margin-left:calc((150% - 360px)/2); /* 150 is 3/2*100% since the width is 2/3*/
}
.right-content {
margin-left:calc(240px + ((200% - 360px)/2) - 150%); /*200% is equal to 150% of the left element */
}
}
<div class="col items-center">
<div class="top"></div>
</div>
<div class="row">
<div class="width-2-3 col">
<div class="left-content">text</div>
</div>
<div class="width-1-3 col">
<div class="right-content">[img]</div>
</div>
</div>
Thanks to #temani-afif I came up with a solution that required only one line to change
- max-width: calc(240px);
+ max-width: calc(180px + 25%);
This way the text container is always left aligned to the top container while taking all the available space until the 33% window-width image container starts. And this works for all window sizes. Thanks for your help everyone! :)
body {
display: flex;
flex-direction: column;
}
.col {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.items-center {
align-items: center;
}
.items-end {
align-items: flex-end;
}
.items-start {
align-items: flex-start;
}
.top {
max-width: 360px;
width: 100%;
height: 50px;
background: tomato
}
.width-2-3 {
width: 66.666%;
}
.width-1-3 {
width: 33.3333%
}
.left-content,
.right-content {
width: 100%;
height: 50px;
}
.left-content {
max-width: calc(180px + 25%);
background: rebeccapurple;
color: white;
}
.right-content {
background: pink;
}
<div class="col items-center">
<div class="top"></div>
</div>
<div class="row">
<div class="width-2-3 col items-end">
<div class="left-content">text</div>
</div>
<div class="width-1-3 col items-start">
<div class="right-content">[img]</div>
</div>
</div>
Why dont you get rid of .item-end and .item-start divs so you can easily control the content.
body {
display: flex;
flex-direction: column;
}
.container {
position:relative;
max-width:360px;
width:100%;
display:flex;
justify-content:center;
}
.different-width {
max-width:450px;
}
.col {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.items-center {
align-items: center;
}
.content-center {
justify-content:center;
}
.top {
max-width: 360px;
width: 100%;
height: 50px;
background: tomato
}
.left-content,
.right-content {
width: 100%;
height: 50px;
}
.width-2-3 {
width: 66.666%;
}
.width-1-3 {
width: 33.3333%
}
.left-content {
max-width: 240px;
background: rebeccapurple;
color: white;
}
.right-content {
background: pink;
}
<div class="col items-center">
<div class="container">
<div class="top"></div>
</div>
</div>
<div class="row content-center">
<div class="container different-width">
<div class="left-content width-1-3">text</div>
<div class="right-content width-2-3">[img]</div>
</div>
</div>
If you need to have more control over the left-content and right-content width, consider using flex-grow and flex-basis.
If you want to control the width of the second container, make another class with a different max-width value.