CSS Flex items vertically and then horizontally - html

If container has fixed width and height, is it possible to move child elements to next line until there is enough space vertically and then, when there it no more vertical space, make last line child element take width space.
It is hard to verbally expain what I want to achieve, so here is JsFiddle of what I currently have: JsFiddle
.parent {
width: 400px;
height: 300px;
background: white;
border: 1px solid black;
display: flex;
flex-wrap: wrap;
overflow: hidden;
}
.child {
width: 160px;
height: 80px;
margin: 4px;
background: red;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
Image of what I would like to achieve:

You can have something similar if you use a column direction. In this case, the overflow will occur on the right and not on the bottom:
.parent {
width: 400px;
height: 300px;
background: white;
border: 1px solid black;
display: flex;
flex-direction:column;
justify-content:flex-end;
flex-wrap: wrap;
overflow: hidden;
}
.child {
width: 160px;
height: 80px;
margin: 4px;
background: red;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

Related

Position sticky with flex-direction column reverse

I am trying to create a sticky central element with flex-direction column-reverse. Using flex-direction column works fine. Is this possible with column-reverse?
.parent {
display: flex;
overflow-y: scroll;
/* works with flex-direction: column; */
flex-direction: column-reverse;
height: 200px;
border: 1px solid #ccc;
position: relative;
}
.child, .sticky {
width: 100%;
height: 40px;
background: gold;
border-bottom: 1px solid #555;
flex-shrink: 0;
}
.sticky {
background: crimson;
position: sticky;
top: 0;
bottom: 0;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="sticky"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
Can you please check the below code? Hope it will work for you. We just add the one div .child-parent in the parent div and set flex properties according to solve your problem.
.parent {
border: 1px solid #ccc;
flex-direction: row;
}
.child-parent {
overflow-y: scroll;
height: 200px;
display: flex;
display: -webkit-flex;
flex-direction: column-reverse;
-webkit-flex-direction: column-reverse;
position: relative;
}
.child,
.sticky {
width: 100%;
height: 40px;
background: gold;
border-bottom: 1px solid #555;
flex-shrink: 0;
flex-direction: row;
}
.sticky {
width: 100%;
background: crimson;
position: sticky;
position: -webkit-sticky;
bottom: 0;
top: 0;
display: flex;
z-index: 1;
flex-shrink: 0;
}
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<style>
</style>
</head>
<body>
<div class="parent">
<div class="child-parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
<div class="child">7</div>
<div class="child">8</div>
<div class="child">9</div>
<div class="child">10</div>
<div class="sticky"></div>
<div class="child">11</div>
<div class="child">12</div>
<div class="child">13</div>
<div class="child">14</div>
<div class="child">15</div>
<div class="child">16</div>
<div class="child">17</div>
<div class="child">18</div>
<div class="child">19</div>
</div>
</div>
</body>
</html>

Align Fifteen Child DIVs as Bullets to Bottom of its Parent Div

I am editing in bullets of a slider. I want to apply gradient background on parent div of bullets so I need to increase height of parent div but when I am increasing the height all bullets are aligning on top of parent div.
HTML
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
CSS
.parent {
height: 200px;
background-image: linear-gradient(to bottom, rgba(255,0,0,0), rgb(27, 4, 4));
width: 100%;
text-align: center;
bottom: 0;
position: absolute;
}
.child {
background-color: blue;
width: 25px;
height: 5px;
margin-left: 2px;
display: inline-block;
}
Please let me know how to align all bullets on bottom of parent div.
JSFIDDLE
Use flexbox and you can easily align them:
.parent {
height: 200px;
background-image: linear-gradient(to bottom, rgba(255, 0, 0, 0), rgb(27, 4, 4));
width: 100%;
text-align: center;
bottom: 0;
position: absolute;
display: flex;
align-items: flex-end; /*put them at the bottom*/
justify-content: center; /*center horizontally*/
flex-wrap:wrap;
align-content: flex-end;
}
.child {
background-color: blue;
width: 25px;
height: 5px;
margin: 5px;
}
body {
margin: 0;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
Not sure I understand what you're looking for, but if you want those lines to be at the bottom of the parent div, you could create another container div, set its position to absolute and bottom to 0. You will also need to find a solution to align it horizontally, such as setting the container width to 100%.
HTML
<div class="parent">
<div class="container">
<div class="child"></div>
...
<div class="child"></div>
</div>
</div>
CSS
.container {
position: absolute;
bottom: 0;
width: 100%;
}
https://jsfiddle.net/1b2fuyvm/27/

Flex-wrap property not responsive when parent has a set width

In the example below, when I set a width for a wrapper, the parent flex container can no longer use the flex-wrap property. The top two boxes won't wrap, but the bottom ones will.
<div class="wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
.wrapper {
width: 700px;
margin: 0 auto;
border: solid cadetblue 5px;
}
.parent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 250px;
min-width: 250px;
max-width: 300px;
flex: 1;
background: mistyrose;
border: solid goldenrod 2px;
margin: 30px;
}
The 'issue' you raise is by design; you're specifying a width for the parent that is wide enough for your children to be wholly contained within (a 700px container for two 300px children). flex-wrap only causes elements to overflow when there's not enough space for the container to hold them. In your example, there is.
To force an overflow responsively, you could either specify a narrow width on the parent(which will cause an overflow for all viewports):
.wrapper {
width: 400px;
margin: 0 auto;
border: solid cadetblue 5px;
}
.parent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 250px;
min-width: 250px;
max-width: 300px;
flex: 1;
background: mistyrose;
border: solid goldenrod 2px;
margin: 30px;
}
<div class="wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
Or use max-width instead(which will only overflow on narrow viewports):
.wrapper {
max-width: 700px;
margin: 0 auto;
border: solid cadetblue 5px;
}
.parent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 250px;
min-width: 250px;
max-width: 300px;
flex: 1;
background: mistyrose;
border: solid goldenrod 2px;
margin: 30px;
}
<div class="wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>

Is there a way, othen than inline-block, for elements to don't break line?

I have elements wrapped into a parent div, and they're all floated to left. The parent element has overflow: scroll and when the parent become thinner than the children, i don't want the children to break line, but the parent to overflow them horizontally.
I've discovered that i can do this by using: display: inline-block for the children to behave text-like and then, set the parent to white-space: nowrap. This way, they will not break.
But i want a solution with the children floated. Can someone help me?
Working example
HTML
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
CSS
.parent{
padding: 3px;
width: 100%;
height: 200px;
background-color: green;
overflow: scroll;
/*does the trick*/
white-space: nowrap;
}
.child{
display: inline-block;
height: 190px;
width: 80px;
background-color: gray;
margin-left: 10px;
}
[edit] - Since Paulie asked in the comments, i've got to say that no, they don't have to be floated for working. I know this. But I want to know if there is another way to accomplish that and I think that there is no better place for this but the SO community
Flexbox can do that and it doesn't even need the white-space:nowrap.
.parent {
padding: 3px;
height: 200px;
background-color: green;
overflow: auto; /* or scroll */
display: flex;
}
.child {
height: 190px;
flex: 0 0 80px;
background-color: gray;
margin-left: 10px;
}
.parent {
padding: 3px;
height: 100px;
background-color: green;
overflow: scroll;
display: flex;
}
.child {
height: 90px;
flex: 0 0 80px;
background-color: gray;
margin-left: 10px;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
JSfiddle Demo
display: table does do that too, though flex is a more appropriate way to do layout than table, unless you need it to work on for example IE8/9, which flex doesn't, but then again, your inline-block is more appropriate than table
.parent{
padding: 3px;
max-width: 100%;
height: 200px;
background-color: green;
overflow: scroll;
display: table;
}
.child{
display: table-cell;
height: 190px;
min-width: 80px;
background-color: gray;
padding-left: 10px;
border: 1px solid white
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

Keep space / padding between Divs

How would I be able to keep the space between my inlined div elements without counting the space as 'pixels'?
For example, currently i'm using margin-right (as my padding between my elements) but is eventually counting that as pixels (the result shows off ugly, see JsFiddle, div element gets pushed down).
#parent .child
{
position: relative;
display: inline-block;
height: 100%;
width: 16.5%;
background-color: green;
margin-right: 15px;
}
JsFiddle
Basically, I just like to have the first item floaten left and the last item floaten right. Now I know many of you guys are thinking, why not just use the feature 'justify'? I've tried using it, but it isn't a really good option since the amount of elements can be everything (10, 5, 8, etc).
Help would be appericiated!
EDIT: This basically is the feature i'd like to achieve but for multiple elements (instead of having only 1 row, there could be 2-16 rows.
You can use text-align: justify. It won't justify the last line, but you can force a new line with a pseudo-element:
#parent {
text-align: justify;
background-color: red;
}
#parent:after {
content: '';
display: inline-block;
width: 100%;
}
#parent .child {
display: inline-block;
height: 100px;
width: 16.5%;
background-color: green;
margin-right: 15px;
margin-bottom: 10px;
}
<div id="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
If I understand it properly, you want to set an internal margin between the children, but not between the edge children and the parent. Something like
.child { margin-right: 15px; }
.child:last-of-line { margin-right: 0; }
Currently there is no way to do that, but you can add an additional wrapper with a negative margin:
#inner-wrapper {
margin-right: -15px;
margin-bottom: -10px;
}
.child {
margin-right: 15px;
margin-bottom: 10px;
}
#parent {
background-color: red;
overflow: hidden;
}
#inner-wrapper {
margin-right: -15px;
margin-bottom: -10px;
}
.child {
vertical-align: top;
display: inline-block;
height: 210px;
width: 16.5%;
background-color: green;
margin-right: 15px;
margin-bottom: 10px;
}
<div id="parent">
<div id="inner-wrapper">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>