Advanced CSS Selector - Select based on styling
Asked Answered
C

4

8

Performance issues aside, is it possible to use a style as a selector? For example, something like:

div[background-image="img/someimg.jpg"] {opacity:.5}

My fallback plan is to use javascript and iterate over divs (adding a class when found), but this might end up being even more expensive given that the page is highly dynamic, and I'm not in control of the divs being added.

Conjugal answered 4/4, 2011 at 6:22 Comment(0)
B
2

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...
  }
}
Bryology answered 4/4, 2011 at 6:29 Comment(2)
Thanks for the thorough response. I'm actually trying to work with html generated from an API, wherein the styles are inline, and there are a ton of them. I don't think the attribute selector will work, given that I don't know what other styles they're going to jam in there.Conjugal
@Conjugal see my answer below which solves this problem: https://mcmap.net/q/81082/-advanced-css-selector-select-based-on-stylingConsequent
C
11

Even if there are a lot of styles, you can do this by using the asterisk as seen here, so this code:

div[style*="box-sizing: border-box;"] {
   background-color: #ffffe0;
}

easily matches this HTML:

<div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, " courier="" new",="" monospace;="" font-size:="" 12px;="" color:="" rgb(51,="" 51,="" 51);="" border-top-left-radius:="" 4px;="" border-top-right-radius:="" border-bottom-right-radius:="" border-bottom-left-radius:="" background-color:="" rgb(251,="" 250,="" 248);="" border:="" 1px="" solid="" rgba(0,="" 0,="" 0.14902);="" background-position:="" initial="" initial;="" background-repeat:="" initial;-en-codeblock:true;"=""><div><font style="font-size: 14px;"><span style="line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(54, 86, 138);">func</span><span style="line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);"> doThis(thing: </span><span style="line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(195, 89, 0);">AnyObject</span><span style="line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);">) {</span><span style="color: rgb(0, 0, 0); font-family: Monaco;">}</span></font></div>
<div><font style="font-size: 14px;"><br></font></div>
<div><font style="font-size: 14px;"><span style="font-variant-caps: normal; line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(54, 86, 138);">func</span><span style="font-variant-caps: normal; line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);"> doThisThing(thing thing: </span><span style="font-variant-caps: normal; line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(195, 89, 0);">AnyObject</span><span style="font-variant-caps: normal; line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);">) {</span><span style="color: rgb(0, 0, 0); font-family: Monaco;">}</span></font></div></div>
Consequent answered 17/8, 2017 at 22:48 Comment(0)
B
2

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...
  }
}
Bryology answered 4/4, 2011 at 6:29 Comment(2)
Thanks for the thorough response. I'm actually trying to work with html generated from an API, wherein the styles are inline, and there are a ton of them. I don't think the attribute selector will work, given that I don't know what other styles they're going to jam in there.Conjugal
@Conjugal see my answer below which solves this problem: https://mcmap.net/q/81082/-advanced-css-selector-select-based-on-stylingConsequent
L
1

I'd suggest manipulating CSS classes rather than individual styles in this case. For example:

div.some-img
{
    background-image: url('img/someimg.jpg');
}

div.some-img-fade
{
    opacity: 5;
}

......

$('div.some-img').each(function() { $(this).addClass('some-img-fade'); });
Latarsha answered 4/4, 2011 at 6:28 Comment(0)
L
0

There's something called DOMSubtreeModified which has now been turned into MutationObserver. This can help you watch the dom for when new elements are added:

// identify an element to observe
var elementToObserve = document.querySelector("#targetElementId");

// create a new instance of `MutationObserver` named `observer`, 
// passing it a callback function
var observer = new MutationObserver(function() {
    console.log('callback that runs when observer is triggered');
});

// call `observe` on that MutationObserver instance, 
// passing it the element to observe, and the options object
observer.observe(elementToObserve, {subtree: true, childList: true});

This example is copy/pasted from mdn docs: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe

Lilliamlillian answered 27/6, 2020 at 4:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.