如果单排的单选按钮有什么不同的样式?

时间:2022-03-28 05:28:12

PLAYGROUND HERE

这里的操场上

I'd like to style radio buttons differently if they fit in a single row. For example:

如果单排单选的话,我想把单选按钮设计成不同的风格。例如:

如果单排的单选按钮有什么不同的样式?

The first container doesn't have enough space to fit all the radio buttons in a single row. Therefore, they appear vertically as normal radio buttons.

第一个容器没有足够的空间来容纳一行中的所有单选按钮。因此,它们垂直地显示为普通的单选按钮。

The second container has enough space. Therefore, the radio buttons appear as buttons.

第二个容器有足够的空间。因此,单选按钮以按钮的形式出现。

Is that possible to achieve this behaviour using CSS only?

是否只有使用CSS才能实现这种行为?

If not, Javascript "hack" is welcome.

如果没有,欢迎使用Javascript“hack”。

PLAYGROUND HERE

这里的操场上


HTML

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 (LESS)

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

7 个解决方案

#1


23  

Not possible in CSS, but it doesn't take much JavaScript.

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

In CSS, add flex-shrink: 0 to > div. This will prevent .container's children from shrinking smaller than their extent.

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

In JavaScript:

在JavaScript中:

  1. Apply the buttons class.
  2. 应用按钮类。
  3. Use Element.getBoundingClientRect to determine if the last child of .container is outside the extent of .container. If so, switch to the radio class. (You also need to take the right padding into account. Thanks to @Moob for pointing that out.)
  4. 使用元素。getBoundingClientRect用于确定.container的最后一个子元素是否位于.container的范围之外。如果是,请切换到radio类。(你还需要考虑到合适的填充。感谢@Moob指出这一点。

Javascript

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

更新JSBin

#2


7  

I can't think of a CSS only solution but you could use JS to test if the items would fit in a row and apply the 'radio' or 'buttons' classname accordingly:

我不能只考虑CSS的解决方案,但是你可以使用JS来测试这些条目是否适合行,并相应地应用“radio”或“button”类名:

Forgive my rough JS - its inelegant and for modern browsers only but you get the idea:

请原谅我的粗糙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
(resize the window / panel to see the effect)

http://jsbin.com/zofixakama/3/edit?html、css、js、输出(调整窗口/面板的大小以查看效果)

Update: If you add .container div {flex-shrink:0;} to the style the JS can be much simpler as we don't have to measure the combined width of the divs (thanks @rick-hitchcock). However, although the code is more elegant, it does not take the container's padding into account.

更新:如果在样式中添加.container div {flex-shrink:0;},那么JS就会简单得多,因为我们不需要测量div的组合宽度(感谢@rick-hitchcock)。然而,尽管代码更加优雅,但它没有考虑容器的填充。

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

参见:http://jsbin.com/zofixakama/5/edit?html、css、js、输出

#3


1  

If I understand what you're asking correctly, you can change your flex-direction portion to row instead of column. This will cause them to align inside the box.

如果我理解正确的话,你可以把弹性方向的部分改为行而不是列。这会使它们在盒子里对齐。

You'll have to do some more styling to properly get the labels to appear the way you want, but this should put them in the row for you. I've updated the playground with my changes.

您将不得不进行更多的样式化,以使标签以您希望的方式出现,但这应该将它们放在行中。我用我的零钱更新了操场。

#4


1  

Try the following example.............. ------------HTML-----------

下面的例子..............试试- - - - - - - - - - - - - - - - - - - - - - - - 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-------------

- - - - - -但css - - - - - - - - - - - - -

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

#5


1  

Wouldn't it work to test for width then if necessary remove the radio button icon and replace with a graphic or shape?

如果有必要的话,把单选按钮的图标去掉,换成图形或者图形,不是很好吗?

.checkbox {
    display:none;
}

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

It's probably not that simple but I use that for check boxes and it seems to work in that situation.

它可能不是那么简单,但我用它来检查箱子,它似乎在这种情况下工作。

#6


1  

You can achieve this only by using css and no need of scripting.

只有使用css和不需要编写脚本,您才能实现这一点。

HTML: You have to place the input within tag which will contain the text.

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

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

CSS: Here in CSS we will have to hide the radio button, so that only the text will be visible. When the user clicks on the text, it actually clicks the radio button.

CSS:在CSS中,我们需要隐藏单选按钮,这样只有文本才可见。当用户单击文本时,它实际上会单击单选按钮。

div lable input#a1{
   display:none;
}

#7


-1  

there is pretty solution CSS only, but you have to know maximum amount of elements in row. It is based on counter, but not on real size.

只有漂亮的CSS解决方案,但是你必须知道行中元素的最大数量。它是基于计数器,而不是实际大小。

For example, if you are sure, that you can put 4 elements into a row, in any case, you may use following selector:

例如,如果您确定可以将4个元素放入一行,无论如何,您可以使用以下选择器:

if amount is more less or equal 4:

如果金额大于或等于4:

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

if amount is more then 4:

如果金额大于4:

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

try this: http://jsbin.com/fozeromezi/2/edit (just remove/add divs)

试试这个:http://jsbin.com/fozeromezi/2/edit(删除/添加div)

#1


23  

Not possible in CSS, but it doesn't take much JavaScript.

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

In CSS, add flex-shrink: 0 to > div. This will prevent .container's children from shrinking smaller than their extent.

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

In JavaScript:

在JavaScript中:

  1. Apply the buttons class.
  2. 应用按钮类。
  3. Use Element.getBoundingClientRect to determine if the last child of .container is outside the extent of .container. If so, switch to the radio class. (You also need to take the right padding into account. Thanks to @Moob for pointing that out.)
  4. 使用元素。getBoundingClientRect用于确定.container的最后一个子元素是否位于.container的范围之外。如果是,请切换到radio类。(你还需要考虑到合适的填充。感谢@Moob指出这一点。

Javascript

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

更新JSBin

#2


7  

I can't think of a CSS only solution but you could use JS to test if the items would fit in a row and apply the 'radio' or 'buttons' classname accordingly:

我不能只考虑CSS的解决方案,但是你可以使用JS来测试这些条目是否适合行,并相应地应用“radio”或“button”类名:

Forgive my rough JS - its inelegant and for modern browsers only but you get the idea:

请原谅我的粗糙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
(resize the window / panel to see the effect)

http://jsbin.com/zofixakama/3/edit?html、css、js、输出(调整窗口/面板的大小以查看效果)

Update: If you add .container div {flex-shrink:0;} to the style the JS can be much simpler as we don't have to measure the combined width of the divs (thanks @rick-hitchcock). However, although the code is more elegant, it does not take the container's padding into account.

更新:如果在样式中添加.container div {flex-shrink:0;},那么JS就会简单得多,因为我们不需要测量div的组合宽度(感谢@rick-hitchcock)。然而,尽管代码更加优雅,但它没有考虑容器的填充。

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

参见:http://jsbin.com/zofixakama/5/edit?html、css、js、输出

#3


1  

If I understand what you're asking correctly, you can change your flex-direction portion to row instead of column. This will cause them to align inside the box.

如果我理解正确的话,你可以把弹性方向的部分改为行而不是列。这会使它们在盒子里对齐。

You'll have to do some more styling to properly get the labels to appear the way you want, but this should put them in the row for you. I've updated the playground with my changes.

您将不得不进行更多的样式化,以使标签以您希望的方式出现,但这应该将它们放在行中。我用我的零钱更新了操场。

#4


1  

Try the following example.............. ------------HTML-----------

下面的例子..............试试- - - - - - - - - - - - - - - - - - - - - - - - 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-------------

- - - - - -但css - - - - - - - - - - - - -

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

#5


1  

Wouldn't it work to test for width then if necessary remove the radio button icon and replace with a graphic or shape?

如果有必要的话,把单选按钮的图标去掉,换成图形或者图形,不是很好吗?

.checkbox {
    display:none;
}

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

It's probably not that simple but I use that for check boxes and it seems to work in that situation.

它可能不是那么简单,但我用它来检查箱子,它似乎在这种情况下工作。

#6


1  

You can achieve this only by using css and no need of scripting.

只有使用css和不需要编写脚本,您才能实现这一点。

HTML: You have to place the input within tag which will contain the text.

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

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

CSS: Here in CSS we will have to hide the radio button, so that only the text will be visible. When the user clicks on the text, it actually clicks the radio button.

CSS:在CSS中,我们需要隐藏单选按钮,这样只有文本才可见。当用户单击文本时,它实际上会单击单选按钮。

div lable input#a1{
   display:none;
}

#7


-1  

there is pretty solution CSS only, but you have to know maximum amount of elements in row. It is based on counter, but not on real size.

只有漂亮的CSS解决方案,但是你必须知道行中元素的最大数量。它是基于计数器,而不是实际大小。

For example, if you are sure, that you can put 4 elements into a row, in any case, you may use following selector:

例如,如果您确定可以将4个元素放入一行,无论如何,您可以使用以下选择器:

if amount is more less or equal 4:

如果金额大于或等于4:

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

if amount is more then 4:

如果金额大于4:

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

try this: http://jsbin.com/fozeromezi/2/edit (just remove/add divs)

试试这个:http://jsbin.com/fozeromezi/2/edit(删除/添加div)