This post was published 9 years ago

There's a chance things are out of date or no longer reflect my views today

How to consistently style form elements

One of the trickiest things to deal with cross browser is the styling of form elements. All browsers influence these strictly, but over the years the ‘appearance’ property has been present in WebKit and Blink browsers, and Firefox to help gain some control. More recently it’s been added to Edge. It is a little more to it than just using this property. I’ll explain the advantages and drawbacks to this and how I handle it. The goal of this post is to give you the base for you to apply your visual style on top of. I will be covering text, button and select elements.

303 views

How to consistently style form elements (featured image)

One of the trickiest things to deal with cross browser is the styling of form elements. All browsers influence these strictly, but over the years the ‘appearance’ property has been present in WebKit and Blink browsers, and Firefox to help gain some control. More recently it’s been added to Edge.

It has a little more to it, than just using this property. I’ll explain the advantages and drawbacks to this and how I handle it. The goal of this post is to give you the base for you to apply your visual style on top of. I will be covering text, button and select elements.

Starting with a base

The first thing you need to do is set up a good base. To freely style your form elements we need to use appearance: none. The support is good, and this does much of the hard work for us.

Prefixes are necessary, -webkit- and -moz-. Also, as noted by Can I use, Edge and IE Mobile support the -webkit- prefix.

However, there will be some more visual browser defaults that are in place. That is border, box-shadow and border-radius, background-colour and font-family. Replacing these with your own preferences, or removing altogether solves that.

.input-base {
  appearance: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  background-color: #fff;
  font-family: Helvetica Neue, Arial, Helvetica, sans-serif; }

Getting a consistent height in Firefox

Firefox has long been known to be a pain for its default line-height. As of Firefox 41, this is still present in <select> elements, you have the freedom to change it on the majority of text/button like elements from what I have found.

The line-height is set to normal by default. I stick with this if I’m not going to be using <select> anywhere. If I’m using <select>, I will set a height, equivalent line-height and only apply padding to the sides.

I’m not a huge fan of setting the height, for a few reasons.

  • It means you need to change more, to adapt it at a later point
  • You have to introduce another set of CSS for a textarea
  • If button text breaks on to a new line it’s less graceful

Getting a consistent height in Edge

Edge is all well and good until it concerns select elements, like Firefox. So the same recommendation stands, setting the height.

Base without <select>

.input-base {
  appearance: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  background-color: #fff;
  font-family: Helvetica Neue, Arial, Helvetica, sans-serif;
  line-height: normal;
  padding: 12px; }

Base with <select>

.input-base {
  appearance: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  background-color: #fff;
  font-family: Helvetica Neue, Arial, Helvetica, sans-serif;
  line-height: normal;
  padding: 0 12px;
  height: 44px;
  line-height: 44px; }

Drawbacks

WebKit and Blink based browsers will handle all form elements much nicer and more consistently, than the likes of Edge and Firefox. With the two applying harder to adjust styles (particularly where it concerns <select>). So while I favour an approach which applies the littlest amount of CSS initially. You may find the height and line-height approach serves you better in the long run.

Other comments

I have seen other approaches for handling the Firefox issue. This only appears to apply to type=submit, so it may be possible to line it up next to a <select> by applying additional padding.

If you view the following pen in Firefox it demonstrates this. I think this approach may vary, and I may explore it further and update this post with a more definitive answer.

See the Pen vNJLwm by Steve (@stevemckinney) on CodePen.

Hopefully, this helps with your styling troubles.

View on Github