如果单选按钮适合一行,如何设置不同的样式?

How to style radio buttons differently if they fit in a single row?

PLAYGROUND HERE

如果单行按钮适合单行,我想采用不同的样式。例如:

第一个容器 space 不足以容纳一行中的所有单选按钮。因此,它们垂直显示为普通单选按钮。

第二个容器足够space。因此,单选按钮显示为按钮。

是否有可能 仅使用 CSS 实现此行为?

如果没有,欢迎Javascript"hack"。

PLAYGROUND HERE


HTML

<div class="container radio">
  <div>
    <input id="a1" type="radio" name="radio">
    <label for="a1">Yes,</label>
  </div>
  <div>
    <input id="a2" type="radio" name="radio">
    <label for="a2">it</label>
  </div>
  <div>
    <input id="a3" type="radio" name="radio">
    <label for="a3">is</label>
  </div>
  <div>
    <input id="a4" type="radio" name="radio">
    <label for="a4">possible</label>
  </div>
  <div>
    <input id="a5" type="radio" name="radio">
    <label for="a5">to</label>
  </div>
  <div>
    <input id="a6" type="radio" name="radio">
    <label for="a6">achieve</label>
  </div>
  <div>
    <input id="a7" type="radio" name="radio">
    <label for="a7">this</label>
  </div>
</div>
<div class="container buttons">
  <div>
    <input id="b1" type="radio" name="buttons">
    <label for="b1">Yes,</label>
  </div>
  <div>
    <input id="b2" type="radio" name="buttons">
    <label for="b2">it</label>
  </div>
  <div>
    <input id="b3" type="radio" name="buttons">
    <label for="b3">is</label>
  </div>
  <div>
    <input id="b4" type="radio" name="buttons">
    <label for="b4">possible</label>
  </div>
</div>

CSS(少)

.container {
  display: flex;
  width: 220px;
  padding: 20px;
  margin-top: 20px;
  border: 1px solid black;

  &.radio {
    flex-direction: column;
  }

  &.buttons {
    flex-direction: row;

    > div {
      input {
        display: none;

        &:checked + label {
          background-color: #ADFFFE;
        }
      }

      label {
        padding: 5px 10px;
        margin: 0 1px;
        background-color: #ccc;
      }
    }
  }
}

只有很好的解决方案CSS,但您必须知道行中元素的最大数量。以专柜为准,不以实际尺码为准。

例如,如果您确定可以将 4 个元素排成一行,在任何情况下,您都可以使用以下选择器:

如果金额大于或等于 4:

div:nth-last-child(-n+5):first-child,
div:nth-last-child(-n+5):first-child ~ div {
    }

如果金额大于 4:

div:nth-last-child(n+5),
div:nth-last-child(n+5) ~ div {
}

试试这个:http://jsbin.com/fozeromezi/2/edit(只有 remove/add 个 div)

如果我正确理解您的问题,您可以将 flex-direction 部分更改为 row 而不是 column。这将使它们在框内对齐。

您需要做一些更多的样式设置才能使标签以您想要的方式正确显示,但这应该会为您将它们排在行中。 I've updated the playground with my changes.

我想不出只有 CSS 的解决方案,但您可以使用 JS 来测试这些项目是否适合一行并相应地应用 'radio' 或 'buttons' 类名:

请原谅我粗糙的 JS - 它不优雅且仅适用于现代浏览器,但你明白了:

var containers = document.querySelectorAll(".container"),
test = function(){
    for (i = 0; i < containers.length; ++i) {
      var container = containers[i],
          divs = container.querySelectorAll("div"),
          iw = 0;
      container.classList.remove("radio");
      container.classList.add("buttons");
      //get the sum width of the div
      for (d = 0; d < divs.length; ++d) {
        iw+=divs[d].offsetWidth;
      }
      var style = window.getComputedStyle(container, null);
      var ow = parseInt(style.getPropertyValue("width"));
      if(ow<=iw){
          container.classList.add("radio");
          container.classList.remove("buttons");            
      }
    }
};

window.onresize = function(event) {
    test();
};
test();

http://jsbin.com/zofixakama/3/edit?html,css,js,output
(调整 window / 面板的大小以查看效果)

Update:如果在样式中添加.container div {flex-shrink:0;},JS 会简单很多,因为我们不必测量 div 的组合宽度(感谢@rick-hitchcock)。不过虽然代码比较优雅,但是没有考虑到容器的padding

参见:http://jsbin.com/zofixakama/5/edit?html,css,js,output

在 CSS 中不可能,但不需要太多 JavaScript。

在CSS中,将flex-shrink: 0添加到> div。这将防止 .container 的 children 缩小到小于它们的范围。

在JavaScript中:

  1. 应用 buttons class.
  2. 使用Element.getBoundingClientRect判断.container的最后一个child是否在.container的范围之外。如果是这样,请切换到 radio class。 (您还需要考虑正确的填充。感谢@Moob 指出这一点。)

Javascript

var container = document.querySelector('.container'),
    lastChild= document.querySelector('.container > :last-child'),
    paddingRight= parseInt(window.getComputedStyle(container, null).getPropertyValue('padding-right')),
    timer;

window.onresize = function() {
  clearTimeout(timer);
  timer= setTimeout(function() {
    container.classList.remove('radio');
    container.classList.add('buttons');
    if (container.getBoundingClientRect().right-paddingRight <
        lastChild.getBoundingClientRect().right) {
      container.classList.add('radio');
      container.classList.remove('buttons');
    }
  });
}

Updated JSBin

试试下面的例子...................... ----------HTML------------

<html>
<head>
 <link rel="stylesheet" href="style.css" type="text/css" /> 
</head>
<body>
    <div class="table-row">
        <div class="col">
                <input type="Radio">This
            </div>
            <div class="col" style="padding-top: 2px;">
                <input type="Radio">Is
            </div>  

            <div class="col">
                <input type="Radio">Simply
            </div>
            <div class="col" style="padding-top: 2px;">
                <input type="Radio">Possible
            </div>  

        </div>  
</body>
</html>

--------CSS-------------

.table-row{  
     display:table-row;     
     /* text-align: center; */
}
.col{
    display:table-cell;
    /* border: 1px solid #CCC; */
}

测试宽度然后在必要时删除单选按钮图标并替换为图形或形状是否可行?

.checkbox {
    display:none;
}

.label {
    display: inline-block;
    height: 20px;
    background: url('picture.png');
}

它可能没那么简单,但我将它用于复选框,它似乎适用于那种情况。

您只需使用 css 即可实现,无需编写脚本。

HTML:您必须将输入放在包含文本的标签中。

<div>
<label for="a1">
    <input id="a1" type="radio" name="radio">Yes,
</label>  </div>

CSS:在 CSS 中,我们必须隐藏单选按钮,以便只有文本可见。当用户点击文本时,实际上是点击了单选按钮。

div lable input#a1{
   display:none;
}