你能否将HTML单选按钮样式化成复选框的外观?

64

我有一个html表单,用户填写并打印。打印后,这些表格将被传真或邮寄到政府机构,并且需要看起来与该机构发布的原始表格足够相似,以便政府官员不会发现这是一份复制品。在表单中输入的数据没有保存在任何地方,甚至没有提交回Web服务器。所有重要的是,我们的用户可以在内部网站上轻松找到这些表格,并使用他们正常的键盘输入到表格中进行打印。

在屏幕上,我想保留单选按钮的样式,以强制和传达单选按钮的使用(只选择一个选项)。但是,当它打印出来时,我需要它以方形复选框样式打印,而不是圆形单选按钮样式。我知道如何使用媒体选择器仅为打印设置样式,所以这不是问题。问题在于,我不知道是否可以完全按照我想要的方式设置单选按钮的样式。

如果我无法使其正常工作,我将不得不创建一个复选框来影响每个单选按钮,使用JavaScript来保持复选框和单选按钮同步,并使用CSS在适当的媒介中显示我关心的内容。显然,如果我可以直接设置其样式,将可以节省很多工作。

16个回答

109
三年后,这个问题几乎可以解决了。实际上,在Firefox 1+、Chrome 1+、Safari 3+和Opera 15+中,使用CSS3 appearance属性完全可以实现。结果是看起来像复选框的单选按钮:

input[type="radio"] {
  -webkit-appearance: checkbox; /* Chrome, Safari, Opera */
  -moz-appearance: checkbox;    /* Firefox */
  -ms-appearance: checkbox;     /* not currently supported */
}
<label><input type="radio" name="radio"> Checkbox 1</label>
<label><input type="radio" name="radio"> Checkbox 2</label>
jsfiddle: http://jsfiddle.net/mq8Zq/

注意:由于缺乏供应商的支持和符合性,此功能最终被从CSS3规范中删除。我建议除非您只需要支持基于Webkit或Gecko的浏览器,否则不要实现它。


5
有没有办法在点击之前隐藏这个东西? - Ame
5
仍然在Chrome上看起来像单选按钮。 - Black
2
这个解决方案根本不起作用 :) 我不是盲人,我可以看到呈现的是单选按钮而不是复选框。 - Ion Scorobogaci
这个不起作用。请考虑下面的答案或访问https://www.w3schools.com/howto/howto_css_custom_checkbox.asp。 - Abel Chipepe

27

这是我使用纯CSS的解决方案(Jsfiddle:http://jsfiddle.net/xykPT/)。

enter image description here

div.options > label > input {
 visibility: hidden;
}

div.options > label {
 display: block;
 margin: 0 0 0 -10px;
 padding: 0 0 20px 0;  
 height: 20px;
 width: 150px;
}

div.options > label > img {
 display: inline-block;
 padding: 0px;
 height:30px;
 width:30px;
 background: none;
}

div.options > label > input:checked +img {  
 background: url(http://cdn1.iconfinder.com/data/icons/onebit/PNG/onebit_34.png);
 background-repeat: no-repeat;
 background-position:center center;
 background-size:30px 30px;
}
<div class="options">
 <label title="item1">
  <input type="radio" name="foo" value="0" /> 
  Item 1
  <img />
 </label>
 <label title="item2">
  <input type="radio" name="foo" value="1" />
  Item 2
  <img />
 </label>   
 <label title="item3">
  <input type="radio" name="foo" value="2" />
  Item 3
  <img />
 </label>
</div>


1
在我看来,这是最强大和多才多艺的答案。 - William
1
这是最佳答案 @William - Let A Pro Do IT

25

CSS3 中:

input[type=radio] {content:url(mycheckbox.png)}
input[type=radio]:checked {content:url(mycheckbox-checked.png)}

实际上:

<span class=fakecheckbox><input type=radio><img src="checkbox.png" alt=""></span>

@media screen {.fakecheckbox img {display:none}}
@media print {.fakecheckbox input {display:none;}}

你需要使用JavaScript来保持<img>和单选按钮的同步(最好首先在其中插入它们)。

我使用了<img>,因为浏览器通常配置为不打印background-image。使用图像比使用其他控件更好,因为图像是非交互式的,不太可能引起问题。


9

2021年纯CSS / HTML解决方案。它使用CSS的appearance: none;属性。

目前似乎与所有主要浏览器兼容:

https://caniuse.com/?search=appearance%3A%20none

input[type="radio"]{
   appearance: none;
   border: 1px solid #d3d3d3;
   width: 30px;
   height: 30px;
   content: none;
   outline: none;
   margin: 0;
   box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}

input[type="radio"]:checked {
  appearance: none;
  outline: none;
  padding: 0;
  content: none;
  border: none;
}

input[type="radio"]:checked::before{
  position: absolute;
  color: green !important;
  content: "\00A0\2713\00A0" !important;
  border: 1px solid #d3d3d3;
  font-weight: bolder;
  font-size: 21px;
}
<input type="radio" name="radio" checked>
<input type="radio" name="radio">
<input type="radio" name="radio">


8
可以使用这个 CSS 实现,我隐藏了默认的单选框并制作了一个外观类似于复选框的自定义单选框。 2022 年完美运作。

.css-prp
{
  color: #17CBF2;
  font-family: arial;
}


.con1 {
  display: block;
  position: relative;
  padding-left: 25px;
  margin-bottom: 12px;
  cursor: pointer;
  font-size: 15px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

/* Hide the browser's default radio button */
.con1 input {
  position: absolute;
  opacity: 0;
  cursor: pointer;
}

/* Create a custom radio button */
.checkmark {
  position: absolute;
  top: 0;
  left: 0;
  height: 18px;
  width: 18px;
  background-color: lightgrey;
  border-radius: 10%;
}

/* When the radio button is checked, add a blue background */
.con1 input:checked ~ .checkmark {
  background-color: #17CBF2;
}
<label class="con1"><span>Yes</span>
  <input type="radio" name="radio1" checked>
  <span class="checkmark"></span>
</label>
<label class="con1"><span>No</span>
  <input type="radio" name="radio1">
  <span class="checkmark"></span>
</label>


1
虽然这个代码可以运行,但你没有仔细阅读任务要求。用户要求不添加第二个输入类型。此外,你可能需要简要概述一下这个代码的工作原理。使用自定义选中状态隐藏输入框并显示勾选标记。 - Dinkheller
1
我已经添加了第二个输入字段以确保单选按钮正常工作。现在将选中属性放在第一个输入字段上,它正在工作。 - Muhammad Affan Aijaz

6

我修改了user2314737的答案,使用font awesome作为图标。对于不熟悉fa的人来说,与img相比,一个显著的好处是字体固有的基于矢量的渲染。也就是说,在任何缩放级别下都没有图像锯齿。

jsFiddle

结果

enter image description here

div.checkRadioContainer > label > input {
 visibility: hidden;
}

div.checkRadioContainer {
 max-width: 10em;
}
div.checkRadioContainer > label {
 display: block;
 border: 2px solid grey;
 margin-bottom: -2px;
 cursor: pointer;
}

div.checkRadioContainer > label:hover {
 background-color: AliceBlue;
}

div.checkRadioContainer > label > span {
 display: inline-block;
 vertical-align: top;
 line-height: 2em;
}

div.checkRadioContainer > label > input + i {
 visibility: hidden;
 color: green;
 margin-left: -0.5em;
 margin-right: 0.2em;
}

div.checkRadioContainer > label > input:checked + i {
 visibility: visible;
}
<div class="checkRadioContainer">
 <label>
  <input type="radio" name="radioGroup" />
  <i class="fa fa-check fa-2x"></i>
  <span>Item 1</span>
 </label>
 <label>
  <input type="radio" name="radioGroup" />
  <i class="fa fa-check fa-2x"></i>
  <span>Item 2</span>
 </label>
 <label>
  <input type="radio" name="radioGroup" />
  <i class="fa fa-check fa-2x"></i>
  <span>Item 3</span>
 </label>
</div>


我选择那个简单而美丽的,但我想知道当一个被选中时,是否可以更改所选span的颜色? - mshwf
1
是的,例如这个CSS:div.checkRadioContainer > label > input:checked + i + span { background-color: silver; } - Beej

6
你可以隐藏默认的单选框外观,然后在伪元素中使用"clip-path"绘制选中状态,无需JavaScript。

 label{
     display: block;
      margin-bottom: 10px;
  }

input[type=radio] {
    appearance: none;
    background-color: #fff;
    width: 15px;
    height: 15px;
    border: 2px solid #ccc;
    border-radius: 2px;
    display: inline-grid;
    place-content: center; 
  }

input[type=radio]::before {
    content: "";
    width: 10px;
    height: 10px;
    transform: scale(0);
    transform-origin: bottom left;
    background-color: #fff;
    clip-path: polygon(13% 50%, 34% 66%, 81% 2%, 100% 18%, 39% 100%, 0 71%);
}

input[type=radio]:checked::before {
    transform: scale(1);
}
input[type=radio]:checked{
    background-color:   #0075FF;
    border: 2px solid #0075FF;
}
<label>
    <input type="radio" name="fruit"> Apple
</label>
<label>
    <input type="radio" name="fruit"> Banana
</label>
<label>
    <input type="radio" name="fruit"> Orange
</label>
<label>
    <input type="radio" name="fruit"> Avocado
</label>


2

简洁美观,使用fontawesome字体图标

input[type=radio] {
    -moz-appearance: none;
    -webkit-appearance: none;
    -o-appearance: none;
    outline: none;
    content: none;
    margin-left: 5px;
}

input[type=radio]:before {
    font-family: "FontAwesome";
    content: "\f00c";
    font-size: 25px;
    color: transparent !important;
    background: #fff;
    width: 25px;
    height: 25px;
    border: 2px solid black;
    margin-right: 5px;
}

input[type=radio]:checked:before {
    color: black !important;
}

1

外观属性在所有浏览器中都无法使用。您可以按照以下方式操作-

input[type="radio"]{
  display: none;
}
label:before{
  content:url(http://strawberrycambodia.com/book/admin/templates/default/images/icons/16x16/checkbox.gif);
}
input[type="radio"]:checked+label:before{
  content:url(http://www.treatment-abroad.ru/img/admin/icons/16x16/checkbox.gif);
}
 
  <input type="radio" name="gender" id="test1" value="male">
  <label for="test1"> check 1</label>
  <input type="radio" name="gender" value="female" id="test2">
  <label for="test2"> check 2</label>
  <input type="radio" name="gender" value="other" id="test3">
  <label for="test3"> check 3</label>  

它在IE 8+和其他浏览器中都可以正常工作


有没有可能如何给:before和label加样式,以便当标签文本溢出到下一行时,它与第一行文本在水平方向上对齐? - Srneczek
@Srneczek 我在标签前添加了一个复选框图像,这样你就知道图像的宽度了。如果是这样,请在<label>的文本周围添加<span>,并将其设置为display:block。然后将宽度添加为margin-left。还要将float:left添加到:before伪元素中。希望这可以帮助到你。 - Md Rafee

0

简单而又最优的解决方案。

.custom-radio[type="radio"]{
   appearance: none;
   border: 1px solid #d3d3d3;
   width: 18px;
   height: 18px;
   content: none;
   outline: none;
   border-radius:100%;
   margin: 0;
   
}

.custom-radio[type="radio"]:checked {
  appearance: none;
  border-radius:100%;
  outline: none;
  padding: 0;
  content: none;
  border: none;
}

.custom-radio[type="radio"]:checked::before{
  position: absolute;
  background:#0c1332 ;
  accent-color:blue;
  border-radius:100%;
  color: white !important;
  content: "\00A0\2713\00A0" !important;
  border: 1px solid #d3d3d3;
  font-weight: bolder;
  font-size: 13px;
}
  <p>Please select your favorite Web language:</p>
  <input type="radio" id="html" class="custom-radio" name="fav_language" value="HTML">
  <label for="html">HTML</label><br>
  <input type="radio" id="css" name="fav_language" class="custom-radio" value="CSS">
  <label for="css">CSS</label><br>
  <input type="radio" id="javascript" name="fav_language" class="custom-radio" value="JavaScript">
  <label for="javascript">JavaScript</label>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接