Make Forms Fun with Flexbox

Curious about deep-diving into Flexbox? Check out our Master CSS Layouts with Flexbox course by front-end dev and General Assembly London teacher Guy Routledge. It’s available for all SitePoint members. Watch our sample video from the course below.

Loading the player…

I’ll come clean: HTML forms are rarely fun – but they’re a necessary part of web development. Fortunately, some historical difficulties can be alleviated with CSS flexbox.

Consider how forms are typically coded without flexbox. What HTML mark-up would you use for the following fields?

The HTML source order of the label and field is inconsistent and depends on the type. The label typically comes before the field but is better after checkboxes and radio buttons. You must re-order your mark-up if you change the type.

Consistently aligning and sizing inputs, textareas and select boxes can be difficult. Most have default styles which can be awkward to change in some browsers.

Aligning a label next to its field requires trial and error to get the positioning correct.

It’s (currently) impossible to style a label according to the field’s activation or content state when it appears first.

Flexbox can solve these issues. We can use clean and consistent HTML where the label is placed after every field and it’s not necessary to add helper CSS classes.

What’s Flexbox?

Flexbox is a magical way to layout multiple elements on the page. They can be aligned in horizontally, vertically, in order, reversed and sized in relation to other elements. Flexbox can be confusing and, even after using them for months, you’ll need to consult documentation now and again. However, the most basic CSS to enable flexbox:

.container {
display: flex;
}

That’s it. All child elements of the .container are now flexbox items which, by default, will size themselves into a single row.

The main difference between flexbox and grid systems (such as the new CSS Grid Module) is that flexbox is one-dimensional. Flexbox items are laid in a line and wrap when necessary. Grids are two-dimensional with defined columns and non-wrapping rows.

Flexbox is less powerful than a grid but it’s ideal for laying out smaller components such as navigation menus, lists and form fields.

Why no Classes?

Those who have adopted CSS philosophies such as SMACSS or BEM will be horrified by the dearth of class definitions in this article. The HTML and tag-targetting CSS is intended to keep the code clean and aid understanding without distraction.

You could consider the code as a base style for all forms on your site – presuming you have a consistent layout throughout. You can add classes should you want to use but they may not necessary for smaller sites or demonstrations.

We apply a width and padding to the label to ensure they align consistently. One disadvantage of flexbox is that you may need to adjust this width if you introduce longer text labels.

Note the flex: 1 1 auto setting for input, textarea and select fields. flex is a shorthand property which specifies how the item can alter its dimensions to fill the available space. The three values are:

flex-grow – the amount of space a flex item can grow in relation to others, e.g. a value of 2 would permit the item to be twice the width of any item with a value of 1.

flex-shrink – similarly, the amount of space a flex item can shrink in relation to others.

flex: 1 1 auto essentially says: use whatever space remains. Our field elements are sized the same and there’s no need to mess around with paddings and borders!

Unfortunately, our checkbox fields are now styled incorrectly (yes, that wouldn’t have happened if we used class names!) but we can target checkboxes and radio fields directly to fix that. The following code places the field first again, stops it using all the space and applies a margin which matches our label width set above:

Older browsers display all fields before the label but the tab ordering remains correct and it is obvious which field you’re using.

My only hesitation is screen readers. Confusion could arise if a reader relies on the HTML source order rather than the associated label text. I’m not aware of any specific issues but please let me know if you encounter one!

Finally, if this encourages you to apply flexbox liberally over your forms, be aware that display: flex cannot be applied to <fieldset> elements owing to bugs in Chrome and Firefox. Hope that tip saves you some of the hours I wasted!

Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler.