【问题标题】:Different styles depending if the number of checked boxes is odd or even不同的样式取决于复选框的数量是奇数还是偶数
【发布时间】:2019-01-19 10:21:47
【问题描述】:

我正在使用 CSS 和 SASS 运行测试,并且有一系列相同的选择器重复和嵌套多次,我想简化我的代码,但不知道该怎么做(应该可以,但我想不通)。

主要想法是我有很多单选按钮(84 个,在 42 组中,每组 2 个同名),并且想要根据检查的单选按钮的数量是奇数还是偶数来为元素添加样式。

为此,现在我在 SASS 中使用 & 来生成当前选择器,并将其与兄弟选择器 ~ 嵌套(顺序并不重要,只是检查的无线电数量)。这是 SASS 代码的简化版本(只有 10 个组):

.rd:checked {
  & ~ &,
  & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & {
    ~ #oddeven {
      background: red; // red if even
    }
  }
  &,
  & ~ & ~ &,
  & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ &,
  & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & {
    ~ #oddeven {
      background: green; // green if odd 
    }
  }
}

这会生成以下 CSS 代码(我添加了 HTML,因此我想要的效果是可见的):

.rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: red;
}

.rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven,
.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: green;
}

#oddeven {
  color: white;
  background: red;
  padding: 1em;
  position: absolute;
  top: 50px;
  right: 0;
  left: 100px;
}
<input type="radio" class="rd" name="rd0" />
<input type="radio" class="rd" name="rd0" /><br/>
<input type="radio" class="rd" name="rd1" />
<input type="radio" class="rd" name="rd1" /><br/>
<input type="radio" class="rd" name="rd2" />
<input type="radio" class="rd" name="rd2" /><br/>
<input type="radio" class="rd" name="rd3" />
<input type="radio" class="rd" name="rd3" /><br/>
<input type="radio" class="rd" name="rd4" />
<input type="radio" class="rd" name="rd4" /><br/>
<input type="radio" class="rd" name="rd5" />
<input type="radio" class="rd" name="rd5" /><br/>
<input type="radio" class="rd" name="rd6" />
<input type="radio" class="rd" name="rd6" /><br/>
<input type="radio" class="rd" name="rd7" />
<input type="radio" class="rd" name="rd7" /><br/>
<input type="radio" class="rd" name="rd8" />
<input type="radio" class="rd" name="rd8" /><br/>
<input type="radio" class="rd" name="rd9" />
<input type="radio" class="rd" name="rd9" />

<div id="oddeven">
  RED background if even number of checked radios (or nothing).<br/>
  GREEN background if odd number of checked radios.
</div>

有没有办法减少/简化 SASS 代码以使其更简洁?现在的情况,很容易出错,而且添加新规则很复杂(针对新的单选按钮集)。

另外,是否有可能以更好的方式做到这一点? (可能使用 mixin 或以某种方式实际嵌套)。我没有使用&amp;~,而是尝试使用CSS 计数器,但我没有找到根据计数器的值添加样式的方法。

注意:我不想使用 JavaScript,只需要 HTML 和 CSS/SASS 来生成规则。

【问题讨论】:

  • 这里有 logic,最好用 JavaScript 处理。如果你坚持用 CSS 来做,你会得到像这样混乱的结果。
  • @NiettheDarkAbsol 我明白这一点。我不介意生成的代码是否混乱。我更关心的是有一个更清洁/更容易维护 SASS 代码。这是一个非常重复的结构,所以可能有一种比我这样做更简单的方法。
  • 在这一点上,我明白这个问题可能适合代码审查......
  • 哈哈 :p 另一个 ;)
  • @TemaniAfif 是的。对于一个更简单的游戏,我发现计算选中的单选按钮的数量是一种自动从一个玩家切换到另一个玩家的替代方法。

标签: css sass css-selectors


【解决方案1】:

您可以使用for loopstring interpolation 和串联生成那些&amp; ~ &amp; ... 选择器:

// function to repeat string:
@function r($string, $times) { 
  $result: "";
  @if $times >= 1 {
    @for $i from 1 through $times {
      $result: $result + $string;
    }
  }
  @return $result;
}

// generate rules:
@for $n from 1 through 10 {
  .rd:checked {
    $s: r(' ~ &', $n - 1);
    $s: '&' + $s;
    @if ($n % 2 == 0) {
      #{$s} ~ #oddeven {
        background: red;
      }
    } @elseif ($n % 2 == 1) {
      #{$s} ~ #oddeven {
        background: green;
      }
    }
  }
}

#oddeven {
  color: white;
  background: red;
  padding: 1em;
  position: absolute;
  top: 50px;
  right: 0;
  left: 100px;
}

我知道它不会产生与您完全相同的 CSS,但也可以实现更多的播放。

工作演示:

.rd:checked ~ #oddeven {
  background: green;
}

.rd:checked ~ .rd:checked ~ #oddeven {
  background: red;
}

.rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: green;
}

.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: red;
}

.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: green;
}

.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: red;
}

.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: green;
}

.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: red;
}

.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: green;
}

.rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ .rd:checked ~ #oddeven {
  background: red;
}

#oddeven {
  color: white;
  background: red;
  padding: 1em;
  position: absolute;
  top: 50px;
  right: 0;
  left: 100px;
}
<input type="radio" class="rd" name="rd0" />
<input type="radio" class="rd" name="rd0" /><br/>
<input type="radio" class="rd" name="rd1" />
<input type="radio" class="rd" name="rd1" /><br/>
<input type="radio" class="rd" name="rd2" />
<input type="radio" class="rd" name="rd2" /><br/>
<input type="radio" class="rd" name="rd3" />
<input type="radio" class="rd" name="rd3" /><br/>
<input type="radio" class="rd" name="rd4" />
<input type="radio" class="rd" name="rd4" /><br/>
<input type="radio" class="rd" name="rd5" />
<input type="radio" class="rd" name="rd5" /><br/>
<input type="radio" class="rd" name="rd6" />
<input type="radio" class="rd" name="rd6" /><br/>
<input type="radio" class="rd" name="rd7" />
<input type="radio" class="rd" name="rd7" /><br/>
<input type="radio" class="rd" name="rd8" />
<input type="radio" class="rd" name="rd8" /><br/>
<input type="radio" class="rd" name="rd9" />
<input type="radio" class="rd" name="rd9" />

<div id="oddeven">
  RED background if even number of checked radios (or nothing).<br/>
  GREEN background if odd number of checked radios.
</div>

【讨论】:

  • 我试过了,效果很好。它可能有点晦涩,但它简化了整个事情,并且更容易添加新的单选按钮集。谢谢!
  • 有一个cross post in Stack Overflow en español。如果您想在那里回复(必须是西班牙语),或者我可以翻译您的答案并将其作为引用此帖子的 wiki 答案分享。
  • 很高兴我能帮上忙 :) 不幸的是我不会说西班牙语,请翻译并在那里分享我的答案。 :)
  • 我创建了 answer on Stack Overflow en español 以感谢您的帖子。我还在small project I developed with it 上记下了这个答案。再次感谢你的帮助! :)
  • 不客气! :) 感谢您的翻译和感谢!而且那个项目看起来很棒:)
【解决方案2】:

如果没有像您在此处所做的那样手动执行此操作,目前在 CSS 中是不可能的。

但是,当 CSS4 选择器可用时,您可以同时使用 :nth-child():last-child

.rd:last-of-type:nth-child(even of :checked) ~ #oddeven {
  background: red;
}
.rd:last-of-type:nth-child(odd of :checked) ~ #oddeven {
  background: green;
}

#oddeven {
  color: white;
  background: red;
  padding: 1em;
  position: absolute;
  top: 50px;
  right: 0;
  left: 100px;
}
<input type="radio" class="rd" name="rd0" />
<input type="radio" class="rd" name="rd0" /><br/>
<input type="radio" class="rd" name="rd1" />
<input type="radio" class="rd" name="rd1" /><br/>
<input type="radio" class="rd" name="rd2" />
<input type="radio" class="rd" name="rd2" /><br/>
<input type="radio" class="rd" name="rd3" />
<input type="radio" class="rd" name="rd3" /><br/>
<input type="radio" class="rd" name="rd4" />
<input type="radio" class="rd" name="rd4" /><br/>
<input type="radio" class="rd" name="rd5" />
<input type="radio" class="rd" name="rd5" /><br/>
<input type="radio" class="rd" name="rd6" />
<input type="radio" class="rd" name="rd6" /><br/>
<input type="radio" class="rd" name="rd7" />
<input type="radio" class="rd" name="rd7" /><br/>
<input type="radio" class="rd" name="rd8" />
<input type="radio" class="rd" name="rd8" /><br/>
<input type="radio" class="rd" name="rd9" />
<input type="radio" class="rd" name="rd9" />

<div id="oddeven">
  RED background if even number of checked radios (or nothing).<br/>
  GREEN background if odd number of checked radios.
</div>

【讨论】:

  • 你确定它会起作用吗? last-of-type 考虑一个类型而不是一个类我猜.. 我也没有在这里得到第 n 个子逻辑
  • 感谢您的回答和分享这种方法,这真的很有趣。我正在审查这个的定义,并且不考虑缺乏浏览器支持,似乎要让它工作,我需要在最后添加一个新的选中单选按钮,不是吗?由于可能发生最后一个类型没有被检查,那么第二个伪类将不会被实现。
猜你喜欢
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 2016-09-23
  • 1970-01-01
  • 2015-03-03
  • 2011-11-12
  • 2015-05-31
  • 1970-01-01
相关资源
最近更新 更多