Add border based on recent items

I have a parent div#main

that contains an unknown number divs

in strings. Each line has 3 divs

which display: inline-block

. Now because of this, the last line can contain 1, 2 or 3 divs

, depending on their number.

If the last row has only one div, I want to add border-left

, and border-right

to her.

If the last line has 2 divs, then I want to add border-right

to the first div

in that line, or border-left

to the second div

.

And if the last line is 3 div, I want to add border-left

, and border-right

the second div (Intermediate).

(You get the full picture when you look at the puller or violin)

I managed to solve this with JS, but I'm looking for a pure CSS solution if there is one.

$('.main').each(function(){

	var div_length = $(this).find('div').length;

	if((div_length % 3) === 0){
		div_last_items = div_length;
	}

	else if((div_length % 3) === 1){
		div_last_items = div_length - 1;
		$(this).find('div:nth-last-child(1)').addClass('active-borders');
	}

	else if((div_length % 3) === 2){
		div_last_items = div_length - 2;
		$(this).find('div:nth-last-child(2)').addClass('active-border');
	}

	$(this).find('div:lt('+div_last_items+')').each(function(i){
		i=i+2;
		if(i % 3 === 0){
			$(this).addClass('active-borders')	
		}		
	});
});
      

.main {
    width: 360px;
    text-align: center;
}
.main>div {
    display:inline-block;
    vertical-align:top;
    width: 100px;
    height: 100px;
    background:red;
    margin-top: 10px;
    margin-bottom: 10px;
}
.main>div:nth-child(3n+2) {
    margin-left: 20px;
    margin-right: 20px;
}

.active-borders{
    border-left: 5px solid black;
    border-right: 5px solid black;
}

.active-border{
    border-right: 5px solid black;
}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>
<hr>
<div class="main">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>
<hr>
<div class="main">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>
      

Run codeHide result



JSFiddle

+3


source to share


2 answers


I never thought it was possible with pure CSS, but it is. All credits will be posted to this response to show how this can be achieved. This answer is based on this, but I am developing a separate answer because the selectors are slightly different here and I wanted to explain them.

Selector additions:

div > div:nth-child(3n) + div:nth-last-child(1) {
  border-left: 5px solid black;
  border-right: 5px solid black;
}
div > div:nth-child(3n+1) + div:nth-last-child(1) {
  border-left: 5px solid black;
}
div > div:nth-child(3n+1) + div:nth-last-child(2) {
  border-left: 5px solid black;
  border-right: 5px solid black;
}

      

Explanation:

div > div:nth-child(3n) + div:nth-last-child(1)
      

  • Select the last child of the parent div

    when it immediately follows the 3n th child . If the last child immediately follows the 3n th child then it will obviously be the only element in the last line.
div > div:nth-child(3n+1) + div:nth-last-child(1)
      

  • Select the last child of the parent div

    when it immediately follows the 3n + 1 th child . If the last child immediately follows the child word 3n + 1 th then this means that there are 2 elements in the last line.
div > div:nth-child(3n+1) + div:nth-last-child(2)
      

  • Select the second last child of the parent div

    when it immediately follows the 3n + 1 th child . If the second last child immediately follows the 3n + 1 th child then this means that the last row has 3 elements.


We cannot use a selector div > div:nth-child(3n+2) + div:nth-last-child(1)

for the case where the last line has 3 elements, because we want the middle element to be styled, not the last one.

.main {
  width: 360px;
  text-align: center;
}
.main>div {
  display: inline-block;
  vertical-align: top;
  width: 100px;
  height: 100px;
  background: red;
  margin-top: 10px;
  margin-bottom: 10px;
}
.main>div:nth-child(3n+2) {
  margin-left: 20px;
  margin-right: 20px;
}
div > div:nth-child(3n) + div:nth-last-child(1) {
  border-left: 5px solid black;
  border-right: 5px solid black;
}
div > div:nth-child(3n+1) + div:nth-last-child(1) {
  border-left: 5px solid black;
}
div > div:nth-child(3n+1) + div:nth-last-child(2) {
  border-left: 5px solid black;
  border-right: 5px solid black;
}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
<hr>
<div class="main">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
<hr>
<div class="main">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
      

Run codeHide result



The selectors in the above snippet are added border-left

to the second div

in the last line if it only has 2 elements. If you need to apply border-right

to the first div

on the last line if it only has 2 elements, you can use the selector below:

div > div:nth-child(3n+1):nth-last-child(2)

      

  • This means select the second last child of the parent div

    when it is also 3n + 1 thdiv

    . If this selector matches, it means that the last line has two elements.

.main {
  width: 360px;
  text-align: center;
}
.main>div {
  display: inline-block;
  vertical-align: top;
  width: 100px;
  height: 100px;
  background: red;
  margin-top: 10px;
  margin-bottom: 10px;
}
.main>div:nth-child(3n+2) {
  margin-left: 20px;
  margin-right: 20px;
}
div > div:nth-child(3n) + div:nth-last-child(1) {
  border-left: 5px solid black;
  border-right: 5px solid black;
}
/*div > div:nth-child(3n+1) + div:nth-last-child(1) {
  border-left: 5px solid black;
}*/
div > div:nth-child(3n+1):nth-last-child(2){
  border-right: 5px solid black;
}
div > div:nth-child(3n+1) + div:nth-last-child(2) {
  border-left: 5px solid black;
  border-right: 5px solid black;
}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
<hr>
<div class="main">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
<hr>
<div class="main">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
      

Run codeHide result


+4


source


In general, adding a border resizes the border element. This geometry change itself can move the element to the next line. The chicken egg problem.



Thus, you cannot do it with CSS. And even with JS, you have to be careful - in some cases you may not want to.

0


source







All Articles