Skip to content

[CSS 2.2] discrepancy in handling auto values for properties in width equality constraint #11267

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
gitspeaks opened this issue Nov 24, 2024 · 5 comments
Labels

Comments

@gitspeaks
Copy link

According to the special note on the definition of 'Block Layout' in CSS Box Model Module Level 4:

"This module originally contained the CSS Level 3 specification prose relating to box generation (now defined in [css-display-3]), the box model (defined here), as well as block layout (now only defined in [CSS2] Chapters 9 and 10). Since its maintenance was put aside during the development of CSS2.1, its prose was severely outdated by the time CSS2 Revision 1 was finally completed. Therefore, the block layout portion of the prose has been retired, to be re-synched to CSS2 and updated as input to a new Block Layout module at some point in the future."

Currently, the specification for width, height, and margin calculations for non-absolutely positioned elements in normal flow is defined under:

In particular, CSS2 Section 10.3.3. Block-level, non-replaced elements in normal flow states:

The following constraints must hold among the used values of the other properties:

margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right = width of containing block

...

If there is exactly one value specified as auto, its used value follows from the equality.

Scenario:

<!DOCTYPE html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      #parent {
        width: 200px;
        height: 100px;
        background-color: blue;
      }

      #child {
        background-color: red;
        margin-left: 0;
        border-left-width: 0;
        padding-left: auto;
        width: 100px;
        padding-right: 0;
        border-right-width: 0;
        margin-right: 0;
      }
    </style>
  </head>
  <body>
    <div id="parent">
      <div id="child">BOX</div>
    </div>
    <script>
      const element = document.getElementById("child");
      const styles = getComputedStyle(element);
      console.log("padding-left:", styles.paddingLeft); // 0
    </script>
  </body>
</html>

Expected result:

The used value for padding-left should be 100px.

Actual result:

(Tested on both Chrome and Firefox)

The used value for padding-left is 0px.

@gitspeaks gitspeaks changed the title (CSS 2.2) discrepancy in handling auto values for properties in width equality constraint [CSS 2.2] discrepancy in handling auto values for properties in width equality constraint Nov 24, 2024
@gitspeaks
Copy link
Author

gitspeaks commented Nov 24, 2024

Additionally, the following claim appears to hold in Firefox but not in Chrome:

If width is not auto and border-left-width + padding-left + width + padding-right + border-right-width (plus any of margin-left or margin-right that are not auto) is larger than the width of the containing block, then any auto values for margin-left or margin-right are, for the following rules, treated as zero.

Scenario:

<!DOCTYPE html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      #parent {
        width: 200px;
        height: 100px;
        background-color: blue;
      }

      #child {
        background-color: red;
        margin-left: 0;
        border-left-width: 0;
        padding-left: 0;
        width: 250px;
        padding-right: 0;
        border-right-width: 0;
        margin-right: auto;
      }
    </style>
  </head>
  <body>
    <div id="parent">
      <div id="child">BOX</div>
    </div>
    <script>
      const element = document.getElementById("child");
      const styles = getComputedStyle(element);
      console.log("margin-right:", styles.marginRight); // -50
    </script>
  </body>
</html>

Expected result:

The used value for margin-right should be 0px.

Actual result:

Chrome: The used value for margin-right is -50px.
Firefox: The used value for margin-right is 0px.

@gitspeaks
Copy link
Author

gitspeaks commented Nov 24, 2024

Additionally, the following claim does not appear to hold in either Firefox or Chrome:

If all of the above have a computed value other than auto, the values are said to be "over-constrained" and one of the used values will have to be different from its computed value. If the direction property of the containing block has the value ltr, the specified value of margin-right is ignored and the value is calculated so as to make the equality true. If the value of direction is rtl, this happens to margin-left instead.

Scenario:

<!DOCTYPE html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      #parent {
        width: 200px;
        height: 100px;
        background-color: blue;
      }

      #child {
        background-color: red;
        margin-left: 0;
        border-left-width: 0;
        padding-left: 0;
        width: 250px;
        padding-right: 0;
        border-right-width: 0;
        margin-right: 50px;
      }
    </style>
  </head>
  <body>
    <div id="parent">
      <div id="child">BOX</div>
    </div>
    <script>
      const element = document.getElementById("child");
      const styles = getComputedStyle(element);
      console.log("margin-right:", styles.marginRight); // 50
    </script>
  </body>
</html>

Expected result:

The used value for margin-right should be -50px.

Actual result:

(Tested on both Chrome and Firefox)

The used value for margin-right is 50px.

@Loirooriol
Copy link
Contributor

padding-left: auto

This is not valid.

If all of the above have a computed value other than auto, the values are said to be "over-constrained"

CSS Align overrides this, see #2328 (comment)

@gitspeaks
Copy link
Author

CSS Align overrides this, see #2328 (comment)

Since CSS3 is intended to be backward compatible with CSS2, is there any document that outlines the key changes? It would be helpful to have a clear summary to avoid potential confusion when navigating the new specifications.

@gitspeaks
Copy link
Author

padding-left: auto

This is not valid.

Thanks! I learned something.

The claim, "If there is exactly one value specified as auto, its used value follows from the equality," is indeed correct and quite clever!

I suggest alternate phrasing for a more straightforward explanation:

"If only one margin (either left or right) is set to auto while the other is not, and the width is not auto, the used value of the auto margin follows from the equality. Similarly, if the width is auto and both margins are non-auto, the used value of the auto width also follows from the equality."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants