Closed Bug 1556581 Opened 4 years ago Closed 4 years ago

[webvtt] change cue's root div element to a pseudo element

Categories

(Core :: Audio/Video: Playback, defect, P2)

defect

Tracking

()

RESOLVED WONTFIX

People

(Reporter: alwu, Assigned: alwu)

References

(Blocks 2 open bugs)

Details

If user set cue's font which is different from our default font sans-serif via pseudo element (::cue), it would make that the outer div box 's height is not equal to the inner cue div box's height. It's one of failed reasons for those web platform ref-tests which are using Ahem and showing multiple cues during testing.

The reason why this issue happens is that the inner cue div element [1] and outer div element [2] use different font, which makes the lineHeight of the outer div box is larger than inner div box's lineHeight.

Therefore, a solution is that we should make the outer div as a pseudo element, so the inner and outer div elements can use the same font when user change font via ::cue.

It's also what the spec mentioned about. According to the spec [3], the ::cue should be appled to the root div element, which means we should change outer div element to a pseudo element, not the inner one.

However, we can't just simply change the outer div element as a pseudo element because it would make setting background color on the inner div element failed. For example, this image [4] shows the outer div element (blue background) and the inner div element (dark blue background).

When user set the background shorthand via ::cue, they want to see the background color is only changed in the inner div, not in the outer div.

In addition, acording to the spec [5], there is an exception for the background shorthand, when user setting the background shorthand, the change should be applied to the background box, which is the inner cue div element.


Therefore, we want to find a way which can change the outer div to a pseudo element and also allow us to change background color only on the inner div when user modifies the background shorthand via ::cue.

[1 ] https://searchfox.org/mozilla-central/rev/f8b11433159cbc9cc80500b3e579d767473fa539/dom/media/webvtt/vtt.jsm#528-529
[2] https://searchfox.org/mozilla-central/rev/f8b11433159cbc9cc80500b3e579d767473fa539/dom/media/webvtt/vtt.jsm#527
[3] https://www.w3.org/TR/webvtt1/#cue-selector
[4] https://drive.google.com/file/d/15haagTdHHyqf1-_fDjs8SUsTXEjK_rA4/view
[5] https://www.w3.org/TR/webvtt1/#ref-for-webvtt-cue-background-box-3

Hi, emilio,

I heared that you might be the right person to ask.

I would like to make the outer div as a pseudo element and prevent user setting the background shorthand on it. Instead, when user setting the background shorthand, I would set those styles on its child div element.

Is it possible to do what I mentioned above using the way like [1] before setting the background shorthand of ::cue to layout? or Is there any other better method to do so?

Thank you.

[1] https://searchfox.org/mozilla-central/rev/f8b11433159cbc9cc80500b3e579d767473fa539/servo/components/style/style_adjuster.rs#179-224

Flags: needinfo?(emilio)

Is it possible to do what I mentioned above using the way like [1] before setting the background shorthand of ::cue to layout? or Is there any other better method to do so?

Not really, since at that point you'd need the "original" background, but you want to forget it on the parent.

So you want something like background: inherit on the child box, but while at the same time using background: initial on the outer box, right? That doesn't seem quite straight-forward.

Can you make the child box inherit the background from the parent, and the parent shrink to be the child's size? (with width: min-content; margin: 0 auto or such?). I guess that'd still be an issue with non-opaque backgrounds, plus for multiple lines.

Also, there's ::cue, but there's also ::cue() (which we don't implement). I assume that ::cue() won't match the outer box, is that right?

A clever thing to do this could be setting visibility: hidden on the outer box, and background: inherit; visibility: visible on the child box. But that's assuming that visibility is not a property that applies to ::cue... But looks like it does, so that doesn't quite cut it.

You could make both elements match ::cue, and use background: initial !important on the root box on the user-agent stylesheet. But I'm not familiar enough with vtt to know if that's going to have any other side effect.

Do you know how other browsers implement this out of curiosity?

Flags: needinfo?(emilio)

(In reply to Emilio Cobos Álvarez (:emilio) from comment #2)

So you want something like background: inherit on the child box, but while at the same time using background: initial on the outer box, right? That doesn't seem quite straight-forward.

Yes, I would like to only change the color in the inner box.

Can you make the child box inherit the background from the parent, and the parent shrink to be the child's size? (with width: min-content; margin: 0 auto or such?). I guess that'd still be an issue with non-opaque backgrounds, plus for multiple lines.

No, the outer and inner box's size can be different, it could be automatically calculated by cue's position or set explicitly by user.

Also, there's ::cue, but there's also ::cue() (which we don't implement). I assume that ::cue() won't match the outer box, is that right?

Yes, it seems to me that for ::cue() we only need to apply the style on the specific text tag (eg. <b>, <i>) user selected.

You could make both elements match ::cue, and use background: initial !important on the root box on the user-agent stylesheet. But I'm not familiar enough with vtt to know if that's going to have any other side effect.

It sounds like a good idea, but I've spent a day trying to implement this way, but I couldn't find a proper way to do that. The problem is that I couldn't find a way to distinguish which element is the outer box in the user-agent stylesheet. I've tried to use (1) set class name in the outer box (2) use different element for inner box (outer:div, inner:span), and none of them can select the outer box successfully by CSS selector.

ex.

::cue.CLASS_NAME { ... }
span::cue {}

Do you know how to select the outer box in the user-agent stylesheet?

Do you know how other browsers implement this out of curiosity?

Sorry, I have checked Chromium's code, but I didn't find the code about handling this. Acutally, I didn't know whether they have this issue or not, because we can't use the dev tool to check the cue box's size, so it's hard to say whether there is any size difference between the inner and outer box.

Thank you!

Flags: needinfo?(emilio)

It sounds like a good idea, but I've spent a day trying to implement this way, but I couldn't find a proper way to do that. The problem is that I couldn't find a way to distinguish which element is the outer box in the user-agent stylesheet. I've tried to use (1) set class name in the outer box (2) use different element for inner box (outer:div, inner:span), and none of them can select the outer box successfully by CSS selector.

That doesn't work, because:

::cue.CLASS_NAME { ... }

That's not a valid CSS selector at all.

span::cue { ... }

That's matching the ::cue pseudo-element of the span element (which of course doesn't match anything)

But even with that I suspect you'll have issues because the inner cue will think it's a ::cue of another ::cue pseudo-element.

Looking at chromium looks like the main interesting bit is here:

Looks like they will match cue for all WebVTTElements.

But ok, let's think this through again. The only issue we're trying to fix is that the height of the cue box doesn't match the height of the inner child when the box-size changes, right? I'm pretty sure we should be able to fix that without changing the pseudo-element.

Can you make the inline box display: inline-block rather than just inline? Compare:

  • data:text/html,<div id="outer" style="background: blue"><span id="inner" style="font-size: 160px; background: purple">FOO</span></span>

  • data:text/html,<div id="outer" style="background: blue"><span id="inner" style="font-size: 160px; background: purple; display: inline-block">FOO</span></span>

Also, the assumption in comment 0 that having the same font would solve your issue is not true, right? See:

  • data:text/html,<div id="outer" style="font-size: 160px; background: blue"><span id="inner" style="font-size: 160px; background: purple; display: inline-block">FOO</span></span>

Another alternative which may work: Maybe line-height: 1, combined with overflow: hidden on the parent?

  • data:text/html,<div id="outer" style="background: blue; overflow: hidden;"><span id="inner" style="font-size: 160px; background: purple; line-height: 1">FOO</span></span>
Flags: needinfo?(emilio)

(In reply to Emilio Cobos Álvarez (:emilio) from comment #4)

But ok, let's think this through again. The only issue we're trying to fix is that the height of the cue box doesn't match the height of the inner child when the box-size changes, right? I'm pretty sure we should be able to fix that without changing the pseudo-element.

The problem we would like to fix is that the outer and inner box size is different because they are applied to different font, which causes different line-height. User can set the inner box's style via ::cue at anytime, but we only set the outer box's style when we create it.

Can you make the inline box display: inline-block rather than just inline? Compare:

  • data:text/html,<div id="outer" style="background: blue"><span id="inner" style="font-size: 160px; background: purple">FOO</span></span>

  • data:text/html,<div id="outer" style="background: blue"><span id="inner" style="font-size: 160px; background: purple; display: inline-block">FOO</span></span>

If I understand display: inline-block correctly, it would make the inner box has an ability to set its width and height, but it's still a inline element.

I've tried this way but it seems not working, because the problem I got now is that the inner and outer box have different font (inner: Ahem, outer: sans-serif) so that the line-height would be different because it's calulated by font size.

Also, the assumption in comment 0 that having the same font would solve your issue is not true, right? See:

  • data:text/html,<div id="outer" style="font-size: 160px; background: blue"><span id="inner" style="font-size: 160px; background: purple; display: inline-block">FOO</span></span>

The problem is that I don't know when user would set font related property via ::cue and what they set, so I have no way to modify outer box's font related property.

Another alternative which may work: Maybe line-height: 1, combined with overflow: hidden on the parent?

  • data:text/html,<div id="outer" style="background: blue; overflow: hidden;"><span id="inner" style="font-size: 160px; background: purple; line-height: 1">FOO</span></span>

I tried it, but line-height is based on the font. As the outer and inner use different font, so the outer box's line-height is still different from the inner box's. In addition, setting overflow: hidden would make my cue floating to the weird position (don't know why).

Thank you!

Flags: needinfo?(emilio)
Blocks: 1534888
Blocks: 1557182
Blocks: 1557185

(In reply to Alastor Wu [:alwu] from comment #5)

I tried it, but line-height is based on the font. As the outer and inner use different font, so the outer box's line-height is still different from the inner box's.

Can you clarify what do you mean by this? The line height does not depend on the actual font used when it's not normal. Can you post an example on the bug of what you're seeing?

In addition, setting overflow: hidden would make my cue floating to the weird position (don't know why).

How is the cue positioned? (Sorry, this week I'm a bit busy on a CSSWG meeting, I can look by myself next week if you don't get to it)

Flags: needinfo?(emilio) → needinfo?(alwu)
No longer blocks: 1557185

After rechecking the spec and checking some CSS documents, I think maybe what I would like to implement in this bug is wrong...

First, the spec defines a cue box [1] which cue text would be put inside. User can adjust cue box's size or position via API, and different cue boxes are usually put on the top or bottom of another cue box. According to that, the cue box apparently is a BLOCK element. (That is the outer box I mentioned in previous comments)

And then, all of cue text would be formed as a node tree, and they are all put below a background box [2], which is display:inline. So the background box is apparently an INLINE element. (That is the inner box I mentioned in previous comments)

According to the spec, any pseudo element or class would be applied to the WebVTT node [3], which is used to represent the cue text [4]. As all these nodes are under a INLINE element, so those styles user defines via pseudo element would only be applied on the INLINE element. We don't have to apply those styles to the BLOCK element.

Therefore, it's make sense that the outer box and inner box has different height and we don't have to force them to have same height.

[1] https://www.w3.org/TR/webvtt1/#webvtt-cue-box
[2] https://www.w3.org/TR/webvtt1/#webvtt-cue-background-box
[3] https://www.w3.org/TR/webvtt1/#the-cue-pseudo-element
[4] https://www.w3.org/TR/webvtt1/#webvtt-node-object

Flags: needinfo?(alwu)
No longer blocks: 1557182

Per comment4, I think the way we currently have is correct, so we don't have to change the outer div element to pseudo element.

Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.