Form Widgets: Translating the Same Style Across Multiple Browsers

Over 90% of websites contain at least one form – a contact, subscription, or search form. From a user’s perspective, a form usually contains some fields and a submit button. From a developer’s perspective, things can become more complex.

Nowadays, web designers are asking for a modern look and feel from the form widgets in order to match the design of the website. However, most of the time this cannot be done out of the box due to browser restrictions.

In this article, “browsers” refers to the latest version of Chrome, Firefox, Safari and IE11, but most of the examples should work on older versions of the browsers as well.

“Form widgets” refers to the following: select, radio button, and checkbox. Naturally these are not the only form widgets that we can work with on HTML5, but these are the challenging ones when it comes to styling, so we will focus on them in this article. The rest of them can be styled with few, if any, problems across platforms.

A best practice when starting styling a website is to reset the default style of the browser. If you are using a framework like Twitter Bootstrap or Zurb Foundation, you don’t have to worry because it already takes care of resetting the style, but there might be cases when you need to style from scratch. In these cases, you can use Meyer’s reset file.

Resetting the default style of a browser is important because you can be sure that your HTML elements look the same on all browsers. All web developers can agree that there are some exceptions: form widgets.

Why don’t form widgets look the same on all browsers?

Our reference browsers are built upon three rendering engines. Both Chrome and Safari use Webkit, Firefox uses Gecko (a “custom made” Mozilla rendering engine), and IE uses Trident. Form widgets are built-in controls supported by each browser, so they render differently depending on the OS and browser you are using.

 

formwidgets_1

As time goes by, new ideas and solutions appear that help us achieve our goal: the same style for form widgets on all browsers. I will discuss some of them, but I might not know about all of the new possible solutions, so feel free to add comments with your ideas.

Checkable Items

Checkable items are widgets whose state can change by clicking on them. There are two kinds of checkable items: the radio button and the checkbox. Both use the “checked” attribute to indicate whether the widget is checked or not.

Let’s consider the following Bootstrap example:

<div class="checkbox">
  <label>
    <input type="checkbox">
    Option one
  </label>
</div>

Styling a checkbox or a radio button by itself can be hard and messy. For example, you are not meant to change the sizes of checkboxes and radio buttons, and browsers can react very differently if you try to do so.

So what’s left to do?

When it comes to styling a checkbox or a radio button, I usually have 2 approaches depending on the restrictions that I might encounter. The end goals of both are hiding the checkbox/radio button and simulating a new (and styled) one.

1) Update HTML and use CSS: This method is very simple and straightforward. Using the example above, we need to add a <span></span> after the <input> and style it accordingly.

HTML:

<div class="checkbox">
  <label>
    <input type="checkbox" class="field-checkbox">
    <span class="lbl"></span>
    Option one
  </label>
</div>

CSS:

First we need to hide the current checkbox.

 .field-checkbox {
 z-index: -100!important;
 width: 1px!important;
 height: 1px!important;
 clip: rect(1px,1px,1px,1px);
 position: absolute;
}

Then we’ll create a fake checkbox, which is really a square with a border. We will use Font Awesome to simulate the checked state of the new checkbox.

.lbl:before {
cursor: pointer;
font-family: fontAwesome;
font-size: 12px;
color: #FFF;
content: "\a0";
background-color: #FAFAFA;	
border: 1px solid #c8c8c8;
box-shadow: 0 1px 2px rgba(0,0,0,.05);
display: inline-block;
text-align: center;
height: 20px;
line-height: 20px;
width: 20px;
position: relative;
}

Now we have the new styled checkbox. All that’s left to do is simulate the checked state.

.field-checkbox:checked + .lbl:before {
 content: '\f00c';
 color: #32a3ce;
 background-color: #F5F8FC;
 border-color: #adb8c0;
 font-size: 18px;
}

Here is the result:

Before

formwidgets_2

After

formwidgets_3

2) Do not update HTML, but style with CSS and JS: I use this solution when I cannot update the HTML because it’s generated from a CMS or framework and I have to work with it as it is. Essentially, it’s the same as the first method, but without the extra <span></span>.

HTML:

<div class="checkbox">
  <label>
    <input type="checkbox">
    Option one
  </label>
</div>

As you can see, the HTML didn’t change.

CSS:

First we need to hide the current checkbox.

 .field-checkbox {
 z-index: -100!important;
 width: 1px!important;
 height: 1px!important;
 clip: rect(1px,1px,1px,1px);
 position: absolute;
}

Now we need to create a fake checkbox, which is just a square with border. Just like in the first example, we will use Font Awesome to simulate the checked state of the new checkbox. Because we do not have the extra <span> element, we need to manipulate the <label> instead.

.checkbox label:after {
cursor: pointer;
font-family: fontAwesome;
font-size: 12px;
color: #FFF;
content: "\a0";
background-color: #FAFAFA;	
border: 1px solid #c8c8c8;
box-shadow: 0 1px 2px rgba(0,0,0,.05);
display: inline-block;
text-align: center;
height: 20px;
line-height: 20px;
width: 20px;
position: relative;
margin-right: 5px;
float: left;
}

Now we have a new styled checkbox.Now we just have to simulate the checked state. To do this, we need to use JavaScript. Why? We can’t style the label;after based on the state of the <input> because the <input> is placed inside the <label>.

The script we need is quite simple: we add an active class on the <label> when the <input> is checked. We use jQuery in this example, so be sure to have it added on your page before you start writing your script.

JavaScript:

<script type="text/javascript">
        $(document).ready(function(){
            $('.field-checkbox').on('click', function() {
                $(this).closest('label').toggleClass('checked');
            });
        });
    </script>

Now that we have the class toggling on the label, we can simple style the new checkbox to simulate its active state.

CSS:

.checkbox label.checked:after {
 content: '\f00c';
 color: #32a3ce;
 background-color: #F5F8FC;
 border-color: #adb8c0;
 font-size: 18px;
}

The result is identical to the last one:

Before

formwidgets_2

After

formwidgets_3

As you can see, it’s nothing complicated. For styling radio buttons you can use the same approach.

Selects

The <select> element is considered an ugly widget because it’s impossible to style it consistently across platforms. However, some other things are possible.

I don’t recommend trying to fix it with only CSS because it will never work as expected. If you want to have full control over <select> widgets, then you have no choice but to rely on JavaScript.

There is an article, titled “How to build custom form widgets,” that helps you build your own <select>, but I would also recommend you use one of the following libraries:

While there are still dark spots when using CSS with HTML forms, there are often ways to get around them and build custom widgets that look nice and are uniform on all of the browsers.

User Experience has become one of the most important factors that keeps users on websites. Even if your website has a wealth of useful information, if it’s hard to access or understand, or if the design is dated, then users will leave it and may never come back. Form elements are an integral part of the overall website, so you should never forget to style them correctly.

If you’ve enjoyed my article, please feel free to leave a comment or ask any questions you may have.

 

Adelina Diacu

Adelina Diacu

Software Engineer

Adelina Diacu is a Software Engineer at the 3Pillar Global Timisoara office. She has over 4 years of experience in front-end development, specifically HTML, CSS, and JavaScript. In her leisure time, she loves to travel, drink tea, and read novels.

Leave a Reply

Related Posts

Costovation – Giving Your Customers Exactly What They ... On this episode of The Innovation Engine podcast, we delve into “cost-ovation,” or innovation that gives your customers exactly what they want – and n...
AI & Machine Learning Will See You Now, and Other Takea... A 3Pillar team and I spent a few days in Santa Clara recently for the 12th annual Health 2.0 Conference. As usual, we spent some time after the confer...
DevSecOps – The Latest Trends in Application Security ... I spent a very rewarding couple of days at DevSecCon in Boston recently. The conference focused on DevSecOps, which is a catch-all phrase for addressi...
Designing the Future & the Future of Work – The I... Martin Wezowski, Chief Designer and Futurist at SAP, shares his thoughts on designing the future and the future of work on this episode of The Innovat...
Selecting The Minimum Viable Toolset for Product Managers Recently I was attending a machine learning conference and during a break, found myself deep in conversation with fellow product managers. As is typic...