Bug 157635 - REGRESSION (STP 4): Unable to target pseudo element webkit-media-controls
Summary: REGRESSION (STP 4): Unable to target pseudo element webkit-media-controls
Status: RESOLVED INVALID
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: Safari Technology Preview
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-12 12:21 PDT by Derk-Jan Hartman
Modified: 2016-05-14 13:18 PDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Derk-Jan Hartman 2016-05-12 12:21:29 PDT
Testcase: https://jsfiddle.net/TheDJ/7q3tt6rw/1/

With current Safari, the CSS here works. On STP 4.0 the controls remain visible.

In case anyone asks why not just remove the 'controls' attribute. I want to have the controls load if someone has JS disabled, and I want to avoid the visual flash of late loading my JS based video player. So until my JS player is fully loaded, there is a rule that if JS is running, hide my controls while the player loads, to prevent confusing for the user.
Comment 1 Derk-Jan Hartman 2016-05-12 12:44:40 PDT
Targeting the lower descendent video::-webkit-media-controls-panel does seem to work... which might be a better idea regardless, but still, a weird issue.
Comment 2 Jer Noble 2016-05-12 13:32:33 PDT
This was caused by the fix for <http://trac.webkit.org/changeset/192252>.
Comment 3 Jer Noble 2016-05-12 13:52:26 PDT
The deal here is that the video's controls live in the video's Shadow DOM, and page style is not supposed to be able to affect elements inside a Shadow DOM.  From that perspective, this is a progression, not a regression.

But the real question is: what is the use case for hiding the default controls?  Why not just remove the "controls" attribute?
Comment 4 Jer Noble 2016-05-12 14:15:49 PDT
(In reply to comment #0)
> Testcase: https://jsfiddle.net/TheDJ/7q3tt6rw/1/
> 
> With current Safari, the CSS here works. On STP 4.0 the controls remain
> visible.

Sorry, I didn't read this description carefully enough the first time through:

> In case anyone asks why not just remove the 'controls' attribute. I want to
> have the controls load if someone has JS disabled, 

They will. We always provide the default controls if JS is disabled.

> and I want to avoid the
> visual flash of late loading my JS based video player. So until my JS player
> is fully loaded, there is a rule that if JS is running, hide my controls
> while the player loads, to prevent confusing for the user.

I think you can do this just by removing the 'controls' attribute.
Comment 5 Jer Noble 2016-05-12 14:19:58 PDT
(In reply to comment #4)
> They will. We always provide the default controls if JS is disabled.

To be clear, this is a requirement of the HMTL specification:

<https://html.spec.whatwg.org/multipage/embedded-content.html#expose-a-user-interface-to-the-user>

"If the [controls] attribute is present, or if scripting is disabled for the media element, then the user agent should expose a user interface to the user. This user interface should include features to begin playback, pause playback, seek to an arbitrary position in the content (if the content supports arbitrary seeking), change the volume, change the display of closed captions or embedded sign-language tracks, select different audio tracks or turn on audio descriptions, and show the media content in manners more suitable to the user (e.g. fullscreen video or in an independent resizable window). Other controls may also be made available."
Comment 6 Derk-Jan Hartman 2016-05-12 15:16:44 PDT
Learned something new today. Thanx for that quote Jer!
Comment 7 Alexey Proskuryakov 2016-05-12 22:55:35 PDT
Sounds like this behaves correctly, so marking the bug as invalid.
Comment 8 Derk-Jan Hartman 2016-05-13 12:39:00 PDT
Hmm, I forgot 1 reason why I wouldn't want to remove the controls attribute... Not all re-users of of our Wikipedia content, are guaranteed to have our Javascript running of course. That means all re-users of Wikipedia content (FB, offline readers, 3rd party mobile apps etc) would have video elements without controls potentially..

It's an option that could be considered, but still not really ideal...
I'd prefer a pure CSS solution for this problem. (top loading JS is not really an option, we are desperately trying to trim that down considerably in favor of styles and progressive JS late loading.

BTW. "The deal here is that the video's controls live in the video's Shadow DOM, and page style is not supposed to be able to affect elements inside a Shadow DOM."

That sounds nice in practice, but as far as I can see, input elements with overriding styling for pseudo controls are everywhere and lot's of stuff would break if we really started following: "page style is not supposed to be able to affect elements inside a Shadow DOM"

And again, as I mentioned, I can easily override a lower level child still.
Comment 9 Jer Noble 2016-05-13 13:06:01 PDT
(In reply to comment #8)
> Hmm, I forgot 1 reason why I wouldn't want to remove the controls
> attribute... Not all re-users of of our Wikipedia content, are guaranteed to
> have our Javascript running of course. That means all re-users of Wikipedia
> content (FB, offline readers, 3rd party mobile apps etc) would have video
> elements without controls potentially..

I think you have some other, better supported techniques available for this scenario. Your in-page CSS could hide (visibility:hidden) the video element entirely (or cover it with a poster <img>, and only un-hide it once your script clears the 'controls' attribute.  The <video> poster image attribute takes time to download, decode, and paint, so this wouldn't introduce any additional flash that wasn't there already.

> That sounds nice in practice, but as far as I can see, input elements with
> overriding styling for pseudo controls are everywhere and lot's of stuff
> would break if we really started following: "page style is not supposed to
> be able to affect elements inside a Shadow DOM"

The names of the pseudo-elements within the <video> element Shadow DOM are an implementation detail, and not an API. We will change them occasionally such that, if pages are allowed to override their styles, those changes will break pages that depend on the arrangement or names of those pseudo-elements.  I suspect the same is true for pages that target specific <input> Shadow DOM elements (and not just <input> pseudo-class rules).

> And again, as I mentioned, I can easily override a lower level child still.

Then that sounds like a bug we need to fix. :)
Comment 10 Derk-Jan Hartman 2016-05-13 14:12:07 PDT
(In reply to comment #9)
> (In reply to comment #8)
> I think you have some other, better supported techniques available for this
> scenario. Your in-page CSS could hide (visibility:hidden) the video element
> entirely (or cover it with a poster <img>, and only un-hide it once your
> script clears the 'controls' attribute.  The <video> poster image attribute
> takes time to download, decode, and paint, so this wouldn't introduce any
> additional flash that wasn't there already.

I just want a style based way to say: "don't show controls", which apparently won't be possible anymore. I'm also not concerned about a FOUC or reflow, i'm specifically concerned about 50 video frames showing a controlbar on mobile device in nigeria that takes 70 seconds to load the entire page. Which would result in one video after the other then loads the JS player. I want to eliminate that temporary moment of controls, after which the user has to reset his expectations with a new set of controls. And I need to keep my DOM clean of non-semantic <img> elements.

I guess the only other alternative that might get me what i want is to use a top loading synchronous JS fragment, but i don't think our performance team will like that. ..

I know, our requirements are somewhat crazy :)
Comment 11 Jer Noble 2016-05-13 15:39:51 PDT
(In reply to comment #10)
> (In reply to comment #9)
> > (In reply to comment #8)
> > I think you have some other, better supported techniques available for this
> > scenario. Your in-page CSS could hide (visibility:hidden) the video element
> > entirely (or cover it with a poster <img>, and only un-hide it once your
> > script clears the 'controls' attribute.  The <video> poster image attribute
> > takes time to download, decode, and paint, so this wouldn't introduce any
> > additional flash that wasn't there already.
> 
> I just want a style based way to say: "don't show controls", which
> apparently won't be possible anymore. I'm also not concerned about a FOUC or
> reflow, i'm specifically concerned about 50 video frames showing a
> controlbar on mobile device in nigeria that takes 70 seconds to load the
> entire page. Which would result in one video after the other then loads the
> JS player. I want to eliminate that temporary moment of controls, after
> which the user has to reset his expectations with a new set of controls. And
> I need to keep my DOM clean of non-semantic <img> elements.

I think I understand; you're more concerned with the look-and-feel of the controls changing half-way through the page-load.

I mean, I'm not really trying to tell you how to redesign your page to work around this issue, but it still seems like there are options. Just off the top of my head, you could do something like this to solve the "javascript disabled" case:

<script>
document.write('<video src="foo"></video>');
</script>
<noscript>
<video controls src="foo"></video>
</noscript>

For the "external users who don't have my javascript player library", the script tag would have to look something like:

document.write('<video src="foo" ' + (hasMyJSLibrary() ? '' : 'controls')  + '></video>');

> I guess the only other alternative that might get me what i want is to use a
> top loading synchronous JS fragment, but i don't think our performance team
> will like that. ..

Well, if you can articulate this use case to the CSS WG (or some representative thereof), the best way to do this moving forward is to convince the WG to add explicit and standardized support for showing or hiding the controls through CSS. Then WebKit can expose just that without pages mucking around with the internals of the controls.

> I know, our requirements are somewhat crazy :)

Crazy requirements make for the most interesting bugs. :)
Comment 12 Derk-Jan Hartman 2016-05-14 13:18:31 PDT
Hmm, why not make it as simple as

video { -webkit-appearance: none }

"the appearance property is to display an element using a platform-native styling based on the operating system's theme. I think that would sort of apply honestly."

It's not a standard, but also not too far off from the other usecases of -webkit-appearance: none