Select last 3 children based on the number of children - html

I'm in a situation where the number of elements shown is variable, and I need solution which I'm not able to achieve, I even doubt if it's possible only with CSS.
I want to make a selection on the last four items only when the total items are 7. the my current CSS gives right result for 7 items but not for an another amount.
how can I combine that so that it looks for nth-last-child(7) and flex-item:nth-child(n+5)?
.flex-container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
padding: 0;
margin: 0;
list-style: none;
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
.flex-item:first-child:nth-last-child(7),
.flex-item:first-child:nth-last-child(7)~.flex-item:nth-child(-n+4) {
flex-basis: 23%;
}
.flex-item:nth-last-child(7)~.flex-item:nth-child(n+5) {
flex-basis: 31%;
background: blue;
}
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
</ul>

Is this what you are looking for?
.flex-item:first-child:nth-last-child(7)
targets the first child when there are only 7 items so that
.flex-item:first-child:nth-last-child(7)~.flex-item:nth-child(n+5)
is only triggered when there are 7 items
.flex-container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
padding: 0;
margin: 0;
list-style: none;
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
.flex-item:first-child:nth-last-child(7),
.flex-item:first-child:nth-last-child(7)~.flex-item:nth-child(-n+4) {
flex-basis: 23%;
}
.flex-item:first-child:nth-last-child(7)~.flex-item:nth-child(n+5) {
flex-basis: 31%;
background: blue;
}
<ul class="flex-container">
<li class="flex-item first">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
</ul>
<br/><br/>
<ul class="flex-container">
<li class="flex-item first">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
<li class="flex-item">8</li>
<li class="flex-item">9</li>
<li class="flex-item">10</li>
</ul>
<br/><br/>
<ul class="flex-container">
<li class="flex-item first">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>

Related

Flex-wrap does not affect nested element

Checkout example first: http://jsfiddle.net/8ofrs0y7/14/
<div class="flex-group">
<ul class="flex-container red">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
</ul>
<ul class="flex-container gold">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
<ul class="flex-container blue">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
<li class="flex-item">8</li>
</ul>
<div>
<style>
.flex-group {
display: flex;
flex-direction: row;
width: 500px;
flex-wrap: wrap;
}
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
list-style: none;
}
.red li {
background: red;
}
.gold li {
background: gold;
}
.blue li {
background: deepskyblue;
}
.flex-item {
width: 100px;
height: 100px;
margin-left: 10px
}
</style>
Every flex-element starts from new line despite of their child elements still able to fit .flex-group container.
Is it possible to place two squares of same color on different lines?
You have given the width of the div with the class name flex group to 500px.
Not sure why you have done that.
So just delete width:500px

Flexbox columns horizontal gaps

I am trying to do a vertical layout with columns that wrap (I have a max height) but I can't center the columns horizontally without also setting a width (which I don't want to). I'm using flexbox and I thought using center on both justify-content and align-items would be enough but it isn't. I would like to have all the vertical columns centered in the parent, how could I achieve that without setting a width to the parent?
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: flex;
flex-flow: column wrap;
justify-content: center;
align-items: center;
max-height: 400px;
}
.flex-item {
background: tomato;
padding: 5px;
width: 50px;
height: 50px;
margin-top: 10px;
line-height: 50px;
color: white;
font-weight: bold;
font-size: 1em;
text-align: center;
}
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
For that you can use align-content: center on flex-container. With this you define how items are distributed along cross-axis which in this case is x because you are using flex-direction: column so y is main-axis and x is cross-axis.
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: flex;
flex-flow: column wrap;
justify-content: center;
max-height: 400px;
border: 1px solid black;
align-content: center;
}
.flex-item {
background: tomato;
padding: 5px;
width: 50px;
height: 50px;
margin-top: 10px;
line-height: 50px;
color: white;
font-weight: bold;
font-size: 1em;
text-align: center;
}
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>

How to rotate two flexbox rows?

I have two flexbox rows that look like this.
Is this possible to rotate them 90 degres so that are located next to each other? I need them to look like this.
<ul class="flex-container longhand">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
<ul class="flex-container longhand">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
CSS
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: flex;
}
.longhand {
flex-flow: wrap row;
}
.flex-item {
color: black;
border: 1px solid black;
width: 50px;
height: 50px;
font-size: 1.3em;
text-align: center;
padding: 10px;
}
Wrap .flex-container with additional div, then make some transformation on it.
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: flex;
}
.longhand {
flex-flow: wrap row;
}
.flex-item {
color: black;
border: 1px solid black;
width: 50px;
height: 50px;
font-size: 1.3em;
text-align: center;
padding: 10px;
}
.container {
transform: translateY(-100%) rotate(90deg);
transform-origin: left bottom;
}
<div class="container">
<ul class="flex-container longhand">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
<ul class="flex-container longhand">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
</div>
Set second flex-container as column using nth-child selector as below,
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: flex;
}
.flex-container:nth-child(2){
flex-direction:column;
}
.longhand {
flex-flow: wrap row;
}
.flex-item {
color: black;
border: 1px solid black;
width: 50px;
height: 50px;
font-size: 1.3em;
text-align: center;
padding: 10px;
}
.flex-container:nth-child(2) > .flex-item{
transform:rotate(90deg);
}
<ul class="flex-container longhand">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
<ul class="flex-container longhand">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
HTML
<ul class="flex-container longhand">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
<ul class="flex-container longhand">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
</ul>
</div>
CSS
.parent
{
display: flex;
}
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: flex;
}
.longhand {
flex-flow: column;
}
.flex-item {
color: black;
border: 1px solid black;
width: 50px;
height: 50px;
font-size: 1.3em;
text-align: center;
padding: 10px;
transform: rotate(90deg)
}
I created a parent so that I can put the two flex containers next to each other. Then I rotated each flex item individually.

css3 flex alignment when one of element is 2 times higher that other element [duplicate]

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 have following code:
I use flex box
What I try done is remove the unnecessary space between third and second row(the eights element is 2 times higher that other element,The eights element should have 4th element on top, 7th and 11th element on left , 15 element on bottom).
.flex-container {
padding: 0;
margin: 0;
list-style: none;
width:900px;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: space-around;
flex-direction: row;
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
.flex-item-double {
height:400px;
}
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
<li class="flex-item flex-item-double">8</li>
<li class="flex-item">9</li>
<li class="flex-item">10</li>
<li class="flex-item">11</li>
<li class="flex-item">12</li>
<li class="flex-item">13</li>
<li class="flex-item">14</li>
<li class="flex-item">15</li>
</ul>
you should to change height to min-height
.flex-container {
padding: 0;
margin: 0;
list-style: none;
width:900px;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: space-around;
flex-direction: row;
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
min-height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
.flex-item-double {
min-height:400px;
}
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
<li class="flex-item flex-item-double">8</li>
<li class="flex-item">9</li>
<li class="flex-item">10</li>
<li class="flex-item">11</li>
<li class="flex-item">12</li>
<li class="flex-item">13</li>
<li class="flex-item">14</li>
<li class="flex-item">15</li>
</ul>

Top gets cut off when using Flexbox

I am using flexbox to layout div's. When I have a lot of li's inside the div, (with each li having a width of 100%/3) the top gets cut off. So I searched online, and they said to insert margin: auto to the inner div. When I do that, I get a new problem. Let me show you:
With margin: auto not applied:
body, html {
height:100%;
margin: 0;
padding:0;
}
#outerWrapper {
background-color: aqua;
height: 100%;
display: flex;
justify-content: flex-start; /* This is ignored */
align-items: center;
overflow: auto;
}
#innerWrapper {
/* margin:auto; /* If this line is removed, then it does flex-start, but the top is cut off */
width: 70%;
list-style-type: none;
padding: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content:flex-start;
}
li {
border: 1px solid black;
box-sizing: border-box;
flex-basis:calc(100%/3);
height:100px;
}
<div id="outerWrapper">
<ul id="innerWrapper">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
<li class="flex-item">8</li>
<li class="flex-item">9</li>
<li class="flex-item">10</li>
<li class="flex-item">11</li>
<li class="flex-item">12</li>
<li class="flex-item">13</li>
<li class="flex-item">14</li>
<li class="flex-item">15</li>
<li class="flex-item">16</li>
<li class="flex-item">17</li>
<li class="flex-item">18</li>
<li class="flex-item">19</li>
<li class="flex-item">20</li>
<li class="flex-item">21</li>
<li class="flex-item">22</li>
<li class="flex-item">23</li>
<li class="flex-item">24</li>
</ul>
</div>
JSFiddle
Problem: flex-start works, but the top is cut off.
With margin: auto applied:
body, html {
height:100%;
margin: 0;
padding:0;
}
#outerWrapper {
background-color: aqua;
height: 100%;
display: flex;
justify-content: flex-start; /* This is ignored */
align-items: center;
overflow: auto;
}
#innerWrapper {
margin:auto; /* If this line is removed, then it does flex-start, but the top is cut off */
width: 70%;
list-style-type: none;
padding: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content:flex-start;
}
li {
border: 1px solid black;
box-sizing: border-box;
flex-basis:calc(100%/3);
height:100px;
}
<div id="outerWrapper">
<ul id="innerWrapper">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
<li class="flex-item">8</li>
<li class="flex-item">9</li>
<li class="flex-item">10</li>
<li class="flex-item">11</li>
<li class="flex-item">12</li>
<li class="flex-item">13</li>
<li class="flex-item">14</li>
<li class="flex-item">15</li>
<li class="flex-item">16</li>
<li class="flex-item">17</li>
<li class="flex-item">18</li>
<li class="flex-item">19</li>
<li class="flex-item">20</li>
<li class="flex-item">21</li>
<li class="flex-item">22</li>
<li class="flex-item">23</li>
<li class="flex-item">24</li>
</ul>
</div>
JSFiddle
Problem: flex-start doesn't work, but top is not cut off.
My question is, how can I have justify-content: flex-start and have the top not get cut off?
Auto margins push the flex item. If you use margin: auto, the element will be pushed equally from all sides, so it will be centered.
If you want it to be aligned to the top, only set the margin-bottom: auto, and let margin-top be 0.
#innerWrapper {
margin-top: 0;
margin-bottom: auto;
}
body,
html {
height: 100%;
margin: 0;
padding: 0;
}
#outerWrapper {
background-color: aqua;
height: 100%;
display: flex;
justify-content: flex-start;
/* This is ignored */
align-items: center;
overflow: auto;
}
#innerWrapper {
margin-top: 0;
margin-bottom: auto;
width: 70%;
list-style-type: none;
padding: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content: flex-start;
}
li {
border: 1px solid black;
box-sizing: border-box;
flex-basis: calc(100%/3);
height: 100px;
}
<div id="outerWrapper">
<ul id="innerWrapper">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
<li class="flex-item">8</li>
<li class="flex-item">9</li>
<li class="flex-item">10</li>
<li class="flex-item">11</li>
<li class="flex-item">12</li>
<li class="flex-item">13</li>
<li class="flex-item">14</li>
<li class="flex-item">15</li>
<li class="flex-item">16</li>
<li class="flex-item">17</li>
<li class="flex-item">18</li>
<li class="flex-item">19</li>
<li class="flex-item">20</li>
<li class="flex-item">21</li>
<li class="flex-item">22</li>
<li class="flex-item">23</li>
<li class="flex-item">24</li>
</ul>
</div>
Alternatively, forgot about auto margins and remove the code which produces the cut:
#outerWrapper {
align-items: center;
}
body,
html {
height: 100%;
margin: 0;
padding: 0;
}
#outerWrapper {
background-color: aqua;
height: 100%;
display: flex;
justify-content: flex-start;
overflow: auto;
}
#innerWrapper {
margin: 0;
width: 70%;
list-style-type: none;
padding: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content: flex-start;
}
li {
border: 1px solid black;
box-sizing: border-box;
flex-basis: calc(100%/3);
height: 100px;
}
<div id="outerWrapper">
<ul id="innerWrapper">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
<li class="flex-item">7</li>
<li class="flex-item">8</li>
<li class="flex-item">9</li>
<li class="flex-item">10</li>
<li class="flex-item">11</li>
<li class="flex-item">12</li>
<li class="flex-item">13</li>
<li class="flex-item">14</li>
<li class="flex-item">15</li>
<li class="flex-item">16</li>
<li class="flex-item">17</li>
<li class="flex-item">18</li>
<li class="flex-item">19</li>
<li class="flex-item">20</li>
<li class="flex-item">21</li>
<li class="flex-item">22</li>
<li class="flex-item">23</li>
<li class="flex-item">24</li>
</ul>
</div>
use
.flex-parent{
display: flex;
align-items: center;
justify-content: center;
}
.flex-child{
margin-top: auto;
margin-bottom: auto;
}
I was having a similar problem and an internet search brought me here.
The answer above didn't work in my case, but what did work was wrapping my content container (that was getting cut off) in a div styled with a min-height:0; rule.
Note: I used min-height because I am using a columnar layout - it would be min-width for rows. In most cases using both probably wouldn't hurt.
html:
<div class="flex-fix">
<div>This content was getting cut off...</div>
</div>
css:
.flex-fix {
min-height: 0;
min-width: 0;
}
I got the clue from this article on css-tricks.com: Flexbox and Truncated Text
Hope this helps.