Is there a reliable selector that can select elements based on styles?

Viewed 46

Here is a function I have written. It works well to get the closest element that has a certain attribute:

// Example of attribute if id

export function getClosestAttribute(
  element: SVGElement,
  attribute: keyof typeof svgAttributeToCssStyle,
  excludeElement: boolean
): string | null {
  let firstIncludedEl: Element | null = element;
  if (excludeElement) {
    firstIncludedEl = element.parentElement;
  }
  if (!firstIncludedEl) {
    return null;
  }
  const closestEl = firstIncludedEl.closest(`[${attribute}]`);
  if (!closestEl) {
    return null;
  }

  return closestEl.getAttribute(attribute);
}

Is it possible to write something similar for styles? E.g. I want to select any elements that have style="...fill:..."?

2 Answers

Update

Another approach is to match two rules. The first "start with" rule matches: color: red, but not background-color: red.

div[style^="color:"] {
  text-decoration: underline;
}

The second rule matches when the string occurs anywhere later in the style value:

div[style*=" color:"] {
  text-decoration: underline;
}

Then we just chain them together:

div[style^="color:"],
div[style*=" color:"] {
  text-decoration: underline;
  opacity: 0.5;
}
<div style="background-color: red;">Should not match
</div>

<div style="font-size: 20px; color: red;">Match
</div>

<div style="color: red; font-size: 32px;">Match
</div>

<div style="font-size: 20px; background-color: red;">Should not match
</div>

__

You could use an attribute selector and look for a style value that contained a string of your choosing. However, white space matters. If you're looking for style*="color: red" but your style value has no space between color: and red, the selector will not find matches.

[attr*=value] Represents elements with an attribute name of attr whose value contains at least one occurrence of value within the string.

Example:

div[style*="color: red"] {
  text-decoration: underline;
}
<div style="color: blue;">Regular div
</div>

<div style="color: red;">Add an underline
</div>

Try:

div[style^="color: red"] {
  text-decoration: underline;
}

This works if style attribute starts with color: red.

Related