I'm trying to have different css styles for a div that has same css class in a row and different for a single div for the same class.

Here's what I'm trying to achieve if the explanation is confusing.

.row {
  display: flex;
  margin: 20px;
}

.number {
  width: 32px;
  height: 32px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.number.bg {
  background-color: #e24381;
  color: #ffffff;
  border-radius: 24px 0 0 24px;
}

.number.bg ~ .number.bg {
  border-radius: 0 24px 24px 0;
}
<div class="row">
  <div class="number">1</div>
  <div class="number bg">2</div>
  <div class="number bg">3</div>
  <div class="number bg">4</div>
  <div class="number">5</div>
  <div class="number">6</div>
  <div class="number bg">7</div>
</div>

This should be the output:

Output

Can it be done by CSS only or does it require JavaScript too?

3 Answers

4
kukkuz On Best Solutions

For a vanilla CSS solution, you can use a pseudo element to do this for you:

  • set border-radius: 25px to the bg element,

  • fill the border gaps in successive bg elements using a pseudo element that is positioned absolutely and stacked behind the bg elements, and shifted using a negative margin.

See demo below:

.row {
  display: flex;
  margin: 20px;
}

.number {
  width: 32px;
  height: 32px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.number.bg {
  background-color: #e24381;
  color: #ffffff;
  border-radius: 25px;
  position: relative;
}

.number.bg+.bg:before {
  content: '';
  display: block;
  background-color: #e24381;
  margin-left: -50%;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  position: absolute;
}
<div class="row">
  <div class="number">1</div>
  <div class="number bg">2</div>
  <div class="number bg">3</div>
  <div class="number bg">4</div>
  <div class="number">5</div>
  <div class="number">6</div>
  <div class="number bg">7</div>
</div>

0
MiXT4PE On

If you want a dynamic solution you'll need to resort to JavaScript as CSS can only identify immediately following (+) or general siblings (~). For a really smart pure CSS solutions see the answers above. For the sake of performance they should be preferred over this solution.

See below for a possible JavaScript solution. Instead of manipulating the classes as I did you could also adjust the CSS directly with:

number.style.borderRadius = `24px`;
number.style.borderRadius = `24px 0 0 24px`;
number.style.borderRadius = `0 24px 24px 0`;

window.onload = () => {
  [...document.querySelectorAll(".number.bg")].map(number => {
    let next = number.nextElementSibling;
    let prev = number.previousElementSibling;

    if (next !== null) {
      if (next.classList.contains('bg') && !prev.classList.contains('left')) {
        number.classList.add("left");
      }
    }
    if (next == null || !next.classList.contains('bg')) {
        number.classList.add(!prev.classList.contains('bg') ? "round" : "right");
    }
  });
};
.row {
  display: flex;
  margin: 20px;
}

.number {
  width: 32px;
  height: 32px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.number.bg {
  background-color: #e24381;
  color: #ffffff;
  border-radius: 0;
}

.number.bg.round {
  border-radius: 24px;
}

.number.bg.right {
  border-radius: 0 24px 24px 0;
}

.number.bg.left {
  border-radius: 24px 0 0 24px;
}
<div class="row">
  <div class="number">1</div>
  <div class="number bg">2</div>
  <div class="number bg">3</div>
  <div class="number bg">4</div>
  <div class="number">5</div>
  <div class="number">6</div>
  <div class="number bg">7</div>
</div>

3
Temani Afif On

Here is an idea using some pseudo element and without JS:

.row {
  display: flex;
  margin: 20px;
  position:relative;
  z-index:0;
}

.number {
  width: 32px;
  height: 32px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.number.bg {
  background-color: #e24381;
  color: #ffffff;
  border-radius: 24px;
  position:relative;
}

.bg +.bg:before {
  content:"";
  position:absolute;
  z-index:-1;
  background:inherit;
  top:0;
  bottom:0;
  left:-50%;
  right:50%;
}

body {
  background:pink;
}
<div class="row">
  <div class="number">1</div>
  <div class="number bg">2</div>
  <div class="number bg">3</div>
  <div class="number bg">4</div>
  <div class="number">5</div>
  <div class="number">6</div>
  <div class="number bg">7</div>
</div>