Reputation: 1638
This is a question I already have a solution to, but I'm wondering if there's a better way. What I want is to use flexbox to have rows of items with even space in between and a line between rows. The first and second example in the snippet below achieve this by using an :after
, but I have to use a fair amount of CSS to hide it on the last row.
.item:nth-child(4n + 1):nth-last-child(4):after,
.item:nth-child(4n + 1):nth-last-child(4):after,
.item:nth-child(4n + 1):nth-last-child(2):after,
.item:nth-child(4n + 1):nth-last-child(1):after{
display: none;
}
Surely there is a better way (using flexbox) Does anyone know?
I tried using a border on each item but obviously this has space between them which doesn't work and then I would still need to hide it using :nth-last-child
.
.outer{
background-color: #ccc;
margin-bottom: 15px;
}
.wrap{
overflow: hidden;
flex: 4;
justify-content: space-between;
flex-flow: row wrap;
width: 80%;
margin: 0 auto;
background-color: #cdcdcd;
display: flex;
}
.item{
width: 23%;
padding-bottom: 30px;
margin-bottom: 30px;
position: relative;
}
.item2{
width: 23%;
padding-bottom: 30px;
margin-bottom: 30px;
position: relative;
border-bottom: 1px solid red;
}
.item:nth-child(4n + 1):after{
content: "";
position: absolute;
left: 0;
width: 500%;
bottom: 0;
border-bottom: 1px solid red;
}
@media (max-width: 768px) {
.item:nth-child(2n + 1):nth-last-child(2):after,
.item:nth-child(2n + 1):nth-last-child(1):after{
display: none;
}
.item{
width: 43%;
}
}
@media (min-width: 768px) {
.item:nth-child(4n + 1):nth-last-child(4):after,
.item:nth-child(4n + 1):nth-last-child(4):after,
.item:nth-child(4n + 1):nth-last-child(2):after,
.item:nth-child(4n + 1):nth-last-child(1):after{
display: none;
}
}
<div class="outer">
<h3>Working example - 8 Items</h3>
<div class="wrap">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
<div class="item">Item 8</div>
</div>
</div>
<div class="outer">
<h3>Working example - 5 Items</h3>
<div class="wrap">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
</div>
</div>
<div class="outer">
<h3>Using normal border</h3>
<div class="wrap">
<div class="item2">Item 1</div>
<div class="item2">Item 2</div>
<div class="item2">Item 3</div>
<div class="item2">Item 4</div>
<div class="item2">Item 5</div>
</div>
</div>
Upvotes: 2
Views: 19949
Reputation: 105913
you could use :before
and avoid the display:none
rules :
.outer{
background-color: #ccc;
margin-bottom: 15px;
}
.wrap{
overflow: hidden;/* will hide first row of item:before */
/* flex: 4; i do not see the use here */
justify-content: space-between;
flex-flow: row wrap;
width: 80%;
margin: 0 auto;
background-color: #cdcdcd;
display: flex;
}
.item{
width: 23%;
padding-bottom: 30px;
margin-bottom: 30px;
position: relative;
}
.item2{/* just to do it different , don ' t mind that part */
width: 23%;
padding : 30px 0;
margin-bottom: -10px;
position: relative;
border-bottom: 1px solid red;
}
.item:nth-child(4n + 1):before{
content: "";
position: absolute;
left: 0;
width: 500%;
top: -30px;
border-bottom: 1px solid red;
}
<div class="outer">
<h3>Working example - 8 Items</h3>
<div class="wrap">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
<div class="item">Item 8</div>
</div>
</div>
<div class="outer">
<h3>Working example - 5 Items</h3>
<div class="wrap">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
</div>
</div>
<div class="outer">
<h3>Using normal border</h3>
<div class="wrap">
<div class="item2">Item 1</div>
<div class="item2">Item 2</div>
<div class="item2">Item 3</div>
<div class="item2">Item 4</div>
<div class="item2">Item 5</div>
</div>
</div>
edit
You can also set a breakpoint and use each item to draw the line
.outer{
background-color: #ccc;
margin-bottom: 15px;
}
.wrap{
overflow: hidden;/* will hide first row of item:before */
/* flex: 4; i do not see the use here */
justify-content: space-between;
flex-flow: row wrap;
width: 80%;
margin: 0 auto;
background-color: #cdcdcd;
display: flex;
}
.item{
width: 23%;
margin: 29px 1% 31px;
position: relative;
}
.item2{/* just to do it different , don ' t mind that part */
width: 23%;
padding : 30px 0;
margin-bottom: -10px;
position: relative;
border-bottom: 1px solid red;
}
.item:before{
content: "";
position: absolute;
left: -20%;
width: 800%;
top: -30px;
border-bottom: 1px solid red;
}
.brkpt .item {
min-width:60px;
max-width:100px;
background:gray
}
<div class="outer">
<h3>Working example - 8 Items</h3>
<div class="wrap">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
<div class="item">Item 8</div>
</div>
</div>
<h3>Working example - 16 Items breaking points every 120px average</h3>
<div class="wrap brkpt">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
<div class="item">Item 8</div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
<div class="item">Item 8</div>
</div>
</div>
<div class="outer">
<h3>Working example - 5 Items</h3>
<div class="wrap">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
</div>
</div>
<div class="outer">
<h3>Using normal border</h3>
<div class="wrap">
<div class="item2">Item 1</div>
<div class="item2">Item 2</div>
<div class="item2">Item 3</div>
<div class="item2">Item 4</div>
<div class="item2">Item 5</div>
</div>
</div>
Upvotes: 2
Reputation: 3435
As i said in small devices you will have serious problem with this method. I suggest you to use this image:
As the bcackground image of total menu (<div class="wrap"
), Of course with some changes related to the height of menu items.
.wrap{
background-image: url(IMAGE-URL);
background-repeat: repeat;
}
Upvotes: 0
Reputation: 1638
I thought of another way. This is a responsive solution. I think this is the best way... To see 4 columns you need to click full page button
.outer{
background-color: #ccc;
margin-bottom: 15px;
}
.wrap{
overflow: hidden;
flex: 4;
justify-content: space-between;
flex-flow: row wrap;
width: 80%;
margin: 0 auto;
background-color: #cdcdcd;
display: flex;
}
.full{
width: 100%;
background-color: red;
margin-bottom: 30px;
height: 1px;
display: none;
}
@media (max-width: 768px) {
.visible-small{
display: block;
}
}
@media (min-width: 768px) {
.visible-large{
display: block;
}
}
.item{
width: 23%;
margin-bottom: 30px;
position: relative;
}
<div class="outer">
<h3>Using extra div</h3>
<div class="wrap">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="full visible-small"></div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="full visible-large visible-small"></div>
<div class="item">Item 5</div>
</div>
</div>
<div class="outer">
<h3>Using extra div</h3>
<div class="wrap">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="full visible-small"></div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="full visible-large visible-small"></div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="full visible-small"></div>
<div class="item">Item 7</div>
<div class="item">Item 8</div>
<div class="full visible-large visible-small"></div>
<div class="item">Item 9</div>
</div>
</div>
Upvotes: 2