Select Element by CSS Style (All with Given Style)

CSS selector by inline style attribute

The inline style attribute is no different to any other HTML attribute and can be matched with a substring attribute selector:

div[style*="display:block"]

It is for this very reason however that it's extremely fragile. As attribute selectors don't support regular expressions, you can only perform exact substring matches of the attribute value. For instance, if you have a space somewhere in the attribute value, like this:

<div style='display: block'>...</div>

It won't match until you change your selector to accommodate the space. And then it will stop matching values that don't contain the space, unless you include all the permutations, ad nauseam. But if you're working with a document in which the inline style declarations themselves are unlikely to change at all, you should be fine.

Note also that this is not at all selecting elements by their actual specified, computed or used values as reflected in the DOM. That is not possible with CSS selectors.

Select Element By CSS style (all with given style)

For Mootools:

var styleEls = $$('*').filter(function(item) {
return item.getStyle('position') == 'absolute';
});

Select element with certain style?

I'd actually use that one:

[style~="position:fixed;"]{
/* whatever */
}

See the explanation here

so it'll catch all elements that have position:fixed; in their style (because they may have other styles attributes as well)

But if that position attribute is not written in the HTML, the selector will not select them. you will have to use JQuery for that. Read here

Advanced CSS Selector - Select based on styling

From the W3C page on Attributes:

CSS 2.1 allows authors to specify rules that match elements which have certain attributes defined in the source document.

Attributes are the things defined from the HTML code itself, like id, class, src, href, etc.:

<a id="foo" href="bar">Foo</a>

Unless you specifically defined the style from within a style attribute, like this:

<div style="background-image: url('img/someimg.jpg');">Foo</div>

You can't do anything with CSS.

If you did do it inline, you could try this selector:

div[style="background-image: url('img/someimg.jpg');"]
{
/* ... */
}

Now that you're worried about performance, you can try using pure-JS to do this (untested):

var divs = document.getElementsByTagName('div');

for (var i = 0; i < divs.length; i++)
{
var current = divs[i];

if (current.style.backgroundImage == "url('img/someimg.jpg')")
{
current.style.opacity = 0.5; // You'll need more hacks for IE...
}
}

How to style the option of an html select element?

There are only a few style attributes that can be applied to an <option> element.

This is because this type of element is an example of a "replaced element". They are OS-dependent and are not part of the HTML/browser. It cannot be styled via CSS.

There are replacement plug-ins/libraries that look like a <select> but are actually composed of regular HTML elements that CAN be styled.

Apply CSS Style on all elements except with a SPECIFIC ID

Use the :not selector:

div:not(#bar){    color:red;}
<div>foo</div><div id="bar">bar</div>

Overwrite all given CSS styles with my CSS selector

The solution that worked for me is using the CSS property all set to a value of revert.

.css-class {
all: revert;
}

The mozilla docs for revert explains it nicely:

The revert CSS keyword rolls back the cascade so that the property takes on the value it would have had if there were no styles in the current style origin.

For firefox and chrome, use unset:

.css-class {
all: unset;
}

See browser hacks for using "media query hacks" for checking the current browser for a cross-browser solution. Also, see this fiddle where the blue box does not inherit the height property:

I hope this solution will work in your project as well.

Javascript, CSS: Get element by style attribute

My suggestion is avoid doing this if at all remotely possible. Instead, use a class to assign the color value, and then you can look up the elements using the class, rather than the color value.

As far as I'm aware, there's no selector (not even in CSS3) that you can use to query a specific style value, which means looping through all elements (or it looks like you can restrict it to all elements with a style attribute) and looking at the element.style.color property. Now, the thing is, even though you write color: #333; in your style attribute, different browsers will echo it back to you in different ways. It might be #333, it might be #333333, it might be rgb(51, 51, 51), it might even be rgba(51, 51, 51, 0).

So on the whole, a very awkward exercise indeed.


Since you've said this is for a Chrome extension, you probably don't have to worry as much about multiple formats, although I'd throw in the ones that we've seen in the wild in case Chrome changes the format (perhaps to be consistent with some other browser, which has been known to happen).

But for instance:

(function() {

// Get all elements that have a style attribute
var elms = document.querySelectorAll("*[style]");

// Loop through them
Array.prototype.forEach.call(elms, function(elm) {
// Get the color value
var clr = elm.style.color || "";

// Remove all whitespace, make it all lower case
clr = clr.replace(/\s/g, "").toLowerCase();

// Switch on the possible values we know of
switch (clr) {
case "#333":
case "#333333":
case "rgb(51,51,51)": // <=== This is the one Chrome seems to use
case "rgba(51,51,51,0)":
elm.style.color = "#444";
break;
}
});
})();

Live example using red for clarity | source - Note that the example relies on ES5 features and querySelectorAll, but as this is Chrome, I know they're there.

Note that the above assumes inline style, because you talked about the style attribute. If you mean computed style, then there's nothing for it but to loop through all elements on the page calling getComputedStyle. Other than that, the above applies.

Final note: If you really meant a style attribute with precisely the value color: #333 and not the value color:#333 or color:#333333; or color: #333; font-weight: bold or any other string, your querySelectorAll could handle that: querySelectorAll('*[style="color: #333"]'). But it would be very fragile.


From your comment below, it sounds like you're having to go through every element. If so, I wouldn't use querySelectorAll at all, I'd use recursive descent:

function walk(elm) {
var node;

// ...handle this element's `style` or `getComputedStyle`...

// Handle child elements
for (node = elm.firstChild; node; node = node.nextSibling) {
if (node.nodeType === 1) { // 1 == Element
walk(node);
}
}
}

// Kick it off starting with the `body` element
walk(document.body);

That way you don't build up large, unnecessary temporary structures. This is probably the most efficient way to walk the entire DOM of a document.

Style select element based on selected option

Unfortunately, yes - this is something not currently possible with only CSS. As mentioned in the answers and comments to this question, there is currently no way to make the parent element receive styling based on its children.

In order to do what you're wanting, you would essentially have to detect which of the children (<option>) is selected, and then style the parent accordingly.

You could, however, accomplish this with a very simple jQuery call, as follows:

HTML

<select>
<option value="foo">Foo!</option>
<option value="bar">Bar!</option>
</select>

jQuery

var $select = $('select');
$select.each(function() {
$(this).addClass($(this).children(':selected').val());
}).on('change', function(ev) {
$(this).attr('class', '').addClass($(this).children(':selected').val());
});

CSS

select, option { background: #fff; }
select.foo, option[value="foo"] { background: red; }
select.bar, option[value="bar"] { background: green; }

Here is a working jsFiddle.

Back to the question about the future of selectors. Yes - the "Subject" selectors are intended to do exactly what you mention. If/when they ever actually go live in modern browsers, you could adapt the above code to:

select { background: #fff; }
!select > option[value="foo"]:checked { background: red; }
!select > option[value="bar"]:checked { background: green; }

As a side-note, there is still debate about whether the ! should go before or after the subject. This is based on the programming standard of !something meaning "not something". As a result, the subject-based CSS might actually wind up looking like this instead:

select { background: #fff; }
select! > option[value="foo"]:checked { background: red; }
select! > option[value="bar"]:checked { background: green; }


Related Topics



Leave a reply



Submit