【问题标题】:CSS for checked radio button with multiple labels具有多个标签的选中单选按钮的 CSS
【发布时间】:2017-07-11 19:01:09
【问题描述】:

检查该单元按钮时,我在广播按钮上的第二个标签上有CSS问题。我已经发现可以在标签标签中使用“for”来创建第二个(和第三个)标签。不可能将所有内容分组到一个标签标签中。

检查广播按钮时如何更改第二个标签的背景?

我的(简化)代码如下,第一个标签有效,第二个标签无效。

.radioclass:checked + label {
  background-color: cyan;
}
<div class="row">
  <div class="col-sm-4">
    <input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
    <label for="id_radiobtn1">first label</label>
  </div>
  <div class="col-sm-4">
    <label for="id_radiobtn1">second label</label>
  </div>
</div>

【问题讨论】:

  • 如果不能改变html结构则需要使用js,因为css中不能调用parent,虽然有:has()但是浏览器还不支持。

标签: html css


【解决方案1】:

css 中的+ 选择器表示“直接兄弟”,即输入之后的下一个元素必须是标签。这只会选择直接兄弟。

另一种选择是~,意思是“任何兄弟”,并针对输入后的任何标签。

在这两种情况下,元素(输入和标签)都在同一个 dom 级别。没有办法遍历 up dom,获取兄弟节点,然后是标签 - 这就是您尝试使用提供的 html 执行的操作。

如果您能够更改 html,则要么将输入放在两个 divs 之外,要么将两个 labels 放在同一个 div 内(在输入之后)。

.radioclass:checked ~ div label {
  background-color: cyan;
}
<div class="row">
  <input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
  <div class="col-sm-4">
    <label for="id_radiobtn1">first label</label>
  </div>
  <div class="col-sm-4">
    <label for="id_radiobtn1">second label</label>
  </div>
</div>

.radioclass:checked ~ label {
  background-color: cyan;
}
<div class="row">
  <div class="col-sm-4">
    <input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
    <label for="id_radiobtn1">first label</label>
    <label for="id_radiobtn1">second label</label>
  </div>
</div>

如果您无法更改 html,那么 JS 是唯一的其他方法(出于演示目的,我已将输入更改为复选框):

$('input').on('change', function(){
  var func = 'removeClass';
  if($(this).is(':checked')) {
    func = 'addClass';
  }
  
  $('label[for="'+$(this).attr('id')+'"]')[func]('checked');
});
label.checked {
  background-color: cyan;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="row">
  <div class="col-sm-4">
    <input class="radioclass" id="id_radiobtn1" type="checkbox" name="radiobtn1" value="1">
    <label for="id_radiobtn1">first label</label>
  </div>
  <div class="col-sm-4">
    <label for="id_radiobtn1">second label</label>
  </div>
</div>

【讨论】:

  • 非常感谢,我会根据您的回答找出最佳解决方案。
【解决方案2】:

仅使用 CSS 是可能的,尽管它确实需要重新排列 HTML,有效地将无线电 &lt;input&gt; 移动到包含 &lt;label&gt; 元素的元素之前;这消除了(在 CSS 中不可能的)遍历&lt;input&gt; 的父元素以设置非兄弟&lt;label&gt; 元素的样式的要求。

/* selects the element with the id of 'id_radiobtn1' when it is
   checked, uses the general sibling combinator (~) to select
   all sibling <div> elements with the class of 'col-sm-4'
   and then finds the descendant <label> elements within
   that/those <div> elements whose 'for' attribute-value is
   equal to 'id_radiobtn1': */
#id_radiobtn1:checked ~ div.col-sm-4 label[for=id_radiobtn1] {
  background-color: cyan;
}
<div class="row">
  <input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1" />
  <div class="col-sm-4">
    <label for="id_radiobtn1">first label</label>
  </div>
  <div class="col-sm-4">
    <label for="id_radiobtn1">second label</label>
  </div>
</div>

现在,如果除了&lt;label&gt; 元素中的第一个之外,您还必须有一个可见的无线电&lt;input&gt;,您可以使用伪元素来有效地伪装,同时隐藏真正的无线电&lt;input&gt;

*,
 ::before,
 ::after {
 /* to include border and padding in the calculated
    dimensions (width/height) of the elements: */
  box-sizing: border-box;
}

.row>input[type=radio] {
  /* hiding the radio <input> elements: */
  display: none;
}

/* selecting the <input> elements whose type is
   equal to 'radio', which is checked and then
   finding all (subsequent) sibling elements
   (using the '~' combinator) which <div>
   elements with a class of 'col-sm-4', and
   traversing to the <label> elements within: */
input[type=radio]:checked~div.col-sm-4 label {
  background-color: cyan;
}

label {
  /* in order to ensure that the descendant
     pseudo-elements are positioned relative
     to their parent element: */
  position: relative;
  /* making room for the pseudo-elements: */
  margin-left: 2em;
}

input[type=radio]+.col-sm-4 label::before {
  /* the content property is required, even
     if only an empty string, to have the
     pseudo-element show up: */
  content: '';
  display: inline-block;
  /* positioning absolutely, in relation to
     the closest ancestor with a non 'static'
     position, in this case the parent
     <label> element: */
  position: absolute;
  /* moving it outside of the <label> element's
     left border, to avoid the background-color: */
  left: -2em;
  /* purely aesthetic: */
  width: 0.8em;
  height: 0.8em;
  /* arbitrary positioning, adjust to taste: */
  top: 50%;
  transform: translateY(-40%);
  /* making the pseudo-element circular in shape: */
  border-radius: 50%;
  /* colouring the faux 'border': */
  box-shadow: 0 0 0 2px #ccc;
}

/* adjusting the colours of the faux radio: */
input[type=radio]:checked+.col-sm-4 label::before {
  box-shadow: 0 0 0 2px #000, inset 0 0 0 3px #fff;
  background-color: limegreen;
}
<div class="row">
  <input class="radioclass" id="id_radiobtn1" type="radio" name="group1" value="1" />
  <div class="col-sm-4">
    <label for="id_radiobtn1">row one first label</label>
  </div>
  <div class="col-sm-4">
    <label for="id_radiobtn1">row one second label</label>
  </div>
</div>
<div class="row">
  <input class="radioclass" id="id_radiobtn2" type="radio" name="group1" value="2" />
  <div class="col-sm-4">
    <label for="id_radiobtn2">row two first label</label>
  </div>
  <div class="col-sm-4">
    <label for="id_radiobtn2">row two second label</label>
  </div>
</div>

【讨论】:

    【解决方案3】:

    您可以在更改事件上使用 Jquery。

    $(document).ready(function() {
    $('#id_radiobtn1').on('change',function(){
    $( "label:contains('second')" ).css( "background-color", "red" );
    });
    });
    .radioclass:checked + label {
      background-color: cyan;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="row">
      <div class="col-sm-4">
        <input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
        <label for="id_radiobtn1">first label</label>
      </div>
      <div class="col-sm-4">
        <label for="id_radiobtn1">second label</label>
      </div>

    【讨论】:

      【解决方案4】:

      你不能用纯 css 来做,因为 css 中的向后是不可能的。你可以帮助 Jquery:

      注意:我将lab2 类插入到标签中。

      $(document).ready(function(){
          $('input[type=radio]').on('change',function(){
              if($('.radioclass').is(':checked'))
                  $('.lab2').addClass('sel');
              else
                  $('.lab2').removeClass('sel');
          })
      })
      

      $(document).ready(function(){
          $('input[type=radio]').on('change',function(){
              if($('.radioclass').is(':checked'))
                  $('.lab2').addClass('sel');
              else
                  $('.lab2').removeClass('sel');
          })
      })
      #id_radiobtn1:checked + label {
          background-color: green;
      }
      
      .sel {
          background-color: red;
      }
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
      <div class="row">
        <div class="col-sm-4">
          <input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
          <label for="id_radiobtn1">first label</label>
        </div>
        <div class="col-sm-4">
          <label for="id_radiobtn1" class="lab2">second label</label>
        </div>
      </div>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多