DocuSign Dev Blog

Brought to you by the development teams at DocuSign

Custom Scalable CSS Radio Buttons

Radio buttons are essential when building forms and dialogs. Sadly enough, there are limited options for styling them. Developers might use one of the following methods to a certain degree of success:

However, at DocuSign we have a very specific requirement — the user needs to be able to “zoom in” on the document and the radio buttons need to get bigger.

We call this “scalable” css buttons, because we need many things to increase in size as we “zoom in” (such as the border thickness).

We use CSS to re-draw the default HTML radio buttons. We did it by hiding the default <input> field, using <label>s with the for attribute and a nested div with border-radius. This way developers can control radio buttons to a pixel (presumably with server-side or front-end width/top/left manipulation).

The custom scalable CSS radio buttons demo:

Try the CSS radio button example yourself in JSFiddle.

To implement our custom CSS radio button, we’re using four containers:

  1. wrapper: .radio-tagger
  2. grey circle: .radio-outer
  3. gradient circle: .radio-inner
  4. blue select circle: .radio-select

We hide the default <input> element (but still keep it in DOM) and put the circles inside of the <label>. This way when users click on the circles, the label will trigger a change event on the input element.

This is accomplished via the for and id attributes on label and input respectively.

Here is the HTML code for a single button with the size of 20 pixels:

<div class="radio-tagger">
  <input type="radio" name="Radio-Group-Small" id="radio1">
    <label for="radio1">
      <div class="radio-outer" style="top: 4px; bottom: 4px; left: 4px; right: 4px;">
      <div class="radio-inner" style="top: 1px; bottom: 1px; left: 1px; right: 1px;">
      <div class="radio-selected" style="top: 2px; bottom: 2px; left: 2px; right: 2px;">
      </div>
      </div>
    </div>
  </label>
</div>

We have inline styles because those elements are dynamically generated from a Backbone.js view. Changing of the button’s size is simple and could be done via jQuery, e.g.,

$('radio-tagger').css({width:100px;height:100px});
$('radio-outer').css({
  top: 12px;
  bottom: 12px;
  left: 12px;
  right: 12px
  });
$('radio-inner').css({
  top: 2px;
  bottom: 2px;
  left: 2px;
  right: 2px
});
$('radio-selected').css({
  top: 5px;
  bottom: 5px;
  left: 5px;
  right: 5px
});

As a result we’ll have a similar radio button (larger than the first) “perfectly” scaled with an increased border size when we “zoom in”:

<div class="radio-tagger">
  <input type="radio" id="radio2">
    <label for="radio2">
      <div class="radio-outer" style="top: 12px; bottom: 12px; left: 12px; right: 12px;">
        <div class="radio-inner" style="top: 2px; bottom: 2px; left: 2px; right: 2px;">
          <div class="radio-selected" style="top: 5px; bottom: 5px; left: 5px; right: 5px;">
          </div>
      </div>
    </div>
  </label>
</div>
comments powered by Disqus