Web UI Elements Styling


Photo by Mohdammed Ali on Unsplash

Web UI Elements such as buttons have a native style but must be improved. Changing the default style triggers obscure side-effects that are not consistent from a browser to another. As a result, getting consistent appearance requires handling most of the css properties ourself.


The button default font-size is 11px on Safari, and 13.3px on Chrome. It's way too small and should be set to a bigger size. On Safari, setting a bigger font-size will change the default appearance with another default appearance, having a gray gradient background and squared borders. In Chrome, the default appearance remains.

To handle the Safari side-effects, we must replace the gray background with either a white or transparent background or a plain color background. Then, we must also slightly round up the border. Changing the background color produces a side effect in Chrome: it removes the default :active style that triggers while pressing the button, and it removes the default rounded border. Since we already added a rounded border to handle the Safari behaviour, we only need to add back behaviour for the hover and press states (see blow).

In a plain button, the color background acts as the body of the button. As such, it doesn't need a border. In an outline button, the border acts as the boundaries of the button, while the body remains white or transparent. In that case, the border is important and can have the same color as the text.

By default, buttons' padding is too small. The body of the button needs to be bigger than just the text size. We add a bit of vertical padding, such as 0.5 em. And then we add a bigger horizontal padding, such as 1 em.

Primary buttons are plain buttons with a noticeable background color. Secondary buttons are outline buttons where the background is transparent so that it does not distract the attention of the user.

button{ font-size:1rem; font-weight:500; border-radius: 3px; padding:0.5em 1em; cursor:pointer; text-transform:uppercase; } outline-button{ border:2px solid black; background:transparent; } plain-button{ border:none; background:var(--primary-color); color:white; }

Buttons behaviour

Because we have opt-out to the default styling, the button lost its "on-hover" and "on-press" visual feedback. We need to manually add it back.

On hover or on press, we slightly change the background color or opacity, for example through a translucent background that makes the button nicely blend with its container background color.

We may add a small animation on press, for example a translation towards the bottom. It gives the impression of a solid button being pressed. Another option is to scale down the button slightly.

button:hover{ background:rgba(20,20,20,0.1) } button:active{ transform:translateY(1px); // transform:scale(.99); }

Links and Button shaped links

Buttons should not trigger navigation to another page. Navigation is reserved to links. As such, buttons are reserved for in-page actions and are mostly found in single page web-apps. Some links do look like a button but the html tag is still a <a> tag. They are Button shaped links

By default, links are underlined. Nowadays, links don't need to be underlined. They are recognisable through their distinct color. Underlining should only happens when the user hovers on the link.

Button shaped links have a button appearance and convey the meaning of an important link that represents going one step forward in the navigation flow. They lead to a new page. They are styled like buttons so that they stand out more compared to simple inline links.

As such we can use the style defined for either a plain button or an outline buttons, while keeping the general rules that apply to links. They need a few additional tunings: they must be changed from inline to inline-blocks and their color must be reverted to inherit or a specific color.

.buttonShapedLink{ display:inline-block; text-decoration:none; color:inherit; ... generic button style }

You can find the result in action on this codepen(to be updated).


Icons are small images that give a visual clue. They are best included as SVG.


The structure of a table is a bit heavy. The two main subcategories are thead and tbody. In the thead, a unique row represented by tr contains a list of headings th. In the tbody, each row represented again by a tr contains a list of data td.

<table> <thead> <tr> <th>Name</th> <th>Race</th> <th>Class</th> <th>Level</th> </tr> </thead> <tbody> <tr> <td>Laddyvia</td> <td>Human</td> <td>Warrior</td> <td>60</td> </tr> </tbody> </table>

By default, the cells are clumped up together without enough space. To improve the visual experience, it's best to give some padding to each cell, such as 1em.

By default, the table comes with no borders at all. It's best to add a border that separates each line (row) of the table. To do that, we cannot set a border at the tr level. As a result, we need to set the border at the td and th level. To avoid layout side-effects, we need to change the border behaviour so that borders don't take their own space and simply merge with each other when needed. This is called border collapse. The table also needs an exterior border, set at the table level. Finally, each cell on a line can have its own border with the next cell, but this is optional.

By default, all lines have the same background-color. It's best to alternate between two colors, so that each line stand out a bit more compared to its previous and next line.

table { border-collapse: collapse; border: #333 solid 3px; } td, th { border-bottom: black solid 2px; padding: 1em; /* border-right:black solid 1px; */ } tr:nth-of-type(2n) { background: #eee; }

You can find the result in action on this codepen.