CSS Selector nth-child - css

I am facing issues writing a slightly complex CSS selector.
I want to select a div with "class" containing 'btn-group', but not 'open'
So I have something like;
div[class*='btn-group']:not([class='open'])
Now the issue is that there are around 5-6 elements that match the above condition. But I want to select the first out of that. How do I do the same?
Would prefer doing using nth-child..

What about: div[class*='btn-group']:not(.open):first-of-type?
[Edit]: This trick does not work if you have <div class="btn-group open"></div> as the first child... (as explained by #Jukka below) a JS-based trick will work, tho:
$("div[class*='btn-group']").not(".open").first()
.css({...});
// OR add a class
// .addClass("class");
http://jsfiddle.net/teddyrised/LdDCH/

try like this
div [class*='btn-group']:not([class='open']):nth-child(1) {
color:Red;
}
Using this you can select first child
Working Fiddle

You cannot. CSS selectors can’t be used that way. But if you provide a more specific HTML context (including containers for the div elements and a description of a pattern that the markup follows), there might be a way that works under some assumptions.
In particular, :nth-child and :nth-of-type only test whether the element is the *n*th child, or the *n*th child of its kind, of its parent. It does not take e.g. classes into account; the is no “nth of a class” selector.

Related

CSS wild card for complex ID's

If I had a css selector such as #subtab-1, #subtab-2 etc
I could make the wildcard selector as suchdiv[id^='subtab-']
But I cannot figure out how to make a wild card for selectors such as
#subtab-1-sub1
#subtab-1-sub2
#subtab-1-sub2
#subtab-2-sub1
#subtab2-sub2
#subtab2-sub-3
etc...
How can you make something like:
div[id^='subtab-*tab-*'] (*=wildcard)
If I am understanding your question correctly, you are trying to select all elements whose id starts with subtab- followed by a number, followed by -sub followed by another number. It also sounds like you want this selector to not match #subtab-1, only things that have a suffix like #subtab-1-sub1.
This cannot be done with CSS. CSS does not supply a selector that will allow wildcards. You can however hack something together that comes pretty close.
Hacky selector that might work
[id^="subtab-"][id*="-sub"] would match any id that starts with subtab- and also contains -sub somewhere in the id. This will probably work but could cause false positives on things like #subtab-1-subtle or #subtab-something-sub2, #subtab-sub, etc.
Another hacky selector that might work
Making the assumption that #subtab-?-sub? elements are always contained inside of #subtab-? elements and that #subtab-? elements can never contain another #subtab-? element, you could use the child combinator to target them: [id^="subtab-"] > [id^="subtab-"]
Relying on a class instead
A better solution would probably be to give all of the elements you are trying to target a common class, for instance <div class="subtab-sub">, then selecting them all would be as easy as .subtab-sub. Using a class would also yield much faster performance than using attribute selectors.
All the ids start with subtab so use
div[id^='subtab']
I'm not sure you want to use IDs constructed in this fashion as a way to address elements in your HTML. I'd experiment with using classes such as subsubtab, and you could try using the nth-child pseudo-class to individually address subtabs or subsubtabs:
<div class="tabs">
<div class="subtab">
<div class="subsubtab">...</div>
<div class="subsubtab">...</div>
...
</div>
<div class="subtab">
...
</div>
</div>
Then, your CSS would look like
div.subsubtab { color: brown; }
or
div.subtab:nth-child(2) { border: 1px solid red; }
Have a look into this jQuery Selector
I think it can work.

How to style parent when parent contains specific child?

I have some html that looks like this:
<div id="parent">
<div id="child"></div>
</div>
I want to apply a default background color to #parent except for when it contains a #child.
So the CSS should end up looking something like this:
#parent {
background: red
}
#parent:contains(#child) {
background: none
}
However, I can't get the :contains pseudo selector to work that way. Is there a way to achieve this?
:contains() was only intended to match elements containing certain text, not elements containing certain other elements. It is because of the complications associated with matching elements by text that there were almost no browser implementations, leading to :contains() being dropped from the spec.
Since there is no parent selector in CSS, and :has() (which does look at elements) only exists in jQuery, you won't be able to achieve this with CSS yet.
For the record, jQuery implements :contains() as well, but it does so according to the old spec, so it uses the name :has() for elements instead.
With jquery
if($("#child").length>0) $("#parent").css("backgroundColor","#fff");
Its not possible with pure css.

recommended css notation

I have a div with an ID:
<div id="main">
What's the correct (or difference) between
div#main {
and
#main {
Regards,
There is a great doco on using efficient CSS selectors, focus on rules with overly qualified selectors:
ID selectors are unique by definition. Including tag or class
qualifiers just adds redundant information that needs to be evaluated
needlessly.
Instead of just applying the style to an element with id main, your selector will re-qualify the element by checking whether or not it's also a div (in that order). To clarify: css selectors are evaluated right to left, unlike same selector syntax when used in jQuery etc.
Re pixelistik's suggestion that div#main is more specific than #main - yes, that is technically correct, however if you have to resort to this to raise a rule's specificity, chances are the structure of CSS you're working on is not as thought through as it should be.
#main matches everything with ID 'main', whereas div#main matches only <div> elements with ID main.
Ideally, you should never have two elements with the same ID, so realistically the two don't make a difference, but there's probably performance related issues regarding whether specifying div makes it find the result faster.
So difference is that:
When you write div#main style will be only for <div> element.
When you write #main it can be used as style for <div>, <span>, <p>, etc.
And what recommend is hard to say, every developer it has it different. So i using for example
span.<nameClass> when is nested in <li> for example.
#nav li span.href a {
...
}
I think it's used when you want that someone class with specific name can have only one element.
So when your write span#href it will works only for <span id="href">Simply dummy text</span> not for others. When you write #href it will works for <span id="href">Simply dummy text</span> or Link but both are correct when you also asking about this. Differences i wrote above.
Both are correct.
div#main is more specific than #main, which means that styles defined with the first selector will override the ones of the second.
Here's a good introduction to CSS specifity:
http://htmldog.com/guides/cssadvanced/specificity/

:last-of-type Pseudo-Class Not Acting as Expected

I'm applying :last-of-type to an element that should be as such. Check out the final div.info (that's the bottom information for each article) on http://www.elemovements.com. Why is it not working?
The :nth-of-type() family of pseudo-classes only look at an element's type, that is, its tag name. They do not filter by your class selector or any other selector.
Therefore, your statements:
I'm applying :last-of-type to an element that is clearly as such. Check out the final div.info
Are contradictory. There's a div.center after that, making that the last div, not your div.info.
You cannot currently use CSS selectors to find your last div.info; you'll have to resort to adding an extra class and/or using JavaScript.
You're having one of the most common misconceptions about CSS. CSS is not read left-to-right, but right to left!
Meaning, the browser will look for div.info:last-of-type, so browser will filter elements in the following order:
Last element of each type (tag name)
Has class of info
Is a div.
Your element does not satisfy these conditions in that order. It may be the last div with class of info, but no last element has a class of info
This 2 are the same:
div.info:last-of-type
div:last-of-type.info
The :last-of-type is hitting the div, not the .info, and the .info is limiting the found results to 0.
Another example:
.section.section-test:last-of-type
Would actually works like: .section:last-of-type.section-test

Select element based on child class

Is there a way in CSS to select an element which has a sub-element with given class?
I want to apply a style to a <ul> list that has <li> with a particular class.
This isn't possible with css, since you're working against the cascade by selecting an ancestor based on a descendant.
The best I can offer and suggest is a jQuery approach:
$(document).ready(
function() {
$('.givenClassName').parent().addClass('something');
}
);
This finds the element with the givenClassName and then selects its parent element and adds the class something to that element.
#Blaenk suggests an alternate approach, which is more versatile (his approach doesn't require the ancestor element to be the parent of the element you're selecting by).
Obviously other JS libraries, and JS all by itself, can achieve the same effect, though I can't offer particular advice, since I'm still only just familiarising myself with JS and mostly with jQuery (why yes, I am ashamed of myself...).
As far as I know, this is unfortunately not possible with CSS.
If you can use Javascript though, jQuery has a nice way of doing this using the closest() method. The documentation for it even lists an example very similar to yours: selecting a ul that has an li of a particular class.
$("li.some-class").closest("ul");
Forgive me if this is not the best way to do it in jQuery. I'm actually new to jQuery and this is one of the methods I've learned so far, and it seemed fitting.
No. The CSS Cascade does not allow for this kind of selector.
The best solution in this case would be either to modify the DOM with JavaScript or to change up the resultant HTML to add classes to the ul tags.
ul li {
/* styles */
}
Is this what you're asking for?

Resources