仅使用CSS切换无线电输入

LGS*_*Son 17 html css css3

以下代码使用脚本在第二次单击时收听无线电切换/取消选中.

我的问题是如何使用CSS执行此操作?

(function(lastimg) {
  document.querySelector("#img-select").addEventListener('click', function(e){
    if (e.target.tagName.toLowerCase() == 'input') {
      if (lastimg == e.target) {
        e.target.checked = false;
        lastimg = null;
      } else {
        lastimg = e.target;
      }      
    }
  });
}());
Run Code Online (Sandbox Code Playgroud)
.container {
  display: flex;
  flex-wrap: wrap;
  max-width: 660px;
}
.container > label {
  flex: 1;
  flex-basis: 33.333%;
}
.container > div {
  flex: 1;
  flex-basis: 100%;
}
.container label img {
  display: block;
  margin: 0 auto;
}
.container input, .container input ~ div {
  display: none;
  padding: 10px;
}

.container #img1:checked ~ #img1txt,
.container #img2:checked ~ #img2txt,
.container #img3:checked ~ #img3txt,
.container #img4:checked ~ #img4txt {
  display: block;
}
Run Code Online (Sandbox Code Playgroud)
<div id="img-select" class="container">
  <input id="img1" type="radio" name="img-descr">
  <input id="img2" type="radio" name="img-descr">
  <input id="img3" type="radio" name="img-descr">

  <label for="img1">
    <img src="http://lorempixel.com/200/200/food/1/" alt="">
  </label>
  <label for="img2">
    <img src="http://lorempixel.com/200/200/food/6/" alt="">
  </label>
  <label for="img3">
    <img src="http://lorempixel.com/200/200/food/8/" alt="">
  </label>

  <div id="img1txt">
    <div>Recipe nr 1</div>
  </div>
  <div id="img2txt">
    <div>Recipe nr 2</div>
  </div>
  <div id="img3txt">
    <div>Recipe nr 3</div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

编辑

我需要一个跨浏览器的解决方案,在主流浏览器上工作,没有脚本,只需要CSS.

为了澄清,我希望它作为普通的无线电输入工作,但是如果在同一时间点击两次或重复,它应该像复选框输入一样切换自身.

只要布局结构保持不变,也允许标记更改,我也更喜欢它是否可以断行,因为页面可以有超过3个配方.

编辑2

问题的主要焦点是如何使无线电输入可切换,尽管由于一些答案显示了用纯CSS切换状态的其他方法,所以任何这样的技巧都是受欢迎的.

Aje*_*i32 18

您无法使用CSS更改单选按钮的功能.CSS仅适用于视觉更改.

也就是说,你可以通过聪明的黑客来模拟这种行为.对于您的示例,我建议使用CSS直观地替换当前所选单选按钮的标签,并将虚拟标签附加到另一个代表"空白"或"空"选项的单选按钮.这样,单击虚拟标签将选择"空白"选项,有效清除您之前的选择:

.container {
  display: flex;
  flex-wrap: wrap;
  max-width: 660px;
}
.container > label {
  flex: 1;
  flex-basis: 33.333%;
}
.container > div {
  flex: 1;
  flex-basis: 100%;
}
.container label img {
  display: block;
  margin: 0 auto;
}
.container input, .container input ~ div {
  display: none;
  padding: 10px;
}

.container #img1:checked ~ #img1txt,
.container #img2:checked ~ #img2txt,
.container #img3:checked ~ #img3txt {
  display: block;
}

.container label[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;
}
Run Code Online (Sandbox Code Playgroud)
<div id="img-select" class="container">
  <input id="noimg" type="radio" name="img-descr">
  <input id="img1" type="radio" name="img-descr">
  <input id="img2" type="radio" name="img-descr">
  <input id="img3" type="radio" name="img-descr">

  <label for="img1">
    <img src="http://lorempixel.com/200/200/food/1/" alt="">
  </label>
  <label for="noimg">
    <img src="http://lorempixel.com/200/200/food/1/" alt="">
  </label>
  <label for="img2">
    <img src="http://lorempixel.com/200/200/food/6/" alt="">
  </label>
  <label for="noimg">
    <img src="http://lorempixel.com/200/200/food/6/" alt="">
  </label>
  <label for="img3">
    <img src="http://lorempixel.com/200/200/food/8/" alt="">
  </label>
  <label for="noimg">
    <img src="http://lorempixel.com/200/200/food/8/" alt="">
  </label>

  <div id="img1txt">
    <div>Recipe nr 1</div>
  </div>
  <div id="img2txt">
    <div>Recipe nr 2</div>
  </div>
  <div id="img3txt">
    <div>Recipe nr 3</div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

(在JSFiddle中查看)


Ori*_*iol 6

如果效果不需要持久,您可以实现类似的播放:focus而不是使用单选按钮.

要使元素可聚焦,请将该tabindex属性设置为整数.如果您不希望通过顺序焦点导航(按"tab"键)到达元素,请使用否定值.

.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;
}
Run Code Online (Sandbox Code Playgroud)
<div id="img-select" class="container">
  <div class="img" tabindex="0">
    <img src="http://lorempixel.com/200/200/food/1/" alt="">
    <span class="unselect" tabindex="-1"></span>
  </div>
  <div class="txt">Recipe nr 1</div>
  <div class="img" tabindex="0">
    <img src="http://lorempixel.com/200/200/food/6/" alt="">
    <span class="unselect" tabindex="-1"></span>
  </div>
  <div class="txt">Recipe nr 2</div>
  <div class="img" tabindex="0">
    <img src="http://lorempixel.com/200/200/food/8/" alt="">
    <span class="unselect" tabindex="-1"></span>
  </div>
  <div class="txt">Recipe nr 3</div>
</div>
Run Code Online (Sandbox Code Playgroud)


Mac*_*ski 5

接受赏金挑战(没有额外的noimg)

.container {
    display: flex;
    flex-wrap: wrap;
    max-width: 660px;
    overflow: hidden;
    position: relative;
}
.container img {
    user-select: none;
    pointer-events: none;
}
.container > label {
    flex: 1;
    flex-basis: 33.333%;
    z-index: 1;
}
.container > div {
    flex: 1;
    flex-basis: 100%;
}
.container label img { margin: 0 auto }
.container input,
.container input ~ div {
    display: none;
    padding: 10px;
}
.container label[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 }
Run Code Online (Sandbox Code Playgroud)
<div id="img-select" class="container">
  <input id="img1" type="radio" name="img-descr">
  <input id="img2" type="radio" name="img-descr">
  <input id="img3" type="radio" name="img-descr">

  <!-- Experimental -->
  <input id="none" type="radio" name="img-descr" checked>
  <label for="none"></label>

  <label for="img1">
    <img src="http://dummyimage.com/200/333" alt="">
  </label>
  <label for="img2">
    <img src="http://dummyimage.com/200/666" alt="">
  </label>
  <label for="img3">
    <img src="http://dummyimage.com/200/999" alt="">
  </label>

  <div id="img1txt">
    <div>Recipe nr 1</div>
  </div>
  <div id="img2txt">
    <div>Recipe nr 2</div>
  </div>
  <div id="img3txt">
    <div>Recipe nr 3</div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)


编辑:根据定义,单选按钮不应该是可切换的(我忘了这是此任务中的额外要求=打破规则).@ Ajedi32答案可能是最好的,但它可以优化(重复图像)?赏金还在比赛中......

编辑2:现在它是功能齐全的解决方案.(做这个技巧/sf/answers/517442691/)

编辑3:多层布局+修复选择.

  • @ Ajedi32图像的可点击区域与标签相比大于图像,没什么大不了的,也很容易修复.我觉得这个打败了你:) (2认同)
  • 感谢你的解决方案,你会得到赏金,虽然我会接受另一个,因为这有一个缺陷,一旦可点击的图像不再存在于一个正方形,定位`none`标签变得更加棘手(有时不在所有). (2认同)