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

Absolute rtl boxes incorrectly float right #1637

Closed
aschmitz opened this issue May 3, 2022 · 2 comments
Closed

Absolute rtl boxes incorrectly float right #1637

aschmitz opened this issue May 3, 2022 · 2 comments
Labels
bug Existing features not working as expected
Milestone

Comments

@aschmitz
Copy link
Contributor

aschmitz commented May 3, 2022

I believe this is a regression in d782952. It appears as though using an absolute box with direction: rtl will affect the box itself, not just its contents. A sample HTML document:

<style>
  body {
    margin: 2em;
  }
  .a {
    direction: rtl;
    position: absolute;
    text-align: right;
    width: 1ch;
  }

  .b {
    margin-left: 2ch;
  }
</style>
<div>
    <div class="a">a</div>
    <div class="b">b</div>
</div>
<div>
    <div class="a">1a</div>
    <div class="b">b</div>
</div>

(If it helps, imagine this as a code block with a line number in .a and content in .b: we want the numbers to be right-justified, but have any overflow go off to the left and not impact or encroach upon the line content.)

Firefox and Chrome will set these divs like so:

A Firefox screenshot of the HTML

Whereas d782952 sets the .a divs to the right of the page:

A WeasyPrint screenshot of the HTML

My read of the CSS 3 Writing Modes spec would be that since direction specifies the "inline base direction", that primarily affects the content of the box, not where the box itself is set. I haven't dug into it enough to be certain, but my guess is that the ltr = [...] in that method should instead check the parent of the box, not the box itself. (Unfortunately, a reference to the parent seems like it might be hard to come by.)

@liZe liZe added the bug Existing features not working as expected label May 5, 2022
@liZe liZe closed this as completed in bc40535 May 5, 2022
@liZe liZe added this to the 55.0 milestone May 5, 2022
@liZe
Copy link
Member

liZe commented May 5, 2022

Thanks again for this perfect bug report. 💛

It appears as though using an absolute box with direction: rtl will affect the box itself, not just its contents.

Right. It’s not that bad, because nobody will ever set direction: rtl on absolute boxes when the layout is ltr

(If it helps, imagine this as a code block with a line number in .a and content in .b: we want the numbers to be right-justified, but have any overflow go off to the left and not impact or encroach upon the line content.)

… DAMN! That’s a good real-life example.

Rule number 1: assuming that "nobody will ever…" is always false when we talk about HTML/CSS.

(Unfortunately, a reference to the parent seems like it might be hard to come by.)

And it was actually really difficult, as the box parent is not the containing block (that’s the first positioned ancestor).

Hopefully, we now store in a style "dict" the style of the parent, so that we can lazily cascade values. I’m sure that it’s not what we should do (rtl support is known to be broken in WeasyPrint, after all), and that other use cases will be broken, but at least that’s better as it fixes your example (and probably many other ones).

Feedback is welcome!

@aschmitz
Copy link
Contributor Author

aschmitz commented May 5, 2022

Thanks! I agree it's definitely a weird use-case. There are probably other things I could do - maybe a float inside an absolutely positioned element? - but this one was working so I figured I'd try to keep it working. 🙂

I spent some time looking through the spec and discussing it with a colleague, but I couldn't really tell whether the spec would want the default position to come from the parent's inline base direction or from the containing block's.

I ended up testing it with a small example:

<style>
  .a {
    background-color: #ace;
    direction: rtl;
    height: 4em;
    position: relative;
  }

  .b {
    background-color: #cea;
    direction: ltr;
    height: 2em;
    margin: 0 10em;
  }

  .c {
    background-color: #eac;
    bottom: 0;
    height: 1em;
    position: absolute;
    width: 2em;
  }
</style>

<div class="a">
  <div class="b">
    <div class="c">
    </div>
  </div>
</div>

I ended up convincing myself that both Firefox and Chrome use the parent's direction rather than that of the containing block, so the fix you have looks like it's even the correct behavior here.

Thanks again for the quick fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Existing features not working as expected
Projects
None yet
Development

No branches or pull requests

2 participants