I've been experimenting with HTML and CSS to create a simple board game without using JavaScript. I use labels and radio buttons to create the different states and simulate the logic for each piece to move around the board.
It works "fine", although the usability is not great. For example, after rolling the dice, the token moves and I show a button to switch to the next user (again controlled with a label and a checkbox)... but that's not ideal, it would be better if the player switch was will perform "automatically."
The problem is that <label>
it can only change one element and I don't know how to make two "actions" (or side effects) be generated with each click.
Is there a way to launch two "state changes" by clicking on a single <label>
or <a>
?
This is a minimal example of the problem: There are two players (specified by turns), a board with 3 spaces (which will be 6 radio buttons: 1 per space and player), and two buttons to change turns (although only one will be visible). If you click on change turn, it will change the turn, and the radio buttons and labels for the other player will be shown. (A more complete example can be found here ).
Is the problem that you have to force the user to click on the button to change turns, or the active player will always be the same. Is there a way to make it so that when you click on a square, not only the square changes but also the turn?
#j1:checked ~ [for=j1],
#j1:checked ~ [for^=casilla-j2],
#j1:checked ~ [name^=casilla-j2],
#j2:checked ~ [for=j2],
#j2:checked ~ [for^=casilla-j1],
#j2:checked ~ [name^=casilla-j1]
{
display: none;
}
/* aquí habría más reglas para ocultar elementos */
<h1>Turno:</h1>
<input type="radio" id="j1" name="jugador" checked /> J1
<input type="radio" id="j2" name="jugador" /> J2
<h1>Tablero: </h1>
Jugador 1:
<input type="radio" id="casilla-j1-1" name="casilla-j1" checked />
<label for="casilla-j1-1">J1 a 1</label>
<input type="radio" id="casilla-j1-2" name="casilla-j1" />
<label for="casilla-j1-2">J1 a 2</label>
<input type="radio" id="casilla-j1-3" name="casilla-j1" />
<label for="casilla-j1-3">J1 a 3</label>
<br/>
Jugador 2:
<input type="radio" id="casilla-j2-1" name="casilla-j2" checked />
<label for="casilla-j2-1">J2 a 1</label>
<input type="radio" id="casilla-j2-2" name="casilla-j2" />
<label for="casilla-j2-2">J2 a 2</label>
<input type="radio" id="casilla-j2-3" name="casilla-j2" />
<label for="casilla-j2-3">J2 a 3</label>
<h1>Cambio de turno:</h1>
<label for="j2">Cambiar turno a jugador 2</label>
<label for="j1">Cambiar turno a jugador 1</label>
Some attempts:
I tried to put a <a>
inside a <label>
to be able to cast two readable changes: :target
with <a>
and :checked
with <label>
(with :target it would control the turn, and with :checked it would control the square the piece goes to). It looks like that structure is valid HTML (at least according to the W3C HTML validator), but it doesn't work . For example, in the following snippet, clicking on the first link activates the text, clicking on the second link checks the box, but clicking on the third link does not do both (which is what I I would want):
#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">Resaltar texto</a>
<label for="cb">Marcar casilla</label>
<label for="cb">
<a href="#test">Resaltar texto Y marcar casilla</a>
</label>
I've also tried playing with combinations of different pseudo-classes: :checked
e :invalid
in particular. Although it was not very helpful because in the case of a checkbox they have the same value at the same time, and in the tests I did required
it does not apply to a single radio button:
div {
color: purple;
}
#radio1:checked ~ div {
color: blue;
}
#radio1:invalid ~ div {
color: red;
}
#radio2:checked ~ div {
color: fuchsia;
}
#radio1:invalid + #radio2:checked ~ div {
color: green;
}
<input type="radio" name="radio1" id="radio1" required />
<input type="radio" name="radio1" id="radio2" />
<div>Texto que debería ser verde cuando radio2 esté pulsado</div>
CSS events work in a very specific way, so an event will only trigger one action, unfortunately. Trying to fire a second one would just overwrite the first one, or it just wouldn't work. However, you can use 2 CSS events bound to the same tag, taking advantage of selectors (:hover, :focus, :active, etc). Of course, each selector has a different behavior.
As for your second example, the :invalid selector didn't seem to work, however the :required selector does what you're looking for (assuming that Radio1 has the required attribute)
I think that using checkBox:focus together with checkBox:checked could achieve the desired effect, although it would be somewhat buggy. As a last option, you could use a duality between :checked and :not(:checked). When someone presses "Dice" they would actually be selecting or deselecting your player checkbox, and every time the value of the checkbox changes, the die is activated
EDITED (AUGUST 02, 2018):
I've been thinking about it a lot, and after doing a lot of research, I just realized that with pure CSS it's impossible to make the change of one input affect the value of another (I'm not saying that's what you expected, but certainly the purpose confused me a bit). I understand that by clicking on the "dice" you change the place of the selected player through an animation, and that by "changing" the turn, you select which of the pieces will move. Now, I don't know how possible it will be to control everything with a single checkbox and use IDs and Classes to make different changes according to the value of the checkbox.
I know you asked to apply it to the first example, but I couldn't apply it with radios and checkbox at the same time, that's why I ask if the structure can be changed
You can use the selector
~
, so if the checkbox is selected, you color the div red#test
.It is not precisely that an event is executing the two actions at the same time, but rather that an event triggers the selection of the checkbox and then when selected the other css rule applies the red color to the other div, for practical purposes it may be the What are you wanting to achieve?
Here an example:
I hope I have been of help to you.
Cheers!