flex-box how to make more responsive "boxes" - html

I want for the boxes to be more responsive, and to keep 1:1 ratio all the time.
When I set min-width to the .box1, .box2 they always take the whole width of the .box ! And it is like they don't respond to height?
I don't want to boxes be full width (or height) of the flex items, since i want some space between them, and I don't want them to overflow their .box container,..( I want keep them inside)
I know I can use media queries to resize the .box1,.box2,.box3, .. but is there any other way?
.grid {
width: 100%;
height: 100%;
display: flex;
flex-flow: row wrap;
justify-content: space-around;
//margin:0 -40px;
}
/*first two children*/
.grid>.box:not(:last-child) {
background: grey;
width: 50%;
}
.box1,
.box2,
.box3 {
border: 2px solid #111;
width: 100px;
height: 100px;
transform: rotate(-45deg);
text-align: center;
}
.box1,
.box2 {
margin: 0 auto;
}
.box p {
position: relative;
color: white;
}
<div class="wrapper">
<div class="grid">
<div class="box">
<div class="box1">
<p>Here is something !</p>
</div>
</div>
<div class="box ">
<div class="box2"></div>
</div>
<div class="box ">
<div class="box3"></div>
</div>
</div>
</div>

I didnt get your complete query but if you want to make square responsive without adjusting its height manually then use padding hack
.box1,
.box2,
.box3{
width: 100%;
height: 0;
padding-bottom: 50%;
postition:relative
background: red;
}

Related

Set full height of main container

I have a wrapper and inside I have 2 divs (left & right). The wrapper takes the height of its content. The left div has a set relative height. What I want is for div right to take 100% of the wrapper height after div left has stretched the wrapper height. How can I achieve this? Thanks in advance.
.wrapper {
width: 100%;
height: fit-content;
background-color: gold;
border:solid 1px red;
}
.wrapper .left {
width: 50%;
height: 20vh;
background-color: pink;
}
.wrapper .right {
width: 50%;
/*something like this*/
height: 100%;
background-color: blue;
}
<div class="wrapper">
<div class="left">
</div>
<div class="right">
</div>
</div>
Couple of things here,
Firstly, I am not sure if you actually meant for your right div to be on the right column. As of now, it's rendered below the left.
I assume that's what you wanted, so I'll suggest a fix it accordingly.
Other than that, I think you have the right idea.
Additionally, you do not need the fit-content.
Please let me know if I am missing something.
.wrapper {
width: 100%;
background-color: gold;
border:solid 1px red;
display: flex;
flex-direction: row;
}
.wrapper .left {
width: 50%;
height: 20vh;
background-color: pink;
}
.wrapper .right {
width: 50%;
background-color: blue;
}
<div class="wrapper">
<div class="left">
</div>
<div class="right">
</div>
</div>

How to set up alternating divs in HTML and CSS?

I am setting up a website that has a gallery of images that alternate vertically.
Boiled down, what I've tried is setting a hard coded width to the div (image in the actual website) then used position to situate the right column of divs. Then added the third div which is supposed to sit in left column after the height of the div in the right column.
.large-container {
width: 200px;
height: 100px;
background-color: blue;
color: white;
}
.small-container {
width: 150px;
height: 50px;
background-color: red;
position:absolute;
top: 100px;
left: 200px;
}
<div style="position:relative;">
<div class="large-container">
This is an outer container
</div>
<div class="small-container">
This has been the small one
</div>
<div class="large-container">
This is an outer container
</div>
</div>
Here is the intended outcome:
intended-outcome
Here is the current outcome:
current-outcome
As you can see the second div in the left column sits directly under the first div. I would like it to sit after the height of the right div.
You Can use css grid, this will make it more dynamically and you'll add whatever containers as you want.
.grid {
display: inline-grid;
grid-template-areas: "l1 ." ". s1" "l2 .";
}
.large-container {
width: 200px;
height: 100px;
background-color: blue;
color: white;
}
.small-container {
width: 150px;
height: 50px;
background-color: red;
top: 100px;
left: 200px;
}
.l1 {
grid-area: l1;
}
.l2 {
grid-area: l2;
}
.s1 {
grid-area: s1;
}
<div class="grid">
<div class="large-container l1">
This is an outer container
</div>
<div class="small-container s1">
This has been the small one
</div>
<div class="large-container l2">
This is an outer container
</div>
</div>
You can Read more info about css grid here
This is a good case to not use "position" and to start using css grid. This can be done easly by defining a grid with 2 columns and 3 rows. And then, just laying down the elements as you wish.
Take a look at the followng example:
.container {
display: grid;
grid-template-columns: 200px 150px;
grid-template-rows: 100px 50px 100px;
}
.large-container {
width: 200px;
height: 100px;
background-color: blue;
color: white;
}
.small-container {
width: 150px;
height: 50px;
background-color: red;
}
.item2 {
grid-row: 2;
grid-column: 2;
}
.item3 {
grid-row: 3;
grid-column: 1;
}
<div class="container">
<div class="large-container item1"></div>
<div class="small-container item2"></div>
<div class=" large-container item3"></div>
</div>
You need to remove position: absolute; on the right column item. Then replace left with margin-left: 200px; and top with margin-top: 100px;
Remove position:absolute; and use margin-left:200px instead of left:200px; for .small-container
.large-container {
width: 200px;
height: 100px;
background-color: blue;
color: white;
}
.small-container {
width: 150px;
height: 50px;
background-color: red;
top: 100px;
margin-left: 200px;
}
<div style="position:relative;">
<div class="large-container">
This is an outer container
</div>
<div class="small-container">
This has been the small one
</div>
<div class="large-container">
This is an outer container
</div>
</div>
Change the CSS on the small container to
.small-container {
width: 150px;
height: 50px;
background-color: red;
margin-left: 200px;
}
Leave all the rest as it is.
Have you tried changing left on .small-container to margin-left: 200px;

How to contrain the aspect ratio of a div [duplicate]

This question already has answers here:
Maintain the aspect ratio of a div with CSS
(37 answers)
Closed 4 years ago.
Im trying to achieve the following:
Where the blue box is of variable height and the yellow box is always of height 50% of the blue box.
Its fairly simple using flex
<div style="display:flex;align-items:center">
<div id="yellow" style="height:50%">
</div>
</div>
The problem is that im trying to keep the inner box a specific ratio, in this case square. How do i approach this?
Bonus points:
How do i generally specify a ratio? Is there a solution that works not only for 1:1 but any x:y?
How would i do that without using flexbox while potentially still aiming for a)?
Extra information: The blue box is always wider than higher, think a button.
I don't think there is a way to define the width using the height (even if we can do the opposite using some trick like padding) but an idea is to rely on a square image that you make invisible in order to keep the ratio. Then the content should be positionned:
#blue {
display: flex;
align-items: center;
justify-content:center;
height:80vh;
background: blue;
}
#yellow {
height: 50%;
background: yellow;
position:relative;
}
img {
max-height:100%;
visibility:hidden;
}
#yellow .content {
position:absolute;
top:0;
right:0;
left:0;
bottom:0;
}
<div id="blue" >
<div id="yellow" >
<img src="https://picsum.photos/500/500?image=1069" >
<div class="content">Some content here</div>
</div>
</div>
But in case the height of the blue is a fixed value, better rely on CSS variable like this:
#blue {
display: flex;
align-items: center;
justify-content:center;
--h:80vh;
height:var(--h);
background: blue;
}
#yellow {
height: calc(var(--h) / 2);
width:calc(var(--h) / 2);
background: yellow;
position:relative;
}
<div id="blue" >
<div id="yellow" >
<div class="content">Some content here</div>
</div>
</div>
A similar answer to the one provided by Temani Afif, but using an svg instead of an image (so no need to the extra request).
Also, it's easier to adapt it to arbitrary aspect ratios
.container {
height: 150px;
background-color: lightblue;
display: flex;
align-items: center;
justify-content: center;
margin: 10px;
}
.aspectRatio {
display: grid;
background-color: yellow;
height: 50%;
}
.aspectRatio svg {
height: 100%;
border: solid 1px red;
animation: resize 1s infinite;
}
.aspectRatio > * {
grid-area: 1 / 1 / 2 / 2;
}
#keyframes resize {
from {height: 100%;}
to {height: 99.9%;}
}
<div class="container">
<div class="aspectRatio">
<svg viewBox="0 0 1 1"></svg>
<div class="inner">square</div>
</div>
</div>
<div class="container">
<div class="aspectRatio">
<svg viewBox="0 0 4 3"></svg>
<div class="inner">ratio 4/3</div>
</div>
</div>
See if this can help you,
.outer {
background-color: lightblue;
height: 100px; /* Change as per your requirement */
display: flex;
align-items: center;
justify-content: center;
max-width: 200px; /* You can Remove this */
}
.inner {
background-color: lightyellow;
height: 50%;
width: 50px;
}
<div style="" class="outer">
<div id="yellow" class="inner">
</div>
</div>
If you rotate by 90deg, it's possible :)
variable width and height of the parent (and ratio)
child is always 50% as tall as its parent
and a square
It'll surimpose to other content if it wants to because of the transform though.
⇒ Codepen
.flex {
display: table-cell; /* allows "vertical" centering (not possible with flex/grid here because of the padding-top trick on child) */
width: 12rem;
height: 20rem;
vertical-align: middle; /* "vertical" centering */
transform: rotate(90deg) translateY(-50%); /* vertical becomes horizontal */
background-color: lightblue;
}
.flex.large {
height: 35rem;
}
.item {
width: 50%;
height: 0;
margin-left: 25%; /* "horizontal" centering */
padding-top: 50%; /* padding-top trick for a square */
background-color: lightyellow;
}
<div class="flex">
<div class="item"></div>
</div>
<hr>
<div class="flex large">
<div class="item"></div>
</div>
Try this if it can help you.(with out flex)
.outerdiv
{
background-color: lightblue;
height: 100px;
display: grid;
align-items: center;
}
.innerdiv
{
background-color: lightyellow;
height: 50%;
width: 50px;
margin:0 auto;
}
<div style="" class="outerdiv">
<div id="yellow" class="innerdiv"></div>
</div>

Inner div with square ratio and flexbox [duplicate]

This question already has answers here:
Maintain the aspect ratio of a div with CSS
(37 answers)
Closed 4 years ago.
Im trying to achieve the following:
Where the blue box is of variable height and the yellow box is always of height 50% of the blue box.
Its fairly simple using flex
<div style="display:flex;align-items:center">
<div id="yellow" style="height:50%">
</div>
</div>
The problem is that im trying to keep the inner box a specific ratio, in this case square. How do i approach this?
Bonus points:
How do i generally specify a ratio? Is there a solution that works not only for 1:1 but any x:y?
How would i do that without using flexbox while potentially still aiming for a)?
Extra information: The blue box is always wider than higher, think a button.
I don't think there is a way to define the width using the height (even if we can do the opposite using some trick like padding) but an idea is to rely on a square image that you make invisible in order to keep the ratio. Then the content should be positionned:
#blue {
display: flex;
align-items: center;
justify-content:center;
height:80vh;
background: blue;
}
#yellow {
height: 50%;
background: yellow;
position:relative;
}
img {
max-height:100%;
visibility:hidden;
}
#yellow .content {
position:absolute;
top:0;
right:0;
left:0;
bottom:0;
}
<div id="blue" >
<div id="yellow" >
<img src="https://picsum.photos/500/500?image=1069" >
<div class="content">Some content here</div>
</div>
</div>
But in case the height of the blue is a fixed value, better rely on CSS variable like this:
#blue {
display: flex;
align-items: center;
justify-content:center;
--h:80vh;
height:var(--h);
background: blue;
}
#yellow {
height: calc(var(--h) / 2);
width:calc(var(--h) / 2);
background: yellow;
position:relative;
}
<div id="blue" >
<div id="yellow" >
<div class="content">Some content here</div>
</div>
</div>
A similar answer to the one provided by Temani Afif, but using an svg instead of an image (so no need to the extra request).
Also, it's easier to adapt it to arbitrary aspect ratios
.container {
height: 150px;
background-color: lightblue;
display: flex;
align-items: center;
justify-content: center;
margin: 10px;
}
.aspectRatio {
display: grid;
background-color: yellow;
height: 50%;
}
.aspectRatio svg {
height: 100%;
border: solid 1px red;
animation: resize 1s infinite;
}
.aspectRatio > * {
grid-area: 1 / 1 / 2 / 2;
}
#keyframes resize {
from {height: 100%;}
to {height: 99.9%;}
}
<div class="container">
<div class="aspectRatio">
<svg viewBox="0 0 1 1"></svg>
<div class="inner">square</div>
</div>
</div>
<div class="container">
<div class="aspectRatio">
<svg viewBox="0 0 4 3"></svg>
<div class="inner">ratio 4/3</div>
</div>
</div>
See if this can help you,
.outer {
background-color: lightblue;
height: 100px; /* Change as per your requirement */
display: flex;
align-items: center;
justify-content: center;
max-width: 200px; /* You can Remove this */
}
.inner {
background-color: lightyellow;
height: 50%;
width: 50px;
}
<div style="" class="outer">
<div id="yellow" class="inner">
</div>
</div>
If you rotate by 90deg, it's possible :)
variable width and height of the parent (and ratio)
child is always 50% as tall as its parent
and a square
It'll surimpose to other content if it wants to because of the transform though.
⇒ Codepen
.flex {
display: table-cell; /* allows "vertical" centering (not possible with flex/grid here because of the padding-top trick on child) */
width: 12rem;
height: 20rem;
vertical-align: middle; /* "vertical" centering */
transform: rotate(90deg) translateY(-50%); /* vertical becomes horizontal */
background-color: lightblue;
}
.flex.large {
height: 35rem;
}
.item {
width: 50%;
height: 0;
margin-left: 25%; /* "horizontal" centering */
padding-top: 50%; /* padding-top trick for a square */
background-color: lightyellow;
}
<div class="flex">
<div class="item"></div>
</div>
<hr>
<div class="flex large">
<div class="item"></div>
</div>
Try this if it can help you.(with out flex)
.outerdiv
{
background-color: lightblue;
height: 100px;
display: grid;
align-items: center;
}
.innerdiv
{
background-color: lightyellow;
height: 50%;
width: 50px;
margin:0 auto;
}
<div style="" class="outerdiv">
<div id="yellow" class="innerdiv"></div>
</div>

Put two outside divs above center div on smaller screen

The subject says it all, but I am looking for a clean simple way to do this. Essentially think of it like this:
[A][__B_][A]
to
[A][A]
[__B_]
Hopefully that is clear enough but I can elaborate if need be.
Thanks in advance!
you can use flexbox order for that
.flex-container {
padding: 0;
margin: 0;
display: flex;
flex-flow: row wrap;
}
.flex-item {
box-sizing: border-box;
background: green;
padding: 20px;
width: 20%;
height: 100px;
border: 1px solid white;
color: white;
text-align: center;
}
#media screen and (max-width: 900px){
.flex-item {
background: green;
width: 50%;
height: 100px;
color: white;
text-align: center;
}
.flex-item:nth-of-type(2) {
order: 3;
width: 100%
}
}
<div class="flex-container">
<div class="flex-item">div a</div>
<div class="flex-item">div b</div>
<div class="flex-item">div a</div>
</div>
read more here: https://developer.mozilla.org/en/docs/Web/CSS/order
If you're starting with 3 elements in a row together, but you need element B to be outside on it's own, you will want to utilize flexbox.
You'd be focusing on the order property for the selectors, and using flex-grow on element B. Read through that document to get an idea on how to set that up, or to make sure that's exactly what you need. Otherwise, you can turn to jQuery.
You can do this by putting all three divs inside one div:
<div class="allthree">
<div class="twoas">
<div class="a"></div>
<div class="a"></div>
</div>
<div class="oneb">
<div class="b"></div>
</div>
</div>
Now add some CSS to this so the b is 100% width and the a is 50% width. Make sure the a is display: inline-block;
.allthree {
width: <your-width>
}
.allthree .twoas {
width: 100%;
}
.allthree .twoas .a {
display: inline-block;
width: 50%;
}
.allthree .oneb {
width: 100%;
}
.allthree .oneb .b {
width: 100%;
}