有没有办法通过单击一个标签来触发两个更改?

Alv*_*oro 30 html css html5 css-selectors css3

我一直在玩HTML和CSS来创建一个简单的2人桌面游戏而不使用任何JavaScript.我使用标签,单选按钮和复选框来创建不同的状态并模仿某些逻辑,以便该部件可以在电路板上移动.

它工作"很好",虽然可用性不是很好.例如,在点击骰子后,磁贴移动,我显示一个按钮以切换到下一个玩家(再次使用标签和复选框控制)...这不是很好,如果它改变了玩家会更好"自动".

问题是<label>只能针对一个元素,我不知道如何只需点击一下就能触发两个"动作"(或副作用).

以下代码是一个MCVE以更好地可视化的问题:有两个玩家(轮流指定的)中,用三个片(由6单选按钮:1个代表的每播放机和瓦)的基板,和两个按钮来改变播放机转(只一个可见).如果您点击转弯按钮,转牌将转到下一位玩家.(这里可以找到更复杂的例子)

问题是用户被迫按下按钮来改变转弯,否则同一个玩家将始终处于活动状态.有没有办法让点击标签时,不仅要激活图块,还要更改转弯?或者在没有的情况下,是否有其他方法可以实现这一目标?(不使用JS)

#p1:checked ~ [for=p1],
#p1:checked ~ [for^=tile-p2],
#p1:checked ~ [name^=tile-p2],
#p2:checked ~ [for=p2],
#p2:checked ~ [for^=tile-p1],
#p2:checked ~ [name^=tile-p1]
{ 
  display: none; 
}

/* more rules to hide/show more elements */
Run Code Online (Sandbox Code Playgroud)
<h1>Players:</h1>
<input type="radio" id="p1" name="player" checked /> P1
<input type="radio" id="p2" name="player" /> P2

<h1>Board: </h1>
Player 1:
<input type="radio" id="tile-p1-1" name="tile-p1" checked />
<label for="tile-p1-1">P1 to 1</label>
<input type="radio" id="tile-p1-2" name="tile-p1" />
<label for="tile-p1-2">P1 to 2</label>
<input type="radio" id="tile-p1-3" name="tile-p1" />
<label for="tile-p1-3">P1 to 3</label>
<br/>
Player 2:
<input type="radio" id="tile-p2-1" name="tile-p2" checked />
<label for="tile-p2-1">P2 to 1</label>
<input type="radio" id="tile-p2-2" name="tile-p2" />
<label for="tile-p2-2">P2 to 2</label>
<input type="radio" id="tile-p2-3" name="tile-p2" />
<label for="tile-p2-3">P2 to 3</label>

<h1>Change of turn:</h1>
<label for="p2">Change to Player 2</label>
<label for="p1">Change to Player 1</label>
Run Code Online (Sandbox Code Playgroud)

有没有办法通过点击一个<label>或两个来触发两个"状态变化" <a>


一些尝试解决这个问题:

我尝试在<a>内部设置一个<label>能够触发两个可读的变化::target:checked(使用:target我将控制玩家的回合,并且:选中:选中它将是棋子的位置).它似乎是有效的HTML(至少根据W3C验证器),但它并没有真正起作用.例如,在下一个片段中,单击第一个链接将突出显示文本,单击第二个链接将标记该框,并且(我希望)单击第三个将同时执行这两个...但它不会:

#test:target {
  color: red;
}

#cb:checked

a, label {
  display: block;
  text-decoration: underline;
  color: blue;
}
Run Code Online (Sandbox Code Playgroud)
<input type="checkbox" id="cb" />
<div id="test">TEST</div>

<a href="#test">Highlight test</a>
<label for="cb">Check the box</label>
<label for="cb">
  <a href="#test">Highlight test AND check the box</a>
</label>
Run Code Online (Sandbox Code Playgroud)

我也试过玩不同的伪类::checked:invalid.它对复选框没有太大作用,因为它们都会同时应用,而且从我的测试中,required它不适用于单个收音机(但我可能做错了):

div {
  color: purple;
}

#radio1:checked ~ div {
  color: blue;
}

#radio2:checked ~ div {
  color: fuchsia;
}

#radio1:invalid ~ div {
  color: red;
}

#radio1:invalid + #radio2:checked ~ div {
  color: green;
}
Run Code Online (Sandbox Code Playgroud)
<input type="radio" name="radio1" id="radio1" required />
<input type="radio" name="radio1" id="radio2" />

<div>Text to be green if radio2 is checked</div>
Run Code Online (Sandbox Code Playgroud)

Tem*_*fif 9

一个想法是考虑:focus标签上的状态,允许您触发两个更改.唯一的缺点是:focus只有on mousedown和disabled 才会启用状态mouseup.

这是一个例子

label:focus + #test {
 color: red;
}

label {
  display: block;
  text-decoration: underline;
  color: blue;
}
Run Code Online (Sandbox Code Playgroud)
<input type="checkbox" id="cb" >

<label for="cb"  tabindex=-1>Check the box and highlight the text</label>
<div id="test">TEST</div>
Run Code Online (Sandbox Code Playgroud)

UPDATE

使用上述逻辑并考虑骰子游戏的初始代码这里是使用动画的想法.诀窍是创建一个具有2个状态的暂停动画,并且:focus我使动画运行以便在状态之间切换.

当然,这不是100%准确,因为它取决于点击的速度,但可以考虑一个想法:

.container {
  position: relative;
}

label {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 50px;
  height: 50px;
  line-height: 50px;
  background: #eeeeee;
  text-align: center;
  animation: changeOrder 0.6s infinite;
}

@keyframes changeOrder {
  from { z-index: 6;}
   to { z-index: 1; }
}
label:nth-of-type(1) { animation-delay: 0s; }
label:nth-of-type(2) { animation-delay: -0.1s; }
label:nth-of-type(3) { animation-delay: -0.2s; }
label:nth-of-type(4) { animation-delay: -0.3s; }
label:nth-of-type(5) { animation-delay: -0.4s; }
label:nth-of-type(6) { animation-delay: -0.5s; }


label:active {
  /*Mandatory to break the stacking context and allow 
       the pseudo element to be above everything*/
  position: static;
  /*For illustration*/
  margin-left: 50px;
  background: red;
}

label:active::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  z-index: 10;
}
.player {
  display:inline-block;
  margin-top:80px;
}

.player:before {
 content:"Player One";
 animation: player .3s infinite step-end;
 animation-play-state: paused;
}

label:focus ~ .player:before{
 animation-play-state: running;
}

@keyframes player {
  0% {
     content:"Player One";
  }
  50% {
     content:"Player Two";
  }

}
Run Code Online (Sandbox Code Playgroud)
<input type="radio" name="cb" id="cb1" value="1">
<input type="radio" name="cb" id="cb2" value="2">
<input type="radio" name="cb" id="cb3" value="3">
<input type="radio" name="cb" id="cb4" value="4">
<input type="radio" name="cb" id="cb5" value="5">
<input type="radio" name="cb" id="cb6" value="6">
<div class="container">
  <label for="cb1" tabindex="-1">1</label>
  <label for="cb2" tabindex="-1">2</label>
  <label for="cb3" tabindex="-1">3</label>
  <label for="cb4" tabindex="-1">4</label>
  <label for="cb5" tabindex="-1">5</label>
  <label for="cb6" tabindex="-1">6</label>
  <span class="player" ></span>
</div>
Run Code Online (Sandbox Code Playgroud)

如果你想要一个静态的永久效果,它非常简单,因为你只需要使持续时间非常小并使用forwards.

.container {
  position: relative;
}

label {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 50px;
  height: 50px;
  line-height: 50px;
  background: #eeeeee;
  text-align: center;
  animation: changeOrder 0.6s infinite;
}

@keyframes changeOrder {
  from { z-index: 6;}
   to { z-index: 1; }
}
label:nth-of-type(1) { animation-delay: 0s; }
label:nth-of-type(2) { animation-delay: -0.1s; }
label:nth-of-type(3) { animation-delay: -0.2s; }
label:nth-of-type(4) { animation-delay: -0.3s; }
label:nth-of-type(5) { animation-delay: -0.4s; }
label:nth-of-type(6) { animation-delay: -0.5s; }


label:active {
  /*Mandatory to break the stacking context and allow 
       the pseudo element to be above everything*/
  position: static;
  /*For illustration*/
  margin-left: 50px;
  background: red;
}

label:active::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  z-index: 10;
}
.player {
  display:inline-block;
  margin-top:80px;
}

.player:before {
 content:"Click the dice!";
 animation: player .1s forwards;
 animation-play-state: paused;
}

label:focus ~ .player:before{
 animation-play-state: running;
}

@keyframes player {
  2%,100% {
     content:"Dice clicked!";
  }

}
Run Code Online (Sandbox Code Playgroud)
<input type="radio" name="cb" id="cb1" value="1">
<input type="radio" name="cb" id="cb2" value="2">
<input type="radio" name="cb" id="cb3" value="3">
<input type="radio" name="cb" id="cb4" value="4">
<input type="radio" name="cb" id="cb5" value="5">
<input type="radio" name="cb" id="cb6" value="6">
<div class="container">
  <label for="cb1" tabindex="-1">1</label>
  <label for="cb2" tabindex="-1">2</label>
  <label for="cb3" tabindex="-1">3</label>
  <label for="cb4" tabindex="-1">4</label>
  <label for="cb5" tabindex="-1">5</label>
  <label for="cb6" tabindex="-1">6</label>
  <span class="player" ></span>
</div>
Run Code Online (Sandbox Code Playgroud)

更新2

这是另一个依赖于过渡并且更准确的想法但是我需要依赖两个骰子,因为每个骰子都会触发一个特定的状态以便改变文本,所以我们需要找到一种方法如何使两个骰子相互叠加并点击更改订单:

.container {
  position:relative;
  margin-top:20px;
  overflow:hidden;
  min-height:50px;
}

label {
  display:block;
  position: absolute;
  top: 0;
  left: 0;
  width: 50px;
  height: 50px;
  line-height: 50px;
  background: #eeeeee;
  text-align: center;
  animation: changeOrder 0.6s infinite;
}
label:active {
  /*Mandatory to break the stacking context and allow 
       the pseudo element to be above everything*/
  position: static;
  width:0;
  height:0;
  overflow:hidden;
}

label:active::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  z-index: 10;
}

@keyframes changeOrder {
  from { z-index: 6;}
   to { z-index: 1; }
}
label:nth-of-type(1),label:nth-of-type(7) { animation-delay: 0s; }
label:nth-of-type(2),label:nth-of-type(8) { animation-delay: -0.1s; }
label:nth-of-type(3),label:nth-of-type(9) { animation-delay: -0.2s; }
label:nth-of-type(4),label:nth-of-type(10) { animation-delay: -0.3s; }
label:nth-of-type(5),label:nth-of-type(11) { animation-delay: -0.4s; }
label:nth-of-type(6),label:nth-of-type(12) { animation-delay: -0.5s; }



label.second {
  left:100px;
}

.player {
  display:inline-block;
  margin-top:80px;
  height: 18px;
  overflow:hidden;
}
.player span {
  display:block;
  margin-top:-18px;
  transition:1000s;
}



label.first:focus ~ .player span{
  margin-top:0;
  transition:0s;
}
label.second:focus ~ .player span{
  margin-top:-36px;
  transition:0s;
}
Run Code Online (Sandbox Code Playgroud)
<input type="radio" name="cb" id="cb1" value="1">
<input type="radio" name="cb" id="cb2" value="2">
<input type="radio" name="cb" id="cb3" value="3">
<input type="radio" name="cb" id="cb4" value="4">
<input type="radio" name="cb" id="cb5" value="5">
<input type="radio" name="cb" id="cb6" value="6">
<div class="container">
<label class="first" for="cb1" tabindex="-1">1</label>
<label class="first" for="cb2" tabindex="-1">2</label>
<label class="first" for="cb3" tabindex="-1">3</label>
<label class="first" for="cb4" tabindex="-1">4</label>
<label class="first" for="cb5" tabindex="-1">5</label>
<label class="first" for="cb6" tabindex="-1">6</label>
  
<label class="second" for="cb1" tabindex="-1">1</label>
<label class="second" for="cb2" tabindex="-1">2</label>
<label class="second" for="cb3" tabindex="-1">3</label>
<label class="second" for="cb4" tabindex="-1">4</label>
<label class="second" for="cb5" tabindex="-1">5</label>
<label class="second" for="cb6" tabindex="-1">6</label>

<div class="player">
 <span> Player One Clicked<br>
  Which player?<br>
  Player Two clicked
 </span>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)

作为旁注,我使用过:focus,:active所以我们可以依赖于状态,因为它们可以一起触发,即使是嵌套元素:

div {
  display:block;
  outline: none;
  padding:10px 0;
}
.first:active + div{
  color:red
}
.second:active + div{
  color:red
}

.first:focus + div{
  border:1px solid red
}
.second:focus + div{
  border:1px solid red
}
Run Code Online (Sandbox Code Playgroud)
<div class="first" tabindex=-1 >
  Click me (only last text will change)
  <div class="second" tabindex=-1 >
    Click me (both text will change)
  </div>
  <div>
    I will be updated
  </div>
</div>
<div>
  I will be updated
</div>
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!这种方法不是我所需要的100%,但它帮助我寻找并寻找模仿我想要的替代方案. (2认同)