"Selecting elements using the nth-of-type CSS selector alongside other

Dealing with a grid layout that includes spacers between certain items, I attempted to use the :nth-of-type selector in CSS to style only the first column of items and not apply those styles to the right side. However, it seems that the CSS gets confused when there are separators present.

https://jsfiddle.net/yquw291h/2/

In the example provided, you can observe that the counting goes awry after each additional div tag, although one would expect the CSS to consider each .box individually.

Is there a method to make the styling affect each item exclusively? I am interested in having specific styles applied only to the first column, and I am open to using a JavaScript-based solution as well.

HTML

<div>
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="splitter">splitter</div>
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="splitter">splitter</div>
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
    <div class="box">8</div>
</div>

CSS

.box {
    width: 48%;
    float: left;
    height: 30px;
    background: #ccc;
}

.box:nth-of-type(odd){
    margin-right: 4%;
    background-color: red;
}

.splitter {
    width: 100%;
    float: left;
}

Answer №1

The concept of :nth-of-type() in CSS may not be fully understood here. It targets the specific type of element (in this case, a div) that is also odd and within the class="box" category to apply styles.

The issue arises when your 5th div is a splitter, which still counts despite lacking the class="box". As a result, the styles are not applied due to your selector specifying .box nth-of-type. The next odd div is actually

<div class="box">2</div>
, sandwiched between the splitters.

To clarify, all the divs within your container are counted. Just because the .box divs contain an even number as text doesn't mean they are evenly numbered entries within your list of divs.

If you're unable to alter the markup as mentioned in a comment, consider utilizing a jQuery approach like the one below (credit to BoltClock for assistance):

var container = document.getElementById("search-results");
var descendants = container.getElementsByTagName("div");
var x, i = 0;
for (x = 0; x < descendants.length; x++) {
    var nth = $(descendants).eq(x);
    if (nth.hasClass("splitter")) {
    i = 0;
    continue;
    }
    if (nth.hasClass("box")) {
        if (i % 2 == 0) {
            nth.addClass("odd");
        }
        i++;
    }
};
.box {
    width: 48%;
    float: left;
    height: 30px;
    background: #ccc;
}

.odd {
    margin-right: 4%;
    background-color: red;
}

.splitter {
    width: 100%;
    float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="search-results">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="splitter">splitter</div>
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="splitter">splitter</div>
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
    <div class="box">8</div>
</div>

You can follow Tim's suggestion to adjust your markup to meet your requirements without JavaScript. Alternatively, consider using distinct elements to segment your content. However, remember this method works effectively only with an even number of divs in each section after a divider (the numbering status is indicated for clarity).

.box {
    width: 48%;
    float: left;
    height: 30px;
    background: #ccc;
}

.box:nth-of-type(odd){
    margin-right: 4%;
    background-color: red;
}

.splitter {
    width: 100%;
    float: left;
}
<div>
    <div class="box">1</div> <!-- odd -->
    <div class="box">2</div> <!-- even -->
    <div class="box">3</div> <!-- odd -->
    <div class="box">4</div> <!-- even -->
    <hr class="splitter"/> <!-- N/A -->
    <div class="box">1</div> <!-- odd -->
    <div class="box">2</div> <!-- even -->
    <div class="box">3</div> <!-- odd -->
    <div class="box">3</div> <!-- even -->
    <hr class="splitter"/> <!-- N/A -->
    <div class="box">1</div> <!-- even -->
    <div class="box">2</div> <!-- odd -->
    <div class="box">3</div> <!-- even -->
    <div class="box">4</div> <!-- odd -->
    <div class="box">5</div> <!-- even -->
    <div class="box">6</div> <!-- odd -->
    <div class="box">7</div> <!-- even -->
    <div class="box">8</div> <!-- odd -->
</div>

At this stage, it may be beneficial to evaluate the necessity of columns. If tabular data is involved, opt for <table>s instead. For side-by-side columns, segregate div groups into "left" and "right" containers for mass styling via respective selectors like .left div {} and .right div {}.

Answer №2

Indeed, the functionality of :nth-of-type is working as expected. This pseudo-class targets the specific element type (in this case, div) within its parent container. To resolve your issue, simply group the boxes within a common parent element with separators:

.box {
    width: 48%;
    float: left;
    height: 30px;
    background: #ccc;
}

.box:nth-of-type(odd){
    margin-right: 4%;
    background-color: red;
}

.splitter {
    width: 100%;
    float: left;
}
<div>
  <div>
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
  </div>
    <div class="splitter">splitter</div>
  <div>
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
  </div>
    <div class="splitter">splitter</div>
  <div>
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
    <div class="box">8</div>
  </div>
</div>

Answer №3

It appears that there may be a misunderstanding regarding the functionality of the :nth-of-type selector. The .box selector does not restrict the :nth-of-type selector; instead, it acts as an additional subfilter. In this scenario, all odd divs are initially selected, followed by styling only those odd divs with the box class.

In the provided example, the odd divs identified are:

<div>
    <div class="box">1</div> <!-- Odd -->
    <div class="box">2</div>
    <div class="box">3</div> <!-- Odd -->
    <div class="box">4</div>
    <div class="splitter">splitter</div> <!-- Odd -->
    <div class="box">1</div>
    <div class="box">2</div> <!-- Odd -->
    <div class="box">3</div>
    <div class="splitter">splitter</div> <!-- Odd -->
    <div class="box">1</div>
    <div class="box">2</div> <!-- Odd -->
    <div class="box">3</div>
    <div class="box">4</div> <!-- Odd -->
    <div class="box">5</div>
    <div class="box">6</div> <!-- Odd -->
    <div class="box">7</div>
    <div class="box">8</div> <!-- Odd -->
</div>

Within these odd divs listed above, only the following meet the additional filter criteria by also containing the class box:

<div>
    <div class="box">1</div> <!-- Odd w/ class box -->
    <div class="box">2</div>
    <div class="box">3</div> <!-- Odd w/ class box -->
    <div class="box">4</div>
    <div class="splitter">splitter</div>
    <div class="box">1</div>
    <div class="box">2</div> <!-- Odd w/ class box -->
    <div class="box">3</div>
    <div class="splitter">splitter</div>
    <div class="box">1</div>
    <div class="box">2</div> <!-- Odd w/ class box-->
    <div class="box">3</div>
    <div class="box">4</div> <!-- Odd w/ class box -->
    <div class="box">5</div>
    <div class="box">6</div> <!-- Odd w/ class box -->
    <div class="box">7</div>
    <div class="box">8</div> <!-- Odd w/ class box-->
</div>

These elements fulfill the specified requirements by also having the box class.

For instance:

Here is an approach to achieve this using various :nth-child selectors for creating CSS ranges. This method can be beneficial if modifying the HTML structure is not feasible, as suggested in other responses:

.box {
  width: 48%;
  float: left;
  height: 30px;
  background: #ccc;
}

.box:nth-child(n+1):nth-child(odd):nth-child(-n+4),
.box:nth-child(n+6):nth-child(even):nth-child(-n+8),
.box:nth-child(n+10):nth-child(even):nth-child(-n+17),
.box:nth-child(n+19):nth-child(odd):nth-child(-n+21){
  margin-right: 4%;
  background-color: red;
}

.splitter {
  width: 100%;
  float: left;
}
<div>
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="box">4</div>
  <div class="splitter">splitter</div>
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="splitter">splitter</div>
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="box">4</div>
  <div class="box">5</div>
  <div class="box">6</div>
  <div class="box">7</div>
  <div class="box">8</div>
  <div class="splitter">splitter</div>
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
</div>

Please note: The provided markup is slightly more comprehensive than what was originally outlined in your question. It is based on the full jsfiddle markup rather than the abbreviated version provided.

Here is your updated fiddle incorporating the aforementioned changes.

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

How can we minimize the data contained in JSON HTML markup?

https://i.stack.imgur.com/mzuB0.png Currently, I am attempting to find a way to conceal the last 12 digits in the price shown on a button, as it is excessively long. The method I am utilizing involves a JSON api and insertAdjacentHTML markup. This snipp ...

downloading responsive design

Using media queries to define backgrounds with separate images based on browser size: @media (min-width:1440px){div.container{background:URL('bg1440.png');}} @media (min-width:960px){div.container{background:URL('bg960.png');}} @media ...

Hiding the initial parent SVG element in the list will also hide all subsequent SVG elements within each section, excluding the container

I encountered a strange issue with my code in the Next framework. When using getServerSideProps, I made a request to my api folder, which resulted in a simple JSON response. Everything seemed to be working fine. The content was displayed perfectly without ...

Guide to retrieving JSON data from a jQuery ajax request

Below is the JSON string generated by json_encode(): [{"ID":"650","DESCR":"FRONTAGE","MAINURL":"images\/98\/30-HEATH (1).JPG","THUMBURL":"images\/98\/30-HEATH (1).JPG","ALBUM":"98"},{"ID":"651","DESCR":"PICTURE","MAINURL":"images\ ...

Fixing a menu hover appearance

I recently encountered a small issue with the menu on my website. When hovering over a menu item, a sub-menu should appear. However, there seems to be a slight misalignment where the submenu appears a few pixels below the actual menu item. Check out the w ...

Resolver for nested TypeORM Apollo queries

I've set up a schema that includes database tables and entity classes as shown below: type User { id: Int! phoneNumber: String! } type Event { id: Int! host: User } Now, I'm attempting to create a query using Apollo like this ...

Is there an issue with passing values to a different page through AJAX?

I am trying to pass a hidden input value from one page to another using AJAX, but for some reason, the value is not getting passed. I have limited experience with PHP, jQuery, and AJAX. Can someone offer assistance? index.php: <?php foreach($imgs a ...

AngularJS ng-include nested form configuration

My application utilizes nested ng-includes. The outer include is a login screen for one application while the inner ng-include includes two templates. The login screen is designed in two steps where the email is checked first and then the password entered. ...

Execute a Jquery Webservice function

Just starting out with Jquery and Ajax. I've been able to retrieve XML data from a web service, but now I need to convert it into an array for use with the AJAX GRIDVIEW. Below is my JS code, the result from the web method, and the desired array forma ...

Use an if statement in Angular to conditionally add a title attribute with an empty value to HTML

How can I conditionally add the title attribute to a div without creating another div and using ngIf? If the permission is true, I want to include a title in my div. Here's what my current div looks like: <div (click)="goToChangelog()&quo ...

The CSS selector seems to be malfunctioning

I am facing an issue with calling HTML elements from CSS using CSS selectors. It's strange that the class selectors work fine, but I'm unable to select the elements directly from CSS. Therefore, I had to assign them classes. What I aim to achiev ...

When a new VueJS project is created, it failed to automatically install the necessary basic HTML files and folders

Hey there, I am completely new to Vue.js. Just recently, I installed the Vue.js/CLI and created a brand new project using vue create test. This prompted me to choose from three options: > Default ([Vue 2] babel, eslint) Default (Vue 3 Preview) ([Vue 3 ...

What exactly is the functionality of this "if" statement that operates without any operators?

I've recently started learning Javascript and I'm currently going through chapter 5 of Eloquent Javascript. In my studies, I encountered a piece of code that is puzzling to me. While I understand the general method and steps of how it works, I&ap ...

Client component in Next.js is automatically updated upon successful login

I am currently working on a Next.js + DRF website that requires authentication. I have set up my navbar to display either a "log in" or "log out" button based on a boolean prop passed from the server side to the client-side: export default async function R ...

Retrieve the callback arguments using sinon.spy within a JavaScript promise

During my test with mocha and sinon, I encountered an issue where I couldn't retrieve a callback value from inside a promise scope of an HTTP-request due to the asynchronous nature of promises. It seems that by the time sinon.spy checks on the callbac ...

What is the technique for choosing the parent's ID with jQuery?

When a user clicks on any team, I need to retrieve the parent's parent ID. For example, if someone clicks on a Premier League Team, I want to store the ID 2 in a variable called league_id. Here are my attempts so far: Using Closest Method $('u ...

The Philosophy Behind Structuring Node.js Modules

There appears to be a common understanding regarding the directory structure in node.js, but I have not come across any official documentation on this topic. Based on my exploration of open source projects, it seems that most projects typically include a ...

how to implement dynamic water fill effects using SVG in an Angular application

Take a look at the code snippet here HTML TypeScript data = [ { name: 'server1', humidity: '50.9' }, { name: 'server2', humidity: '52.9', }, { name: 'server3', humidity: ...

Failure to give an error message occurred during a POST request on Parse.com and ExpressJS platform

I'm facing an issue where a POST request I send fails with error code 500 and there is nothing showing up in my server side error log. It seems like the cloud method may be missing. What's interesting is that the same POST request works fine wit ...

Troubleshooting React and Material-UI: Adjusting <slider> component for use with personalized data

I am facing a challenge with using the Material-UI slider to showcase API data. The unique aspect here is that the slider is intended for displaying data without any interactivity. Encountering an error message: Slider.js:91 Uncaught TypeError: nearest.to ...