Question

-webkit-appearance does a wonderful job at letting you customize the appearance of your radio buttons. However, browsers that don't use webkit and older browsers, don't really support this. So it wont work.

I am looking for a solution that will work with both, browsers that don't use webkit (like Firefox and IE) and older webkit browsers that don't support CSS3.

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;
}

Any thoughts/solutions?

Was it helpful?

Solution

Realizing an idea sometimes is not really easy. If user just need to click/hover on the circle (of the radio button) to interact with it, we can easily customize the radio. But the normal behavior of a radio button is also allow user to click/hover on the label text to interact with it. That means we may need one more label (for the text). But it's not such easy. That label can only allow user to click to interact with the hidden radio, hovering on that label won't effect anything (normally that label is appended at last, so we also have no way to traverse backwards to select the fake radio (which are made by 2 pseudo-element :before and :after). So I decided to use only 1 label. This label contains an empty span element as the first child, following this span is of course the text for the radio button. The span element is where we style the fake radio. However if letting them inline by default and the text is long, it will jump to the next line and vertically line up with the left edge of the fake radio (which is right above at the first line) , this is considered to be very ugly and should be avoided. So we need to make the label displayed as a table (using display:table), the first column is the span element (apply display:table-cell), the label text will be automatically wrapped by the second column. That way when the text is long, all the lines will be wrapped by the second column.

Here are the code details:

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;
}

Note that the outer div in the HTML code above is just a container grouping the 2 radio buttons to test the ability to wrap the long text.

Here is the Working Demo.

OTHER TIPS

Note that -webkit-appearance appearance has it's equivalents for other browser types. So you may try those and see what the result is going to look like in other browsers.

Unfortunately, until different browser types will exist, you will always have to account for the different ways they parse your code. There is no one good solution, it will always be dependant on what you're trying to achieve and your targeted audience / browser type.

Here is an example:

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

Example credit: appearance | CSS-Tricks

Also, here is a very good resource, if you would like to know more on the different CSS properties and their browser vendor specific variants: Vendor-prefixed CSS Property Overview

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top