30 votes

Existe-t-il un moyen de déclencher deux modifications en cliquant sur une seule étiquette?

J'ai été jouer avec le langage HTML et CSS pour créer un simple 2-joueur de jeu de plateau sans utiliser de JavaScript. J'utilise des étiquettes, des boutons radio et des cases à cocher pour créer différents états et imiter certains la logique de sorte que la pièce se déplacer autour de la carte.

Il fonctionne "bien", même si l'ergonomie n'est pas grande. Par exemple, après avoir cliqué sur le dé, le carreau se déplace, et je l'affichage d'un bouton pour changer le joueur suivant (contrôlé à nouveau avec une étiquette et une case à cocher)... ce qui n'est pas grand, il serait mieux si elle a changé de joueur "automatiquement".

Le problème est que l' <label> ne cible qu'un élément, et je ne sais pas comment déclencher deux "actions" (ou effets secondaires) avec un seul clic.

Le code suivant est un mcve afin de mieux visualiser le problème: il y a deux joueurs (spécifié par tours), une carte avec trois carreaux (représenté par 6 boutons radio: 1 par joueur et carrelage), et deux boutons pour changer de joueur de tour (seul visible). Si vous cliquez sur le bouton modifier, le tour va passer au joueur suivant. (Un exemple plus complexe peut être trouvé ici)

Le problème est que les utilisateurs sont obligés d'appuyer sur le bouton pour changer de tour, sinon le même joueur sera toujours active. Est-il un moyen de faire en sorte que lorsqu'une étiquette est cliqué, pas seulement la tuile est activé, mais aussi le tour est changé? Ou, en son absence, est-il une autre solution pour y parvenir? (sans utiliser de 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 */
<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>

Est-il possible de déclencher deux "changements d'état" en cliquant sur un seul <label> ou <a>?


Quelques tentatives de résoudre ce:

J'ai essayé de mettre un <a> à l'intérieur d'un <label> à être en mesure de déclencher deux lisible changements: :target et :checked (avec l' :cible, je le contrôle de la tour du joueur, et avec le :vérifié ce serait la position de l'instrument). Il semble être valide HTML (au moins selon le validateur du W3C), mais ça ne fonctionne pas vraiment. Par exemple, dans le prochain extrait, en cliquant sur le premier lien, mettez en surbrillance le texte, en cliquant sur la deuxième marque de la boîte, et (j'espère) en cliquant sur le troisième serait de faire les deux... mais il n'est pas:

#test:target {
  color: red;
}

#cb:checked

a, label {
  display: block;
  text-decoration: underline;
  color: blue;
}
<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>

J'ai aussi essayé de jouer avec les différents pseudo-classes: :checked et :invalid. Il n'a pas fait beaucoup pour une case à cocher, car ils s'appliquerait dans le même temps, et de mes tests, required ne s'applique pas à une seule radio (mais j'ai peut-être fait quelque chose de mal):

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;
}
<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>

10voto

Temani Afif Points 69370

Une idée est de considérer que l' :focus de l'état sur l'étiquette qui vous permettra de déclencher des deux modifications. Le seul inconvénient est que l' :focus de l'état ne sera activé que sur l' mousedown et désactivé à l' mouseup.

Voici un exemple

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

label {
  display: block;
  text-decoration: underline;
  color: blue;
}
<input type="checkbox" id="cb" >

<label for="cb"  tabindex=-1>Check the box and highlight the text</label>
<div id="test">TEST</div>

Mise à JOUR

À l'aide de la logique ci-dessus et compte tenu de la code initial du jeu de dés, voici une idée à l'aide de l'animation. L'astuce consiste à créer une pause d'animation avec 2 états et sur l' :focus - je faire de l'animation en cours d'exécution afin de basculer entre les états.

Bien sûr, ce n'est pas précis à 100%, car cela dépendra de la vitesse du clic, mais il peut être une idée à envisager:

.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";
  }

}
<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>

Dans le cas où vous voulez une statique permanent effet, c'est assez simple, car vous avez seulement besoin de faire de la durée très petites et utiliser 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!";
  }

}
<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>

Mise à JOUR 2

Voici une autre idée qui s'appuient sur la transition et est plus précis, MAIS j'ai besoin de compter sur deux dés que chacun va déclencher un état spécifique afin de changer le texte, nous avons donc besoin de trouver un moyen de faire les deux dés au-dessus les uns des autres et de modifier leur ordre sur cliquez sur:

.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;
}
<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>

Comme une note de côté, je l'ai utilisé, :focus et :active , de sorte que nous pouvons compter sur ces états, car ils peuvent être déclenchés ensemble, même avec élément imbriqué:

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
}
<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>

4voto

cyr-x Points 7948

Concernant votre question, il est impossible de cibler plusieurs éléments via l' for attribut html d'une étiquette de l'élément.

Mais si un rechargement de la page est très bien pour commencer un nouveau jeu, vous n'aurez pas vraiment besoin de cibler deux entrées à la fois avec une étiquette.

Voici un simple jeu de dés en utilisant uniquement CSS:

.board {
  width: 100%;
  height: 200px;
  background: green;
  position: relative;
}

.board .title {
  color: white;
  font-weight: 300;
  text-align: center;
}

.board .title #p2-turn {
  display: none;
}

.dice {
  width: 50px;
  height: 50px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  background: white;
  cursor: pointer;
  text-align: center;
}

.dice .pips {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  animation: diceRoll 600ms infinite;
  z-index: 10;
}

.dice:active .pips {
  animation-play-state: paused;
}


.dice .pips:nth-child(2) { animation-delay: 100ms; }
.dice .pips:nth-child(3) { animation-delay: 200ms; }
.dice .pips:nth-child(4) { animation-delay: 300ms; }
.dice .pips:nth-child(5) { animation-delay: 400ms; }
.dice .pips:nth-child(6) { animation-delay: 500ms; }

.dice.dice--p2 {
  display: none;
}

.results {
  position: absolute;
  left: 0;
  top: 30px;
  bottom: 0;
  right: 0;
  background: black;
  color: white;
  display: none;
  text-align: center;
  line-height: 100px;
}

.results > .result {
  display: none;
}


@keyframes diceRoll {
  from { 
    z-index: 6;
  }
  to { 
    z-index: 1;
  }
}

/* LOGIC */

[name="p1-result"]:checked ~ .board .title #p1-turn {
  display: none;
}

[name="p1-result"]:checked ~ .board .title #p2-turn {
  display: block;
}

[name="p1-result"]:checked ~ .board .dice--p1 {
  display: none;
}

[name="p1-result"]:checked ~ .board .dice--p2 {
  display: block;
}

[name="p1-result"]:checked ~ [name="p2-result"]:checked ~ .results {
  display: block;
}



#p1-result-2:checked ~ #p2-result-1:checked ~ .results #p1-results,
#p1-result-3:checked ~ #p2-result-1:checked ~ .results #p1-results,
#p1-result-4:checked ~ #p2-result-1:checked ~ .results #p1-results,
#p1-result-5:checked ~ #p2-result-1:checked ~ .results #p1-results,
#p1-result-6:checked ~ #p2-result-1:checked ~ .results #p1-results,
#p1-result-3:checked ~ #p2-result-2:checked ~ .results #p1-results,
#p1-result-4:checked ~ #p2-result-2:checked ~ .results #p1-results,
#p1-result-5:checked ~ #p2-result-2:checked ~ .results #p1-results,
#p1-result-6:checked ~ #p2-result-2:checked ~ .results #p1-results,
#p1-result-4:checked ~ #p2-result-3:checked ~ .results #p1-results,
#p1-result-5:checked ~ #p2-result-3:checked ~ .results #p1-results,
#p1-result-6:checked ~ #p2-result-3:checked ~ .results #p1-results,
#p1-result-5:checked ~ #p2-result-4:checked ~ .results #p1-results,
#p1-result-6:checked ~ #p2-result-4:checked ~ .results #p1-results,
#p1-result-6:checked ~ #p2-result-5:checked ~ .results #p1-results,

#p1-result-1:checked ~ #p2-result-2:checked ~ .results #p2-results,
#p1-result-1:checked ~ #p2-result-3:checked ~ .results #p2-results,
#p1-result-1:checked ~ #p2-result-4:checked ~ .results #p2-results,
#p1-result-1:checked ~ #p2-result-5:checked ~ .results #p2-results,
#p1-result-1:checked ~ #p2-result-6:checked ~ .results #p2-results,
#p1-result-2:checked ~ #p2-result-3:checked ~ .results #p2-results,
#p1-result-2:checked ~ #p2-result-4:checked ~ .results #p2-results,
#p1-result-2:checked ~ #p2-result-5:checked ~ .results #p2-results,
#p1-result-2:checked ~ #p2-result-6:checked ~ .results #p2-results,
#p1-result-3:checked ~ #p2-result-4:checked ~ .results #p2-results,
#p1-result-3:checked ~ #p2-result-5:checked ~ .results #p2-results,
#p1-result-3:checked ~ #p2-result-6:checked ~ .results #p2-results,
#p1-result-4:checked ~ #p2-result-5:checked ~ .results #p2-results,
#p1-result-4:checked ~ #p2-result-6:checked ~ .results #p2-results,
#p1-result-5:checked ~ #p2-result-6:checked ~ .results #p2-results {
  display: block;
}

#p1-result-1:checked ~ #p2-result-1:checked ~ .results #draw,
#p1-result-2:checked ~ #p2-result-2:checked ~ .results #draw,
#p1-result-3:checked ~ #p2-result-3:checked ~ .results #draw,
#p1-result-4:checked ~ #p2-result-4:checked ~ .results #draw,
#p1-result-5:checked ~ #p2-result-5:checked ~ .results #draw,
#p1-result-6:checked ~ #p2-result-6:checked ~ .results #draw {
  display: block;
}
<input type="radio" name="p1-result" id="p1-result-1" value="1">
<input type="radio" name="p1-result" id="p1-result-2" value="2">
<input type="radio" name="p1-result" id="p1-result-3" value="3">
<input type="radio" name="p1-result" id="p1-result-4" value="4">
<input type="radio" name="p1-result" id="p1-result-5" value="5">
<input type="radio" name="p1-result" id="p1-result-6" value="6">

<input type="radio" name="p2-result" id="p2-result-1" value="1">
<input type="radio" name="p2-result" id="p2-result-2" value="2">
<input type="radio" name="p2-result" id="p2-result-3" value="3">
<input type="radio" name="p2-result" id="p2-result-4" value="4">
<input type="radio" name="p2-result" id="p2-result-5" value="5">
<input type="radio" name="p2-result" id="p2-result-6" value="6">


<div class="board">
  <h2 class="title">
    Player
    <span class="turn" id="p1-turn">1</span>
    <span class="turn" id="p2-turn">2</span>
    turn 
  </h2>
  <div class="dice dice--p1">
    roll
    <label class="pips" for="p1-result-1"></label>
    <label class="pips" for="p1-result-2"></label>
    <label class="pips" for="p1-result-3"></label>
    <label class="pips" for="p1-result-4"></label>
    <label class="pips" for="p1-result-5"></label>
    <label class="pips" for="p1-result-6"></label>
  </div>

  <div class="dice dice--p2">
    <label class="pips" for="p2-result-1"></label>
    <label class="pips" for="p2-result-2"></label>
    <label class="pips" for="p2-result-3"></label>
    <label class="pips" for="p2-result-4"></label>
    <label class="pips" for="p2-result-5"></label>
    <label class="pips" for="p2-result-6"></label>
  </div>
</div>

<div class="results">
  <div class="result" id="p1-results">Player 1 won!</div>
  <div class="result" id="p2-results">Player 2 won!</div>
  <div class="result" id="draw">Draw!</div>
</div>

Ce pourrait être facilement adapté pour afficher les joueurs actuels de tuiles et de determain un certain résultat.

4voto

Chris Scheurle Points 111

Édité réponse pour refléter les modifications apportées à la question initiale:

Essayez de définir les différents états où chaque état reflète à la fois le joueur actif et de la position des pièces, comme:

input {
  position: absolute;
  bottom: 1em;
  right: 1em;
  margin: 2px;
}

.status {
  margin: 1em;
  font-family: sans-serif;
  display: none;
}
.active1:checked ~ #status1,
.active2:checked ~ #status2,
.win1:checked ~ #status3,
.win2:checked ~ #status4 {
  display: block
}

#board {
  position: relative;
  top: 0;
  left: 0;
  border: 1px solid black;
  padding: 2px 3px;
  margin: 1em auto;
  width: 27em;
  height: 12em;
}
#board:before {
  display: block;
  position: absolute;
  bottom: 0;
  left: 0;
  margin: 2px;
  height: 9em;
  width: 9em;
  background: silver;
  content: ' ';
}
#board:after {
  display: block;
  position: absolute;
  bottom: 0;;
  right: 0;
  margin: 2px;
  height: 9em;
  width: 9em;
  background: silver;
  content: ' ';
}

.piece {
  position: absolute;
  z-index: 2;
  width: 1em;
  height: 1em;
  padding: 1em;
  margin: 1px;
  border-radius: 666em;
  line-height: 1em;
  text-align: center;
}
#piece1 {
  background: white;
  color: black;
  border: 1px solid black;
}
#piece2 {
  background: black;
  color: white;
  border: 1px solid white;
}
.win2:checked ~ #piece1,
.win1:checked ~ #piece2 {
  display: none;
}
.active1:checked ~ #piece1,
.active2:checked ~ #piece2 {
  border: 1px solid red;
}
.p1_1:checked ~ #piece1,
.p2_1:checked ~ #piece2 {
  left: 3em;
  bottom: 3em;
}
.p1_2:checked ~ #piece1,
.p2_2:checked ~ #piece2 {
  left: 12em;
  bottom: 3em;
}
.p1_3:checked ~ #piece1,
.p2_3:checked ~ #piece2 {
  right: 3em;
  bottom: 3em;
}

label {
  display: none;
  position: absolute;
  bottom: 0;
  z-index: 3;
  width: 9em;
  height: 9em;
  margin: 2px;
  text-indent: -666666em;
  /*background: green;*/
  opacity: .25;
  cursor: pointer;
}
label.pos1 {
  left: 0;
}
label.pos2 {
  left: 9em;
  margin: 2px 3px;
}
label.pos3 {
  right: 0
}
label.restart {
   top: 0;
   left: 0;
   width: 27em;
   height: 12em;
   padding: 0 1px;
   /*background: orange;*/
}
label.win1,
label.win2 {
  /*background: blue;*/
}
.active1.p2_1:checked ~ label.active1.opp1,
.active1.p2_2:checked ~ label.active1.opp2,
.active1.p2_3:checked ~ label.active1.opp3,
.active2.p1_1:checked ~ label.active2.opp1,
.active2.p1_2:checked ~ label.active2.opp2,
.active2.p1_3:checked ~ label.active2.opp3 {
  display: block;
}
.active1.p1_1:checked ~ label.active1.pos1,
.active1.p1_2:checked ~ label.active1.pos2,
.active1.p1_3:checked ~ label.active1.pos3,
.active2.p2_1:checked ~ label.active2.pos1,
.active2.p2_2:checked ~ label.active2.pos2,
.active2.p2_3:checked ~ label.active2.pos3 {
  display: none;
}
.active1.p2_1:checked ~ label.win1.pos1,
.active1.p2_2:checked ~ label.win1.pos2,
.active1.p2_3:checked ~ label.win1.pos3,
.active2.p1_1:checked ~ label.win2.pos1,
.active2.p1_2:checked ~ label.win2.pos2,
.active2.p1_3:checked ~ label.win2.pos3 {
  display: block;
}
.win1:checked ~ label.restart,
.win2:checked ~ label.restart {
  display: block;
}
<html>
  <head>
    <meta charset="utf-8">
    <title>some game</title>
  </head>
  <body>
    <div id="board">
      <input id="s1" class="active1 p1_1 p2_2" type="radio" name="state" value="1">
      <input id="s2" class="active1 p1_1 p2_3" type="radio" name="state" value="2" checked="checked">
      <input id="s3" class="active1 p1_2 p2_1" type="radio" name="state" value="3">
      <input id="s4" class="active1 p1_2 p2_3" type="radio" name="state" value="4">
      <input id="s5" class="active1 p1_3 p2_1" type="radio" name="state" value="5">
      <input id="s6" class="active1 p1_3 p2_2" type="radio" name="state" value="6">
      <input id="s7" class="active2 p1_1 p2_2" type="radio" name="state" value="7">
      <input id="s8" class="active2 p1_1 p2_3" type="radio" name="state" value="8">
      <input id="s9" class="active2 p1_2 p2_1" type="radio" name="state" value="9">
      <input id="s10" class="active2 p1_2 p2_3" type="radio" name="state" value="10">
      <input id="s11" class="active2 p1_3 p2_1" type="radio" name="state" value="11">
      <input id="s12" class="active2 p1_3 p2_2" type="radio" name="state" value="12">
      <input id="s13" class="win1 p1_1" type="radio" name="state" value="13">
      <input id="s14" class="win1 p1_2" type="radio" name="state" value="14">
      <input id="s15" class="win1 p1_3" type="radio" name="state" value="15">
      <input id="s16" class="win2 p2_1" type="radio" name="state" value="16">
      <input id="s17" class="win2 p2_2" type="radio" name="state" value="17">
      <input id="s18" class="win2 p2_3" type="radio" name="state" value="18">
      <div id="status1" class="status">Player 1:</div>
      <div id="status2" class="status">Player 2:</div>
      <div id="status3" class="status">Player 1 won!</div>
      <div id="status4" class="status">Player 2 won!</div>
      <div id="piece1" class="piece">p1</div>
      <div id="piece2" class="piece">p2</div>
      <label for="s1" class="active2 pos2 opp1">Player 2: move piece to position 2</label>
      <label for="s2" class="active2 pos3 opp1">Player 2: move piece to position 3</label>
      <label for="s3" class="active2 pos1 opp2">Player 2: move piece to position 1</label>
      <label for="s4" class="active2 pos3 opp2">Player 2: move piece to position 3</label>
      <label for="s5" class="active2 pos1 opp3">Player 2: move piece to position 1</label>
      <label for="s6" class="active2 pos2 opp3">Player 2: move piece to position 2</label>
      <label for="s7" class="active1 pos1 opp2">Player 1: move piece to position 1</label>
      <label for="s8" class="active1 pos1 opp3">Player 1: move piece to position 1</label>
      <label for="s9" class="active1 pos2 opp1">Player 1: move piece to position 2</label>
      <label for="s10" class="active1 pos2 opp3">Player 1: move piece to position 2</label>
      <label for="s11" class="active1 pos3 opp1">Player 1: move piece to position 3</label>
      <label for="s12" class="active1 pos3 opp2">Player 1: move piece to position 3</label>
      <label for="s13" class="win1 pos1">Player 1: move piece to position 1</label>
      <label for="s14" class="win1 pos2">Player 1: move piece to position 2</label>
      <label for="s15" class="win1 pos3">Player 1: move piece to position 3</label>
      <label for="s16" class="win2 pos1">Player 2: move piece to position 1</label>
      <label for="s17" class="win2 pos2">Player 2: move piece to position 2</label>
      <label for="s18" class="win2 pos3">Player 2: move piece to position 3</label>
      <label for="s2" class="restart">Restart game</label>
    </div>
  </body>
</html>

C'est juste quelques très simple exemple, où chaque joueur peut déplacer son morceau à n'importe quel champ il veut et si son adversaire du morceau qui se produit afin d'être sur qu'il gagne.

Dans un scénario réel, vous pourriez envisager d'utiliser une partie HTML et CSS-les préprocesseurs, comme Pug / Jade et Sass pour itérer sur tous les possibles de l'état de combinaisons.

Mise à jour

Je ne pouvais pas obtenir ce hors de ma tête, j'ai donc joué un peu ...

:focus semble être un bon point de départ, j'ai donc essayé (astuce: assurez-vous de fixer tabindex="0"sur le <label>s). Mais il y a toujours un certain ordre de choses, et je ne pouvais pas trouver un moyen de l'atteindre bidirectionnel relations à l'aide de ~.

Donc, je suis retourné à mon commentaire d'hier, au sujet de faire l'expérience de la "joueur suivant bouton "plus " couramment". Voici mon code (l'idée de base est de changer le "joueur suivant" pour un "confirmer mouvement" de l'état, où le joueur peut confirmer leurs déplacer ou de choisir une autre tuile pour déplacer). Non, c'est pas la réponse à votre question, mais il semble comme une solution à votre problème (et c'échelles de 'bien' plus ou moins, à moins linéaire, pas cubique). html/css semble un peu encombrant poster ici et Jade/Sass je ne pouvais pas aller au travail, donc voici les liens vers ces fichiers:

3voto

Dustin Halstead Points 134

Honnêtement, je ne pense pas qu'il y a une méthode qui permet de basculer de multiples case états en utilisant seulement l'HTML et du CSS.

Cela ne veut pas dire qu'il ne pouvait pas être plus intuitive avec des CSS par style les éléments d'une manière qui rend la commutation entre les joueurs se sentent plus comme c'est tout simplement partie du processus.

J'ai préparé un rapide et sale, fragment exemple qui fournit une méthode de mise en œuvre (à l'aide de la base de l'opacité et de styles de curseur). Cependant, cette méthode peut être utilisée dans un certain nombre d'approches différentes.

Par exemple, vous pouvez déplacer la mourir hors de l'écran ou passer un div pour les éléments de bloc d'être vu/clic (à l'aide de positionnement absolu et z-index).

En fait, le z-index approche pourrait être utilisée afin de permettre aux joueur de commutation sans avoir à déplacer le curseur à tous, ce qui rend plus intuitive du point de vue du joueur.

Die rolling.

Espérons que ces idées aideront à obtenir le ballon -- ou mourir, en roulant.

-1voto

confetti Points 477

C'est ce que vous cherchez?

 .boxes {
  height: 80px;
  width: 80px;
  background-color: white;
  border: 1px solid black;
  position: relative;
}

.boxes span {
  position: absolute;
  width: 100%;
  height: 100%;
}

.boxes a div {
  display: none;
}

.boxes a:target div {
  display: block;
  height: 80px;
  width: 80px;
  background-color: black;
  border: 1px solid black;
  position: absolute;
  margin-left: 150px;
}

.boxes a:target span {
  background-color: black;
}

a {
  color: white;
} 
 <div class="boxes">
  <a href="#firstgroup" id="firstgroup">
    <span>Box A</span>
    <div>Box B</div>
  </a>
</div>

<div class="boxes">
  <a href="#secondgroup" id="secondgroup">
    <span>Box C</span>
    <div>Box D</div>
  </a>
</div> 

Cela utilise :target pour modifier les attributs de plusieurs éléments par un seul déclencheur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X