[go: nahoru, domu]

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

[css-text-decor-4] Composition of inset shadows #7251

Open
fantasai opened this issue May 4, 2022 · 19 comments
Open

[css-text-decor-4] Composition of inset shadows #7251

fantasai opened this issue May 4, 2022 · 19 comments

Comments

@fantasai
Copy link
Collaborator
fantasai commented May 4, 2022

Wrt stacking order of inset shadows, @smfr wrote:

Maybe the inset shadow never overlaps the stroke, but conceptually I'd expect the inset shadow to render below the text stroke (but above the fill).

This brings up a couple questions:

  • The obvious: What is the stacking order of inset shadows wrt stroke?
  • Less obvious: Are text decorations composited with their text before being shadowed?

Here's a fun test case. From an authoring perspective, I think I'd expect the shadow to have a consistent color throughout...

But if we composit the text and the decorations together for shadowing, we can't say that the inset shadows are between the stroke and fill since text and decorations are stroked independently.

@SebastianZ
Copy link
Contributor

The obvious: What is the stacking order of inset shadows wrt stroke?

As an author, I agree with @smfr that putting the inset shadows between stroke and fill would be the expected stacking order. The reason is that the shadows are used to style the inner part of the text while the stroke is an outline for the text.

  • Less obvious: Are text decorations composited with their text before being shadowed?

Here's a fun test case. From an authoring perspective, I think I'd expect the shadow to have a consistent color throughout...

But if we composit the text and the decorations together for shadowing, we can't say that the inset shadows are between the stroke and fill since text and decorations are stroked independently.

Again, from an author's perspective, you'd expect the inset shadows to be between fill and stroke. And I agree that outset shadows are expected to not overlap.
That means, from a specification and implementation perspective inset and outset need to be handled differently. For inset shadows, they'd need to be drawn before compositing text and decorations and their fills and strokes and for outset shadows, text and decorations including their fills and strokes should be composited first.

Having said that, current implementations (tested your example in Chrome 101 and Firefox 100) obviously do not composite text and decorations - and are thus not following the spec. - and ignore the stroke for outset shadows (tested with -webkit-text-stroke because browsers don't implement stroke yet).

Sebastian

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed composition of inset shadows.

The full IRC log of that discussion <TabAtkins> Topic: composition of inset shadows
<fantasai> astearns: Let's give ppl time to reveiw
<TabAtkins> github: https://github.com//issues/7251
<TabAtkins> fantasai: I wanted to ask what we should do with inset shadows - what's their stacking order wrt stroke?
<TabAtkins> fantasai: Expectation is probably that it's between fill and stroke
<TabAtkins> fantasai: But then are we compositing the text decorations with their text before shadowing? If so we can't layer shadows between
<TabAtkins> fantasai: You'd ahve to shadow each letter and decoration independently to do that
<TabAtkins> smfr: Issue says Chrome and Firefox have somewhat surprising behavior, so [...missed]
<TabAtkins> fantasai: Sebastian said "from author's persepctive, expect inset between fill and stroke", but outsets should be below both, so that would require them to be treated differently.
<TabAtkins> fantasai: If you have a semi-transparent shadow on text with spread/blur, don't think you'd expect it to be darker where letters are near each other - you'd want them to be shadowed as a whole. That requires compositing text *then* shadowing.
<TabAtkins> fantasai: We might not have an answer today, just wanted thoughts on it.
<TabAtkins> astearns: If we dont' ahve opinions from the surprising-behavior browsers, do we know who to ask? Is there a Blink engineer we could talk about?
<TabAtkins> emilio: What's webkit behavior?
<TabAtkins> fantasai: Less interested in current behavior, want to know what we actually want. Changing now isn't going to be a compat question, as we don't have inset shadows yet, and the behavior changes are subtle for outsets anyway (but real)
<TabAtkins> fantasai: So question is what authors want, what's possible to implement, and what's the intersection of those two.
<TabAtkins> astearns: So I suggest we come up with that definition so impls ahve something to chew on
<TabAtkins> astearns: I think you have the outline of possibilities, but not yet a firm decision on what authors would prefer
<TabAtkins> fantasai: Right, it's just me and sebastian
<TabAtkins> smfr: Is there prior art in InDesign or similar?
<TabAtkins> astearns: I could go take a look
<TabAtkins> astearns: This is not anything I've looked at before tho, not sure if Photoshop/etc behavior is necessarily what we want. I'll take an action to go look.
<TabAtkins> fantasai: Might be interesting to ask people on those teams, who have probably thought about it
<TabAtkins> smfr: I'd like to see some more artistic examples rendered with Chrome and Firefox in th eissue, to show the bad behavior more clearly
<TabAtkins> astearns: So let's take back to the issue and get more clarity on what we want to specify here.
<TabAtkins> astearns: And I'll take an action ot see if I can divine any intent from my company's tooling

@jensimmons
Copy link
Contributor

In discussing this with @fantasai after the call, this mental model struck me — for strokes, strikethroughs , insets & other such shadows.

Imagine we are making signs to carry in a protest or parade. We decide to cut out giant letters in cardbaord (to be carried separately by separate people or something). For some reason, we've got strikethroughs (cut out of the same cardboard, not separate pieces taped on later). We decide to paint these letters in bright yellow with a neon blue stroke. Then we go out into the sun. And there's a shadow. What does that shadow do? That's what we should do.

@fantasai
Copy link
Collaborator Author
fantasai commented Jun 1, 2022

My understanding from discussing with @jensimmons was that it made the most sense from an authoring perspective to composit text, including its decorations and stroke, and then to shadow that, both for outset shadows and for inset shadows. So I think this is the proposal.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-text-decor-4] Composition of inset shadows.

The full IRC log of that discussion <dael> Topic: [css-text-decor-4] Composition of inset shadows
<dael> github: https://github.com//issues/7251
<dael> fantasai: After the call lastweek jensimmons and I chatted about what is reasonable behavior and how does it relate to decorations and stroke
<jensimmons> q+
<dael> fantasai: She gave a bunch of examples. Author expectionation is text including stroke is composit together and shadowed for outset. Same should be for insit
<dael> fantasai: So you're taking text and dropping or lifting above paper. Doing same for inset as outset makes this cleaner.
<dael> fantasai: That's my proposal. If we want variety in future we can do something to allow for it, but this seems like a good default
<dael> jensimmons: Clearifying. When I was reading back our conversation I can see many authors might want shadow between stroke and center part of letter. I don't know. If definitely easier to impl with everything shadowed that's sort of compelling reason to do it
<dael> jensimmons: If I could have anything what authors would want is opportunity to do both. Could be great graphic dsign. Does seem like authors might want shadow between stroke
<Rossen_> ack jensimmons
<astearns> fwiw I have some details from Adobe’s design tools, but inset-shadow is not a built-in feature in any of them. It’s something you have to do on your own (so pretty much any combination is possible)
<dael> fantasai: My take away is while authors might want both when you have stroke text and stroke text decor and drop shadow that ends up being [missed]. In most cases with no stroke we want to make sure that works and in that case you want to composit together
<dael> smfr: We don't allow authors to control compositing for inset box shadow. Maybe start with one impl and if we get authors requests for more control we can do in future
<dael> fantasai: I think right answer is composite text, decor, and stroke together an shadow as one unit
<dael> Rossen_: What can we resolve on?
<Rossen_> q?
<dael> fantasai: Prop: Composite the text, stroke, and decoration and then shadow it for both types of shadow
<dael> fantasai: I think that' b/c when you have no stroke then you want to composite and that's more common than stroking text
<dael> jensimmons: Agree without stroke everything composites together and then shadow
<dael> Rossen_: Additional comments on this?
<dael> smfr: Still want to see pretty pictures to show us how this should look
<dael> Rossen_: Examples would be great
<dael> fantasai: I have a test case showing how it should not work
<dael> fantasai: I took text and put strike through and then shadow that and if you shadow the strike through's shadow is darker. Looks bad
<dael> Rossen_: Ready to resolve?
<dael> Rossen_: Prop: Composite the text, stroke, and decoration and then shadow it for both types of shadow
<dael> Rossen_: Or smfr do you want examples first?
<dael> smfr: w/o stroke okay but would like pictures. With stroke I think inset shadow needs to be between fill and stroke
<dael> fantasai: Problem is b/c it's between fill and stroke so you have to fold the stroke into that sandwich
<dael> smfr: Text stroke doesn't apply to decorations?
<astearns> +1 to smfr adding inset shadow between fill and stroke
<dael> fantasai: Can't remember. I think text stroke...I can't remember
<dael> fantasai: In any case stroke on text is between text and strike-through. So if shadow text decoration with text you have to also shadow stroke b/c it's in between
<dael> smfr: Still hard to visualize
<dael> smfr: astearns I don't suppose you could drive adobe tools to create options
<dael> astearns: I could play with Illustrator. Got feedback from Dirk and illustrator lets you do all the options
<dael> Rossen_: Let's allow those examples to take place and then come back to resolve. There's lack of clear expectations without illustration and I'm sensing hesitency
<dael> astearns: Could someone summerize the bits and pieces would like in example? fill,s troke, decoration, inside shadows, outside shadows?
<dael> fantasai: Line-through makes it fun
<dael> smfr: I think inset shadows and line-through combo is most interesting
<dael> Rossen_: We're 3 minutes over. astearns do you have what you need?
<dael> astearns: Yeah, I can do something for next week
<dael> Rossen_: Fantastic, thank you. We'll discuss again next week

@astearns
Copy link
Member
astearns commented Jun 2, 2022

Idle thought - could/should we add decoration and shadow to paint-order?

@SebastianZ
Copy link
Contributor
SebastianZ commented Jun 2, 2022

I workmate created a mockup for me showing two different approaches regarding text decorations.

Inset shadow for text with decoration

It shows several things:

  • The paint order is fill, then shadow(s), then stroke. But SVG defines a paint-order property which lets you change the order of fill and stroke. (This property seems to apply to HTML elements as well.) In that case the order would be stroke, fill, shadow(s).
  • The point above emphasizes that the text shadow should start at the edge of the fill and not be influenced by the stroke's edge. If people want the shadow to start at the stroke's edge, they can specify a spread radius.
  • The upper example shows what I meant in my previous comment. I.e. first the shadows are painted, then the compositing happens. Or more precisely, the paint order and composition steps (for line-through) are
      1. fill of text
      2. inset text shadows of text
      3. stroke of text
      4. fill of decoration
      5. inset text shadows of decoration
      6. stroke of decoration
      7. composite everything
    The order of 1-3 and 4-6 varies between decorations as some are painted below the text, others above. And as noted earlier, the order may also be influended by the paint-order property.
  • The lower example composites first and then applies the shadows. The steps for that are
      1. fill of text
      2. fill of decoration
      3. composite those two
      4. inset text shadows of composition
      6. stroke of composition
      7. composite everything
    Here, the order of 1 and 2 vary depending on the type of decoration. And again, the paint-order property might change the order of the steps, too.

The mockup doesn't show an outset shadow but that would be painted in an eighth step. Though the order would be first the shadow then the composition.
I know this would complicate the rendering and goes against the current definition of the painting order, though I believe that's what authors expect and what provides the best results.

@jensimmons I can't completely follow your example but I assume you mean the lower one. Please correct me if I'm wrong.
Though after bringing up this real life example, a photo of you standing in the sun and holding some giant letters cut out of a cardboard to illustrate what you wrote would make my day! 😆

Sebastian

@fantasai
Copy link
Collaborator Author
fantasai commented Jun 7, 2022

@SebastianZ That's helpful, thanks! However, the problem is that stroke is implemented on each letter and each text-decoration separately, not on the whole thing. So we can't actually get the second rendering you have. If you remove the stroke, or if you overlay the shadow on the stroke and fill together, then that's a rendering that's actually possible. Jen Simmons and I were arguing that this, while not what you have exactly, is still a better option than the first one.

@astearns
Copy link
Member
astearns commented Jun 8, 2022

I have been playing around with this a bit today, and I am not sure it makes sense to create inset shadows from a combination of glyphs and decorations. It is certainly hard to do (beyond my skills, at least) in Illustrator. I have asked for help.

Here are separate shadows:

image

For a combined effect I guess there would be more shadowing in the yellow areas off the top of the strikethough? I don’t think I would want that.

Dumb smudging of shadows on it:
image

@SebastianZ
Copy link
Contributor

I have to admit I read through last call's discussion just now.

fantasai: Prop: Composite the text, stroke, and decoration and then shadow it for both types of shadow
fantasai: I think that' b/c when you have no stroke then you want to composite and that's more common than stroking text
jensimmons: Agree without stroke everything composites together and then shadow

I am strongly opposed to first compositing fill and stroke before shadowing. That would mean the shadow is painted above the stroke, covering it.
Authors definitely expect the stroke to be above fill and shadows. And it looks like @smfr and others agree with that.

smfr: Text stroke doesn't apply to decorations?
+1 to smfr adding inset shadow between fill and stroke
fantasai: Can't remember. I think text stroke...I can't remember

Checking using -webkit-text-stroke, Chromium and WebKit do apply the color of the text stroke to decorations but not the stroke itself. Gecko doesn't apply it to decorations. See this example.
In my opinion, strokes should apply to decorations as well.

However, the problem is that stroke is implemented on each letter and each text-decoration separately, not on the whole thing. So we can't actually get the second rendering you have. If you remove the stroke, or if you overlay the shadow on the stroke and fill together, then that's a rendering that's actually possible. Jen Simmons and I were arguing that this, while not what you have exactly, is still a better option than the first one.

I don't have a strong opinion on which rendering is better. @astearns' examples obviously match my first rendering (with text and decoration being separated). My second rendering is definitely more legible, though that's probably just because of the font used and the position of the strike-through.

@fantasai @jensimmons As far as I know, stroke as doesn't have any standards compliant implementations yet. So are your statements about what's possible based on -webkit-text-stroke?

Sebastian

@fantasai
Copy link
Collaborator Author
fantasai commented Jun 8, 2022

@SebastianZ You have to consider what's more common: using text-shadow on text with a stroke and no decorations, or on text with decorations and no stroke. You're trying to optimize the former at the expense of the latter, but I think the latter is far more common.

And for decorated, unstroked text, I think the right answer is pretty clear: we want the decoration and the text composited before being shadowed. Drawing the shadows independently over the text and the line decoration looks weird and wrong.

Since text stroke is sandwiched between the decoration (which is drawn over it) and the text fill (which is drawn under it), getting the common cases right requires compositing the stroke with the text before shadowing it.

As for whether for stroked, undecorated text the shadow should be inside the stroke or over it: @jensimmons asserts that both renderings could be desirable. But only one of them is compatible both with handling decorations and with how we handle outer shadows, so by default I think that's what we have to do.

@SebastianZ
Copy link
Contributor

@SebastianZ You have to consider what's more common: using text-shadow on text with a stroke and no decorations, or on text with decorations and no stroke. You're trying to optimize the former at the expense of the latter, but I think the latter is far more common.

I can't tell what will be used more often. Of course, text with decorations is far more common than text with strokes. Though I assume that strokes will be much more common in combinatino with other stylistic ways to emphasize text like inset shadows.

And for decorated, unstroked text, I think the right answer is pretty clear: we want the decoration and the text composited before being shadowed. Drawing the shadows independently over the text and the line decoration looks weird and wrong.

I don't agree with you that there's a clear preference for one of the variants. Especially when the decoration has a different color than the text, it might look better the to shadow text and decoration independently. And again, this is for inset shadows. Outset shadows should definitely be drawn after compositing text and decorations to avoid the overlapping shown in the example of your initial post.

Though I believe we should provide some more renderings for that to show the differences. With them it will probably be easier to decide on that.

Since text stroke is sandwiched between the decoration (which is drawn over it) and the text fill (which is drawn under it), getting the common cases right requires compositing the stroke with the text before shadowing it.

From that and the previous paragraph, I guess the rough rendering steps you suggest are

  1. fill of text
  2. stroke of text
  3. fill of decoration
  4. stroke of decoration
  5. composite everything
  6. outset shadows and above them everything composited
  7. inset shadows

Is that correct? (Note that these steps don't fully reflect the paint order. They outline the order in which rendering happens.)

As for whether for stroked, undecorated text the shadow should be inside the stroke or over it: @jensimmons asserts that both renderings could be desirable.

And I assert that only that only the rendering with stroke above the shadow is desirable.
Though we should provide some renderings for that as well, so the differences become obvious.

Sebastian

@smfr
Copy link
Contributor
smfr commented Jun 8, 2022

One way to move forward here would be to declare that inset shadow interactions with text decorations is unspecified. Indeed, https://www.w3.org/TR/fill-stroke-3/#text-decor says that text decoration fill and stroke (may) get their own properties, so it might be reasonable to say that text decorations don't affect inset shadows on text, or are shadowed independently.

@fantasai
Copy link
Collaborator Author
fantasai commented Jun 15, 2022

it might look better the to shadow text and decoration independently

For inset shadows, this will look very unnatural. Try it.

Fundamentally shadows is about creating a "cut-out" effect, where the text is lifted above or shifted below the canvas. It doesn't work if you shadow text and its decorations independently, whether for inset shadows or for outset shadows.

Including the stroke in the cutout may or may not be what you want, but it's at least consistent with that model. Shadowing decorations independently is not.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Composition of Inset Shadows.

The full IRC log of that discussion <fantasai> Topic: Composition of Inset Shadows
<fantasai> astearns: Some additional discussion and a few attempts at mockups
<fantasai> astearns: trying to figure out what to do wrt text-shadow inset and text decorations
<astearns> github: https://github.com//issues/7251
<fantasai> github: https://github.com//issues/7251
<fantasai> Sebo: Discussing paint order and compositing fill/stroke/shadow
<fantasai> Sebo: lot of discussion around that
<fantasai> Sebo: My point of view was that composition should be done so that the inset shadow is between fill and stroke
<miriam> present_
<fantasai> Sebo: but fantasai said that this could lead to some perf issues ...
<fantasai> fantasai: not perf issue
<smfr> q+
<emilio> fantasai: One issues is that the stroke comes between the text and the text-decoration, so if you have a strike through you are going to stroke text then strike-through, so if you want to shadow between text and fill you are going to also need to shadow the text decoration
<emilio> ... the point of shadows is to create an inset / outset effect
<emilio> ... so you if you have text and decorations with their shadows it looks super weird
<emilio> ... for text that's decorated makes more sense to shadow text + decoration at the same time
<emilio> ... so you we can't shadow between fill and stroke
<emilio> ... that is also an issue because if you don't strike together a semi-transparent shadow will look darker on the decoration
<astearns> ack smfr
<emilio> smfr: for outset shadows I agree we want to composite + shade text and decoration together
<bradk> Issue link, please? Sorry, I arrived late
<emilio> ... does any of the illustrations in the example match what fantasai is proposing?
<bradk> Thanks
<emilio> fantasai: I don't think any of them are
<emilio> smfr: can we get an illustration of what the behavior should be?
<fantasai> https://github.com//issues/7251#issuecomment-1145287101
<emilio> fantasai: if we ignore the stroke on the second one that's the effect you'd get
<emilio> ... if you consider the stroke because the text decoration has its own independent stroke, but the shadow effect in that comment is what you'd get
<emilio> smfr: so you want stroking behavior of first line and shadowing behavior of the second?
<emilio> fantasai: yes
<Sebo> q+
<astearns> I think it would be weird to have a stroke on the decoration but no shadow cast by that stroke
<emilio> fantasai: I think most cases would have either stroke or text-decor
<emilio> ... the top rendering doesn't quite work
<emilio> ... you still have two things that are cut out but flat
<emilio> ... the second one seems like you pushed the text into the canvas which is somewhat consistent with the effect
<emilio> ... it's also consistent between inset and outset shadows
<emilio> ... there's cases where drawing the inset shadow between fill/stroke looks better but the effect is that when you have decorations it'd look wrong
<emilio> smfr: if we stroke using top and shadow using the bottom one it's going to look very weird too
<emilio> fantasai: let's say you have strokes that are similar color for shades of yellow/orange
<emilio> ... you cut that out and shade it behind the canvas
<emilio> smfr: maybe Sebo or fantasai can illustrate the behavior in a drawing tool
<emilio> ... if it's hard to do in a drawing tool it's possibly hard to do programmatically too
<emilio> astearns: hard to do for me in a drawing tool doesn't mean hard to do in a drawing tool :)
<emilio> fantasai: we can try to work on that tomorrow
<emilio> astearns: whenever we can have them it'd be great to have pictures of what fantasai is trying to express
<astearns> ack Sebo
<emilio> ... I'm having a hard time following
<smfr> q+
<astearns> ack smfr
<emilio> smfr: one more q and one more statement. Inset shadows are going to require masking on the text, so lots of texts with inset shadows are going to get pretty expensive
<emilio> ... and authors can have very small text with very large blur radius
<emilio> ... so not sure we need some limits here
<emilio> astearns: if you have a shadow with a big offset does it mean that the shadow appears in another line? That sounds tricky
<emilio> smfr: potentially? Good point

@astearns astearns removed the Agenda+ label Jun 15, 2022
@bradkemper
Copy link
Contributor

I think this is what @fantasai was proposing in the meeting this morning, but I could be wrong.

image

@meyerweb
Copy link
Member

I think this is what @fantasai was proposing in the meeting this morning, but I could be wrong.

The interruptions in the shadow along the line-through really bug me. I’d almost prefer the inverse, which would give the impression of the letter forms casting shadows onto the line-through.

@smfr
Copy link
Contributor
smfr commented Jun 17, 2022

Some discussion in the WebKit rendering team came to the conclusion that anything other than the top line in #7251 (comment) would be very hard to implement. I think we either leave this undefined (and see if any browser does something more complex), or we specify that inset shadows for glyphs and text decorations do not interact.

In addition, the issue was raised that large shadow offsets can cause the inset shadow to "leak" into adjacent glyphs, adjacent inline elements, or adjacent lines. That implies that we may need some spec text that describes whether any of those things should happen.

@SebastianZ
Copy link
Contributor

I think we either leave this undefined (and see if any browser does something more complex), or we specify that inset shadows for glyphs and text decorations do not interact.

As the results differ a lot and inset shadows for texts will probably mostly be used on large text, it should probably be defined. Though I also assume we are actually discussing some edge cases here with decorations overlapping the text (significantly) because authors will presumably rather use inset text shadows on undecorated text. Or, if it's decorated, they'll rather use underlining which has ink skipping applied by default. So maybe it would be fine to leave this undefined. Though that are just assumptions from my side.

@smfr Can you also share some insights on whether it's easier to draw the shadow above the stroke or between stroke and fill?

In addition, the issue was raised that large shadow offsets can cause the inset shadow to "leak" into adjacent glyphs, adjacent inline elements, or adjacent lines. That implies that we may need some spec text that describes whether any of those things should happen.

Of course, from an author's point of view, the inset shadows should stay within the glyph even with large offsets. If that's technically feasible is the question here. It would probably mean that the inset shadow needs to be rendered for each glyph individually and then be clipped.

Sebastian

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

8 participants