Toggle Radio Input Using Css Only
Solution 1:
You can't change the functionality of radio buttons using CSS. CSS is designed for visual changes only.
That said, you can simulate this behavior with a clever hack. For your example, I'd recommend using CSS to visually replace the label for the currently selected radio button with a dummy label attached to another radio button representing a "blank" or "empty" selection. That way, clicking the dummy label would select the "blank" option, effectively clearing your prior choice:
.container {
display: flex;
flex-wrap: wrap;
max-width: 660px;
}
.container > label {
flex: 1;
flex-basis: 33.333%;
}
.container > div {
flex: 1;
flex-basis: 100%;
}
.containerlabelimg {
display: block;
margin: 0 auto;
}
.containerinput, .containerinput ~ div {
display: none;
padding: 10px;
}
.container#img1:checked ~ #img1txt,
.container#img2:checked ~ #img2txt,
.container#img3:checked ~ #img3txt {
display: block;
}
.containerlabel[for=noimg] {
display: none;
}
.container#img1:checked ~ label[for=img1],
.container#img2:checked ~ label[for=img2],
.container#img3:checked ~ label[for=img3] {
display: none;
}
.container#img1:checked ~ label[for=img1] + label[for=noimg],
.container#img2:checked ~ label[for=img2] + label[for=noimg],
.container#img3:checked ~ label[for=img3] + label[for=noimg] {
display: block;
}
<divid="img-select"class="container"><inputid="noimg"type="radio"name="img-descr"><inputid="img1"type="radio"name="img-descr"><inputid="img2"type="radio"name="img-descr"><inputid="img3"type="radio"name="img-descr"><labelfor="img1"><imgsrc="http://lorempixel.com/200/200/food/1/"alt=""></label><labelfor="noimg"><imgsrc="http://lorempixel.com/200/200/food/1/"alt=""></label><labelfor="img2"><imgsrc="http://lorempixel.com/200/200/food/6/"alt=""></label><labelfor="noimg"><imgsrc="http://lorempixel.com/200/200/food/6/"alt=""></label><labelfor="img3"><imgsrc="http://lorempixel.com/200/200/food/8/"alt=""></label><labelfor="noimg"><imgsrc="http://lorempixel.com/200/200/food/8/"alt=""></label><divid="img1txt"><div>Recipe nr 1</div></div><divid="img2txt"><div>Recipe nr 2</div></div><divid="img3txt"><div>Recipe nr 3</div></div></div>
Solution 2:
If the effect does not need to be persistent, you can achieve something similar playing with :focus
instead of using radio buttons.
To make an element focusable, set the tabindex
attribute to an integer. Use a negative one if you don't want the element to be reached via sequential focus navigation (pressing the "tab" key).
.container {
display: flex;
flex-wrap: wrap;
max-width: 660px;
}
.container > .img {
flex: 1;
position: relative;
}
.container > .img > .unselect {
display: none;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}
.container > .txt {
display: none;
order: 1;
flex-basis: 100%;
}
.container > .img:focus > .unselect,
.container > .img:focus + .txt {
display: block;
}
<divid="img-select"class="container"><divclass="img"tabindex="0"><imgsrc="http://lorempixel.com/200/200/food/1/"alt=""><spanclass="unselect"tabindex="-1"></span></div><divclass="txt">Recipe nr 1</div><divclass="img"tabindex="0"><imgsrc="http://lorempixel.com/200/200/food/6/"alt=""><spanclass="unselect"tabindex="-1"></span></div><divclass="txt">Recipe nr 2</div><divclass="img"tabindex="0"><imgsrc="http://lorempixel.com/200/200/food/8/"alt=""><spanclass="unselect"tabindex="-1"></span></div><divclass="txt">Recipe nr 3</div></div>
Solution 3:
Bounty Challenge Accepted (without the extra noimg
)
.container {
display: flex;
flex-wrap: wrap;
max-width: 660px;
overflow: hidden;
position: relative;
}
.containerimg {
user-select: none;
pointer-events: none;
}
.container > label {
flex: 1;
flex-basis: 33.333%;
z-index: 1;
}
.container > div {
flex: 1;
flex-basis: 100%;
}
.containerlabelimg { margin: 0 auto }
.containerinput,
.containerinput ~ div {
display: none;
padding: 10px;
}
.containerlabel[for=none] {
position: absolute;
bottom: 0;
top: 0;
left: 0;
right: 0;
z-index: 0;
}
.container#img1:checked ~ label[for=img1],
.container#img2:checked ~ label[for=img2],
.container#img3:checked ~ label[for=img3] {
pointer-events: none;
z-index: -1;
}
.container#img1:checked ~ #img1txt,
.container#img2:checked ~ #img2txt,
.container#img3:checked ~ #img3txt { display: block }
<divid="img-select"class="container"><inputid="img1"type="radio"name="img-descr"><inputid="img2"type="radio"name="img-descr"><inputid="img3"type="radio"name="img-descr"><!-- Experimental --><inputid="none"type="radio"name="img-descr"checked><labelfor="none"></label><labelfor="img1"><imgsrc="http://dummyimage.com/200/333"alt=""></label><labelfor="img2"><imgsrc="http://dummyimage.com/200/666"alt=""></label><labelfor="img3"><imgsrc="http://dummyimage.com/200/999"alt=""></label><divid="img1txt"><div>Recipe nr 1</div></div><divid="img2txt"><div>Recipe nr 2</div></div><divid="img3txt"><div>Recipe nr 3</div></div></div>
EDIT: By definition radio buttons shouldn't be toggleable (I forgot that this was an additional requirement in this task = to broke the rules). @Ajedi32 answer is probably the best, but it can be optimized (repeated images)? Bounty still in game...
EDIT 2: Now it's fully functional solution. (doing this trick https://stackoverflow.com/a/7392038/2601031)
EDIT 3: Multi-layer layout + Repaired selection.
Solution 4:
The answer is you can't unselect or uncheck a radio button in CSS only, as the radio button only becomes unchecked once you click on a different radio button. As only one radio button can be active at once, this will uncheck the previously checked radio button.
input:checked + label {
color: green;
}
input:not(:checked) + label {
color: red;
}
So you'll have to stick with using the JS function you posted.
Here are a couple of nice articles with further explanation :
Solution 5:
The trick is using :target
. I added two empty <a>
tags in each block, and set them to cover the block completely in order to perform the click event. The first link is for the real :target
event, and second link is just for undo it, with a bit help of z-index
to make it happen.
ul {
padding: 0;
margin: 0;
}
li {
display: inline-block;
vertical-align: top;
position: relative;
}
a {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
div {
display: none;
}
.target{
z-index: 1;
}
.target:target {
z-index: -1;
}
.target:target ~ div{
display: block;
}
<ul><li><ahref="#link-1"id="link-1"class="target"></a><ahref="#"></a><imgsrc="//dummyimage.com/150/333"><div>a</div></li><li><ahref="#link-2"id="link-2"class="target"></a><ahref="#"></a><imgsrc="//dummyimage.com/150/666"><div>b</div></li><li><ahref="#link-3"id="link-3"class="target"></a><ahref="#"></a><imgsrc="//dummyimage.com/150/999"><div>c</div></li></ul>
Post a Comment for "Toggle Radio Input Using Css Only"