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

4 Reasons Everyone is Wrong About Blockchain: Your Guide to ... You know a technology has officially jumped the shark when iced tea companies decide they want in on the action. In case you missed that one, Long Isl...
3Pillar Recognized as a Leading Experience Designer by Forre... Fairfax-based product development company named to its second Forrester report in 2018 FAIRFAX, VA (June 18) - Today, 3Pillar Global, a global cust...
3 Cloud Optimization Projects That Will Pay for Themselves i... AWS introduced 1,430 new features and tools in 2017, including 497 in the 4th quarter alone. This means that it can be a challenge for even the mos...
The Connection Between Innovation & Story On this episode of The Innovation Engine, we'll be looking at the connection between story and innovation. Among the topics we'll cover are why story ...
Go Native (App) or Go Home, and Other Key Takeaways from App... I just returned from my first WWDC. I feel like I learned more in a week at Apple’s annual developer’s conference than I have in years of actually dev...