仅使用CSS切换无线电输入

时间:2016-03-22 18:50:28

标签: html css css3

以下代码使用脚本在第二次点击广播时切换/取消选中广播。

我的问题是如何使用仅限CSS

执行此操作



"dbac"

>>> allPermutations = ['abcd', 'cbad', 'abdc', 'cbda', 'dbca', 'dbac']
>>> lexSorted = sorted(allPermutations, reverse=True) # ['dbca', 'dbac', 'cbda', 'cbad', 'abdc', 'abcd']
>>> lexSorted.pop(0)
'dbca'

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




修改

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

为了澄清,我希望它作为普通的无线电输入工作,但如果点击两次,或重复点击,则应该将其自身切换为复选框输入。

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

修改2

问题的主要焦点是如何使无线电输入可切换,但由于一些答案显示了使用纯CSS切换状态的其他方法,因此欢迎使用任何此类技巧。

7 个答案:

答案 0 :(得分: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;
}
<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>

View in JSFiddle

答案 1 :(得分:6)

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

要创建元素focusable,请将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;
}
<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>

答案 2 :(得分:5)

接受赏金挑战(无额外noimg

&#13;
&#13;
.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 }
&#13;
<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>
&#13;
&#13;
&#13;

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

编辑2:现在它是功能齐全的解决方案。 (做这个技巧https://stackoverflow.com/a/7392038/2601031

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

答案 3 :(得分:2)

答案是您不能仅取消选中或取消选中CSS中的单选按钮,因为单击单选按钮后,单选按钮才会取消选中。由于一次只能激活一个单选按钮,因此将取消选中之前选中的单选按钮。

input:checked + label {
    color: green;
}

input:not(:checked) + label {
    color: red;
}

所以你必须坚持使用你发布的JS函数。

以下是一些有待进一步解释的好文章:

CSS Click Events

How To Generate CSS Click Events

答案 4 :(得分:2)

诀窍是使用:target。我在每个块中添加了两个空<a>标记,并将它们设置为完全覆盖块以执行click事件。第一个链接用于真正的:target事件,第二个链接仅用于撤消它,在z-index的帮助下实现它。

<强> jsFiddle

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>
    <a href="#link-1" id="link-1" class="target"></a>
    <a href="#"></a>
    <img src="//dummyimage.com/150/333">
    <div>a</div>
  </li>
  <li>
    <a href="#link-2" id="link-2" class="target"></a>
    <a href="#"></a>
    <img src="//dummyimage.com/150/666">
    <div>b</div>
  </li>
  <li>
    <a href="#link-3" id="link-3" class="target"></a>
    <a href="#"></a>
    <img src="//dummyimage.com/150/999">
    <div>c</div>
  </li>
</ul>

答案 5 :(得分:1)

试一试 的 HTML                         这太棒了吗?                      是                      没有         

    <div class="switch-field">
      <div class="switch-title">Three fields? Sure.</div>
      <input type="radio" id="switch_3_left" name="switch_3" value="yes" checked/>
      <label for="switch_3_left">One</label>
      <input type="radio" id="switch_3_center" name="switch_3" value="maybe" />
      <label for="switch_3_center">Two</label>
            <input type="radio" id="switch_3_right" name="switch_3" value="no" />
      <label for="switch_3_right">Three</label>
    </div>
</form>

CSS:

.switch-field {
  font-family: "Lucida Grande", Tahoma, Verdana, sans-serif;
  padding: 40px;
    overflow: hidden;
}

.switch-title {
  margin-bottom: 6px;
}

.switch-field input {
  display: none;
}

.switch-field label {
  float: left;
}

.switch-field label {
  display: inline-block;
  width: 60px;
  background-color: #e4e4e4;
  color: rgba(0, 0, 0, 0.6);
  font-size: 14px;
  font-weight: normal;
  text-align: center;
  text-shadow: none;
  padding: 6px 14px;
  border: 1px solid rgba(0, 0, 0, 0.2);
  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
  -webkit-transition: all 0.1s ease-in-out;
  -moz-transition:    all 0.1s ease-in-out;
  -ms-transition:     all 0.1s ease-in-out;
  -o-transition:      all 0.1s ease-in-out;
  transition:         all 0.1s ease-in-out;
}

.switch-field label:hover {
    cursor: pointer;
}

.switch-field input:checked + label {
  background-color: #A5DC86;
  -webkit-box-shadow: none;
  box-shadow: none;
}

.switch-field label:first-of-type {
  border-radius: 4px 0 0 4px;
}

.switch-field label:last-of-type {
  border-radius: 0 4px 4px 0;
}

答案 6 :(得分:1)

我有一个中途的解决方案:

  • 双击时清除选择但不点击(按要求)
  • 但是(这就是“中途”),双击当前所选项目时不会清除选择(仅当双击其他项目时)

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

        .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;
            width: 200px;
            height: 200px;
            z-index: 1;
            display: none;
        }

        .container #img1:checked ~ label[for=none],
        .container #img2:checked ~ label[for=none],
        .container #img3:checked ~ label[for=none] {
            display: block;
        }

        @keyframes hideNone {
            from {
                z-index: 3;
            }
            to {
                z-index: 3;
            }
        }

        .container #img1:checked ~ label[for=img1],
        .container #img2:checked ~ label[for=img2],
        .container #img3:checked ~ label[for=img3] {
            animation-name: hideNone;
            animation-delay: 0.3s;
            animation-duration: 99999s;
        }

        .container #img1:checked ~ label[for=none] {
            left: 0;
        }

        .container #img2:checked ~ label[for=none] {
            left: 220px;
        }

        .container #img3:checked ~ label[for=none] {
            left: 440px;
        }

        .container #img1:checked ~ #img1txt,
        .container #img2:checked ~ #img2txt,
        .container #img3:checked ~ #img3txt {
            display: block
        }
<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">

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

    <input type="button" autofocus>
    <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>

还在考虑如何改进它...... :)