Skip to content
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

Handling of out-of-flow elements #74

Closed
fred-wang opened this issue Feb 19, 2019 · 19 comments
Closed

Handling of out-of-flow elements #74

fred-wang opened this issue Feb 19, 2019 · 19 comments

Comments

@fred-wang
Copy link
Contributor

cc @mrego

I'm not sure there is a concrete use case to e.g. absolutely position a numerator of a fraction. I think Gecko supports it but WebKit does not.

See https://bugs.webkit.org/show_bug.cgi?id=178865

Original report: https://gitlab.com/mathml/MathMLinHTML5/issues/9

@davidcarlisle davidcarlisle transferred this issue from w3c/mathml-core Feb 20, 2019
@fred-wang
Copy link
Contributor Author

cc @bfgeek

@fred-wang
Copy link
Contributor Author

I agree on the suggestion in w3c/mathml#48 (comment)
If one wants to position an out-of-flow element, it's easier to describe its coordinates with respect to the parent.

@fred-wang
Copy link
Contributor Author

fred-wang commented Jul 5, 2019

From w3c/mathml#48:

See a simple test case:
https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=6699

Safari & Firefox differ.

Here there are a few sub-questions:

Can MathML elements becomes out-of-flow?
Can MathML elements be containing-blocks for out-of-flow elements?
What this the static-position for OOF elements?

(2) Has some complexities, e.g. if they aren't allowed to be containing-blocks for OOFs, you also need to define that things that implicitly define containing-blocks, e.g. filter() aren't allowed on MathML elements.

My personal preference (subject to change) would probably be to allow OOFs on any element, and allow for any element to be a containing-block.

But this depends on other decisions.

The static-position probably wants to follow flex/grid.

This needs tests with various elements, and various combinations of containing blocks.
In addition there needs to be tests with fixed, etc.e

@tabatkins
Copy link
Member

Static position can't meaningfully follow flex/grid, as they have flex/grid-specific definitions that don't generalize to other layouts.

If at all possible, defining staticpos as the start-start corner of the containing block would be ideal, as it just makes life so much simpler.

@NSoiffer
Copy link
Contributor

NSoiffer commented Aug 5, 2019

At the 5/8/19 meeting, we decided to treat out of flow elements as if they aren't part of layout/don't exist for rendering. The error repair mechanism in w3c/mathml#15 will kick in. Hence, if someone uses position:absolute (or display:none or ...) for the first child of an mfrac, then the fraction will render as if it only has one child (i.e., the denominator). Hence, the denominator will appear in the numerator position and the denominator will be error-corrected into an empty mrow.

Note: if someone want to prevent the denominator from shifting up, then they can add an mrow around the out of flow numerator and so there will still be two children to the fraction.

The meeting did not discuss the containing block part of the issue.

@tabatkins
Copy link
Member

The behavior you're describing is 👍, exactly what you'd expect from a rendering model.

@fred-wang
Copy link
Contributor Author

fred-wang commented Sep 9, 2019

Proposal:

  1. All MathML elements can be containing blocks.

  2. The OOF children are placed relative to the start-start corner of the containing block (which is just the parent per 1.)? So "3" will be shifted away by (10,15) from the top/left corner of the mfrac:

     <mfrac>
       <mn>1</mn>
       <mn>2</mn>
       <mn style="position: absolute; left: 10px; top: 15px;">3</mn>
     </mfrac>
    

I'm not exactly sure what is the definition of "static-position" and I was not really able to find any in https://drafts.csswg.org/css-position-3/ ; MathML Core already defines position of children for "position: static" children (for example 1 and 2 are positioned with relatively complex rules) but I guess no one proposes to change that here.

@rwlbuis has done some work as per https://github.com/mathml-refresh/mathml/issues/16#issuecomment-518364768 but I'm not sure what he did regarding block container & child positions.

@fred-wang
Copy link
Contributor Author

In addition to absolutely positioned boxes, out-of-flow boxes also include floated boxes:

https://drafts.csswg.org/css2/visuren.html#positioning-scheme

I propose that for the layout of a math box, the float/clear properties on its children are ignored, similarly to what is done for grid/flexbox. So concretely,

  <math>
    <mfrac>
       <mn style="float: left">1</mn>
       <mn style="clear: left">2</mn>
    </mfrac>
  </math>

is laid out the same as

  <math>
    <mfrac>
       <mn>1</mn>
       <mn>2</mn>
    </mfrac>
  </math>

@NSoiffer
Copy link
Contributor

A few responses:

  1. I think only math and mtable should be considered block level elements in MathML. This is consistent with earlier decisions regarding setting width/height, and also probably consistent with how borders are treated.

  2. Treating float by ignoring it seems counter to the decision in definition of children? mathml#133 where children are defined to be "in-flow child boxes". Since float is out-of-flow, it wouldn't be a child and would be ignored.

Comments:
When an element is floated relative the block, that affects layout in various ways. E.g., the block width is reduced (AFAIK) and potentially the height is changed. I suspect this complicates the MathML layout so a bonus of restricting what is a block element is that layout is simplified.

clear is not on of the listed out-of-flow properties, so we could ignore it except for maybe block level elements (math/mtable in my argument) as I believe clear affects layout when float is used (which would be relative to the block).

@fred-wang
Copy link
Contributor Author

2. Treating `float` by ignoring it seems counter to the decision in w3c/mathml#133 where children are defined to be "in-flow child boxes". Since `float` is out-of-flow, it wouldn't be a child and would be ignored.

The idea is to ignore the CSS float property so that a child with a specified float left/right is effectively not floated and so the only out-of-flow children are the absolutely positioned ones.

@fred-wang fred-wang changed the title Position of out-of-flow elements Handling of out-of-flow elements Sep 15, 2019
@fred-wang
Copy link
Contributor Author

fred-wang commented Sep 15, 2019

During Thursday's meeting (2019/09/12) the consensus was:

  • Ignore float/clear (the spec says that now).
  • All MathML elements are containing block.
  • The position is relative to the start-start corner of the containing block.

@chrishtr
Copy link

  • All MathML elements are containing block.

Containing block for all descendants, correct?

@NSoiffer
Copy link
Contributor

This needs tests for positioning so it can be closed.

In addition, the spec likely needs to say more -- it says very little about out-of-flow elements. It currently has "Floats: float and clear are treated as none on all MathML elements." which seems wrong.

@fred-wang
Copy link
Contributor Author

For now I've tweaked the spec to say it forces float to none on MathML element via the UA sheet, but maybe that's not exactly what we want. I've been experimenting with the following test case:

<!-- Floating math element in HTML -->
<div>
  Lorem ipsum
  <math style="float: left">
    <msqrt>
      <mfrac>
        <mn>1</mn>
        <mn>2</mn>
      </mfrac>
    </msqrt>
  </math>
</div>

<!-- Floating MathML element in MathML element -->
<div>
  <math>
    <mtext>Lorem ipsum</mtext>
    <msqrt style="float: left">
      <mfrac>
        <mn>1</mn>
        <mn>2</mn>
      </mfrac>
    </msqrt>
  </math>
</div>

<!-- Floating HTML element in mtext element -->
<div>
  <math>
    <mtext>Lorem ipsum
      <span style="float: left">\sqrt{\frac{1}{2}}</span>
    </mtext>
  </math>
</div>

I'm currently getting the following rendering in WebKit, Firefox, Chrome (from top to bottom), which is a bit inconsistent:

mathml-floats

Chrome works as I would expect. WebKit completely drops the floats in MathML. Firefox is not able to place floats in mtext.

I guess it is fine to have a floating <math> root (it's placed by the parent layout) or floats in token elements (https://w3c.github.io/mathml-core/#layout-of-mtext relies on block flow). However, we probably want to prevent floats in pure MathML layout since we currently don't define any special behavior for them.

@fred-wang
Copy link
Contributor Author

Another interesting case is floats in <mtd>:

<!-- Floating math element in HTML table cell -->
<div>
  <math>
    <mtable>
      <mtr>
        <mtd>
          <mtext>Lorem ipsum</mtext>
          <msqrt style="float: left">
            <mfrac>
              <mn>1</mn>
              <mn>2</mn>
            </mfrac>
          </msqrt>
        </mtd>
      </mtr>
    </mtable>
  </math>
</div>

which is not handled by Chrome, causes line break in Firefox and is handled by WebKit.


For now I'm leaning towards adjusting computed style of elements with a "display: math" parent to force float: none.

@bfgeek
Copy link

bfgeek commented Nov 23, 2022

For now I've tweaked the spec to say it forces float to none on MathML element via the UA sheet, but maybe that's not exactly what we want. I've been experimenting with the following test case:

Yeah likely not exactly what you want as that'll prevent elements form floating. You can likley rely on the spec text from:
https://drafts.csswg.org/css-flexbox-1/#flex-containers

E.g. something like "Math containers are not block containers, etc etc etc"

@fred-wang
Copy link
Contributor Author

@bfgeek Thanks. I think this was the spirit of the previous formulation, but it seems a bit unprecise. I was thinking about adjusted computed style to be 'none'. https://w3c.github.io/csswg-drafts/css2/#float-position seems to say something similar for absolutely positioned elements and all browsers interpret that has computing the style to none.

@fred-wang
Copy link
Contributor Author

I've prepared tests for out-of-flow elements in Chromium:
https://chromium-review.googlesource.com/c/chromium/src/+/4056220
https://chromium-review.googlesource.com/c/chromium/src/+/4055563

For now, the choice I made for float is to adjust the computed value to none in 'math' display types, so that MathML-specific layout does not need to deal with them. This is doing a bit more than what is stated in the flexbox/grid specifications which only mention that they don't create floating children. It seems WebKit interpreted the latter as adjusting the computed value of float to none, while Firefox/Chome just ignore the float property. I've opened w3c/csswg-drafts#8130 ; we can likely revise what do for display: math depending on the decision in the CSSWG.

Regarding, absolutely/fixed positioned element, the containing block is defined in https://w3c.github.io/csswg-drafts/css2/#containing-block-details ; Chrome is already able to place absolutely/fixed positioned element in MathML layout using that containing block as a reference point, so I only needed to write the tests accordingly.

Probably MathML Core can be a bit more precise in https://w3c.github.io/mathml-core/#layout-algorithms in "Layout and positioning of out-of-flow child boxes." mentioning the case of floats and referring to CSS2 for the containing block of absolutely/fixed positioned elements.

fred-wang added a commit that referenced this issue Dec 7, 2022
@fred-wang
Copy link
Contributor Author

I believe this bug is resolved. The spec has been aligned on Chromium's behavior and tests added accordingly.

Floats

Similar wording as flex/grid is used: "The float property does not create floating of elements whose parent's computed display value is block math or inline math, and does not take them out-of-flow."

Tests were added to check that:

  • float property is ignored within elements defaulting to display: math (including token elements)
  • float works within a display: block MathML element
  • float applies to the element

Other out-of-flow elements

The general layout algorithm now refers to CSS Position 3 for absolutely-positioned and fixed-positioned: "Layout and positioning of absolutely-positioned and fixed-positioned boxes, as described in [CSS-POSITION-3]. "

Tests were added to verify

  • visual rendering of absolutely positioned mtext elements.
  • visual rendering of fixed positioned mtext elements.
  • coordinates of absolutely/fixed positioned node for all MathML elements.

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

No branches or pull requests

6 participants