Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use nth-of-type for classes -- not elements [duplicate]

I am working on a simple HTML for an image gallery. Each row of the gallery can have 2, 3 or 4 images. (In an 2-image row, each image element is named type-2, the same goes to type-3 and type-4.)

Now I want to select the last element of each row to set a custom margin. My HTML is like this:

<div id="content">
    <div class="type-2"></div>
    <div class="type-2"></div> <!-- I want this, 2n+0 of type-2 -->
    <div class="type-3"></div>
    <div class="type-3"></div>
    <div class="type-3"></div> <!-- this, 3n+0 of type-3 -->
    <div class="type-4"></div>
    <div class="type-4"></div>
    <div class="type-4"></div>
    <div class="type-4"></div> <!-- this, 4n+0 of type-4 -->
    <div class="type-2"></div>
    <div class="type-2"></div> <!-- this -->
    <div class="type-3"></div>
    <div class="type-3"></div>
    <div class="type-3"></div> <!-- this -->
    <div class="type-4"></div>
    <div class="type-4"></div>
    <div class="type-4"></div>
    <div class="type-4"></div> <!-- this -->
</div>

I think the following CSS would work but it didn't:

.type-2:nth-of-type(2n+0) {margin-right:0;}
.type-3:nth-of-type(3n+0) {margin-right:0;}
.type-4:nth-of-type(4n+0) {margin-right:0;}

What this CSS selects is:

<div id="content">
    <div class="type-2"></div>
    <div class="type-2"></div> <!-- selected by .type-2:nth-of-type(2n+0) -->
    <div class="type-3"></div> <!-- selected by .type-3:nth-of-type(3n+0) -->
    <div class="type-3"></div>
    <div class="type-3"></div>
    <div class="type-4"></div>
    <div class="type-4"></div>
    <div class="type-4"></div> <!-- selected by .type-4:nth-of-type(4n+0) -->
    <div class="type-4"></div>
    <div class="type-2"></div> <!-- selected by .type-2:nth-of-type(2n+0) -->
    <div class="type-2"></div>
    <div class="type-3"></div> <!-- selected by .type-3:nth-of-type(3n+0) -->
    <div class="type-3"></div>
    <div class="type-3"></div>
    <div class="type-4"></div>
    <div class="type-4"></div> <!-- selected by .type-4:nth-of-type(4n+0) -->
    <div class="type-4"></div>
    <div class="type-4"></div>
</div>

I can edit my HTML to achieve what I want, but just out of curiosity, is there some kind of CSS for this?

Edit: this question may look like a duplicate of questions asking if nth-child and nth-of-type can be applied to classes -- not elements. I already knew the answer is no. What I'm really asking for is a pure CSS solution/hack for it, and the chosen answer did just that.

like image 640
Hoang Huynh Avatar asked Oct 19 '13 17:10

Hoang Huynh


People also ask

Does nth of type work with class?

There cannot be a way to select :nth-of-type() of a class, because :nth-of-type() only selects the nth child of its type.

How do you select the nth element of a class in CSS?

The :nth-child(n) selector matches every element that is the nth child of its parent. n can be a number, a keyword (odd or even), or a formula (like an + b). Tip: Look at the :nth-of-type() selector to select the element that is the nth child, of the same type (tag name), of its parent.

What's the difference between the nth of type () and Nth child () selector?

The nth-of-type is very similar to the nth-child pseudo-class. The main difference is that it specifically considers the type of the element getting selected before checking any other logic. Let's use our example from above but apply nth-of-type instead.

How do you apply the same style to multiple elements?

When you group CSS selectors, you apply the same styles to several different elements without repeating the styles in your stylesheet. Instead of having two, three, or more CSS rules that do the same thing (set the color of something to red, for example), you use a single CSS rule that accomplishes the same thing.


4 Answers

This is not possible to do with CSS Selectors Level 3 (at least, without CSS hacks, extra markup, or JavaScript).

The draft CSS Selectors Level 4 proposes the :nth-match() pseudo-class, which would do what you want:

:nth-match(2n+0 of .type-2) {margin-right:0;}
:nth-match(3n+0 of .type-3) {margin-right:0;}
:nth-match(4n+0 of .type-4) {margin-right:0;}

This is not yet implemented by any browser that I know of, but there is a bug filed to implement it in Chrome.

like image 84
Brian Campbell Avatar answered Oct 12 '22 04:10

Brian Campbell


With only CSS hacks, without modifying your markup, you can do something like the below:

[class*=' type-'], [type^='type-']{ /* Set all the divs to float: left initially */
    float: left;
    content: url('http://static.adzerk.net/Advertisers/db5df4870e4e4b6cbf42727fd434701a.jpg');
    height: 100px; width: 100px;
}

.type-2 + .type-2 + div{
    clear: both; /* Clear float for a div which follows two div with class type-2 */
}

.type-3 + .type-3 + .type-3 + div {
    clear: both; /* Clear float for a div which follows three div with class type-3 */
}

.type-4 + .type-4 + .type-4 + .type-4 + div {
    clear: both; /* /* Clear float for a div which follows four div with class type-4 */
}

Demo Fiddle

like image 29
Harry Avatar answered Oct 12 '22 02:10

Harry


nth-child and nth-of-type are pseudo classes and can only be applied to elements.

.layout:nth-of-type is a pseudo-class of a class and so will not work.

Jquery's EQ might offer a solution

http://api.jquery.com/eq/

like image 7
Paulie_D Avatar answered Oct 12 '22 04:10

Paulie_D


Short answer

There is no way to do what you're asking in pure css.

Why

:nth-of-type Can only be used against an element selector like so:

div:nth-of-type(2n+0) { margin-right: 0; }

Reference link.

Possible JS solution

You can try your luck with some jQuery though:

var $this;

$('[class^="type-"]').each(function (){

  $this = $(this);

  if ( $this.attr('class') !== $this.next().attr('class') )
    $this.addClass('last');

});

Then use .type-2.last to access your "last row of type".

Demo

Heres a demo.

like image 3
hitautodestruct Avatar answered Oct 12 '22 02:10

hitautodestruct