Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex-like CSS Attribute Selector Wildcard Capture

Tags:

javascript

css

Let's say I have the following HTML:

<div class="tocolor-red">    tocolor </div>
<div class="tocolor-blue">   tocolor </div>
<div class="tocolor-green">  tocolor </div>
<div class="tocolor-yellow"> tocolor </div>

Instead of having to repeat CSS code like the snippet below for each color...

.tocolor-red{
  background: red;
}
.tocolor-red::before {
  content: "red";
}

... is there a way to write a CSS rule that captures the color from the css class instead? For the sake of due diligence, I've looked up attribute selectors already and I've noticed that there are a number of ways you can use wildcards in css already. However, I haven't found anything that would allow me to capture the wildcard text and as part of a rule.

If regex worked for CSS, the rule would look something like this:

.tocolor-([\w+]) {
   background: $1;
}
.tocolor-([\w+]:before {
   content: $1;
}
like image 722
stephen Avatar asked Sep 14 '25 00:09

stephen


1 Answers

CSS has no means to support regular expression captures, while you could select all elements with a class that begins with the string tocolor-, CSS has no means of capturing the value of the string to apply it to a rule.

Incidentally, and somewhat belatedly, one way to do this with JavaScript:

// retrieve all elements containing the string 'tocolor-':
var elements = document.querySelectorAll('[class*="tocolor-"]'),

// declaring two variables for use in later loops:
    classes, colorString;

// iterating over the (Array-like) collection of elements,
// using Function.prototype.call() to be able to apply the
// Array.prototype.forEach() method on the collection:
Array.prototype.forEach.call(elements, function (elem) {
    // 'elem' is the individual node of the collection
    // over which we're iterating.

    // creating an Array of the classes from the element:
    classes = Array.prototype.slice.call(elem.classList, 0);

    // creating a new Array, using Array.prototype.map():
    colorString = classes.map(function (c) {
        // 'c' is the specific class of the Array of classes
        // over which we're iterating.

        // if the current class ('c') begins with the string
        // 'tocolor-' then we return that class
        if (c.indexOf('tocolor-') === 0) {

            // after first replacing the 'tocolor-' string
            // with an empty string:
            return c.replace('tocolor-','');
        }
    });

    // setting the color of the element ('elem') to
    // the string found:
    elem.style.color = colorString;
});

var elements = document.querySelectorAll('[class*="tocolor-"]'),
  classes, colorString;
Array.prototype.forEach.call(elements, function(elem) {
  classes = Array.prototype.slice.call(elem.classList, 0);
  colorString = classes.map(function(c) {
    if (c.indexOf('tocolor-') === 0) {
      return c.replace('tocolor-', '');
    }
  });
  elem.style.color = colorString;
});
<div class="tocolor-red">tocolor</div>
<div class="tocolor-blue">tocolor</div>
<div class="tocolor-green">tocolor</div>
<div class="tocolor-yellow">tocolor</div>
like image 111
David Thomas Avatar answered Sep 15 '25 15:09

David Thomas