Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS selector to match elements by attribute's name start

Is there any CSS selector to match these elements? (I need it for adblocker config, looked at W3C selectors document - no hints found there. Generic solution needed because part after data-d- gets randomized by the site).

<div data-d-9y3x>
<div data-d-m01>
<div data-d-whatever>
like image 212
Max Avatar asked Nov 29 '15 06:11

Max


People also ask

Which selector is used to apply CSS to a group of elements?

The CSS class Selector The class selector selects HTML elements with a specific class attribute. To select elements with a specific class, write a period (.) character, followed by the class name.

How do I select an element by attribute name?

To select elements by an attribute name, pass a selector with the attribute's name to the querySelectorAll() method, e.g. document. querySelectorAll('[title]') . The querySelectorAll method will return a collection of the elements that have the provided attribute set.

How are the CSS selectors matched against the elements by the browser?

CSS Selectors are matched by browser engines from right to left. So they first find the children and then check their parents to see if they match the rest of the parts of the rule.

What is the CSS selector for an a tag containing the title attribute?

The [attribute] selector is used to select elements with a specified attribute.


2 Answers

No, there is currently no way to select elements based on the presence of an attribute whose name is starting with a certain value. The starts with selection is only possible for attribute values.

Such a selector is not mentioned in the CSS Selectors Level 4 spec also and so it doesn't look like it would be available anytime soon.

You have the following choices:

  • Use group of selectors with all possible attribute name values in the format element[attribute-name]. But this option is not viable when the exact attribute names are not fixed/unknown.
  • Use JavaScript (or some other scripting library of your preference). Below is a very quick rough sample for the benefit of future visitors.

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

for (var i = 0; i < el.length; i++) {
  var attr = el[i].attributes; /* get all attributes on the element */
  for (var j = 0; j < attr.length; j++) {
    if (attr[j].name.indexOf('data-') == 0) { /* if element has an attribute whose name has data- */
      el[i].style.color = 'red';
      break;
    }
  }
}
<div data-d-9y3x>Some</div>
<div data-d-m01>text</div>
<div data-d-whatever>content</div>
<div test-data-d-whatever>and</div>
<div d-whatever>more</div>
<div testdata-d-whatever>...</div>
like image 198
Harry Avatar answered Sep 21 '22 20:09

Harry


With ES6+ you can use spread operator (...) and then filter those element that their attribute names' start with data-d-:

var res = [...document.querySelectorAll("*")]
    .filter(t => [...t.attributes]
                 .filter(({ name }) => name.startsWith("data-d-")).length > 0)

console.log(res);
<div data-d-9y3x>Some</div>
<div data-d-m01>text</div>
<div data-d-whatever>content</div>
<div test-data-d-whatever>and</div>
<div d-whatever>more</div>
<div testdata-d-whatever>...</div>
like image 34
Alireza Ahmadi Avatar answered Sep 19 '22 20:09

Alireza Ahmadi