自定义单选按钮

Customizing Radio buttons

本文关键字:单选按钮 自定义      更新时间:2023-09-26

-webkit外观在让您自定义单选按钮的外观方面做得很好。然而,不使用webkit和旧浏览器的浏览器并不真正支持这一点。所以它不起作用。

我正在寻找一个同时适用于这两种浏览器的解决方案,即不使用webkit的浏览器(如Firefox和IE)和不支持CSS3的旧版webkit浏览器。

input[type="radio"] {
    margin: 50px 50px 0 0; padding: 0;
    width: 200px; height: 200px;
    position: relative; clear: none; float: left; display: inline-block;
    cursor: pointer; outline: none;
    background-color: #231f20;
    -webkit-appearance: none;
}

有什么想法/解决方案吗?

实现一个想法有时并不容易。如果用户只需要点击/悬停在(单选按钮的)圆圈上就可以与它交互,我们可以很容易地自定义单选按钮。但单选按钮的正常行为也是允许用户点击/悬停在标签文本上与之交互。这意味着我们可能需要多一个标签(用于文本)。但这并不容易。该标签只能允许用户点击以与隐藏的无线电进行交互,悬停在该标签上不会产生任何影响(通常该标签最终会被附加,因此我们也无法向后遍历以选择伪无线电(由2个伪元素:before:after组成)。所以我决定只使用一个标签。这个标签包含一个空的span元素作为第一个子元素,这个跨度后面当然是单选按钮的文本。span元素是我们设计假收音机的样式的地方。然而,如果默认情况下让它们内联,并且文本很长,它将跳到下一行,并与假收音机的左边缘垂直对齐(就在第一行的正上方),这被认为是非常丑陋的,应该避免。因此,我们需要将label显示为一个表(使用display:table),第一列是span元素(应用display:table-cell),标签文本将自动被第二列包裹。这样,当文本很长时,所有的行都将被第二列换行。

以下是代码详细信息:

HTML

<div>
  <span class='radio'>
    <input type='radio' id='r1'name='radios' checked='true'/>
    <label for='r1'><span></span>
      Can I be wrapped when I grow longer and longer?
    </label>
  </span><br/>
  <span class='radio'>
    <input type='radio' id='r2' name='radios'/>
    <label for='r2'><span></span>Vote me up please :)</label>
  </span>
</div>

CSS

span.radio > input[type='radio'] {
  display:none;    
}
span.radio > label {    
  display:table;     
}
span.radio > label > span {
  display:table-cell;
  width:20px;    
  white-space:nowrap;    
}
span.radio > label > span:before {
  content:'';
  width:20px;
  height:20px;
  border-radius:50%;
  display:inline-block;
  box-shadow: 0 0 4px 2px gray inset;
  vertical-align:middle;       
}
span.radio > label > span:after {
  content:'';
  position:relative;    
  display:inline-block;
  vertical-align:middle; 
  left:-16px;    
  width:12px;
  height:12px;
  border-radius:50%;
  box-shadow:0 0 3px 1px red;
  background:radial-gradient(circle at 2px 2px, white, red);
  visibility:hidden;
}
span.radio > label:hover > span:before {
  box-shadow: 0 0 5px 3px orange inset;
}
span.radio > input[type='radio']:checked + label > span:after {
  visibility:visible;
}
span.radio {    
  display:inline-block;
  margin-bottom:3px;
}
/* This is not part of the custom radio input, it's just a group container 
to test the text wrapping ability of the label text */
div {
  border:1px solid black;
  width:400px;     
  font-size:30px;
  padding:5px;
}

请注意,上面HTML代码中的外部div只是一个将2个单选按钮分组的容器,用于测试包装长文本的能力。

这是工作演示

请注意,-webkit-appearance的外观与其他浏览器类型相当。所以你可以尝试一下,看看其他浏览器的结果会是什么样子。

不幸的是,在出现不同的浏览器类型之前,您必须始终考虑它们解析代码的不同方式。没有一个好的解决方案,它总是取决于你试图实现的目标和你的目标受众/浏览器类型。

这里有一个例子:

.thing {
  -webkit-appearance: value;
  -moz-appearance:    value;
  appearance:         value;
}

示例信用:外观|CSS技巧

此外,如果您想了解更多关于不同CSS属性及其浏览器供应商特定变体的信息,这里有一个非常好的资源:供应商前缀的CSS属性概述