Using padding to space an input and label

Something I started doing lately is using the padding
of a <label>
element to create the space between it and an <input>
instead of a margin
or grid/flexbox gap
. I’m sure a bunch of people already do this, but it’s something that only recently dawned on me.
Users sometimes miss their target, clicking/tapping just outside of an element’s bounds. If you use a touchscreen or trackpad you know how common that is. Accuracy gets even worse if you introduce variables like vehicles, movement, and disabilities.
To remedy this, I started using the padding
of <label>
s to make the dead space around inputs clickable as well. A click on a <label>
is treated as a click on its associated <input>
, so this effectively makes an input’s target larger and easier to hit.
The scenario #
Let's say we have some standard radio button markup:
html snippet: HTML for standard radio button markup
html<fieldset> <legend>Do you like apples?</legend> <div> <input type="radio" id="applesRadioYes" name="applesRadio" checked> <label for="applesRadioYes">Yes, I love them</label> </div> <div> <input type="radio" id="applesRadioNo" name="applesRadio"> <label for="applesRadioNo">No, they're disgusting</label> </div> </fieldset>
css snippet: CSS for standard radio button markup
cssfieldset > div { display: grid; grid-template-columns: auto auto; justify-content: start; align-items: center; gap: 1.5rem; } fieldset > div:not(:last-of-type) { margin-bottom: 1.5rem; }
That results in something that looks like this:

But because the space between the radio and label is a grid gutter created with the gap
property, it’s not actively clickable. Check out this demo where you can toggle the clickable areas visually on and off.
See the Pen Radio button with gap spacing by Darin (@dsenneff) on CodePen.
If you click outside of the radio button, label, or in the space between them then nothing happens.
An alternative #
Instead of the gap
property, if I use padding
to create that space then I can make the clickable area much larger.
css snippet: CSS for using padding to space the input and label
cssfieldset > div { display: grid; grid-template-columns: auto; justify-content: start; align-items: center; gap: 0; } fieldset > div:not(:last-of-type) { margin-bottom: .5rem; } fieldset input { grid-column: 1; grid-row: 1; position: relative; z-index: 1; } fieldset label { grid-column: 1; grid-row: 1; padding: .5rem; padding-left: .5rem; position: relative; left: -.5rem; }
Here, I change the wrapping <div>
’s number of grid columns from 2 to 1 and set its gap
property to 0
. I then place both the <input>
and <label>
into the same grid cell by setting their grid-column
and grid-row
properties to 1
.
The <label>
then gets some padding
that increases its footprint around all four sides. The left padding value has a much higher value than the others, which is what creates the space between the radio button and text. Lastly, the position
and left
properties shift the label slightly left.
This all combines to make the radio and text one continuous clickable block with safe zones around all four sides to catch stray clicks. View the clickable areas of the demo below and see how it’s forgiving of clicks that are slightly out of bounds.
See the Pen Radio button with padding spacing by Darin (@dsenneff) on CodePen.
For the obsessive designers out there, this also has the secondary benefit of avoiding that flicker of hover styles that normally occurs when moving a mouse between the <input>
and <label>
.
There’s other ways to accomplish this without using padding
, like using pseudo elements, but this way seems simple and easy to me.
Downsides #
Are there any drawbacks to this approach over the typical margin
or gap
spacing? I haven’t encountered any, but would love to hear if anybody knows of any gotchas.
Conclusion #
Do you use this approach? I’d love to hear how it’s worked for you. It seems so obvious to me now, and it’s become my default on new projects.