Go to homepage

Projects /

Vertical text alignment in buttons and inputs

Vertical text alignment in buttons and inputs

Have you ever struggled with vertically aligning the content of your interactive elements? You're in good company. A lot of us do.

In this article, we'll look at how to center the content of buttons and input elements using line-height, padding, and flexbox.

⚡️ Design 10x faster with our library of COMP_NUM components →

So, what's our goal here?

We want to build a system where:

  1. the content of buttons and input elements is perfectly aligned
  2. buttons and input elements have the same height
  3. font-size, line-height, padding, and border determine the size of buttons and inputs*

*An alternative approach would be setting a fixed height (e.g., height: 40px;) and a line-height equal to the height value (e.g., line-height: 40px;) for all buttons and inputs. However, using padding (instead of a fixed height) is safer because the button will adapt to its content under all circumstances.

Basic button and input style #

The height and vertical alignment of buttons and inputs is determined by the combination of borders, padding, font-size, and line-height.

factors influencing button/input height
factors influencing button/input height

With that in mind, let's define the basic style of buttons and inputs:

<input class="form-control" type="text" value="Input element">
<button class="btn">Button</button>

<style>
  .btn, .form-control {
    /* reset user agent stylesheet */
    background-color: transparent;
    padding: 0;
    border: 0;
    border-radius: 0;
    color: inherit;
    appearance: none;

    /* make sure properties affecting height have same value */
    font-size: 1em;
    line-height: 1.2;
    padding: 0.5em var(--padding-x);
    border-width: 2px;
    border-style: solid;
  }
  
  /* button */
  .btn {
    display: inline-flex;
    justify-content: center; /* center the content horizontally */
    align-items: center; /* center the content vertically */
    --padding-x: 1.2em;
    border-color: transparent; /* hide button border */
  }
  
  /* input */
  .form-control {
    --padding-x: 0.5em;
  }
</style>

Takeaway points from the above snippet:

  • We set the display value of the buttons equal to inline-flex so that we can use the justify-content and align-items properties to center the content (particularly handy if you place an icon inside a button).
  • We apply the same vertical padding, font-size, line-height, and border-width to buttons and inputs.
  • Even tough we don't plan on adding a visible border to the buttons, we apply it anyway (with a transparent color) to make sure buttons and inputs have the same height.
  • The line-height value needs to be slightly bigger than "1". If you use "1", the input elements won't accept it, and they'll be taller than the buttons. In our example, we're applying "1.2" (you could use "normal" if you prefer).

This basic style will ensure buttons and input elements have the same height and that their content is vertically aligned. You can modify their font-size (e.g., set a fixed font-size) or apply a different font-family, and it won't affect the alignment. After all, we're just pushing the content using padding and border.

You can also scale them up/down taking advantage of the Em units.

Make 'em pretty #

All left to do is creating a bespoke theme for our buttons and inputs:

Exceptions #

There may be cases where we need to set a fixed height for our button/input elements, and the default line-height will break the alignment.

In such cases, we can remove the vertical padding and set the line-height equal to the height value.

Here's a workaround based on creating height utility classes that behaves slightly differently when applied to buttons and inputs:

.height-30, .height-40, .height-50 {
  height: var(--height);

  &.btn, &.form-control {
    line-height: var(--height);
    padding-top: 0;
    padding-bottom: 0;
  }
}

.height-30 {
  --height: 30px;
}

.height-40 {
  --height: 40px;
}

.height-50 {
  --height: 50px;
}

Feedback? #

Do you use a different method you'd like to share? Let us know on Twitter!

Project duplicated

Project created

Globals imported

There was an error while trying to export your project. Please try again or contact us.