htmlcsscss-selectorscustom-data-attribute

Can I select an element based on a data value greater than comparison?


<div data-age="30">30</div>

Is there a way to have (PURE CSS) div in red when age<18 and in blue where age>18


Solution

  • Now with conditional statement support in the background property, we can do it. This currently has limited support; use Chrome (version 138+) to test:

    @property --a {
      syntax: "<number>";
      inherits: false;
      initial-value: 0; 
    }
    
    .box {
      --a: sign(attr(data-age type(<number>)) - 17);
      background: if(style(--a: 1): blue; else: red);
    
      font-size: 30px;
      padding: 5px;
      display: inline-block;
      font-family: monospace;
      color: #fff;
    }
    
    .box::before {
      content: attr(data-age);
      display: inline-block;
    }
    <div data-age="30" class="box"></div>
    <div data-age="18" class="box"></div>
    <div data-age="9" class="box"></div>
    <div data-age="17" class="box"></div>
    <div data-age="0" class="box"></div>

    Old answer

    Here is an idea based on this previous answer where you can consider CSS variables:

    .box {
      font-size:30px;
      padding:5px;
      display:inline-block;
      font-family:monospace;
      overflow:hidden;
      color:#fff;
      background:
         linear-gradient(red,red) 0 0/100% calc((18 - var(--a))*1px),
         blue;
    }
    .box:before {
      content:attr(style);
      text-indent:-4ch;
      display:inline-block;
    }
    <div style="--a:30" class="box"></div>
    <div style="--a:18" class="box"></div>
    <div style="--a:9 " class="box"></div>
    <div style="--a:17" class="box"></div>
    <div style="--a:0 " class="box"></div>

    You can also do it for text coloration:

    .box {
      font-size:30px;
      padding:5px;
      display:inline-block;
      font-family:monospace;
      overflow:hidden;
      border:5px solid transparent;
      background:
         linear-gradient(#fff,#fff) padding-box,
         linear-gradient(red,red) 0 0/100% calc((18 - var(--a))*1px),
         blue;
    }
    .box:before {
      content:attr(style);
      text-indent:-4ch;
      display:inline-block;
      color:transparent;
      background:
         linear-gradient(red,red) 0 0/100% calc((18 - var(--a))*1px),
         blue;
      -webkit-background-clip: text;
      background-clip: text;
      -webkit-text-fill-color: transparent;
    }
    <div style="--a:30" class="box"></div>
    <div style="--a:18" class="box"></div>
    <div style="--a:9 " class="box"></div>
    <div style="--a:17" class="box"></div>
    <div style="--a:0 " class="box"></div>