Skip to content

[css-break-4] Should fragmentation of block-level replaced-elements be configurable? ("object-slice") #3404

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
bernhardf-ro opened this issue Dec 6, 2018 · 8 comments

Comments

@bernhardf-ro
Copy link

"Some content is not fragmentable, for example many types of replaced elements [CSS21] (such as images"
from https://drafts.csswg.org/css-break-4/#end-block (actually slightly below that ID)

We have always considered replaced elements as monolithic, until there was customer demand for optionally breaking inside images.

So we implemented the property object-slice, effective on block-level replaced elements (for simplicity from now on called "images"):
https://www.pdfreactor.com/product/doc_html/index.html#css-property-ro-object-slice

The initial value none keeps the previous behavior, i.e. monolithic.
auto and avoid allow fragmentation of the image, avoid preferring to move it entirely to the next fragment container if it fits there.
(To avoid overflow and loss of information avoid could also be considered as initial value. Large block-level replaced-elements should be rare enough for this to have very little impact on existing documents.)
Please note that we are only talking block-direction breaks. Handling inline-direction overflow of images is not part of the scope of this property.

Additionally, to avoid splitting off small parts at the beginning or end of the image, and to be more in line with blocks containing inline content, we also added support for the orphans and widows properties. Their values are just multiplied with the used line-height of the image box and cause breaks to be avoided or happen earlier, as in text.

I would like to put the property and related behavior up for discussion and consideration, to give authors (of documents, or of print style sheets) the needed control over large images.

@fantasai
Copy link
Collaborator

fantasai commented Dec 7, 2018

The current spec behavior for monolithic box is avoid, and may or may not slice across pages depending on the UA's choice. See https://drafts.csswg.org/css-break-4/#unforced-breaks

The current behavior in browsers seems to vary a lot. :) Chrome's behavior is pretty broken: it skips a page even if it's at the top, and then clips the image anyway. Gecko slices the image by default if it's block-level; there's a pending patch to make it obey break-inside. It clips it if it's inline-level, since it has no facility for breaking line boxes across lines.

Personally I think we shouldn't add a new property here, just re-use break-inside and maybe have it default to avoid in the UA style sheet for IMG, OBJECT, etc. An author that wants the auto behavior can then specify break-inside: auto. I don't think clipping the image without at least attempting to avoid a break in the first place is useful and certainly shouldn't be the default as it's the most lossy option. The default should probably be to avoid breaking, and then ideally to slice if it can't fit on one page.

What do you think of using break-inside to control this instead of adding object-slice?

Separately: Honoring widows and orphans in that way is a curious idea, but definitely a distinct one from controlling breaking at all. Would you mind filing it separately?

@JABClari
Copy link

JABClari commented Dec 7, 2018

Break-inside is the ideal option

@bernhardf-ro
Copy link
Author

(created #3405 for orphans and widows)

I have 2 concern with break-inside, I'm not sure either is serious enough. For both I assume the auto and avoid values of break-inside and object-slice act the same.

  1. There is no none value. So there would be no way to specify that the image should not be fragmented at all.
    a) While this most often will not be the preferred behavior it might be useful, e.g. to optimize layouts that will be further manipulated by JavaScript.
    b) Also some authors may (for more or less rational reasons) prefer monolithic elements to not be fragmented.

  2. The initial value (auto) is not matching the preferred/expected default behavior (avoid).
    a) User agent style sheets can correct this for the affected HTML elements. However, having to adjust the default behavior of a group of elements, when the engine knows that they all belong to that groups, feels to me like introducing an avoidable redundancy.
    b) Also this would make writing new style sheets for XML with no existing user agent styles more complex. Although I'm not sure whether that is a priority.

@fantasai fantasai added css-break-3 Current Work and removed css-break-3 Current Work labels May 13, 2020
@fantasai
Copy link
Collaborator

Wrt 1) if we need a never value, I think it would make sense to also add it for non-replaced elements.

Wrt 2) the UA stylesheet is frequently used for things like this, so I don't think it's an unusual thing to do. But if we want to switch break avoidance purely on replacedness rather than element type, we could add an allow value instead, and have auto switch behavior based on whether the element is replaced or not.

@faceless2
Copy link

faceless2 commented Sep 29, 2020

We like the proposal to use break-inside. I was going to argue for keeping the two values auto and avoid, with no new value allow, and adding something like this in the user-agent stylesheet rules for HTML:

img, svg, math, embed, canvas, object { break-inside: avoid }

Easy enough, except object is not always replaced - it depends on whether the "fallback content" is rendered.

So I figure you either 1) need to some way to determine whether the fallback content is rendered in object, maybe object:empty or object:valid, 2) add something like a :replaced selector, or 3) add break-inside: allow and have auto collapse to avoid or allow based on replacedness, as suggested by @fantasai. I recall that selectors reflecting the load state of the DOM aren't too popular around here, so that leans towards 3.

EDIT: for completeness another option would be to change the default behaviour for replaced content to break-inside: auto , i.e. to allow it. I don't know how much of an impact that would have on shipping implementations though.

@bernhardf-ro
Copy link
Author

We are in favor of adding never and allow and have auto behave as the former for replaced elements and the latter otherwise. Those should work on all elements the property applies to.

Images fragmenting by default would be highly unexpected for our customers.

@astearns astearns added this to the TPAC-2020-08-23 milestone Oct 16, 2020
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Controlling fragmentation of block-level replaced elements.

The full IRC log of that discussion <fantasai> Topic: Controlling fragmentation of block-level replaced elements
<fantasai> github: https://github.com//issues/3404

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Should fragmentation of block-level replaced-elements be configurable? (“object-slice”), and agreed to the following:

  • RESOLVED: add "break-inside: allow" to enable slicing of images even if they could fit in the next page
The full IRC log of that discussion <Rossen_> Topic: Should fragmentation of block-level replaced-elements be configurable? (“object-slice”)
<Rossen_> github: https://github.com//issues/3404
<fremy> fantasai: the issue is that, for replaced elements, we can't control whether they are breaking or not
<fremy> fantasai: we would like to add a control to say "hey, even if you could avoid slicing, you don't need to"
<fremy> fantasai: the proposal would be to add a new property for this
<fremy> fantasai: I would rather add a value for break-inside
<fremy> fantasai: then if you add "allow" then we trigger this behavior
<fremy> fantasai: auto is avoid for replaced and allow for non-replaced
<fremy> fantasai: in the future, we can also add "never" which is not like "avoid" because it doesn't even slice, it justs get clipped
<Rossen_> q
<fremy> fantasai: this should be a different issue though, let;s walk back
<fremy> fantasai: I would like to propose "break-inside: allow" that would enable to slice a replaced element
<fremy> florian: we should accept this otherwhise what we accepted in the previous issue doesn't make much sense
<fremy> florian: so I am in support
<fremy> Rossen_: any other thoughts?
<fremy> Rossen_: hearing no other remark, let's call for objections
<fremy> RESOLVED: add "break-inside: allow" to enable slicing of images even if they could fit in the next page
<fremy> fantasai: can we discuss the "never" value?
<fremy> fantasai: I would like to suggest taking this here
<fremy> fantasai: we add "never" which prevent slicing if slicing would be necessary, and then we just clip
<fremy> fantasai: it's fine because it's an opt-in
<fremy> Rossen_: do we want to resolve this now?
<fremy> Rossen_: the name "never" seems a bit too strong
<fremy> florian: that's not the meaning of never we want here
<fremy> fantasai: we just overflow and clip
<fremy> myles: the last issue we said the reverse
<fremy> florian: yes, that is the 'avoid' behavior
<fremy> florian: the proposal is to add a new behavior
<fremy> JonathanNeal: but you have to print it right?
<fremy> JonathanNeal: engines don't slice an image now
<fantasai> s/JonathanNeal/faceless2/
<fantasai> s/JonathanNeal/faceless2/
<fremy> fantasai: I am pretty sure it's not true
<fremy> fantasai: avoid allows to slice across pages as a last resolt
<jfkthame> +1 to florian
<fremy> florian: this proposal is to disallow that
<fremy> Rossen_: the name confused me
<fremy> Rossen_: but this could be lack of caffeine
<fremy> Rossen_: do we really want to take this now?
<fremy> Rossen_: it's a break 4 thing, let's maybe open a new issue
<fremy> Rossen_: unless fantasai you feel strongly we should resolve now
<fremy> fantasai: no we don't need to, but it would be nice
<fremy> Rossen_: and the resolution we just took covers that no?
<fremy> fantasai: no it's a different behavior
<myles> q+
<fremy> Rossen_: ok, let's resolve on keep working on this
<fremy> Rossen_: but with keyword tbd
<Rossen_> ack myles
<fremy> myles: reading through the thread, one of the issue is that there are no example use cases
<fremy> myles: and I think it would be useful to have them, because we could hit cases
<fremy> myles: like what you can fit in the first column would be 1px
<fantasai> s/behavior/behavior. We discussed allowing things to break without avoidance, that currently avoid breaking (by moving to a next page first). The other option discussing now is to forbid breaking./
<fremy> myles: so we should think about this more
<fremy> Rossen_: the way I'm perceiving this is very similar to ink-overflow, it's just decorative like it's an image but it works like a shadow or something
<fremy> Rossen_: I need that decoration to take some space, but when printing I don't care about it
<fremy> Rossen_: at least that's what I understood
<fremy> Rossen_: but I don't know how frequently this is needed
<fremy> florian: if that's the use case, you don't need that behavior
<fremy> florian: because you don't want to push if possible to the next page
<fremy> myles: yes, in this case, you don't want the decoration at the top of the next column
<fremy> myles: so this is not what we described there
<fremy> florian: ok, let's open a new issue to review use cases
<fremy> Rossen_: let's move to the next issue

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