Normalize.css: input font: inherit also pulls in line height

Created on 29 Apr 2016  Ā·  39Comments  Ā·  Source: necolas/normalize.css

I have a search form where the parent element sets a line height to vertically centre the text in the form. The following rule brings that line height to the text inside the input in the form:

button,
input,
optgroup,
select,
textarea {
font: inherit; /* 1 */
}

Perhaps this was overlooked? I don't think it's a great 'normalisation' as I don't think anyone would expect this particular aspect of the font style to come through. Perhaps we could be more specific and inherit just the font-face?

bug

Most helpful comment

I just updated to v5.0.0 and noticed, that all my buttons are broken. But all the other elements (like span) that use same classes and look like buttons - they are fine. I've read this thread and understood why this happened.

Dudes, you're totally wrong. I'll explain.

Everything has started with @brendon and his huge line-height (e.g. line-height:100px), which is used to center the content of a search form vertically:
image

But Brendon is now complaining that the input inherits this huge line-height:100px and everything looks awful, like this:
image

So, Brendon, guess what? line-height:100px is a hack. It's not the general purpose of line-height to center objects vertically. Thus you have at least 2 options:

  1. Stop using this hack in this place. Use a more appropriate technique of vertical centering instead.
  2. Or simply define height for your inputs. height+border-box is one of best ways to make inputs look exacly the same in all the browsers.

Okay, what's going on now?

  1. Now normalize.css sets font-family:sans-serif to all the form elements. That means that buttons look differently from the other elements on the site:
    image

font-family:sans-serif is totally useless. All the modern sites use the same font for the buttons as for all other elements. So almost every developer would be glad to have the inheritance here (see #642).

Quote from issue #642:

As a user of this library, the most common thing I do is set a base font for a project. Usually on body. I then appreciate that font being (weakly) inherited by every element automatically. (Weakly, meaning very easy to override in special cases). This is a simple technique to achieve consistent site appearance.
<...>
If my site uses Open Sans as its base font I will probably want my form elements to use Open Sans.

Yes, I understand that normalize.css is about normalization, not convenience. But font-family:inherit makes buttons look exacly the same in all the browsers, so IT IS about normalization.


  1. line-height:1.15 is another terrible idea.
    Many methodologies say that in most of the cases we shouldn't stylish tags. We should use classes instead. Thus many developers have classes like .btn .btn_green .btn_big, which are used to stylish any tags as buttons. No matter is it button or span, they'll be looking exacly the same:
<button class="btn btn_green">Button</button>
<span class="btn btn_green">Span</span>

image

But if we remove the inheritance the perfection is broken:
image

So, for font anything but inherit is a terrible idea.
If you think the opposite, then you're probably doing something wrong. For example, using line-height to center a complex scene vertically.

All 39 comments

I’m not a fan of styling inputs beyond what’s necessary. However, inheriting all font styles may be an expectation of normalize.css. I’m not sure if this particular choice is ā€œthe exception that proves the ruleā€ (which is why body { margin: 0 } happens), and that it must stay in future releases, but I would need a lot more input from the community, particularly from the bootstrap community.

@battaglr, @patrickhlauke, I would very much be interested in your input here, no pun intended. :)

@jonathantneal, @brendon, sadly this is the trade-off of using inherit. In the past using it in other properties has proven to be problematic, as in #502.

Pondering some options I can think of three possible actions:

1) Leave it as it is, accepting the trade-offs of inherit.

2) Remove the normalization altogether —not a good idea IMO.

3) Declare explicit values instead of inherit, using the default values of most browsers, and our own opinionated defaults:

font: small/normal sans-serif;

Or if we want to be even more explicit, and avoid some quirks of the font property we could use:

font-family: sans-serif;
font-size: small;
line-height: normal;

Notes:

I would like to hear other opinions. :smiley:

Hum, apparently I missed a fairly obvious fourth option, that is a middle ground:

font-family: inherit;
font-size: inherit;
line-height: inherit;

If we do this we still have to deal with potential problems of inherit, but by being explicit we don't take anyone by surprise while using the font property that may be a bit confusing for some. Also we avoid inheriting things like font-style, font-weight, etc.

As a bonus point, we could remove the the optgroup declaration.

I don't like the idea to use inherit with _shorthand_ syntax because that affects every single property:

Being _explicit_ seems more reasonable to me. Also because a new property could be added; as it happened with font-stretch that was _not part of the original properties to include in font_.

I agree, that's a great compromise :)

@thierryk, we totally agree on this (thank you for the spec links).

What would you suggest as possible solution for this?

@battaglr using inherit with a limited set of properties is definitely an improvement but I don't see how your suggestion solves the problem. From my understanding, @brendon does not want this:

line-height: inherit;

Or am I missing something? Because his comment ("great compromise") seems to say otherwise...

@thierryk, sorry you're right, I didn't notice the line-height inclusion. I don't think line-height should be inherited by any of those elements. Most tend to have their own 'surroundings' that look weird when a line-height is applied.

My comment should be: It's a great compromise, provided you're inheriting logical aspects of the font. What is 'logical' is probably a matter of opinion.

The specs say that the initial value for line-height is normal. Do we know the discrepancies between browsers and controls regarding the initial value of that property? Because if we _need_ to set a line-height value then it may be better to go with normal rather than inherit as this should lead to more "predictable" results, no?

I’m with @thierryk on this, because line-height: normal would be a spec normalization, and the current style is opinionated, anyway. However, a lot of people might be expecting this with normalize.css, line-height and all, so I hope for more feedback.

I'm happy with normal.

@jonathantneal, @thierryk, @brendon, I may have expressed myself wrong, since I was not necessarily advocating for a particular solution, but hopping to open an interesting discussion (like this one) by presenting some options.

I think that line-height: normal would be a good replacement for inherit —as I mentioned in a previous comment—, but I'll ask the same question than @thierryk:

Do we know the discrepancies between browsers and controls regarding the initial value of that property?

If I'm understanding right, we all agree that would be a good idea to stop using font and just normalize only the 3 properties that —apparently— differ in browsers. Having something like this:

font-family: inherit || sans-serif;
font-size: inherit || ??;
line-height: normal; /* If indeed requires normalization */

Generally I would prefer an _explicit_ value over inherit for these properties, but I'm not sure about font-size.

To be honest, I don't like inherit. If normalize.css is about:

  • Preserving useful defaults, unlike many CSS resets.
  • Normalizing styles for a wide range of elements.
  • Correcting bugs and common browser inconsistencies.

Then I think we should avoid using inherit because this value relates to styles set by authors _instead of styles set by UAs_. In other words, I think normalizes.css should _style elements the same regardless of projects_ and inherit does not help to achieve that.

I understand that most authors expect to have these values inherited but I don't think this is the job of normalizes.css. In my opinion, people should use custom rules targeting form controls for this. normalizes.css should not become a "base"/opinionated style sheet.

I don't know. May be there should be a _companion_ file, containing rules that do not _belong_ to normalize.css but that are pretty much meant to be included in every project.

I would also agree that setting the normalization to line-height: normal would be good, as well as making font-family and font-size match up more (opinionatedly) with the main content/body styles.

@patrickhlauke but how do we draw the line? Don't you think opinionated styles belong to a library?
I know we already have exceptions (i.e. margin:0 on body) but that does not mean there is a good rational for it.

This is a recent comment from @jonathantneal:

This would be much more useful in something like sanitize.css,. normalize.css should not get into overriding OS styling.

I think making font-family and font-size opinionated is the goal of _other_ libraries.

For what it's worth, this is one of the reasons I didn't want to include normalize.css as a dependency on yahoo.com, because I feared we could end up on-boarding things we could not have expected—and this issue is the perfect example of that.

@jovilog in this comment you say:

this removed line [line-height:normal;] (with button added to the selector) seems the only "elegant" way to achieve same-height inputs and buttons across all browsers

but what we're suggesting here is to include that style for input (line-height:normal). I wonder why this is creating a problem in Internet Explorer though (per your comment). It seems this is the default IE styling for input, no?

Basically, I would be happy with the original posters "problem", i.e. inheriting line-height on all elements. My problem is IE is not behaving like the other browsers, see https://jsfiddle.net/8ppqodc4/9/

I could not find a way to make IE (11 and below, don't know about EDGE) behave like the others, so the most unobtrusive way to normalize all browsers seems to be adding

input, button { line-height: normal; }

which was (without button) removed in the commit I commented on. And after the removal, my buttons and inputs were out of line in IE.

So, in my comment, I moaned about the removal of said line. I would like to see it back, except there's a better way to make IE expand the height of the whole input by inheriting line-height.

@jovilog It is not a problem with inheritance per se because the computed value shows the _expected_ line-height value (i.e. 45px), it is just that Internet Explorer ignores that value (line-height has no effect on the layout of the box). Note that this was also the case in Firefox for a very long time.

[line-height:normal + padding] seems the only "elegant" way to achieve same-height inputs and buttons across all browsers

Actually, I think you'd have a better chance to achieve _same height_ across browsers by relying on the height property instead of using line-height + vertical padding (give it a try).

@thierryk

It is not a problem with inheritance per se because the computed value shows the expected line-height value (i.e. 45px), it is just that Internet Explorer ignores that value (line-height has no effect on the layout of the box).

Right, that's true. But is normalize.css about normalizing computed values or what's actually on screen? In most cases, the two are the same, but here?

Keeping elements as flexible as possible is a core concept of modern best practices in (responsive) web design. Using a fix height to somewhat reset appearance seems so against this. Where's my thinking wrong here?

@jovilog

Keeping elements as flexible as possible is a core concept of modern best practices in (responsive) web design. Using a fix height to somewhat reset appearance seems so against this. Where's my thinking wrong here?

You said you were using padding to fix the issue in Internet Explorer, I simply suggested you should give height a try. None of these solutions are "flexible", it is just that height may be a better one.

I was not suggesting to _normalize_ input by styling them with an explicit height.

@thierryk
I'm using padding (and a unitless line-height on the body element) as basics in the author stylesheet to get the basic look I want, which is not unusual, I believe.
I'm not using it to fix the issue with IE. IE applies padding on inputs just like any other browser.

Until the recent removal of input { line-height: normal; }, this worked great.

but what we're suggesting here is to include that style

Yes, yes, please!

@battaglr wrote:

line-height: normal; /* If indeed requires normalization */

I was just substantiating the progress of this issue with a related issue (in my opinion) and example, i.e. inputs _do_ require this normalization (except there's a better way to make IE inherit line-height like the other browsers).

So, ideally, IE would expand the box of inputs with growing (inherited) line-height. Since I don't know how this could possibly be done, I am all for line-height: normal coming back, because this makes inputs look quite consistent across browsers.

[offtopic]
I was not looking for an alternative to padding, which works just fine and is much more flexible than height:

  • padding is ignored by checkboxes and radio buttons, height is not
  • therefore padding can be applied to one low specific selector as a base style, selectors for height need to be unnecessarily specific
  • padding can impossibly clip the text, an explicit height could

[/offtopic]

I think a PR will do now. :)

Since no PR has been made, I’ll be making the PR for this.

  • Remove inherit from the shorthand font, and avoid shorthands in general.
  • Restore inherit to font-family and font-size as another _exception to the rule_.
  • Possibly add normal or a computed value to line-height if normalization is necessary.

@jonathantneal, I was waiting to have some time to tackle this, but needed to iron some things. My thoughts so far:

1) Totally agree on removing font in favor of more specific properties. But I differ in the values you're proposing.

2) Totally agree with @thierryk here regarding inherit:

Then I think we should avoid using inherit because this value relates to styles set by authors instead of styles set by UAs. In other words, I think normalizes.css should style elements the same regardless of projects and inherit does not help to achieve that.

Also notice that inherit has been the reason of many opened issues and unexpected behaviours —that's why we removed color from input, among others.

Regarding the implementation, I would:

I would really like to have the time to test all this.

@battaglr, wonderful! I think we very much agree. Effectively, you are suggesting we use something closer to the computed values than inherit, which in this case I also prefer. We need to make a CodePen test for line-height: normal that I can apply across all of the browsers we support. That will be a goal for this week, if you have not already made it and will not have the time. Thanks a bunch for your notes.

@jonathantneal, awesome! And crazy week over here, so if you have the time to take this go ahead. šŸ˜‰

Test

  1. First, I unset the border, font family, font size, height, margin, and padding on a text input.
  2. I create 3 test inputs; one using line-height: normal, another using line-height: 1.15, and the last not setting the line height at all.
  3. I expect that line-height: normal equates line-height: 1.15, so I set the element’s font size as 40px and measure the offsetHeight of the element, expecting to see 46 because 40 * 1.15 = 46.

Test Results

  1. In most browsers, all 3 tests return 46.
  2. In Chrome 50 for Windows (and 48 for Nexus 9), line-height: 1.15 normalizes the line height, which is otherwise 45.
  3. In Firefox 45 for Mac, line-height: 1.15 really normalizes the line height, which is otherwise 41.
  4. In Safari for iOS 9, the result is always 48 unless you explicitly set the height to a non-auto length. I don’t know what this is due to; shadow elements?

https://app.crossbrowsertesting.com/public/i76b092cd2b52b86/screenshots/z8f9760e01ee5fdbef3e

I met the problem just now, However use line-height: normal works

Thank you @jonathantneal, @battaglr, and all the rest of you who chipped in to fix this one up :)

The font-family should stay inherit IMO, as it overrides the font-family set on html or body in an author stylesheet. I have to set it again on form controls now.
The separation of line-height has the same effect, but is very welcome as I tried to point out in a former comment.

I just updated to v5.0.0 and noticed, that all my buttons are broken. But all the other elements (like span) that use same classes and look like buttons - they are fine. I've read this thread and understood why this happened.

Dudes, you're totally wrong. I'll explain.

Everything has started with @brendon and his huge line-height (e.g. line-height:100px), which is used to center the content of a search form vertically:
image

But Brendon is now complaining that the input inherits this huge line-height:100px and everything looks awful, like this:
image

So, Brendon, guess what? line-height:100px is a hack. It's not the general purpose of line-height to center objects vertically. Thus you have at least 2 options:

  1. Stop using this hack in this place. Use a more appropriate technique of vertical centering instead.
  2. Or simply define height for your inputs. height+border-box is one of best ways to make inputs look exacly the same in all the browsers.

Okay, what's going on now?

  1. Now normalize.css sets font-family:sans-serif to all the form elements. That means that buttons look differently from the other elements on the site:
    image

font-family:sans-serif is totally useless. All the modern sites use the same font for the buttons as for all other elements. So almost every developer would be glad to have the inheritance here (see #642).

Quote from issue #642:

As a user of this library, the most common thing I do is set a base font for a project. Usually on body. I then appreciate that font being (weakly) inherited by every element automatically. (Weakly, meaning very easy to override in special cases). This is a simple technique to achieve consistent site appearance.
<...>
If my site uses Open Sans as its base font I will probably want my form elements to use Open Sans.

Yes, I understand that normalize.css is about normalization, not convenience. But font-family:inherit makes buttons look exacly the same in all the browsers, so IT IS about normalization.


  1. line-height:1.15 is another terrible idea.
    Many methodologies say that in most of the cases we shouldn't stylish tags. We should use classes instead. Thus many developers have classes like .btn .btn_green .btn_big, which are used to stylish any tags as buttons. No matter is it button or span, they'll be looking exacly the same:
<button class="btn btn_green">Button</button>
<span class="btn btn_green">Span</span>

image

But if we remove the inheritance the perfection is broken:
image

So, for font anything but inherit is a terrible idea.
If you think the opposite, then you're probably doing something wrong. For example, using line-height to center a complex scene vertically.

Hi @olegcherr, thanks for bringing this to everyones attention. Perhaps the original PR would end up being more appropriate?: https://github.com/necolas/normalize.css/issues/591#issuecomment-230505380

@olegcherr, I know it's a hack. Still, one who sets a large line height on text for aesthetic reasons would probably not want their form inputs inheriting that line height either. Perhaps line-height should be left untouched by normalize. Or perhaps we can be more specific and inherit only for button and not other inputs?

I agree with @olegcherr that setting font-family: sans-serif; on the input elements is not such a great idea. @battaglr mentiones this is done because the font-family is also set for the html, but this is no longer the case since 7.0.0. I would expect that all browsers use the same font for body text and inputs, so using font-family: inherit; is the logical option for me.

I don't know what happened, @jonathantneal. I did not mean to unassign you.

I’m still here. :) Feel free to read the related threads to understand how I cannot help. I agree that inherit, while not a normalization, would provide a less opinionated default.

@TimVevida, considering the current direction of the project, I agree that going back to inherit would be the best thing to do.

At 2017-10-31 04:14:10, "Luciano Battagliero" notifications@github.com wrote:

@TimVevida, considering the current direction of the project, I agree that going back to inherit would be the best thing to do.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.

Was this page helpful?
0 / 5 - 0 ratings