1

I want to have a class cX where x is a number between 0 and 100. I could add c0 to c100 to my css. But well, I'd like to avoid that.

I know there are ways to match element attributes like h2[rel="external"]. But is it also possible to match class names? Would it also possible to use the matched value within the rule?

Example

.c[x] { height: x%; }
boop
  • 7,413
  • 13
  • 50
  • 94
  • What should happen if say there is an element with class c101? – Harry Feb 06 '16 at 07:03
  • @Harry ideally the rule would ignore it. But I could live without the restriction – boop Feb 06 '16 at 07:04
  • @CBroe how is this a duplicate? I want to know how to reuse the matched value as well. I don't see that in the question or in any answer. – boop Feb 06 '16 at 07:07
  • You are looking for elements whose class name match a specific pattern and so that answer should be the solution. As for **matched value**, no you **can't do that with CSS**. – Harry Feb 06 '16 at 07:09
  • @Harry when I match `24` i want to use it and set `height: 24px` – boop Feb 06 '16 at 07:10
  • 1
    Why not use SASS to generate all the rules you want? – Aziz Feb 06 '16 at 07:10
  • well then, JavaScript manipulation or server-side script to output inline CSS.. I don't think a pure CSS solution exists – Aziz Feb 06 '16 at 07:12
  • Sorry, I overlooked that part too; voted to re-open. Agree with @Aziz, a CSS preprocessor like SASS or LESS is what you should use to achieve this. (Another option would be client-side creation of the necessary stylesheet rules via JavaScript.) – CBroe Feb 06 '16 at 07:12
  • Unless you’re planning to use this in excess (thousands of classes, different names) or to set dozens of different properties each time, I don’t think filesize should be an issue. Especially if you GZIP it before sending to the client. – CBroe Feb 06 '16 at 07:14
  • @Aziz inline css wouldn't change the file size in the end, I care more about the transferred filesize than the stylesheet filesize. CBroe: yeah may be micro-optimization but I was curios if it's possible, since it would be neat. – boop Feb 06 '16 at 07:15
  • _“I care more about the transferred filesize than the stylesheet filesize”_ – again, I think GZIP should compress that quite well, especially since it will contain so much repetition. – CBroe Feb 06 '16 at 07:17
  • 1
    the 100 CSS rules would generate a 2kb file, very very small and could be 1kb GZIPPED – Aziz Feb 06 '16 at 07:20
  • 1
    @Brettetete: I've reopened it but as I said earlier you can't reuse the value inside the ruleset. There is no other pure CSS solution for it. – Harry Feb 06 '16 at 07:20
  • I found it, it's CSS `attr` function, see my answer - however it is not supported ATM so you'll have to resort to the other methods – Aziz Feb 06 '16 at 08:16

1 Answers1

4

EDIT - CSS attr

After a bit of research, I found that there is a CSS function called attr which is exactly what you are looking for, however, its support is currently limited to the CSS content property and not others, however, it is interesting to keep an eye on it, I reckon it will be the solution of the future

From Moz MDN:

The attr() CSS function is used to retrieve the value of an attribute of the selected element and use it in the style sheet. It can be used on pseudo-elements too and, in this case, the value of the attribute on the pseudo-element's originated element is returned.

Your code would probably look like this:

.c { height: attr(data-height %, 0); }

HTML

<div class="c" data-height="1"></div>
...

This will get the height from the element's data attribute and sets it with the % percentage unit and falls back to 0 if data-height is not found.


Current supported methods:

From the W3 Docs:

6.3.2. Substring matching attribute selectors

Three additional attribute selectors are provided for matching substrings in the value of an attribute:

[att^=val]

Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.

[att$=val]

Represents an element with the att attribute whose value ends with the suffix "val". If "val" is the empty string then the selector does not represent anything.

[att*=val]

Represents an element with the att attribute whose value contains at least one instance of the substring "val". If "val" is the empty string then the selector does not represent anything. Attribute values must be CSS identifiers or strings. [CSS21] The case-sensitivity of attribute names in selectors depends on the document language.

As discussed in the comments, there is no pure CSS solution at the moment, you could try one of the following approaches:

SASS

@for $i from 1 through 100 {
    $height: percentage($i/100);
   .c#{$i} {height: $height;}
}

Output:

.c1 {height: 1%;}

.c2 {height: 2%;}

.c3 {height: 3%;}

...

LESS

.c-gen(@index) when (@index > 0){
  .c@{index}{
    height: @index * 1%;
  }
  .c-gen(@index - 1);
}
.c-gen(100);

LESS code by Harry


Server Side

You could make your server side script output inline CSS for each item

PHP Example:

<?php 
for ($i = 1; $i <= 100; $i++) {
    echo "<span height='".$i."%'>".$i."</span>";
} 
?>

Output

<span height="1%">1</span>
...

jQuery

var i = 0;
$('.c').each(function() {
  i++;
  $(this).attr('height', i + '%');
  //console.log(i); //debug
});
Community
  • 1
  • 1
Aziz
  • 7,685
  • 3
  • 31
  • 54
  • [Here](http://lesscss.org/less-preview/#%7B%22less%22%3A%22.c-gen(%40index)%20when%20(%40index%20%3E%200)%7B%5Cn%20%20.c%40%7Bindex%7D%7B%5Cn%20%20%20%20height%3A%20%40index%20*%201%25%3B%5Cn%20%20%7D%5Cn%20%20.c-gen(%40index%20-%201)%3B%5Cn%7D%5Cn.c-gen(100)%3B%22%7D) is a version using Less. Feel free to add it to your answer as I don't think there is much point in adding another one. – Harry Feb 06 '16 at 07:40