how can I compound css selectors together - css

is it possible to use a :not() selector with a :nth-of-type(1) selector?
i.e.
I want to select the first that doesn't have the title "something"
<html>
<head>
<style type="text/css">
p
{
color:#000000;
}
p:not([title=something]):nth-of-type(1)
{
color:#ff0000;
}
</style>
</head>
<body>
<h1>This is a heading</h1>
<p title="something">This is a paragraph.</p>
<p>This is another paragraph.</p>
<p>This is another paragraph.</p>
<div>This is some text in a div element.</div>
</body>
</html>

The nth-of-type is acting on the original selector (p), it's not acting on the result of p:not([title=something]).
p:not([title=something]):nth-of-type(1)
This is saying, find the <p> without a title of "someting" that is also the 1st <p> on the page. This doesn't find any elements as the 1st <p> has the title "something".
What you want is the 1st <p> that doesn't contain the title "something". I don't know if CSS has a good way of doing that.
If you're willing to use jQuery, you can use do this:
$('p:not([title="something"]):eq(0)')
or:
$('p').not('[title="something"]').eq(0)

The problem is that the nth-of-type pseudo-class is defined as:
[nth-of-type] matches elements on the basis of their positions within a parent element’s list of child elements.
So the pseudo-class :nth-of-type(1) is limiting your selection to the p child at position 1.
Your pseudo-class not([title=something]) is limiting your selection to the p elements without the attribute/value title='something', just as you suspect.
The two selectors together are resulting in no elements because the p child at position 1 has title='something'.
For a better understanding, try the following:
p:nth-of-type(1) { color: red; }
p:not([title=something]) { text-decoration:underline; }
More information: Pseudo-classes, nth-of-type

As mentioned by the other answers, :nth-of-type() only refers to the element type, which in this case is p. The selector p:not([type=something]):nth-of-type(1) simply means a p element that is :not([type=something]) and is also the first p.
Anyway, what you're asking can be done in pure CSS using the general sibling selector, but may involve unnecessarily verbose and repetitive selectors:
p:not([title=something]) ~ p:not([title=something])
{
color:#000000;
}
p:not([title=something])
{
color:#ff0000;
}
If you just want to apply this to p elements without a title attribute, you can shorten your selectors a little:
p:not([title]) ~ p:not([title])
{
color:#000000;
}
p:not([title])
{
color:#ff0000;
}
I came up with this technique for use with classes first, which I describe in greater detail here, but it can be applied to a number of things, including attributes, for which I have another example here.

Related

Can you set multiple elements hover declaration to only one div?

I have few elements with the same property once its hovered over. I would like to know if I can set all those element at once such as below
#el1:hover el2:hover el3:hover .test{
}
I know the normal way would be
#el1:hover .test{
}
Is it possible to do something like this or similar on css, Please few free to update the question title as I found it hard to describe the problem.
You can do it like this:
#el1:hover, #el2:hover, #el3:hover .test{
// some code
}
To have a deeper understanding of CSS Selectors read
CSS Selectors
Combinators and groups of selectors
If the id of the parent elements starts with el you can use the [attr^="value"] starts-with attribute selector.
[id^="el"]:hover .test{
// some code
}
Otherwise you will have to use the , to separate the selectors
#el1:hover .test,
#el2:hover .test,
#el3:hover .test{
// some code
}
Finally you could add a common class to the parent elements so that you can target it directly
<div id="el1" class="common-class">
<span class="test">..</span>
</div>
<div id="el5" class="common-class">
<span class="test">..</span>
</div>
and use
.common-class:hover .test{
// some code
}
Yes it will be work, you just need to add comma after each class or id. That comma will seperate the css class or id and style will be apply on all mentioned classes, ids or element references.
#el1:hover, #el2:hover, #el3:hover .test{
some style
}
CSS Group Selector
When you apply same css style properties on diffrent elements using Classes, ID, or references is called group selector.
For example if you want to make color of following elements
<h2>Group Selector Heading</h2>
<p>Group Selector Paragraph</p>
<div class="container">Group Selector Container</div>
<span id="message">Group Selector Message</span>
You can apply color on all above elements by using group selector method. It will minimize the code.
h2, p, .container, #message{
color:#FF0000;
}
<!DOCTYPE html>
<html>
<head>
<style>
#el1:hover, #el2:hover, #el3:hover , .test{
color:orange
}
</style>
</head>
<body>
<h1 id="el1">My First CSS Example</h1>
<h1 id="el2">My First CSS Example</h1>
<h1 id="el3">My First CSS Example</h1>
<h1 class="test">My First CSS Example</h1>
</body>
</html>

CSS :not selector without combining

I am trying to figure out how :not selector works. First of all I try this code
<!DOCTYPE html>
<html>
<head>
<style>
p {
color: #000000;
}
:not(p) {
color: #ff0000;
}
</style>
</head>
<body>
<h1>This is a heading</h1>
<p class="example">This is a paragraph.</p>
<p>This is another paragraph.</p>
<div>This is some text in a div element.</div>
</body>
</html>
It works as ı expect the paragraphs aren't styled and the text in the div and the heading are red. After that I am changing the part in the style tags to this:
<style>
:not(p) {
color: #ff0000;
}
</style>
This time it doesn't work as I expected. Although I want all the elements that are not paragraphs to be red all of them are displayed as red.
Furthermore I am changing the code between the style tags to this:
<style>
:not(p.example) {
color: #ff0000;
}
</style>
This time I am expecting the elements doesn't fit to "p.example" (h1, div and the second paragraph) to be red but none of the elements are affected.
What do I miss? Shouldn't the examples shown above select all the elements those don't fit to the argument selector? Is there a rule about not using the :not selector alone (e.g not as p:not or h1:not)?
Neither of the previous answers is entirely correct.
In your second case, merely specifying
:not(p)
colors everything red because it colors the body, and color is inherited.
You to NOT have to specify, as one answer claims,
body :not(p) {
color: #ff0000;
}
That is almost exactly equivalent to :not(p) (which means *:not(p)). Nor do you have to specify any other parent such as .main as another answer claims.
The third example fails because the argument to :not is not a simple selector. The syntax you gave seems to be trying to do is to select everything that is not a p with the example class. As another respondent pointed out, what you probably meant was everything that is a p but without the example class, for which p:not(.example) is correct.
To select elements which are not A and not B (in other words not (A or B), just do
:not(A):not(B)
For example,
:not(h1):not(p)
which in this example will apply to the body and the div. A more realistic example would be to select p's other than those with either of two classes:
p:not(.class1):not(.class2)
The selector :not(p) matches all elements except p elements. This includes the body element. When your only style sheet is :not(p) { color: #ff0000; }, you thus set all content color red, since the p elements inherit color from their parents (here p) when no color is set on them directly.
If you want to set the color of content to red except for p elements and their descendants, you thus need to be more explicit. A simple way, assuming that this all you want to color, is to set the overall color to red and then override it for p elements, letting inner elements inherit color:
body { color: red }
p { color: black }
The reason why :not(p.example) does not work at all is that the operand of :not must be a simple selector, namely a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class, but not any combination of these; and p.example isn’t simple.
You could use the combined selector :not(p):not(.example), which matches any element except p elements in class example. And this is probably what you want. But the rule won’t work the way want, since here, too, the selector matches the body element, among other things, and its color gets inherited by the only element that has not got color specified for it directly. So even in this case, you would need to think otherwise, setting e.g.
body { color: red }
p.example { color: black }
After #abhitalks comments/feedback. In your first example is nothing wrong, just is related to only inherited properties which will not work. color is inherited, but border is not:
Take a look here Full property table
:not(p) {
color: #f00;
border: 1px solid gray;
}
<h1>This is a heading</h1>
<p class="example">This is a paragraph.</p>
<p>This is another paragraph.</p>
<div>This is some text in a div element.</div>
In you second example:
Selectors level 3 does not allow anything more than a single simple
selector within a :not() pseudo-class.
You can change it to:
body :not(.example) {
color: #ff0000;
}
<h1>This is a heading</h1>
<p class="example">This is a paragraph.</p>
<p>This is another paragraph.</p>
<div>This is some text in a div element.</div>
When you use :not selector, you should mentioned some parent. Based on that parent only it will work. Otherwise it will select all the elements only.
<div class="main">
<h1>This is a heading</h1>
<p class="example">This is a paragraph.</p>
<p>This is another paragraph.</p>
<div>This is some text in a div element.</div>
</div>
CSS:
.main :not(p) {
color: #ff0000;
}
Also if you don't want to select particular element using :not selector you need to use like below.
p:not(.example)
{
color:green;
}
FIDDLE DEMO

set only the css style of first adjacent div with a class name

How can I set the style of only the first div that has class "bla"? (not the second).
<div class="outer">
<div>
....(more div's, unknown how many)
<div class="bla">
....
<div class="bla">some content</div>
</div>
....
</div>
</div>
I'm assuming with this answer that by adjacent elements you mean sibling elements. If you were referring to parent-child elements then go with N1xx1's answer. That being said...
You can't target the first bla with css selectors alone. But you can target all the blas but the first. So, one possibility is to set the styles you want only on the first bla on all blas. Then override those styles by targeting all blas but the first. Like so:
.bla {
...styles for the first bla..
}
.bla ~ .bla {
...override styles set on first bla that you dont want on the others
}
The tilde between the two ".bla"'s is called the general sibling selector. If you've never heard of it, head on over to css selectors spec.
You can do simple workaround for this since you can't do that with any special selector:
.bla {
/* style here, example: */
background-color: #f00;
}
.bla .bla {
/* negate the style, example: */
background-color: transparent;
}
I hope this is what you were looking for.
According to pure css, you can't select according to the ordering of the html elements. Search the spec (here: http://www.w3.org/TR/CSS2/selector.html). There is nothing that refers to how many or in what order html elements match the given selectors.
Javascript:
getElementsByClass('bla')[0].style
EDIT: JOPLOmacedo provided a CSS only (better) answer
I've also found a way to select for instance the second <p> after a <h1> tag:
h1 + p + p{
background: red;
}
Just thought I'd share that.

How to lessen CSS

<div id="tt">test1</div>
<div id="blabla">test2</div>
<div id="test">
<div id="blabla">test3</div>
<div id="tt">test4</div>
</div>
<style>
#tt {color:blue;}
#blabla {color:green;}
#test #tt, #test #blabla etc... {color:red;}
</style>
Is there a way to avoid repeating #test?
Thanks ;)
For the particular example that was the question before it underwent major revisions:
* { color: red }
CSS is very much about context though. It isn't very good when dealing with hypotheticals that have little resemblance to the real code.
Depends on what you want to do. If you want all the text nodes to be red and the parent element is #test, then you just need #test {color:red}. If you need to be more specific, and give a color only for a child, then you can use .child {color:blue}, but if you want to color a child of #test, then you will need to specify the ancestor descendant, in other words #test .child {color:green}
Edit
Example according my comment http://jsbin.com/udoya3
Instead of using id here, you should use id and class. An id should be unique : one id, one element. Class aren't unique. A class can have more than one element.
<style>
.tt,.t {color:red;}
</style>
<div class="tt">test1</div>
<div id="test">
<div class="tt">test2</div>
</div>
#test, #t, #tt { color:red; }
is perfectly valid code.
an #id takes precedence over any other styling (ie a class) which can have adverse effects, but may also be desired.
what are you actually trying to do? save a few characters when writing your css?

How to skip first child?

<div id="main">
<p> one </p>
<p> two </p>
<p> three </p>
<p> four </p>
<p> five </p>
<div>
I don't want to apply css on first <p>One</p>
p {color:red}
I need just opposite of :first-child.
With the negation pseudo-class:
p:not(:first-child) { color: red; }
Browser support is very strong now, but alternatives include:
p { color: red; }
p:first-child { color: black; }
and:
* + p { color: red; }
Quentin's :not() solution works great for modern browsers:
p:not(:first-child) { color: red; }
His alternative for older browsers also works well, except it makes use of an overriding rule for the first child. It's not required, however...
You can simply use a sibling selector to apply the same rule as the one above, without the need to override it for p:first-child. Either one of these rules will work:
The adjacent sibling selector, which matches any p that comes directly after a p:
p + p { color: red; }
The general sibling selector, which matches any p that comes anywhere after a p:
p ~ p { color: red; }
Both combinators work identically here; the subtle differences between them only apply when you have other elements in the mix. Refer to the links provided for details.
I think :nth-child() will do the trick.
p:nth-child(n+2){
background-color:red;
}
This styles all of the p tags except for the first because it starts on the 2nd child. You could then style the first p tag separately with p:first-child.
Works everytime and doesn't need undoing:
p + p {
/* do 15 special things */
}
It takes every P that was preceded by a P. Don't set a property to undo it later. You should only add, if you can help it, not subtract.
You can also use "tilde" ( ~ ) operator
<!DOCTYPE html>
<html>
<head>
<style>
p ~ p {
background:#ff0000;
}
</style>
</head>
<body>
<h1>This is a heading</h1>
<p>The first paragraph.</p>
<p>The second paragraph.</p>
<p>The third paragraph.</p>
<p>The fourth paragraph.</p>
</body>
</html>
Here is the JSFiddle demo http://jsfiddle.net/RpfLa/344/
Did a quick test on FF 17, Chrome 23, Safari 5.1, IE9, IE1-8 on compaitbility mode

Resources