Combining Two or More CSS Selectors with a Boolean Condition

Combining two or more CSS selectors with a boolean condition

These should work:

&& = div.message.error {}
|| = div.message, div.error {}

Don't think you can do "not"

Edit: Just did a quick test to confirm:

<html>
<head>
<style type="text/css">
div.error.message {
background-color: red;
}
div.message, div.error {
border: 1px solid green;
}
</style>
</head>
<body>
<div>None</div>
<div class="error">Error</div>
<div class="message">Message</div>
<div class="error message">Error Message</div>
</body>
</html>

The "message", "error" and "error message" divs all have a green border and only the "error message" div has a red background.

CSS and and or

&& works by stringing-together multiple selectors like-so:

<div class="class1 class2"></div>

div.class1.class2
{
/* foo */
}

Another example:

<input type="radio" class="class1" />

input[type="radio"].class1
{
/* foo */
}

|| works by separating multiple selectors with commas like-so:

<div class="class1"></div>
<div class="class2"></div>

div.class1,
div.class2
{
/* foo */
}

Selector for element having one of two classes, but not both

You want :not(.first), :not(.last) which is the Selectors level 3-supported version of :not(.first.last) (from Selectors 4, not yet supported by all browsers, as well as jQuery):

ul.tabs > li.active:not(.first), ul.tabs > li.active:not(.last) {    background-color: #F00;}
<ul class="tabs">    <li class="first">1st</li>    <li class="active last">2nd</li></ul>
<ul class="tabs"> <li class="active first last">1st</li></ul>

CSS selector, multiple attributes, OR operator

You will need to repeat the property attribute selector for each OR condition, combining each one with the second attribute selector like so:

[property="some URL"][resource], [property="some URL"][typeof] { color: red; }

Reference: http://www.w3.org/TR/css3-selectors/#attribute-selectors

CSS Selector (A or B) and C?

is there a better syntax?

No. CSS' or operator (,) does not permit groupings. It's essentially the lowest-precedence logical operator in selectors, so you must use .a.c,.b.c.

Can you use if/else conditions in CSS?

Not in the traditional sense, but you can use classes for this, if you have access to the HTML. Consider this:

<p class="normal">Text</p>

<p class="active">Text</p>

and in your CSS file:

p.normal {
background-position : 150px 8px;
}
p.active {
background-position : 4px 8px;
}

That's the CSS way to do it.


Then there are CSS preprocessors like Sass. You can use conditionals there, which'd look like this:

$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}

Disadvantages are, that you're bound to pre-process your stylesheets, and that the condition is evaluated at compile time, not run time.


A newer feature of CSS proper are custom properties (a.k.a. CSS variables). They are evaluated at run time (in browsers supporting them).

With them you could do something along the line:

:root {
--main-bg-color: brown;
}

.one {
background-color: var(--main-bg-color);
}

.two {
background-color: black;
}

Finally, you can preprocess your stylesheet with your favourite server-side language. If you're using PHP, serve a style.css.php file, that looks something like this:

p {
background-position: <?php echo (@$_GET['foo'] == 'bar')? "150" : "4"; ?>px 8px;
}

In this case, you will however have a performance impact, since caching such a stylesheet will be difficult.

Can the :not() pseudo-class have multiple arguments?

Why :not just use two :not:

input:not([type="radio"]):not([type="checkbox"])

Yes, it is intentional

how to chain selectors with OR condition (alternative result set if main is empty)

This behavior in some places is called "coalescing". Here's a generic jQuery plugin that does it for you (editing after great feedback, see the comments).

// The namespace function
jQuery.coalesce = function(selectors){

var out;

$.each(selectors, function(i, v){
var el = jQuery(v);
if (el.length) {
out = el;
return false;
}
});

return out || jQuery();
};

// The jQuery plugin
jQuery.fn.coalesce = function(){
return jQuery.coalesce(this.selector.split(",")); //a little brittle
};

So, in a world where #foo doesn't exist, and a and div do, if you do:

jQuery.coalesce(["#foo", "a", "div"])

That returns jQuery("a") if #foo doesn't exist, or jQuery("#foo") if #foo does exist.

If you require using it in the middle of the chain, you can use $("#foo, a, div").coalesce(), but its vulnerable to commans within the selectors themselves.



Related Topics



Leave a reply



Submit