Suppose you have a <div> with the following CSS:
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 500px;
height: 300px;
Notice that there is a fixed height. But suppose any child <div>s have a height of only 50px.
When these children wrap, the rows are evenly distributed vertically to fill the fixed height of the parent. This can be seen here. In that example, the two rows that result from wrapping each gain an equal space under them, such that each row and its space takes up half of the parent's height. But if there are more rows, the height will be redistributed evenly, such that they each take up (1/n_rows)%. Of course, a picture is worth 103 words...
Goal: Be able to fix the amount of space between rows. (As I dynamically add items I want the rows to fill in bit by bit without each new row causing the others to shift upwards.)
I haven't found a way to do this. It's not related to item height, margin, or padding, or to the flex gap. References on flex-wrap do not seem to mention this space and I have had no luck with Google. Of course I could just remove the parent's fixed height, but I'd rather not, because then items under the parent will shift as it grows instead.
If I understand your question correctly, you're looking for align-content: flex-start.
Related
I am displaying verse: poetry and song lyrics.
I have one layout in which the lyrics flow as multi-column text. I have it working with flex layout, but it is not 100% to my satisfaction. See this codepen: https://codepen.io/sidewayss/pen/WNNEBgV
The remaining issue is the horizontal spacing of the columns. Flex layout spreads the columns as if I had set an alt version of align-items:space-between. I want the columns to align left, which can be accomplished only by setting the width of the container <div> to one pixel greater than the width at which it starts scrolling horizontally, the minimum width for displaying all the text.
It seems to me that there should be a way to do this with grid layout, but I have not been able to make it happen. I have tried a variety of settings, including the various auto flow settings.
Is there a solution for this in CSS, or do I have to rely on JavaScript? I have a way of doing it in JS, and I already have code that manipulates these elements, but I'd much rather do it in CSS. It seems like a supremely reasonable layout request, at least to me. The biggest problems I've encountered with grid layout are the need to set the number of rows and columns and to size those columns. I want that to be all automatic because otherwise I'm still writing JS code to set those values.
div {
display:flex;
flex-direction:column;
flex-wrap:wrap;
height:300px;
overflow-x:scroll;
/* align block to start*/
align-content: flex-start;
}
span {
padding:0 8px;
/* align child block to start*/
align-self: flex-start;
}
I need to do suitable css for: creating a boxes that can be splitted to one or more columns depend on the screen size. (for example: if I have 7 boxes it can appear in big screen in 7 columns and 1 row, or it can appear in smaller screen in 2 rows and 4 columns, and etc.
Now I am doing in the div container:
display: flex;
flex-wrap: wrap;
overflow-y: auto;
overflow-x: hidden;
and in the box class:
height: 166px;
width: 320px;
I want that if I have a small screen and I have enough place to only one column, for example: if the div parent have 600 px width, I will have just one column of boxes but a lot of extra space, I will want that the boxes will shrink in that case to width 250px (minimum width), and that I will have 2 columns..
I want to use flex-shrink only when I have one column that created from the display flex.
How can I do it? (I want it to work in all browsers, that is why I didn't use grid)
Thanks
This question already has answers here:
Create a Masonry grid with flexbox (or other CSS)
(3 answers)
Is it possible for flex items to align tightly to the items above them?
(5 answers)
Closed 5 years ago.
Using flex
.container {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
.box {
width: 46%;
flex-grow: 1;
}
gets the next picture:
Using floating
.container {
overflow: hidden;
}
.box {
display: inline-block;
float: left;
}
gets me the next picture:
The task requires that there would be no vertical spaces between boxes (how it is in the first column with flexbox or in the second column with floating), so the boxes float to each other filling ALL available space.
Boxes widths are the same, but boxes heights differ.
Should be responsive, so the 2 columns get into one when viewport shrinks.
Appreciate any help or hints.
UPDATE: I would like to explain why the solution here (question for which is marked as duplicate) doesn't work form me – in that question, items are about the same, they are pretty much homogeneous, so they can be approximately calculated how much items goes into which column. In my example, items can be of very different sizes, so if 2 (for example) columns created, it is not clear hot to put html layout, how many divs goes into which column, so, for example, 'header 1' box can be the same height as 2-5 together – and their height is dynamic.
You can use column-width property (CSS columns), though you might have to check the browser support for that feature.
Here is the documentation.
Here is a fiddle for the same.
I've started using the flexbox recently and there often comes the situation where I need to distribute space on the main axis between elements.
I often hesitate between width and flex-grow. For example, if I want one item to measure 2 measures, and the other 1 measure, adding up to 100%, I have two choices. I can either set width: 66.6% and width: 33.3%, or flex-grow: 2 and flex-grow: 1.
Sometimes if I want one element to grow the rest of the space, I can either do width: 100% or flex-grow: 1.
How do I choose? What are the differences/considerations in using width vs. flex-grow?
width and flex-grow are two entirely different CSS properties.
The width property is used for defining the width of elements.
The flex-grow property is used for distributing free space in a flex container. This property doesn't apply a specific length to an element, like the width property. It simply allows a flex item to consume whatever space may be available.
Sometimes if I want one element to grow the rest of the space, I can either do width: 100% or flex-grow: 1. How do I choose?
Yes, if there is one element in the row, width: 100% and flex-grow: 1 may have the same effect (depending on padding, border and box-sizing settings).
But what if there are two elements, and you want the second one to take the remaining space? With a sibling in the container, width: 100% causes an overflow. I guess you can do something like this:
width: calc(100% - width of sibling);
But what if the sibling's width is dynamic or unknown? calc is no longer an option.
The quick and easy solution is flex-grow: 1.
While width and flex-grow are apples-to-oranges, width and flex-basis are apples-to-apples.
The flex-basis property sets the initial main size of a flex item and is similar to width.
What are the differences between flex-basis and width?
For the differences between flex-basis and flex-grow see:
flex-grow not sizing flex items as expected
I am trying to replicate the behavior of tables using flexbox, for greater predictability and control. Here's a codepen of what I have currently.
Here's the SCSS:
.flex-table
display: flex
flex-direction: column
flex-wrap: nowrap
.flex-table-row
display: flex
flex-direction: row
flex-wrap: nowrap
.flex-table-item
flex-basis: 0
flex-grow: 1
.flex-table-item > :nth-child(3n + 3)
border: 1px solid red
flex-grow: 0
white-space: nowrap
My question is, how can I get the width of the each element in a column to take up the width of its content or the width of the largest element in the column, whichever is greater?
Here's an image of what I have:
I would like the box of Header 3 to equal the width of the other two elements. Also, if Content 2-2 or Content 3-2, grows, I want all columns to expand to have an equal width of the largest column, similar a table. I know I can partially do this with min-width, but I want an approach which works with dynamic content of any width.
At the end of the day, to do this (with flexboxes) the header and the content below will need to be grouped in columns instead of the way you have it now in which all headers are in the same row. I believe the way I mention makes more sense anyways, but maybe you need something different.
Here is a JSFiddle of what I am describing. As you can see, in each column each element will dynamically resize to the width of the largest element in that column. In addition, the flex-basis: 0 makes sure that every column resizes to the same width as the largest column. If the width of one column resizes, they all do.
Really all I did is switch from row to column:
.flex-table-column {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
Let me know if you have questions on this or if I missed the mark.