Bug 1592286 - Add URL-mapped policy support to the Picture-in-Picture toggle. r=mstriemer
[gecko.git] / toolkit / themes / shared / media / videocontrols.css
blobe1fc749cf5226ef87011326f7976c56b25ed438d
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 @namespace url("http://www.w3.org/1999/xhtml");
7 .videocontrols {
8 writing-mode: horizontal-tb;
9 width: 100%;
10 height: 100%;
11 display: inline-block;
12 overflow: hidden;
14 direction: ltr;
15 /* Prevent unwanted style inheritance. See bug 554717. */
16 text-align: left;
17 list-style-image: none !important;
18 font: normal normal normal 100%/normal sans-serif !important;
19 text-decoration: none !important;
20 white-space: normal !important;
23 .controlsContainer {
24 --clickToPlay-size: 48px;
25 --button-size: 30px;
26 --timer-size: 40px;
27 --timer-long-size: 60px;
28 --track-size: 5px;
29 --thumb-size: 13px;
30 --label-font-size: 13px;
31 --pip-toggle-bgcolor: rgb(0, 96, 223);
32 --pip-toggle-text-and-icon-color: rgb(255, 255, 255);
33 --pip-toggle-padding: 5px;
34 --pip-toggle-icon-width-height: 16px;
35 --pip-toggle-translate-x: calc(100% - var(--pip-toggle-icon-width-height) - 2 * var(--pip-toggle-padding));
37 .controlsContainer.touch {
38 --clickToPlay-size: 64px;
39 --button-size: 40px;
40 --timer-size: 52px;
41 --timer-long-size: 78px;
42 --track-size: 7px;
43 --thumb-size: 16px;
44 --label-font-size: 16px;
47 /* Some CSS custom properties defined here are referenced by videocontrols.js */
48 .controlBar {
49 /* Do not delete: these variables are accessed by JavaScript directly.
50 see videocontrols.js and search for |-width|. */
51 --clickToPlay-width: var(--clickToPlay-size);
52 --playButton-width: var(--button-size);
53 --scrubberStack-width: 64px;
54 --muteButton-width: var(--button-size);
55 --volumeStack-width: 48px;
56 --castingButton-width: var(--button-size);
57 --closedCaptionButton-width: var(--button-size);
58 --fullscreenButton-width: var(--button-size);
59 --positionDurationBox-width: var(--timer-size);
60 --durationSpan-width: var(--timer-size);
61 --positionDurationBox-width-long: var(--timer-long-size);
62 --durationSpan-width-long: var(--timer-long-size);
65 .touch .controlBar {
66 /* Do not delete: these variables are accessed by JavaScript directly.
67 see videocontrols.js and search for |-width|. */
68 --scrubberStack-width: 84px;
69 --volumeStack-width: 64px;
72 .controlsContainer [hidden],
73 .controlBar[hidden],
74 .pictureInPictureToggleButton[hidden],
75 .videocontrols[inDOMFullscreen] > .controlsContainer > .controlsOverlay > .pictureInPictureToggleButton {
76 display: none;
79 .controlBar[size="hidden"] {
80 display: none;
83 .controlsSpacer[hideCursor] {
84 cursor: none;
87 .controlsContainer,
88 .progressContainer {
89 position: relative;
90 height: 100%;
93 .stackItem {
94 position: absolute;
95 left: 0;
96 bottom: 0;
97 width: 100%;
98 height: 100%;
101 .statusOverlay {
102 display: flex;
103 flex-direction: column;
104 justify-content: center;
105 align-items: center;
106 background-color: rgb(80,80,80, .85);
109 .controlsOverlay {
110 display: flex;
111 flex-direction: column;
112 justify-content: center;
113 position: relative;
116 .controlsSpacerStack {
117 display: flex;
118 flex-direction: column;
119 flex-grow: 1;
120 justify-content: center;
121 align-items: center;
124 .controlBar {
125 position: relative;
126 display: flex;
127 box-sizing: border-box;
128 justify-content: center;
129 align-items: center;
130 overflow: hidden;
131 height: 40px;
132 padding: 0 9px;
133 background-color: rgba(26,26,26,.8);
136 .touch .controlBar {
137 height: 52px;
140 .controlBar > .button {
141 height: 100%;
142 min-width: var(--button-size);
143 min-height: var(--button-size);
144 padding: 6px;
145 border: 0;
146 margin: 0;
147 background-color: transparent;
148 background-repeat: no-repeat;
149 background-position: center;
150 background-origin: content-box;
151 background-clip: content-box;
152 -moz-context-properties: fill;
153 fill: #ffffff;
156 .touch .controlBar > .button {
157 background-size: 24px 24px;
160 .controlBar > .button:hover {
161 fill: #48a0f7;
164 .controlBar > .button:hover:active {
165 fill: #2d89e6;
168 .playButton {
169 background-image: url(chrome://global/skin/media/pauseButton.svg);
171 .playButton[paused] {
172 background-image: url(chrome://global/skin/media/playButton.svg);
175 .muteButton {
176 background-image: url(chrome://global/skin/media/audioUnmutedButton.svg);
178 .muteButton[muted] {
179 background-image: url(chrome://global/skin/media/audioMutedButton.svg);
181 .muteButton[noAudio],
182 .muteButton[noAudio]:hover,
183 .muteButton[noAudio]:hover:active {
184 background-image: url(chrome://global/skin/media/audioNoAudioButton.svg);
185 fill: white;
187 .muteButton[noAudio] + .volumeStack {
188 display: none;
191 .castingButton {
192 background-image: url(chrome://global/skin/media/castingButton-ready.svg);
195 .castingButton[enabled] {
196 background-image: url(chrome://global/skin/media/castingButton-active.svg);
199 .closedCaptionButton {
200 background-image: url(chrome://global/skin/media/closedCaptionButton-cc-off.svg);
202 .closedCaptionButton[enabled] {
203 background-image: url(chrome://global/skin/media/closedCaptionButton-cc-on.svg);
206 .fullscreenButton {
207 background-image: url(chrome://global/skin/media/fullscreenEnterButton.svg);
209 .fullscreenButton[fullscreened] {
210 background-image: url(chrome://global/skin/media/fullscreenExitButton.svg);
213 .controlBarSpacer {
214 flex-grow: 1;
217 .volumeControl::-moz-range-thumb,
218 .scrubber::-moz-range-thumb {
219 height: var(--thumb-size);
220 width: var(--thumb-size);
221 border: none;
222 border-radius: 50%;
223 background-color: #ffffff;
224 filter: drop-shadow(0px 0px 2px rgba(0,0,0,0.65));
227 .volumeControl::-moz-focus-outer,
228 .scrubber::-moz-focus-outer {
229 border: 0;
232 .progressBackgroundBar {
233 display: flex;
234 flex-direction: column;
235 justify-content: center;
236 align-items: center;
239 .progressStack {
240 position: relative;
241 width: 100%;
242 height: var(--track-size);
245 .scrubberStack {
246 /* minus margin to get basis of required width */
247 min-width: calc(var(--scrubberStack-width) - 18px);
248 flex-basis: calc(var(--scrubberStack-width) - 18px);
249 flex-grow: 2;
250 flex-shrink: 0;
251 margin: 0 9px;
254 .volumeStack {
255 max-width: 60px;
256 min-width: var(--volumeStack-width);
257 flex-grow: 1;
258 flex-shrink: 0;
259 margin-right: 6px;
260 margin-left: 4px;
263 .bufferBar,
264 .progressBar,
265 .scrubber,
266 .volumeBackground,
267 .volumeControl {
268 bottom: 0;
269 left: 0;
270 position: absolute;
271 width: 100%;
272 height: 100%;
273 padding: 0;
274 border: 0;
275 border-radius: calc(var(--track-size) / 2);
276 margin: 0;
277 background: none;
278 background-color: transparent;
281 .bufferBar,
282 .volumeBackground {
283 background-color: rgba(0,0,0,0.7);
286 .bufferBar::-moz-progress-bar,
287 .progressBar::-moz-progress-bar,
288 .volumeBackground::-moz-meter-bar {
289 height: 100%;
290 padding: 0;
291 margin: 0;
292 border: 0;
293 border-radius: calc(var(--track-size) / 2);
294 background: none;
297 .scrubber:hover::-moz-range-thumb,
298 .volumeControl:hover::-moz-range-thumb {
299 background-color: #48a0f7;
302 .scrubber:active::-moz-range-thumb,
303 .volumeControl:active::-moz-range-thumb {
304 background-color: #2d89e6;
307 .scrubber::-moz-range-track,
308 .scrubber::-moz-range-progress {
309 background-color: transparent;
312 .volumeControl::-moz-range-progress,
313 .volumeControl::-moz-range-track {
314 height: var(--track-size);
315 border-radius: calc(var(--track-size) / 2);
318 .volumeControl::-moz-range-progress {
319 background-color: #ffffff;
322 .volumeControl::-moz-range-track {
323 background-color: rgba(0,0,0,0.7);
327 .bufferBar::-moz-progress-bar {
328 background-color: rgba(255,255,255,0.3);
329 border-radius: calc(var(--track-size) / 2);
332 .progressBar::-moz-progress-bar {
333 background-color: #00b6f0;
336 .textTrackList {
337 position: absolute;
338 right: 5px;
339 bottom: 45px;
340 max-width: 80%;
341 border: 1px solid #000000;
342 border-radius: 2.5px;
343 padding: 5px 0;
344 vertical-align: middle;
345 background-color: #000000;
346 opacity: 0.7;
349 .touch .textTrackList {
350 bottom: 58px;
353 .textTrackList > .textTrackItem {
354 display: block;
355 width: 100%;
356 height: var(--button-size);
357 font-size: var(--label-font-size);
358 padding: 2px 10px;
359 border: none;
360 margin: 0;
361 white-space: nowrap;
362 overflow: hidden;
363 text-align: left;
364 text-overflow: ellipsis;
365 color: #ffffff;
366 background-color: transparent;
369 .textTrackList > .textTrackItem:hover {
370 background-color: #444444;
373 .textTrackList > .textTrackItem[on] {
374 color: #48a0f7;
377 .positionLabel,
378 .durationLabel {
379 display: none;
382 .positionDurationBox {
383 text-align: center;
384 padding-inline-start: 1px;
385 padding-inline-end: 9px;
386 white-space: nowrap;
387 font: message-box;
388 font-size: var(--label-font-size);
389 font-size-adjust: 0.55;
390 color: #ffffff;
393 %ifdef XP_MACOSX
394 .positionDurationBox {
395 font-size-adjust: unset;
396 font-family: "Helvetica Neue", "Helvetica", sans-serif;
398 %endif
400 .duration {
401 display: inline-block;
402 white-space: pre;
403 color: #929292;
406 .statusIcon {
407 width: 36px;
408 height: 36px;
409 margin-bottom: 20px;
412 /* Not showing the throbber on mobile because of conflict with m.youtube.com (see bug 1289412) */
413 .controlsContainer:not(.mobile) .statusIcon[type="throbber"] {
414 background: url(chrome://global/skin/media/throbber.png) no-repeat center;
417 .controlsContainer:not(.mobile) .statusIcon[type="throbber"][stalled] {
418 background: url(chrome://global/skin/media/stalled.png) no-repeat center;
421 .statusIcon[type="error"],
422 .statusIcon[type="pictureInPicture"] {
423 background-size: contain;
424 background-repeat: no-repeat;
425 background-position: center;
428 .statusIcon[type="error"] {
429 min-width: 70px;
430 min-height: 60px;
431 background-image: url(chrome://global/skin/media/error.png);
434 .statusIcon[type="pictureInPicture"] {
435 min-width: 84px;
436 min-height: 84px;
437 background-image: url(chrome://global/skin/media/pictureinpicture.svg);
438 -moz-context-properties: fill, stroke;
439 fill: #fff;
440 stroke: #fff;
443 .pictureInPictureToggleButton {
444 display: flex;
445 -moz-appearance: none;
446 position: absolute;
447 background-color: var(--pip-toggle-bgcolor);
448 color: var(--pip-toggle-text-and-icon-color);
449 border: 0;
450 padding: var(--pip-toggle-padding);
451 right: 0;
452 top: 50%;
453 translate: var(--pip-toggle-translate-x) -50%;
454 transition: opacity 160ms linear, translate 160ms linear;
455 min-width: max-content;
456 pointer-events: auto;
457 opacity: 0;
460 .pictureInPictureToggleButton[policy="hidden"] {
461 display: none;
464 .pictureInPictureToggleButton[policy="top"] {
465 top: 0%;
466 translate: var(--pip-toggle-translate-x);
469 .pictureInPictureToggleButton[policy="one-quarter"] {
470 top: 25%;
473 .pictureInPictureToggleButton[policy="three-quarters"] {
474 top: 75%;
477 .pictureInPictureToggleButton[policy="bottom"] {
478 top: 100%;
479 translate: var(--pip-toggle-translate-x) -100%;
482 .pictureInPictureToggleIcon {
483 display: inline-block;
484 background-image: url(chrome://global/skin/media/pictureinpicture.svg);
485 background-position: center left;
486 background-repeat: no-repeat;
487 -moz-context-properties: fill, stroke;
488 fill: var(--pip-toggle-text-and-icon-color);
489 stroke: var(--pip-toggle-text-and-icon-color);
490 width: var(--pip-toggle-icon-width-height);
491 height: var(--pip-toggle-icon-width-height);
492 min-width: max-content;
495 .statusIcon[type="pictureInPicture"]:dir(rtl),
496 .pictureInPictureToggleIcon:dir(rtl) {
497 transform: scaleX(-1);
500 .pictureInPictureToggleLabel {
501 margin-inline-start: var(--pip-toggle-padding);
505 * For the Picture-in-Picture toggle, we don't use the built-in :hover
506 * pseudoclass because there are many sites where the arrangement of the DOM
507 * or the CSS will conspire to prevent :hover from matching on the <video>
508 * itself. PictureInPictureToggleChild takes care of punching through those
509 * barriers, and manually sets a .hovering class.
512 .controlsOverlay.hovering > .pictureInPictureToggleButton {
513 opacity: 0.8;
516 .controlsOverlay[hidetoggle="true"].hovering > .pictureInPictureToggleButton:not(.hovering) {
517 opacity: 0;
520 .controlsOverlay.hovering > .pictureInPictureToggleButton.hovering {
521 opacity: 1;
522 translate: 0 -50%;
525 .controlsOverlay.hovering > .pictureInPictureToggleButton.hovering[policy="top"] {
526 translate: 0;
529 .controlsOverlay.hovering > .pictureInPictureToggleButton.hovering[policy="bottom"] {
530 translate: 0 -100%
533 @supports -moz-bool-pref("media.videocontrols.picture-in-picture.video-toggle.testing") {
535 * To make automated tests faster, we drop the transition duration in
536 * testing mode.
538 .pictureInPictureToggleButton {
539 transition-duration: 10ms;
543 /* Overlay Play button */
544 .clickToPlay {
545 min-width: var(--clickToPlay-size);
546 min-height: var(--clickToPlay-size);
547 border-radius: 50%;
548 background-image: url(chrome://global/skin/media/playButton.svg);
549 background-repeat: no-repeat;
550 background-position: 54% 50%;
551 background-size: 40% 40%;
552 background-color: #1a1a1a;
553 -moz-context-properties: fill;
554 fill: #ffffff;
555 opacity: 0.8;
556 position: relative;
557 top: 20px;
560 .controlsSpacerStack:hover > .clickToPlay,
561 .clickToPlay:hover {
562 opacity: 0.55;
565 .controlsSpacerStack:hover > .clickToPlay[fadeout] {
566 opacity: 0;
569 .controlBar[fullscreen-unavailable] .fullscreenButton {
570 display: none;
573 .statusOverlay[fadeout],
574 .statusOverlay[error] + .controlsOverlay > .controlsSpacerStack {
575 opacity: 0;
578 .pictureInPictureOverlay {
579 display: flex;
580 flex-direction: column;
581 justify-content: center;
582 align-items: center;
583 opacity: 1;
584 background-color: rgb(12, 12, 13);
587 /* Status description formatting */
588 .statusLabel {
589 padding: 0 10px;
590 text-align: center;
591 font: message-box;
592 font-size: 14px;
593 color: #ffffff;
596 .statusLabel {
597 display: none;
600 [status="errorAborted"] > [id="errorAborted"],
601 [status="errorNetwork"] > [id="errorNetwork"],
602 [status="errorDecode"] > [id="errorDecode"],
603 [status="errorSrcNotSupported"] > [id="errorSrcNotSupported"],
604 [status="errorNoSource"] > [id="errorNoSource"],
605 [status="errorGeneric"] > [id="errorGeneric"],
606 [status="pictureInPicture"] > [id="pictureInPicture"] {
607 display: inline;
610 %ifdef XP_WIN
611 @media (-moz-windows-default-theme: 0) {
612 .controlsSpacer,
613 .clickToPlay {
614 background-color: transparent;
617 %endif