Custom input [type = "radio"]

For form, input [type = "radio"] style is not always so friendly, were mixed in different browsers.

On the radio button custom style, our previous scripts have been used to achieve, but you can now use the new pseudo-classes: checkbox to achieve.

If the style is set to direct the radio button, then this pseudo-class is not practical, because not many style can work on the radio button. However, checking may be based on a state touches the radio button combination selector to other elements to the style set by.

In many cases, whether for a unified form elements, or for a good user experience, we will choose to label elements and input [type = "radio"] used together. When <label> element is associated with a radio button, it may also function as the trigger switch .

Ideas:

1 may be added to generate content (pseudo-element) of <label> element, and based on the status to a radio button to set the style;

2. Then put the real radio button to hide;

3. Finally, the generated content to beautify it.

Solution:

1. The structure of a simple piece of code:

Copy the code
<div class="female">
    <input type="radio" id="female" name="sex" />
    <label for="female">女</label>
</div>
<div class="male">                
    <input type="radio" id="male" name="sex" />
    <label for="male">男</label>
</div>

2. Generate a pseudo-element, as the radio buttons ized, give style add some pseudo-element:

Copy the code
input[type="radio"] + label::before {
    content: "\a0"; /*不换行空格*/
    display: inline-block;
    vertical-align: middle;
    font-size: 18px;
    width: 1em;
    height: 1em;
    margin-right: .4em;
    border-radius: 50%;
    border: 1px solid #01cd78;
    text-indent: .15em;
    line-height: 1; 
}

What it is today:

The original radio buttons still visible, but we add style give check the status of a radio button:

3. Check the state of the radio button to add different styles: 

input[type="radio"]:checked + label::before {
    background-color: #01cd78;
    background-clip: content-box;
    padding: .2em;
}

What it is today: 

4. Now the original radio buttons hidden:

input[type="radio"] {
    position: absolute;
    clip: rect(0, 0, 0, 0);
}

 What it is today:

When hide the original radio button, if you use display: none; so, as it will switch focus from the keyboard tab key to completely remove the queue.

Thus it can be cut, which allows the size of the sheared zero, thus hiding the original radio button.

 

 


 

Here is the old content:

In order to show the greatest degree of their differences, and to look good, first define a number of styles:

Copy the code
<form action="">
    <div class="sex">
        <div class="female">
            <label for="female">女</label>
            <input type="radio" name="sex" id="female">
        </div>
        <div class="male">
            <label for="male">男</label>
            <input type="radio" name="sex" id="male">
        </div>
    </div>
</form>
Copy the code
body { margin: 0; }
input { padding: 0; margin: 0; border: 0; }
.female, .male {
    position: relative;
    height: 40px;
    line-height: 40px;
    margin-left: 40px;
}
.sex label {
    display: block;
    height: 40px;
    width: 40px;
    line-height: 40px;
    font-size: 20px;
    cursor: pointer;
}
.sex input {
    z-index: 3;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 40px;
    margin: auto;
    display: block;
    width: 30px;
    height: 30px;
    cursor: pointer;
}

Then observed each browser, you will find very different:

ie:

edge:

opera:

chrome:

firefox:

For firefox browser, even set the width and height is still no effect, input [type = "radio"] of the circle or the initial state so much. Other browser's performance is inconsistent, in order to achieve the same effect, we need to do is compatible processing.

Ideas:

1. The input [type = "radio"] hidden, opacity: 0; placed in the top, when we click on it, the original event will be able to respond correctly.

2. Custom a circle, a lower layer, the original simulation similar fashion;

3. achieve selected input [type = "radio"] used js, in a custom underlying element changes its original background color.

Code:

Copy the code
<form action="">
    <div class="sex">
        <div class="female">
            <label for="female">女</label>
            <input type="radio" name="sex" id="female">
            <span class="female-custom"></span> <!-- 同下面的 span 一样作为自定义的元素 -->
        </div>
        <div class="male">
            <label for="male">男</label>
            <input type="radio" name="sex" id="male">
            <span class="male-custom"></span>    
        </div>
    </div>
</form>
Copy the code
body { margin: 0; }
input { padding: 0; margin: 0; border: 0; }
.female, .male {
    position: relative; /* 设置为相对定位,以便让子元素能绝对定位 */
    height: 40px;
    line-height: 40px;
    margin-left: 40px;
}
.sex label {
    display: block;
    height: 40px;
    width: 40px;
    line-height: 40px;
    font-size: 20px;
    cursor: pointer;
}
.sex input {
    z-index: 3;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 40px;
    margin: auto; /* 这里及以上的定位,可以让该元素竖直居中。(top: 0; bottom: 0;) */
    opacity: 0;
    display: block;
    width: 30px;
    height: 30px;
    cursor: pointer;
}
.sex span {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 40px;
    margin: auto;
    display: block;
    width: 25px;
    height: 25px;
    border: 1px solid #000;
    border-radius: 50%;
    cursor: pointer;
}        
.sex span.active {
    background-color: #000;            
}
Copy the code
$("#male").click( function () {
    $(this).siblings("span").addClass("active");
    $(this).parents("div").siblings("div").children("span").removeClass("active");
});
$("#female").click( function () {
    $(this).siblings("span").addClass("active");
    $(this).parents("div").siblings("div").children("span").removeClass("active");
});

这样处理后,在浏览器中展示效果全部一样了:

 

扩展:

1. 对于代码中出现的定位,对父元素使用 position: relative; 给子元素使用 position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; 能实现让子元素相对于父元素居中(满足水平居中和竖直居中)显示。如果只是需要竖直居中,则不需要添加 right: 0; 和 left: 0; 的样式。

2. 有时当我们不容易确定子元素的高度时,可以这样设置:对父元素 position: relative; 对子元素 position: absolute; top: 10px; bottom: 10px; margin: auto; 这样一来,子元素的高度就是父元素的高度减去20px后的值了,同样,top 和 bottom 支持百分数,可扩展性更强。

 

优化更新:

需求:

1. 有时候我们需要内联的单选样式;

2. 选中的按钮内的小圆圈不需要占满整个外圈的大小。

思路:

1. 让每一个包裹选择的 div 左浮动;

2. 给父元素添加圆形的外边框,子元素设置一个稍小于父元素大小的背景。

代码:

Copy the code
<form action="">
    <div class="fruit">
        <div class="apple">
            <label for="apple">苹果</label>
            <input type="radio" name="fruit" id="apple">
            <div class="user-defined">
                <span class="circle"></span>
            </div>
        </div>
        <div class="banana">
            <label for="banana">香蕉</label>
            <input type="radio" name="fruit" id="banana">
            <div class="user-defined">
                <span class="circle"></span>
            </div>
        </div>
        <div class="orange">
            <label for="orange">橘子</label>
            <input type="radio" name="fruit" id="orange">
            <div class="user-defined">
                <span class="circle"></span>
            </div>
        </div>
    </div>
</form>
Copy the code
* { box-sizing: border-box; }

body { padding: 50px; }

input { padding: 0; margin: 0; border: 0; }

.fruit:before { content: ""; display: table; }

.fruit:after { content: ""; display: table; clear: both; }

.fruit > div { position: relative; float: left; margin-right: 50px; width: 80px; height: 40px; line-height: 40px; }

.fruit > div:last-child { margin-right: 0; }

.fruit label { display: block; width: 50px; height: 40px; line-height: 40px; cursor: pointer; }

.fruit input { z-index: 3; display: block; opacity: 0; position: absolute; top: 0; bottom: 0; left: 50px; margin: auto; width: 30px; height: 30px; cursor: pointer; }

.fruit .user-defined { z-index: 2; position: absolute; top: 0; bottom: 0; left: 50px; margin: auto; width: 30px; height: 30px; border: 1px solid #000; border-radius: 50%; cursor: pointer; }

.fruit .user-defined span.circle  { display: block; width: 24px; height: 24px; margin-top: 2px; margin-left: 2px; background-color: transparent; border-radius: 50%; }

.fruit .user-defined span.active  { background-color: #000; }
$("input").click(function() {
    $(this).siblings("div").children("span").addClass("active");
    $(this).parents("div").siblings("div").find("span").removeClass("active");
});

效果显示如下:

 

优化更新: (2016年11月07日)

需求:

1. 有时候我们的选择只有两种,比如性别;

2. 这种选择希望能像手机系统设置里的切换一样。

思路:

1. 让每一个包裹选择的 div 左浮动;

2. 让当前子元素添加区别的背景。

预期结果:

代码:

Copy the code
<div class="sex">
    <span class="warning fl">性别确定后将不可更改!</span>
    <div class="select fr">
        <div class="male fl">
            <label for="male">                        
                <input type="radio" name="sex" id="male" checked>男
            </label>
            <span class="btn active">男</span>
        </div>
        <div class="female fl">
            <label for="female">
                <input type="radio" name="sex" id="female">女
            </label>
            <span class="btn">女</span>
        </div>                    
    </div>         
</div>
Copy the code
/*性别*/
.sex span.warning {
    font-size: 1.4rem;
    color: #ccc;
}
.sex .male,
.sex .female {
    position: relative;
    width: 4rem;
    height: 3.9rem;
    z-index: 1;
    line-height: 3.9rem;
    text-align: center;
}
.sex .male label,
.sex .female label {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 4rem;
    height: 3.9rem;
    z-index: 3;
    opacity: 0;
    margin: auto;
    display: inline-block;
    line-height: 3.9rem;
    cursor: pointer;
}
.sex input {
    display: inline-block;
    vertical-align: middle;/*让默认的单选样式的圆圈和“男”“女”的文本没有高差,看起来在同一水平线*/
    height: 2.8rem;
    line-height: 2.8rem;
    margin: 0; /*清除浏览器默认的外边距*/
}
.sex .male span.btn,
.sex .female span.btn {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 4rem;
    height: 2.8rem;
    z-index: 2;
    margin: auto;
    display: inline-block;
    line-height: 2.6rem;
    text-align: center;
    border: .1rem solid #fe5454;
    color: #fe5454;
}
.sex .male span {
    border-top-left-radius: .2rem;
    border-bottom-left-radius: .2rem;
}
.sex .female span {
    border-top-right-radius: .2rem;
    border-bottom-right-radius: .2rem;
}
.sex .male span.active,
.sex .female span.active {
    background-color: #fe5454;
    color: #fff;
}    

If you use jQuery to write switching function, then it is a simple few lines of code:

$(".select label").click(function() {
    $(this).siblings("span").addClass("active");
    $(this).parent().siblings("div").find("span").removeClass("active");
}); 

Finally, the effect of radio made out of the original style no opacity: 0; hide:

Radio original style opacity: 0; hide:

 

Guess you like

Origin www.cnblogs.com/donve/p/10948815.html