Wrapping different sized divs with no vertical whitespace [duplicate] - javascript

This question already has answers here:
Is it possible for flex items to align tightly to the items above them?
(5 answers)
Closed 2 years ago.
When I resize my window, I am wanting a row of divs of different sizes to cascade, however when I try with Flexbox I am getting vertical white space due to the differing sizes of the divs.
Is there any way in which I can remove this whitespace/specify how much there is between the divs?
Here is a link to my stackblitz
.content {
color: #fff;
font: 100 24px/100px sans-serif;
height: 150px;
text-align: center;
}
.content div {
width: 300px;
}
.red {
background: orangered;
height: 40px;
}
.green {
background: yellowgreen;
height: 150px;
}
.blue {
background: steelblue;
height: 150px;
}
/* Flexbox Styles */
.content {
display: flex;
flex-wrap: wrap;
}
<div class="content">
<div class="red">1</div>
<div class="green">2</div>
<div class="blue">3</div>
</div>

The problem is here is that you are setting a width of 300px to the colored children of content with
.content div {
width: 300px;
}
as the .content div has no width, it's the size of its parent, which is 100% of the screen width, . So, it will display as much divs as it can within its own width.
If you resize to something between 300px and 599px, you should have all your divs aligned as you wish.
What I think you'll want to use here is a media query that will set your .content div to flex-direction: column once screen width is inferior to the size you want. Let's say 900px, so once your three colored children don't all fit on the same line, they align vertically. You will also need to remove the flex-wrap: wrap that's forcing the elements to stay on the same line.
It would look something like this:
#media screen and (max-width: 900px) {
.content {
flex-direction: column;
flex-wrap: nowrap;
}
}

Related

How do I move components within my button horizontally and vertically based on screen width?

I would like my button, which contains 3 components (1 being on the far left, 2 being in the center, and 3 being on the far right (because of align-center: space between), which I need for another variant), to function like this, when the screen size is greater than 560px:
where flex-direction: row keeps it functioning how I want. Then, I want to change it slightly when the screen width drops below 560px. I would like to move the 1 component above the 2 and 3 components and be centered between them (horizontally), as can be seen here...
I was able to achieve the solution with the picture when I placed a div surrounding component 1 and 2, but then I cannot achieve the final solution when the screen width is below 560px. I have been able to achieve that solution as well when I pair component 2 and 3 within the same div as well, but that makes the wider function not work how I want either.
I imagine there's a way to achieve what I want without enforcing these div groupings, but I'm not really sure. I'm also somewhat new to Javascript, so any advice about something I've said would be appreciated too.
I used a breakpoint to change the ruleset for both the container element (button in your case) and the children.
The below example is in LESS, but you can see the compiled CSS in this codepen by using the dropdown on the CSS panel.
#mediumQuery: ~"screen and (max-width:560px)";
.container {
display : flex;
flex-direction: row;
column-gap : 20px;
border : 2px solid #yellow;
padding : 10px;
width : 100vw;
div {
display : inline-block;
border : 2px solid #purple;
width : 200px;
height : 100px;
font-size : 40px;
line-height : 100px;
text-align : center;
&:last-child{
margin-left: auto;
}
}
#media #mediumQuery {
display : block;
flex-direction : unset;
column-gap : unset;
border : 2px solid #lightBlue;
text-align : center;
div {
margin : 20px;
&:first-child {
display : block;
margin : auto;
}
}
}
}
you can put the div you want to be on top into another container and then play with #media queries and adjust how you want
main {
display: flex;
flex-wrap: wrap;
max-width: 560px;
border: 1px solid;
}
div {
width: 100px;
height: 100px;
border: 1px solid;
}
div:nth-child(3) {
margin-left: auto;
}
#media screen and (max-width: 560px) {
main {
justify-content: space-between;
}
section {
width: 100%;
}
section div {
margin: auto;
}
}
#media screen and (max-width: 240px) {
main {
flex-direction: column;
justify-content: center;
align-items: center;
}
div:nth-child(3) {
margin: auto;
}
}
<main>
<section>
<div>1</div>
</section>
<div>2</div>
<div>3</div>
</main>

Can I apply CSS to a flex-item when it wraps onto a new row?

.wrapper {
border: 5px solid pink;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.a-fc {
background-color: purple;
width: 300px;
/*height: 100px;*/
}
.b-fc {
background-color: orange;
display: flex;
flex-direction: column;
/*flex-wrap: wrap;*/
flex-basis:70px;
flex-grow:1;
}
.b-fc > * {
flex-grow: 1;
flex-basis: 100px;
}
.b-fc > *:nth-child(1) {
background-color: red;
}
.b-fc > *:nth-child(2) {
background-color: blue;
}
.b-fc > *:nth-child(3) {
background-color: green;
}
<div class="wrapper">
<div class="a-fc">
<div>a1</div>
</div>
<div class="b-fc">
<div>b1</div><div>b2</div><div>b3</div>
</div>
</div>
FC = flex-container.
FI = flex-item.
I am able to place .b-fc onto a new row when the space left for it to exist on the original row goes below 70px.
My task: I want b-fc's FIs to stack vertically when no new row is created/they don't wrap. I want b-fc's FIs to align horizontally when b-fc wraps.
Current solution
In the code-snippet above, I've tried to achieve my task by writing one set of properties that work for both scenarios by setting a `flex-basis` on `.b-fc`'s FIs. If the space left for `.b-fc`'s FIs is less than this flex-basis (100px), the FIs will stack vertically. The weakness: i) if `.b-fc`'s `width`'s larger than 300px, its FIs align horizontally ii) When `.b-fc` wraps, its FIs wrap when `.bf-c` is less than 300px.
Therefore, I'm figuring it'd be more powerful to be able to apply CSS when .b-fc wraps. Is this possible?
*Idea 1: CSS variables & JS*
Perhaps using CSS variables/SASS I could continually assess whether FC - .a-fc <= than 70px. If true, apply stylings to .b-fc.
Idea 2: media-queries
Another option is to test when row2 is made, use media queries to capture this and apply CSS to .b-fc with media queries.
P.S. Similar question has been asked here before in 2015. Maybe new techniques have transpired since.
For this particular case you can consider the use of max() combined with flex-basis. The trick is to either have 0px (horizontal item) or a very big value (vertical items).
You will note that this is not a generic solution and the value is based on your html structure:
395px = 300px (width of a-fx) + 70px (flex-basis of b-fc) + 10px (border of wrapper) + 16px (default body margin) - 1px
.wrapper {
border: 5px solid pink;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.a-fc {
background-color: purple;
width: 300px;
}
.b-fc {
background-color: orange;
display: flex;
flex-wrap: wrap;
flex-basis: 70px;
flex-grow: 1;
}
.b-fc>* {
flex-grow: 1;
flex-basis: max(0px, (100vw - 395px)*100);
height: 100px;
}
.b-fc>*:nth-child(1) {
background-color: red;
}
.b-fc>*:nth-child(2) {
background-color: blue;
}
.b-fc>*:nth-child(3) {
background-color: green;
}
<div class="wrapper">
<div class="a-fc">
<div>a1</div>
</div>
<div class="b-fc">
<div>b1</div>
<div>b2</div>
<div>b3</div>
</div>
</div>
So to answer your question: No, we cannot apply CSS on wrapping (CSS cannot detect wrapping) but we can always find workaround of each case.
Similar questions:
Without media queries how to achieve 3 column desktop to 1 column mobile layout
CSS grid maximum number of columns without media queries

Perfectly center images in react column

I'm having difficulty aligning some images inside of bootstrap 4 columns. I have tried using the CSS property text-align: center, and this will center the image horizontal. My columns take up a large amount of the view port though, so I also need the images to be centered vertical.
Here is what my react component is returning. class="img13" is what i am attempting to center.
<div id="border">
<div class="container">
<div class="row tower">
<div class="col-sm-3 towers" id="tower1">
<div class="tower-icon"><img class="img13" src={character}></img></div>
</div>
</div>
</div>
</div>
Here is the CSS that I currently have. It hard codes an image to be centered in one column, but if i change the display size for the site, or use a different image, it is no longer centered.
.row{
display: flex;}
.towers {
color: white;
height: 100%;
position: relative;
}
.tower-icon{
margin-top: 52%;
margin-bottom: 48%;
}
.img13{
height: auto;
width: 100%;
}
Start Menu here is an attached picture of what the component looks like. The background is the column, and the 'start' picture is the class="img13"
You can take advantage of flexbox and auto center align everything within the .tower-icon div like so:
.tower-icon {
display: flex;
align-items: center;
justify-content: center;
}
Just please note that the logo will horizontally and vertically center within the constraints of the column with the .col-sm-3 class.
Test link:
https://jsbin.com/sekosibizo/edit?css,output
Set the div containing the image to be the height of the viewport, then set its display property to flex. Then give the image a margin: auto.
.tower-icon {
height: 100vh;
display: flex;
}
.img13 {
margin: auto;
height: auto;
width: 100%;
}

Show Complete Pictures in Catalog

I have catalog of 6 picture. I am showing them in 1 row. On larger screens all 6 photos shows correctly, but when i change screen width to tablet size of mobile size, picture cuts in half.
The behaviour i want is that, show all 6 pictures on larger screen, but as soon as user window size, only picture which can be shown completely in that particular screen size show show, and other should get hide. Right now, I am using overflow: hidden and container of fixed size.
Below are some screenshots to show the issue,
The question is too general but I think this would be a sample for it.
add below styles to the div wraps images.
.wrapper {
display: flex;
flex-wrap: wrap;
overflow: hidden;
// the following styles are optional but you must specify width and height
width: 100%;
height: 320px;
padding: 20px;
}
and add these styles to images.
img {
height: 100%;
width: auto;
// optional
margin-right: 50px;
margin-top: 50px;
}
The wrapper styles make that images wrap in multiple lines if they expand the wrapper width and overflow: hidden makes that only single line shows
Use width:100% on img tag in html
OR
You can use it n your style-sheet like
img{
width:100%;
}
also try to use objectfit:contain if you img has some fixed height width
here is amir mahdi digbari expanded solution in action.
You can achieve the same with css grid but flexbox is good enough for this.
.img {
height: 200px;
width: 200px;
border: 1px solid red;
}
.wrapper {
display: flex;
overflow: hidden;
width: 100%;
height: 200px;
flex-wrap: wrap;
justify-content: space-around;
border: 2px solid blue;
}
.container {
width: 1250px;
max-width: 100%;
margin: auto;
}
<div class="container">
<div class="wrapper">
<div class="img">Img1</div>
<div class="img">Img2</div>
<div class="img">Img3</div>
<div class="img">Img4</div>
<div class="img">Img5</div>
<div class="img">Img6</div>
</div>
</div>
Happy coding!

how to let block element height auto while itself has no child element [duplicate]

This question already has answers here:
Flexbox fill available space vertically
(2 answers)
Flexbox height percentages [duplicate]
(1 answer)
Closed 5 years ago.
Problem: Assume that we have three div elements in a div element as the code below. I want to set the inner div's height auto. For example, if the height of the outer div is 300px and we have three inner elements, the height of the inner element should be 100px.
What I know: If the inner element has no child elements, the height of the inner element is 0px. However, can we change this phenomenon?
Reason: 100px = 300px / 3.
Solver: I can use js to solve this problem. However, I want to know if i can use css to solve this problem.
#outer {
width: 300px;
height: 300px;
;
display: flex;
flex-direction: column;
}
#inner1 {
background: #ccc;
}
#inner2 {
background: red;
}
#inner3 {
background: blue;
}
<div id="outer">
<div id="inner1"></div>
<div id="inner2"></div>
<div id="inner3"></div>
</div>
Apply flex:1 to your inner flex elements. flex:1 is a shorthand css of
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
Reference Link
flex-grow
flex-shrink
flex-basis
Stack Snippet
#outer {
width: 300px;
height: 300px;
display: flex;
flex-direction: column;
}
#outer div {
flex: 1;
}
#inner1 {
background: #ccc;
}
#inner2 {
background: red;
}
#inner3 {
background: blue;
}
<div id="outer">
<div id="inner1"></div>
<div id="inner2"></div>
<div id="inner3"></div>
</div>

Categories