:focus styling on custom radio input

I have a custom radio input style that is implemented more or less like this:

<input type="radio" id="testradio" class="visuallyhidden custom-radio">
<label for="testradio">...</label>

.custom-radio + label:before {
  content: ""
  // Styling goes here
}

.custom-radio:focus + label:before {
  outline: 1px solid black;
]

This works great except for one nagging detail: the focus style for keyboard navigation. I can tab-select the group of radio buttons and use the arrow keys to change the selected one, but the default :focus outline doesn't appear because the input tag is hidden.

I tried adding my own focus style as above, but this ends up behaving differently than the default browser styling. By default, Chrome (and other browsers I assume) will draw an outline only when you are keyboard-selecting the radio inputs, not when you click them. However, the CSS :focus style seems to apply when clicking the radio input as well (or in this case, clicking the label), which looks really bad.

Basically my question is this: how do I apply a :focus style to a radio input that fully simulates the default browser behavior, ie does not appear from a mouse click focus? Or is there another way I can customize this radio input that will help me preserve the default behavior?

Edit: Here's a JSFiddle demonstrating what I'm talking about. On the first row, you can click a radio button and then navigate with the arrow keys - the outline only appears when you use the keyboard. On the second row, clicking the radio button immediately triggers the focus style.

http://jsfiddle.net/7Ltcks3n/1/


The issue is that apparently Blink browsers maintain focus on radio elements after they are clicked, but Firefox and Safari don't.

As a workaround, you could add a class to the document on mousedown and touchstart that hides your added ring, and remove it on keydown .

Working example:

var className = 'focus-radio-hide-ring';
var add = function() {
    document.documentElement.classList.add(className);
};
var remove = function() {
    document.documentElement.classList.remove(className);
};
window.addEventListener('mousedown', add, true);
window.addEventListener('touchstart', add, true);
window.addEventListener('keydown', remove, true);
.custom-radio {
	position: absolute;
	opacity: 0;
}
.custom-radio + label {
	cursor: pointer;
}
.custom-radio + label:before {
	content: "";
	display: inline-block;
	vertical-align: middle;
	width: 0.75em;
	height: 0.75em;
	margin-right: 0.25em;
	background: #EEEEEE;
	border: 1px solid #AAAAAA;
	border-radius: 50%;
}
.custom-radio:checked + label:before {
	background: #6666FF;
}

/* Add styles here: */ 
.custom-radio:focus + label:before {
	box-shadow: 0 0 4px 1px rgba(0, 0, 0, 1);
}
/* Add disable them again here: */ 
.focus-radio-hide-ring .custom-radio:focus + label:before {
	box-shadow: none;
}
<p><input placeholder="Tab from here"></p>

<input id="testradio" type="radio" class="custom-radio">
<label for="testradio">Example</label>

You can achieve this behavior through scripting. First you need bind keypress event to radio and add the outline style in that handler whenever the radio gets focused or active(by means of adding your custom-radio class to active input). so that you can omit the outline style on mouse click.


This will not fix your issue at the moment, but there is actually a selector coming which does exactly what you need: :focusring (https://github.com/w3c/csswg-drafts/pull/709). Right now it only works in Firefox, but should be coming to other browsers as well.

You could use JS like sumankumarg suggests, but you can also use the border of the fake input to show focus state like so: http://jsbin.com/rofawiginu/edit?html,css,output

链接地址: http://www.djcxy.com/p/70528.html

上一篇: 占位符背景颜色

下一篇: :定制无线电输入的造型