Don't Use Fixed CSS height or width on Buttons, Links, or Any Other Text Containers
Published Saturday, October 7, 2023 — 5 minute read
Despite some web design tools specifying CSS
height values for elements like buttons, setting
max-height can actually put you at risk for failing WCAG 2.2 Success Criterion 1.4.4 Resize Text.
This Success Criterion requires:
Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality.
When using fixed values for CSS properties that affect an element's computed height and width, text inside of the element will get cut off when text size is increased.
You might be thinking, "But when I zoom in my browser to 200% the button text looks fine!" This is probably a common misconception with this Success Criterion. I definitely didn't know for a while that browser zoom is only part of the story!
Digging deeper using the Understanding SC 1.4.4: Resize Text docs, it says we (the "authors") have to handle the case when a user only increases the size of their text since their browser (or some other "user agent") might not have zoom capability.
The docs say:
If the user agent doesn't provide zoom functionality but does let the user change the text size, the author is responsible for ensuring that the content remains usable when the text is resized.
This Success Criterion is one reason why it's good practice to use
rem units for the CSS
font-size property and no units for the
line-height property. Text must be resizeable up to 200% without a mechanism like browser zoom.
But how? It's easier to handle than you might think!
Note: For the purpose of these demos, please pretend that we're using
rem units for
font-size. I use
px units here so as to not inherit the base font styles from my website.
First, let's take a look at what happens when text size is increased while using fixed values for
width. Before the text size is increased, the button looks great! Not so great after increasing the text size though.
Before text size is increased
<button style="font-size: 16px; height: 36px; line-height: 18px; width: 82px;"> delete all </button>
After text size is increased
<button style="font-size: 32px; height: 36px; line-height: 18px; width: 82px;"> delete all </button>
Now let's take the same code and try using no units for
padding for affecting the button's
width. We shouldn't see the text get cut off at all when the text size is doubled.
Demo 2a: Before text size is increased
<button style="font-size: 16px; line-height: 1.125; padding: 8px;"> delete all </button>
Demo 2b: After text size is increased
<button style="font-size: 32px; line-height: 1.125; padding: 8px;"> delete all </button>
One technique the Understanding docs for note is C28: Specifying the size of text containers using em units. In my experience I've found this approach harder to maintain as viewport sizes shrink.
Think of a mobile device with large text size settings. It's possible the text container sized with
em units would end up wider than the viewport. If the text is cut off by the device size, that means we're at risk for failing not one but two WCAG 2.2 Success Criterion:
One option for preventing this while using Technique C28 could be to leverage a CSS property like
max-width, but personally I prefer to use the least number of CSS properties possible (for lower long term maintenance cost). Instead of using
max-width it's likely we can just use
padding and let the browser do it's default magic for making elements fit in a viewport.