Are CSS Variable changes possible upon a radio button's checked selector being triggered?

▼魔方 西西 提交于 2021-02-04 07:28:28

问题


I have the following CodePen: Test LCD with CSS Variables, in which upon clicking labels with specific digits, results in the appropriate LCD segments to be "lit" based on algebraic equations I've determined to mimic a BCD to 7-Segment Display Decoder, in order to simulate an LCD display...

I currently have the first segment's equation mentioned in the CSS. Clicking on a digit in the CSS should theoretically result in the appropriate four --input variables to be populated with a pulse (0 or 1) and then the equation determines the opacity based off the equation for that segment...

Segment A (the top segment) should change as follows:

  • 0: on
  • 1: off
  • 2: on
  • 3: on
  • 4: off
  • 5: on
  • 6: on
  • 7: on
  • 8: on
  • 9: on

Where "on" being an opacity of 1, and "off" being an opacity of 0.05.

However, even though we have the initial default at 0 (which is on), clicking on say, 1 or 4, does not change the segment opacity...

The code is below, could anyone point out what I may be doing wrong? Many thanks in advance...

The HTML:

<div id="led-screen">
    <div class="digit">
        <div class="segment segment-a"></div>
        <div class="segment segment-b"></div>
        <div class="segment segment-c"></div>
        <div class="segment segment-d"></div>
        <div class="segment segment-e"></div>
        <div class="segment segment-f"></div>
        <div class="segment segment-g"></div>
    </div>
</div>
<div id="buttons">
    <label class="digit-button" for="digit-7">7</label>
    <label class="digit-button" for="digit-8">8</label>
    <label class="digit-button" for="digit-9">9</label>
    <label class="digit-button" for="digit-4">4</label>
    <label class="digit-button" for="digit-5">5</label>
    <label class="digit-button" for="digit-6">6</label>
    <label class="digit-button" for="digit-1">1</label>
    <label class="digit-button" for="digit-2">2</label>
    <label class="digit-button" for="digit-3">3</label>
    <label class="digit-button" for="digit-0">0</label>
    <input type="radio" name="digit-radio" id="digit-0" checked="checked"/>
    <input type="radio" name="digit-radio" id="digit-1" />
    <input type="radio" name="digit-radio" id="digit-2" />
    <input type="radio" name="digit-radio" id="digit-3" />
    <input type="radio" name="digit-radio" id="digit-4" />
    <input type="radio" name="digit-radio" id="digit-5" />
    <input type="radio" name="digit-radio" id="digit-6" />
    <input type="radio" name="digit-radio" id="digit-7" />
    <input type="radio" name="digit-radio" id="digit-8" />
    <input type="radio" name="digit-radio" id="digit-9" />
</div>

The CSS:

:root {
    --input_0: 0; /* z */
    --input_1: 0; /* y */
    --input_2: 0; /* x */
    --input_3: 0; /* w */
    --led_r: 42;
    --led_g: 45;
    --led_b: 34;
    --led_o: 0;
    --led_o_base: 0.95;
    --led_o_offset: 0.05;
}

#led-screen {
    background-color: #b7ac90;
    width: 800px;
    height: 200px;
    display: block;
}

#digit-0:checked {
    --input_0: 0;
    --input_1: 0;
    --input_2: 0;
    --input_3: 0;   
}
#digit-1:checked {
    --input_0: 1;
    --input_1: 0;
    --input_2: 0;
    --input_3: 0;   
}
#digit-2:checked {
    --input_0: 0;
    --input_1: 1;
    --input_2: 0;
    --input_3: 0;   
}
#digit-3:checked {
    --input_0: 1;
    --input_1: 1;
    --input_2: 0;
    --input_3: 0;   
}
#digit-4:checked {
    --input_0: 0;
    --input_1: 0;
    --input_2: 1;
    --input_3: 0;   
}
#digit-5:checked {
    --input_0: 1;
    --input_1: 0;
    --input_2: 1;
    --input_3: 0;   
}
#digit-6:checked {
    --input_0: 0;
    --input_1: 1;
    --input_2: 1;
    --input_3: 0;   
}
#digit-7:checked {
    --input_0: 1;
    --input_1: 1;
    --input_2: 1;
    --input_3: 0;   
}
#digit-8:checked {
    --input_0: 0;
    --input_1: 0;
    --input_2: 0;
    --input_3: 1;   
}
#digit-9:checked {
    --input_0: 1;
    --input_1: 0;
    --input_2: 0;
    --input_3: 1;   
}

.digit {
    width: 75px;
    height: 150px;
    float: right;
    margin-right: 50px;
    margin-top: 10px;
    transform: skew(-5deg);
}

.segment-a {
    position: relative;
    left: 0;
    top: 0;
    --led_o: calc(((2 * var(--input_3) * var(--input_2) * var(--input_1) * var(--input_0)) - (2 * var(--input_3) * var(--input_2) * var(--input_0)) - (var(--input_3) * var(--input_1) * var(--input_0)) - (var(--input_3) * var(--input_1)) + (var(--input_3) * var(--input_0)) - (2 * var(--input_2) * var(--input_1) * var(--input_0)) + (var(--input_2) * var(--input_1)) + (2 * var(--input_2) * var(--input_0)) - var(--input_2) + (var(--input_1) * var(--input_0)) - var(--input_0) + 1) * var(--led_o_base) + var(--led_o_offset));
    background-color: rgba(var(--led_r), var(--led_g), var(--led_b), var(--led_o));
    /* 2wxyz-2wxz-wyz-wy+wz-2xyz+xy+2xz-x+yz-z+1 */
}
.segment-b {
    position: relative;
    transform: rotate(90deg);
    left: 41px;
    top: 21px;
}
.segment-c {
    position: relative;
    transform: rotate(90deg);
    left: 41px;
    top: 83px;
}
.segment-d {
    position: relative;
    left: 0;
    top: 104px;
}
.segment-e {
    position: relative;
    transform: rotate(90deg);
    left: -41px;
    top: 43px;
}
.segment-f {
    position: relative;
    transform: rotate(90deg);
    left: -41px;
    top: -59px;
}
.segment-g {
    position: relative;
    left: 0;
    top: -38px;
}

.segment {
    width: 60px;
    height: 20px;
}

回答1:


With your actual code this is not possible. From the specification:

Custom properties are ordinary properties, so they can be declared on any element, are resolved with the normal inheritance and cascade rules, can be made conditional with @media and other conditional rules, can be used in HTML’s style attribute, can be read or set using the CSSOM, etc.

As you can read, Custom properties (i.e. CSS variables) are ordinary properties so if you don't have a parent/child relation to use inheritance you cannot share a value between different elements.

Here is a basic example to better understand the issue:

:root {
  --c:red;
}

.box {
  /* --c:blue (uncomment this to change the color)*/
}

.element {
  background:var(--c);
  height:50px;
}

.extra {
  --c:green; /* this will do nothing */
}
<div class="box">
  <div class="element"></div>
</div>
<div class="extra"></div>

In the above example, changing the custom property inside extra will change nothing for element (this is the equivalent of your input element). If you change the value inside box you can affect the element because it's a parent element and we will have inheritance.

The only way to obtain what you want is to make sure you have a parent/child relation to be able to change the property.

Here is a simplified example that you can adjust to your need:

:root {
  --a:0;
  --b:0;
  --c:0;
}

.wrapper > div{
  height:50px;
  width:50px;
  display:inline-block;
  margin:10px;
}

.a {
  background:rgb(calc(var(--a)*255),0,0);
}
.b {
  background:rgb(calc(var(--b)*255),calc(var(--b)*255),0);
}
.c {
  background:rgb(calc(var(--c)*255),0,calc(var(--c)*255));
}


#n1:checked ~ .wrapper {
  --a:0;
  --b:0;
  --c:1;
}
#n2:checked ~ .wrapper {
  --a:0;
  --b:1;
  --c:0;
}

#n3:checked ~ .wrapper {
  --a:0;
  --b:1;
  --c:1;
}

#n4:checked ~ .wrapper {
  --a:1;
  --b:0;
  --c:0;
}
#n5:checked ~ .wrapper {
  --a:1;
  --b:0;
  --c:1;
}
<input type="radio" name="change" id="n1" >
<input type="radio" name="change" id="n2" >
<input type="radio" name="change" id="n3" >
<input type="radio" name="change" id="n4" >
<input type="radio" name="change" id="n5" >
<div class="wrapper">
  <div class="a"></div>
  <div class="b"></div>
  <div class="c"></div>
</div>

UPDATE

Here is a full example with segment coloration:

:root {
  --s1:1;
  --s2:1;
  --s3:0;
  --s4:1;
  --s5:1;
  --s6:1;
  --s7:1;
}

.wrapper{
  height:150px;
  width:100px;
  display:block;
  margin:10px;
  background:
    linear-gradient(red,red) top         /100% calc(var(--s1)*20px),
    linear-gradient(red,red) bottom      /100% calc(var(--s2)*20px),
    linear-gradient(red,red) center      /100% calc(var(--s3)*20px),
    linear-gradient(red,red) top right   /calc(var(--s4)*20px) 50%,
    linear-gradient(red,red) top left    /calc(var(--s5)*20px) 50%,
    linear-gradient(red,red) bottom right/calc(var(--s6)*20px) 50%,
    linear-gradient(red,red) bottom left /calc(var(--s7)*20px) 50%;
  background-color:#000;
  background-origin:content-box;
  background-repeat:no-repeat;
  padding:20px;
}

#n1:checked ~ .wrapper {
  --s1:0;
  --s2:0;
  --s3:0;
  --s4:1;
  --s5:0;
  --s6:1;
  --s7:0;
}
#n2:checked ~ .wrapper {
  --s1:1;
  --s2:1;
  --s3:1;
  --s4:1;
  --s5:0;
  --s6:0;
  --s7:1;
}

#n3:checked ~ .wrapper {
  --s1:1;
  --s2:1;
  --s3:1;
  --s4:1;
  --s5:0;
  --s6:1;
  --s7:0;
}

#n4:checked ~ .wrapper {
  --s1:0;
  --s2:0;
  --s3:1;
  --s4:1;
  --s5:1;
  --s6:1;
  --s7:0;
}
#n5:checked ~ .wrapper {
  --s1:1;
  --s2:1;
  --s3:1;
  --s4:0;
  --s5:1;
  --s6:1;
  --s7:0;
}

#n6:checked ~ .wrapper {
  --s1:1;
  --s2:1;
  --s3:1;
  --s4:0;
  --s5:1;
  --s6:1;
  --s7:1;
}

#n7:checked ~ .wrapper {
  --s1:1;
  --s2:0;
  --s3:0;
  --s4:1;
  --s5:0;
  --s6:1;
  --s7:0;
}
#n8:checked ~ .wrapper {
  --s1:1;
  --s2:1;
  --s3:1;
  --s4:1;
  --s5:1;
  --s6:1;
  --s7:1;
}

#n9:checked ~ .wrapper {
  --s1:1;
  --s2:1;
  --s3:1;
  --s4:1;
  --s5:1;
  --s6:1;
  --s7:0;
}
<input type="radio" name="change" id="n1" >1
<input type="radio" name="change" id="n2" >2
<input type="radio" name="change" id="n3" >3
<input type="radio" name="change" id="n4" >4
<input type="radio" name="change" id="n5" >5
<input type="radio" name="change" id="n6" >6
<input type="radio" name="change" id="n7" >7
<input type="radio" name="change" id="n8" >8
<input type="radio" name="change" id="n9" >9
<div class="wrapper">
  
</div>

Related question to get more details about CSS variables scope: CSS scoped custom property ignored when used to calc var in outer scope



来源:https://stackoverflow.com/questions/55931363/are-css-variable-changes-possible-upon-a-radio-buttons-checked-selector-being-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!