Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Heights rendering differently in Chrome and Firefox [duplicate]

I found if we set a block level element with height:auto or height: 0~100% without set up parent's height with explicitly value, and its block level child has bottom margin, then it will calculate height differently in Chrome, but not in Firefox. For the case which set height: 1%:

http://codepen.io/anon/pen/BjgKMR

html {    background: pink;  }    body {    background: yellow;  }    div {    height: 1%;  }    inner {    margin-bottom: 30px;    margin-top: 20px;  }
<div>    <p class="inner">block level element</p>  </div>

The height of div block will be calculated as the margin-bottom + content height of p element. I am confused about why the height: 1% should be computed as to auto because the parent elements(html and body tag) not set its height explicitly, but has different height as we just directly set the height to auto?

If we directly set it to height: auto, it will clearly just set the height as its child block-level element's height, which is not include its bottom margin.

html {    background: pink;  }    body {    background: yellow;  }    div {    height: auto;  }    inner {    margin-bottom: 30px;    margin-top: 20px;  }
<div><p class="inner">block level element</p></div>

I have read the CSS 2.1 spec and think about my question might covered with the height property and margin collapse topic, but still cannot understand why it behaves different in Chrome ver. 47.0.2526, though Firefox ver. 44.0.2 will display the height with same value.

Listed references:
https://www.w3.org/TR/CSS2/visudet.html#the-height-property

  • 10.5: percentage

    ... If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'. ...

  • 10.6.3: Block-level non-replaced elements in normal flow when overflow computes to visible.

    ... if 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:

    The element's height is the distance from its top content edge to the first applicable of the following:

    1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
    2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin does not collapse with the element's bottom margin
    3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
    4. zero, otherwise

https://www.w3.org/TR/2011/REC-CSS2-20110607/box.html#collapsing-margins

  • 8.3.1 collapsing margins.

    The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.

    The bottom margin of an in-flow block box with a 'height' of 'auto' and a 'min-height' of zero collapses with its last in-flow block-level child's bottom margin if the box has no bottom padding and no bottom border and the child's bottom margin does not collapse with a top margin that has clearance.

    ... If the top and bottom margins of a box are adjoining, then it is possible for margins to collapse through it. In this case, the position of the element depends on its relationship with the other elements whose margins are being collapsed.

    • If the element's margins are collapsed with its parent's top margin, the top border edge of the box is defined to be the same as the parent's.
    • Otherwise, either the element's parent is not taking part in the margin collapsing, or only the parent's bottom margin is involved. The position of the element's top border edge is the same as it would have been if the element had a non-zero bottom border.
like image 833
James Yang Avatar asked Feb 21 '16 06:02

James Yang


People also ask

Is Firefox more optimized than Chrome?

Is Firefox Faster Than Chrome? No, Chrome is significantly faster and more memory-efficient than Firefox.

What makes Chrome and Firefox different?

Firefox is a free and open-source web browser that provides a number of features for easy web browsing. Google Chrome is a free web browser but it is not open source, it is the most used web browser for desktop.

Can I have both Firefox and Chrome on the same computer?

Yes, you can run both Firefox and Chrome. However, one will need to be the default browser. For example, Windows will need to know what browser to use when opening links in programs. Certain programs may be coded to only use Internet Explorer, so it is a good idea to leave that installed.

Is Firefox quantum based on chromium?

Firefox is not based on Chromium (the open source browser project at the core of Google Chrome). In fact, we're one of the last major browsers that isn't. Firefox runs on our Quantum browser engine built specifically for Firefox, so we can ensure your data is handled respectfully and kept private.


1 Answers

So first you have the W3C standards, which are a set of guidelines for browser makers.

And then you have the browser makers, who are free to do whatever they want (as evidenced by a history of deviations by Internet Explorer).

In particular, with CSS percentage heights, there are clear differences in behavior among browsers.

You've posted one example. Here's another:

Percentage Heights in Flexbox: Chrome/Safari vs Firefox/IE

When working with flexbox, Chrome and Safari resolve percentage heights on flex items based on the value of the parent's height property. Firefox and IE11/Edge prioritize the parent's flex height.

It appears Webkit browsers adhere to a more traditional interpretation of the spec:

CSS height property

percentage
Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly and this element is not absolutely positioned, the value computes to "auto".

auto
The height depends on the values of other properties.

In other words, for percentage height to work on an in-flow child, the parent must have a set height.

That is the traditional interpretation of the spec: The term "height" means the value of the height property. My own view is that this language is vague and open to interpretation, but the height property requirement has become the predominant implementation. I've never seen min-height or max-height work on a parent when dealing with percentage values.

Recently, however, Firefox and IE have broadened their interpretation to accept flex heights, as well.

Examples of Firefox and IE using a parent's flex height as reference for a child's percentage height:

  • Chrome ignoring flex-basis in column layout
  • Chrome / Safari not filling 100% height of flex parent
  • Height is not correct in flexbox items in Chrome
  • Flexbox in Chrome--How to limit size of nested elements?

Knowing which browsers are in compliance with the spec is a bit difficult because, as I mentioned before, the spec language seems vague and open to interpretation.

With the last update to this part of the definition being in 1998 (CSS2), and the advent of new forms of height such as flex height, an update seems long overdue.

I think it's fair to say that when it comes to percentage heights, until the spec definition gets an update, you can expect rendering differences among browsers.


Alternative Solutions

Here are two alternatives to consider when wanting a child element to take the parent's full height.

  1. Apply display: flex to the parent. This automatically sets align-items: stretch, which tells the child to expand the full available height of the parent.

  2. Apply position: relative on the parent and position: absolute; height: 100%; width: 100% on the child. With absolute positioning, a percentage height will work without a specified height on the parent.

like image 114
Michael Benjamin Avatar answered Sep 17 '22 15:09

Michael Benjamin