【发布时间】:2019-05-01 00:45:51
【问题描述】:
我得到了一个带有方形单选按钮的设计。
有没有办法让单选按钮看起来像这样?
我想我可以做到这一点的唯一方法是使用图像,并通过$.on('click') 方法交换检查/检查状态。
【问题讨论】:
-
您不必使用图像,您可以使用 CSS,但这是首选方式,因为单选按钮是由浏览器生成的。
我得到了一个带有方形单选按钮的设计。
有没有办法让单选按钮看起来像这样?
我想我可以做到这一点的唯一方法是使用图像,并通过$.on('click') 方法交换检查/检查状态。
【问题讨论】:
只需 CSS 即可轻松完成,无需 JS。基本概念是为输入的兄弟元素设置样式,创建一个“假”单选按钮:
/*
* Hide the inputs.
*/
input {
display: none;
}
/*
* Then, style the label so it looks like however you want.
* Here's a quick rundown of how I did it here:
*/
/*
* Some basic positioning styles, and we give it the pointer cursor to show
* that it's clickable
*/
label {
display: inline-block;
padding: 5px 10px;
cursor: pointer;
}
/*
* With how I decided to build this, the position: relative is super important.
* We're going to position a pseudo element within this element(As it is the containing box)
*/
label span {
position: relative;
line-height: 22px;
}
/*
* Because we're using pseudo elements, a content property is required to make them appear.
*/
label span:before,
label span:after {
content: '';
}
/*
* We are using the :before peudo elemnt as the actual button,
* then we'll position the :after over it. You could also use a background-image,
* font-icon, or really anything if you want different styles.
* For the specific style we're going for, this approach is simply the easiest, but
* once you understand the concept you can really do it however you like.
*/
label span:before {
border: 1px solid #222021;
width: 20px;
height: 20px;
margin-right: 10px;
display: inline-block;
vertical-align: top;
}
label span:after {
background: #222021;
width: 14px;
height: 14px;
position: absolute;
top: 2px;
left: 4px;
transition: 300ms;
opacity: 0;
}
/*
* This is the most important part of this whole file, if you understand what's happening here
* you can really make this in so many different ways.
*
* We start by selecting the input inside of the label, with "label input". From there we use the
* ":checked" selector to *only* select the input when it is checked. We then use the immediate sibling
* selector(+) to select the span, and then it's pseudo element :after(What we are using to mark the button)
* Because we already styled the :after, all we have to do is set the opacity to 1, making it fade in.
*/
label input:checked+span:after {
opacity: 1;
}
/*
* A little styling for the demo
*/
body {
background: #fbfbfb;
font-family: Arial;
font-weight: bold;
color: rgba(0, 0, 0, 0.7);
}
<label>
<input type="radio" name="radio">
<span>EMAIL</span>
</label>
<label>
<input type="radio" name="radio">
<span>PHONE</span>
</label>
查看代码 cmets 以获得更深入的解释,但这里是基础知识:
首先创建一个<label> 作为包装器。我们使用标签是因为在其上触发的事件也会在关联的输入上触发:
<label></label>
给它添加一个输入:
<label>
<input type="radio" name="demo">
</label>
请记住,单选按钮必须具有相同的名称才能进行分组。现在我们在输入之后抛出一个<span>,所以我们的CSS中有一些目标。
<label>
<input type="radio" name="demo">
<span></span>
</label>
HTML 已经全部设置好了。检查CSS那里的解释,它会更容易理解。
【讨论】:
这是我所知道的最简单的,一个不需要标签或脚本的纯 CSS 解决方案。完全兼容需要几个供应商前缀:
input[type='radio'] {
box-sizing: border-box;
appearance: none;
background: white;
outline: 2px solid #333;
border: 3px solid white;
width: 16px;
height: 16px;
}
input[type='radio']:checked {
background: #333;
}
如上所述,box-sizing 和 appearance 属性应以供应商为前缀:
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
【讨论】:
您不需要设置单选按钮的样式。只需使用 div:
小提琴示例:http://jsfiddle.net/kLGf4/2/
html:
<section>
<header>
<h1>Perfered Method of Contact</h1>
</header>
<div> <span>Choice 1</span>
<div class="square-radio square-radio--clicked">
<div class="square-radio--content"></div>
</div>
</div>
<div> <span>Choice 2</span>
<div class="square-radio">
<div class="square-radio--content"></div>
</div>
</div>
</section>
css:
.square-radio {
border: 1px solid black;
margin: 2px;
width: 40px;
height: 40px;
position: relative;
}
.square-radio--clicked .square-radio--content{
margin: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: black;
width: 20px;
height: 20px;
}
js:
$(document).ready(function () {
$(document).on("click", ".square-radio", function () {
$(this).toggleClass("square-radio--clicked");
});
});
【讨论】:
input[type=radio] {
padding: 0.5em;
-webkit-appearance: none;
outline: 0.1em solid black;
outline-offset: 0.1em;
}
input[type=radio]:checked {
display: inline-block;
background-color: #000;
}
<label for="radioA"><input type="radio" name="radio1" value="A"/> A</label><br>
<label for="radioB"><input type="radio" name="radio1" value="B"/> B</label><br>
<label for="radioC"><input type="radio" name="radio1" value="C"/> C</label><br>
<label for="radioD"><input type="radio" name="radio1" value="D"/> D</label>
【讨论】:
试试这个:
HTML:
<label class="active">
Email
<span></span>
<input type="radio" name="n1" value="email" checked />
</label>
<label>
Phone
<span></span>
<input type="radio" name="n1" value="phone" />
</label>
CSS:
label {
width: 125px;
display: block;
float: left;
}
label input {
display: none;
}
label span {
display: block;
width: 17px;
height: 17px;
border: 1px solid black;
float: left;
margin: 0 5px 0 0;
position: relative;
}
label.active span:after {
content: " ";
position: absolute;
left: 3px;
right: 3px;
top: 3px;
bottom: 3px;
background: black;
}
JS(需要 jquery):
$(document).ready(function () {
$('label').click(function() {
$('.active').removeClass("active");
$(this).addClass("active");
});
});
这是一个小提琴,您可以在其中看到它的实际效果:http://jsfiddle.net/wqdHE/2/
【讨论】:
在搜索在 Bootstrap 上下文中实现方形单选按钮时,我最终找到了这篇 SO 帖子。
我还在网上找到了其他资源,其中大部分是基于纯 CSS 的。这篇文章中的大多数答案也是基于纯 CSS。
作为非 CSS 开发人员,涉及伪元素的纯 CSS 解决方案,我发现它们冗长且令人费解。令人费解是因为我无法通过在浏览器上的开发人员工具中检查样式来弄清楚解决方案是如何工作的。
因此我更喜欢基于 JS 的解决方案,@agconti 的回答 https://stackoverflow.com/a/24517110/936494 有助于推导它。下面我发布我的工作解决方案
环境
HTML
<div class="form-horizontal">
<div class="form-group">
<div class="col-md-offset-1 col-md-10 square-radios-container">
<div>
<div class="square-radio">
<div class="square-radio-content"><i class="fa fa-check fa-fw"></i></div>
</div>
<span class="square-radio-label">Option 1</span></div>
<br />
<div>
<div class="square-radio">
<div class="square-radio-content"><i class="fa fa-check fa-fw"></i></div>
</div>
<span class="square-radio-label">Option 2</span></div>
</div>
</div>
</div>
CSS
.square-radio {
border: 2px solid #ccc;
border-radius: 4px;
width: 1.25em;
height: 1.25em;
float: left;
.square-radio-content {
display: none;
margin-top: -8px;
margin-left: -2px;
color: #00CDFF;
font-size: 18px;
}
}
.square-radio-label {
margin-left: 6px;
font-weight: bold;
}
JS
(function ($) {
bindClickEventOnSquareRadios = function() {
var squareRadios = $('.square-radios-container').find('.square-radio');
squareRadios.off('click').on('click', function(event) {
var squareRadioObj = $(this);
// Reset radio selection for all radios except the one clicked.
var squareRadiosContainerObj = squareRadioObj.closest('.square-radios-container');
var presentlyCheckedRadio = squareRadiosContainerObj.find('.square-radio-clicked').find('.square-radio-content').hide();
presentlyCheckedRadio.find('.square-radio-content').hide();
presentlyCheckedRadio.removeClass('square-radio-clicked');
// Show the clicked radio as checked
squareRadioObj.addClass('square-radio-clicked');
squareRadioObj.find('.square-radio-content').show();
});
};
}) (jQuery);
$(document).ready(function(){
bindClickEventOnSquareRadios();
});
渲染的输出看起来像
希望这对喜欢基于 JS 的解决方案的人有所帮助。
注意:需要调整样式以匹配所需的偏好。
【讨论】: