CSS: selecting the adjacent siblings of a certain class, starting from the first and

I am working on achieving the following goal:

https://i.sstatic.net/xHoIG.png

Elements containing values should have a gray 'ribbon'. Elements with values are given a class selected, while elements without any value do not have this class.

This is how my HTML code appears:

<div class="row">
    <span>.</span>
    <span>.</span>
    <span class="selected">2</span> <!-- Should be gray & rounded (left) -->
    <span class="selected">3</span> <!-- Should be gray -->
    <span class="selected">2</span> <!-- Should be gray & rounded (right) -->
    <span>.</span>
    <span>.</span>
    <span class="selected">5</span> <!-- Should be gray & rounded (left) -->
    <span class="selected">5</span> <!-- Should be gray & rounded (right) -->
    <span>.</span>

</div>
<div class="row">
    ...
</div>

In order to achieve the gray ribbon effect, I believe I need the following CSS rules:

  1. All elements with the class selected should have a gray background. This part is straightforward.
  2. The first and last element of a group of adjacent elements with the class 'selected' should have rounded corners. This part presents a challenge.

To the best of my understanding, there is no CSS selector like :first-of-class. Additionally, even if there were one, it would not suffice because multiple 'ribbons' can appear on the same line. Ideally, I would require something similar to :first-adjacent-sibling-of-class.

Is there a way to accomplish this using pure CSS, or will I need to utilize JavaScript?

Answer №1

My solution involves the addition of a new class called not-selected, which targets the adjacent selected element.

.selected{
  background-color: #b7dafd;
}
span{
  float: left;
  padding: 10px;
  position: relative;
}
.not-selected+.selected{
  border-radius: 20px 0 0 20px;
  padding-left: 25px;
}
.selected+.not-selected:before{
  content: '';
  display: block;
  position: absolute;
  left:0;
  top: 0;
  height: 100%;
  border-right: 20px solid #b7dafd;
  border-radius: 0 20px 20px 0;
}
<div class="row">
    <span class="not-selected">.</span>
    <span class="not-selected">.</span>
    <span class="selected">2</span> <!-- Should be gray & rounded (left) -->
    <span class="selected">3</span> <!-- Should be gray -->
    <span class="selected">2</span> <!-- Should be gray & rounded (right) -->
    <span class="not-selected">.</span>
    <span class="not-selected">.</span>
    <span class="selected">5</span> <!-- Should be gray & rounded (left) -->
    <span class="selected">5</span> <!-- Should be gray & rounded (right) -->
    <span class="not-selected">.</span>
    <span class="not-selected">.</span>
    <span class="not-selected">.</span>
    <span class="selected">2</span> <!-- Should be gray & rounded (left) -->
    <span class="selected">3</span> <!-- Should be gray -->
    <span class="selected">2</span> <!-- Should be gray & rounded (right) -->
    <span class="not-selected">.</span>
    <span class="not-selected">.</span>
    <span class="not-selected">.</span>
    <span class="selected">5</span> <!-- Should be gray & rounded (left) -->
    <span class="selected">5</span> <!-- Should be gray & rounded (right) -->
    <span class="not-selected">.</span>
    <span class="not-selected">.</span>
    <span class="not-selected">.</span>
</div>

Answer №2

For your INQUIRY, I believe this solution would be most suitable.

By incorporating the style

span.selected+span.selected:before
, rest assured that your chosen selection will remain intact and won't wrap to the next line.

Give it a try and let me know if you require any further assistance. Thank you. Cheers!

div {
  display: inline-block
}

span {
  display: inline-block;
  float: left;
  padding: 15px;
  position: relative;
  /* top: 0; */
  margin: 10px 0;
}

span.selected {
  background: gray;
  border-radius: 50%;
}

span.selected+span.selected:before {
  content: '';
  height: 100%;
  width: 40px;
  position: absolute;
  background: gray;
  top: 0;
  left: -20px;
  z-index: -1;
}

span.selected+span.not {
  border-radius: 50%;
}
<div>
  <span class="selected">1</span>
  <span class="selected">2</span>
  <span class="selected">3</span>
  <span class="selected">4</span>
  <span class="selected">5</span>
  <span class="not">6</span>
  <span class="not">7</span>
  <span class="not">8</span>
  <span class="not">9</span>
  <span class="selected">10</span>
  <span class="selected">11</span>
  <span class="selected">12</span>
  <span class="selected">13</span>
  <span class="selected">14</span>
  <span class="selected">15</span>
  <span class="not">16</span>
  <span class="not">17</span>
  <span class="not">18</span>
  <span class="not">19</span>
  <span class="not">20</span>
</div>

Answer №3

  • Each .selected represents a circle shape.

  • All sibling elements of the first .selected with the class .selected ~ have negative margins and the left side set to border-radius: 0

  • Any .selected element that comes after a :not(.selected) + is also displayed as a circle, but with a positive left margin.

  • Elements with the class :not(.selected) following a .selected + are given a positive left margin.

  • The text will not wrap unless specifically instructed to do so through markup

Demo

.row {
  white-space: nowrap;
}

.selected {
  background: grey;
  height: 4ex;
  width: 4ch;
  border-radius: 50%;
  display: inline-block;
  margin: 0 -4px;
  line-height: 2;
  text-align: center;
}

.selected~.selected {
  margin: 0 -12px;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}

*:not(.selected)+.selected {
  border-top-left-radius: 50%;
  border-bottom-left-radius: 50%;
  margin: 0 -12px 0 12px
}

.selected+*:not(selected) {
  margin: 0 0 0 12px
}
<div class="row">
  <span>.</span>
  <span>.</span>
  <span class="selected">2</span>
  <span class="selected">3</span>
  <span class="selected">2</span>
  <span>.</span>
  <span>.</span>
  <span class="selected">5</span>
  <span class="selected">5</span>
  <span>.</span>
</div>
<div class="row">
  <span>.</span>
  <span>.</span>
  <span class="selected">2</span>
  <span class="selected">3</span>

  <span>.</span>
  <span class="selected">2</span>
  <span>.</span>
  <span class="selected">5</span>
  <span class="selected">5</span>
  <span>.</span>
  <span class="selected">2</span>
  <span class="selected">2</span>
  <span class="selected">2</span>
  <span>.</span>
  <span>.</span>
  <span>.</span>
  <span class="selected">5</span>
  <span class="selected">5</span>
  <span class="selected">5</span>
</div>
<span class="selected">5</span>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Showcasing top performers via JavaScript tabs

I have two tabs on my webpage: "Overall Leaderboard" and "Weekly Leaderboard". Each tab displays a leaderboard with different scores. When I click on the "Overall Leaderboard" tab, it shows a leaderboard with specific scores. Now, my question is how can ...

Can an unordered list be nested inside an inline list item in HTML or XHTML?

Take note that the li with child ul is set to display:inline - example code provided below <style type="text/css"> ul.nav_main li { display: inline } ul.nav_submenu li { display: block } </style> <ul class="nav_main"> <li>I ...

Is Safari causing issues with the CSS slider animation?

Currently, I am working on implementing a CSS-only slider (no jQuery) in WordPress using the code from this source: http://codepen.io/dudleystorey/pen/kFoGw An issue I have encountered is that the slider transitions are not functioning correctly in Safari ...

Issue with Firefox causing Bootstrap form to appear incorrectly

I recently created a customized form using Bootstrap, but unfortunately, I'm encountering an issue with Firefox. Despite functioning perfectly on other browsers, the radio buttons are being pushed off the edge of the page and aren't displaying pr ...

Is there a way to retrieve a CSS file using AJAX from a separate origin?

Whenever I am trying to load a CSS file via AJAX from my dreamhost account, I encounter the error message that says No 'Access-Control-Allow-Origin' header is present on the requested resource. After searching for solutions online, I stumbled upo ...

What is the proper way to display the initial content of the menu?

I am currently working on a website design for an upcoming festival. The festival spans over three days, so I have created buttons to navigate and load the content for each day separately. Is there a way for me to make the content for the first day di ...

Moving a mouse from one element to another does not reset its state

Link to code: https://codesandbox.io/s/objective-darwin-w0i5pk?file=/src/App.js Description: There are four gray squares in this example, each with a different shade of gray. The goal is to change the background color of each square when the user hovers o ...

Difficulty arises when trying to merge a dropdown menu with a horizontally scrolling menu

I am attempting to include a dropdown menu within a horizontally long menu. In order to achieve this, I have merged the script for displaying a scrollable menu with that of a dropdown menu. However, in doing so, the dropdown menu does not pop out from the ...

Tips for showcasing information on an HTML website

I am currently facing an issue with displaying addresses retrieved from a database in my project. The problem lies in the formatting of the address when it is displayed on the page. Currently, the address is being displayed as follows: Address: 1 Kings S ...

What is the best way in jQuery to display a particular div with a unique id when a link is clicked?

I have a div with the following structure: <article id="#pippo">blablabla</article> which I have hidden using jQuery $('article').hide(); Now, I want to create a link menu that displays a specific article id when it's clicked ...

What is the best way to restrict the size of a table that is filled with data from a database?

Currently using a combination of React, Node, Express, and Postgres to populate a table with data retrieved from Postgres. The issue arises when the table becomes overly long, prompting the need to display only 5 rows at once while adding a scroll bar for ...

Switch up image transitions using Javascript

I have already completed the css and html structure for my project. However, I am encountering issues with the JavaScript functionality. I really like the image effect on this website: (the blue one). I have attempted to replicate it here: , but have bee ...

Uncovering Inline Styles Infused with Javascript for Effective Debugging of Javascript Code

SITUATION: I have recently inherited a website from the previous developer who has scattered important functions across numerous lengthy JS files. I am struggling to track down the source of an inline CSS style within the JS or identify which function is d ...

Tips for changing the size of a div using an absolute div position

Is it possible for the #parent div to resize based on the dimensions of the #child div (if the #child div is using position:absolute;)? Similar to how the #t_parent table resizes according to the size of the #t_child table. <div id="parent" style="pos ...

ASP:Menu: Want to style bulleted lists using CSS

I am currently utilizing ASP:Menu and I would like to customize the menu display as outlined below. Can you please advise on how to implement the CSS styling and what modifications are required? Products Instock Out-of-Stock Orders Purchase Orders Sa ...

Ways to enable JavaScript code to accept input from both a text field and a text

I have a JavaScript code that allows users to input text and choose to make it bold, italicized, or underlined. For example, if the user checks the bold option, the text will appear in bold format. Here is the JavaScript code I am using: $('input[n ...

Personalize the bootstrap-vue styling within your Nuxt project

Currently, I am working on a nuxt project and utilizing bootstrap-vue as a styling module for my components. I am unsatisfied with the default styles provided and wish to incorporate some customization. Specifically, I aim to modify the appearance of the ...

How to create a full-page background image using Bootstrap?

Take a look at this example: In the provided example, there is a background landing page that expands to fit the width of the viewport, remains responsive, and does not take up the full width of the page. How can you utilize bootstrap to manually code an ...

Getting rid of all CSS properties currently set for the Mobile view

Utilizing third-party library components in my project. The library includes components that come with predefined styles for mobile devices. I am seeking to completely UPDATE these properties within my own code. When I say "update," I mean removing all th ...

When the window is resized, the nested div parent and child are overlapping

Is there a way to fix the issue of the content div overlapping the logo div when resizing the browser window? I would like the logo to resize along with the window. @charset "utf-8"; /* CSS Document */ html, body { background-color:#ffffff; mar ...