393 lines
12 KiB
CSS
393 lines
12 KiB
CSS
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/* This CSS file is for the Picture-in-Picture toggle.
|
|
*
|
|
* The "experiment" class is used to enable styling for the VARIANT version
|
|
* of the toggle for upcoming PiP Nimbus experiments.
|
|
* @see Bug 1811314.
|
|
*
|
|
* To see each section of style changes, search "PIP STYLING" in this file.
|
|
*/
|
|
|
|
/* SHARED PIP STYLING */
|
|
|
|
.controlsOverlay[hidetoggle="true"].hovering > .pip-wrapper:not(.hovering) {
|
|
/* If this isn't !important, it will fail to override the other opacity
|
|
* rules, which are currently defined below this point in this file. */
|
|
opacity: 0 !important;
|
|
}
|
|
|
|
.pip-wrapper {
|
|
position: absolute;
|
|
cursor: pointer;
|
|
-moz-appearance: none;
|
|
background: none;
|
|
color: inherit;
|
|
border: none;
|
|
text-align: unset;
|
|
top: calc(70% - 40px);
|
|
opacity: 0;
|
|
padding-inline: 0;
|
|
transition: opacity 200ms;
|
|
--pip-icon-size: 24px;
|
|
--pip-icon-width-with-margins: calc(2 * var(--pip-toggle-margin) + var(--pip-icon-size));
|
|
--pip-highlight-style: solid rgba(0, 254, 255, 1);
|
|
--pip-highlight-width: 2px;
|
|
--pip-toggle-distanceFromVideoEdge: 18px;
|
|
--pip-toggle-focus-outline-offset: 1px;
|
|
--pip-toggle-margin: 8px;
|
|
--pip-border-radius-toggle: 4px;
|
|
--pip-box-shadow-default: 0 0 4px rgba(255, 255, 255, 0.9);
|
|
--pip-box-shadow-hover: 0 0 10px rgba(255, 255, 255, 0.7);
|
|
--pip-expanded-height: 40px;
|
|
--pip-expanded-min-width: 200px;
|
|
--pip-expanded-max-width: max-content;
|
|
}
|
|
|
|
/* Adjust sizing of the regular toggle wrapper to correctly show the
|
|
* focus outline when navigating via keyboard. */
|
|
.pip-wrapper[has-used],
|
|
.pip-wrapper[small-video] {
|
|
height: var(--pip-icon-width-with-margins);
|
|
width: var(--pip-icon-width-with-margins);
|
|
border-radius: var(--pip-border-radius-toggle);
|
|
margin-right: calc(var(--pip-icon-width-with-margins) * -1);
|
|
}
|
|
|
|
.pip-wrapper[policy="hidden"] {
|
|
display: none;
|
|
}
|
|
|
|
.pip-wrapper[policy="top"] {
|
|
top: 0%;
|
|
translate: var(--pip-toggle-translate-x);
|
|
}
|
|
|
|
.pip-wrapper[policy="one-quarter"] {
|
|
top: 25%;
|
|
}
|
|
|
|
.pip-wrapper[policy="middle"] {
|
|
top: 50%;
|
|
}
|
|
|
|
.pip-wrapper[policy="three-quarters"] {
|
|
top: 75%;
|
|
}
|
|
|
|
.pip-wrapper[policy="bottom"] {
|
|
top: 100%;
|
|
translate: var(--pip-toggle-translate-x) -100%;
|
|
}
|
|
|
|
.pip-wrapper[medium-video] > .pip-expanded > .pip-icon-label > .pip-label {
|
|
font-size: 13px;
|
|
}
|
|
|
|
.pip-wrapper[medium-video] > .pip-expanded {
|
|
font-size: 11px;
|
|
}
|
|
|
|
.pip-wrapper[position="right"] {
|
|
/* move from the right by total width of pip toggle so that it is at least visible in the video element */
|
|
right: calc(var(--pip-icon-width-with-margins) + var(--pip-toggle-distanceFromVideoEdge));
|
|
}
|
|
|
|
/* Re-position the first-time toggle such that it will always be the same distance away from the right edge
|
|
* of the video, even if the label and/or message string(s) are long. */
|
|
.pip-wrapper[position="right"] > .pip-expanded {
|
|
translate: calc(-100% + var(--pip-icon-width-with-margins));
|
|
transform-origin: right;
|
|
}
|
|
|
|
.pip-wrapper[position="left"] {
|
|
left: var(--pip-toggle-distanceFromVideoEdge);
|
|
}
|
|
|
|
.pip-expanded,
|
|
.pip-small,
|
|
.pip-icon,
|
|
.pip-explainer {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
}
|
|
|
|
.pip-wrapper > .pip-expanded {
|
|
display: flex;
|
|
opacity: 0;
|
|
align-items: center;
|
|
scale: 0.33 1;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.pip-wrapper:not([small-video], [has-used]) > .pip-small {
|
|
opacity: 0;
|
|
transition: opacity 200ms;
|
|
}
|
|
|
|
.pip-wrapper:not([small-video], [has-used]) > .pip-expanded {
|
|
opacity: 1;
|
|
scale: 1;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.pip-wrapper:not([small-video], [has-used]).hovering > .pip-expanded {
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.pip-icon {
|
|
top: 8px;
|
|
left: 8px;
|
|
pointer-events: none;
|
|
background-image: url("chrome://global/skin/media/picture-in-picture-open.svg");
|
|
background-position: center, center;
|
|
background-repeat: no-repeat;
|
|
background-size: var(--pip-icon-size) var(--pip-icon-size);
|
|
-moz-context-properties: fill;
|
|
fill: currentColor;
|
|
height: var(--pip-icon-size);
|
|
width: var(--pip-icon-size);
|
|
}
|
|
|
|
.videocontrols[localedir="rtl"] .pip-icon {
|
|
transform: scaleX(-1);
|
|
}
|
|
|
|
.pip-wrapper[position="left"] > .pip-expanded > .pip-icon-label > .pip-label {
|
|
margin-left: var(--pip-icon-width-with-margins);
|
|
margin-right: var(--pip-toggle-margin);
|
|
}
|
|
|
|
.pip-small {
|
|
width: 40px;
|
|
height: 40px;
|
|
}
|
|
|
|
.pip-wrapper[position="left"] > .pip-expanded > .pip-icon-label > .pip-icon {
|
|
display: none;
|
|
}
|
|
|
|
.pip-wrapper:is([small-video], [has-used]) > .pip-expanded,
|
|
.pip-wrapper[position="right"]:not([small-video], [has-used]) > .pip-icon {
|
|
display: none;
|
|
}
|
|
|
|
.pip-wrapper[position="right"] > .pip-expanded > .pip-icon-label > .pip-icon {
|
|
position: relative;
|
|
top: 0;
|
|
left: 0;
|
|
display: inline-block;
|
|
}
|
|
|
|
.pip-wrapper[position="right"] > .pip-expanded > .pip-icon-label {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-content: center;
|
|
}
|
|
|
|
.pip-wrapper[position="right"] > .pip-expanded > .pip-icon-label > .pip-icon,
|
|
.pip-wrapper[position="right"] > .pip-expanded > .pip-icon-label > .pip-label {
|
|
margin-block: auto;
|
|
}
|
|
|
|
.pip-wrapper[position="right"] > .pip-expanded > .pip-icon-label > .pip-icon {
|
|
margin-inline: var(--pip-toggle-margin);
|
|
}
|
|
|
|
.pip-wrapper[position="right"] > .pip-expanded > .pip-icon-label > .pip-label {
|
|
margin-right: var(--pip-toggle-margin);
|
|
}
|
|
|
|
@media (prefers-reduced-motion) {
|
|
.pip-wrapper,
|
|
.pip-expanded,
|
|
.pip-small,
|
|
.pip-explainer {
|
|
/* Transition changes in other rules may override this one if reduced motion is preferred.
|
|
* Make sure this one always takes priority. */
|
|
transition: none !important;
|
|
}
|
|
}
|
|
|
|
|
|
/* NO EXPERIMENT - PIP STYLING */
|
|
|
|
.controlsOverlay:not(.experiment).hovering > .pip-wrapper:not(:focus-visible) {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.controlsOverlay:not(.experiment).hovering > .pip-wrapper.hovering {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* If the PiP toggle is keyboard focused, always show it at 100% opacity */
|
|
.pip-wrapper:not([policy="hidden"], .experiment):focus-visible {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* If showing the expanded PiP toggle, don't outline the
|
|
* parent wrapper element - the expanded toggle handles its
|
|
* own outline. This also affects the regular toggle for small-videos. */
|
|
.pip-wrapper:not([policy="hidden"], [has-used], .experiment):focus-visible {
|
|
outline: none;
|
|
}
|
|
|
|
/* Override outline set by ua.css for the regular toggle. */
|
|
.pip-wrapper[has-used]:not([policy="hidden"], .experiment):focus-visible {
|
|
outline: var(--control-focus-outline);
|
|
}
|
|
|
|
.pip-wrapper:not(.experiment) > .pip-small {
|
|
background-color: rgba(12, 12, 13, 0.65);
|
|
box-shadow: 0 4px 4px rgba(12, 12, 13, 0.25);
|
|
border-radius: var(--pip-border-radius-toggle);
|
|
}
|
|
|
|
.pip-wrapper:not(.experiment) > .pip-expanded,
|
|
.pip-wrapper:not(.experiment) > .pip-small {
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* If first-time toggle is visible and then switched to the regular toggle for smaller videos,
|
|
* maintain the border shown on the first-time toggle. */
|
|
.pip-wrapper:not([has-used], .experiment) > .pip-small {
|
|
border: var(--pip-highlight-width) var(--pip-highlight-style);
|
|
}
|
|
|
|
.pip-wrapper:not(.experiment) > .pip-expanded {
|
|
border: var(--pip-highlight-width) var(--pip-highlight-style);
|
|
transition: opacity 250ms, scale 200ms;
|
|
height: var(--pip-expanded-height);
|
|
background-color: rgba(12, 12, 13, 0.9);
|
|
box-shadow: 0 4px 4px rgba(12, 12, 13, 0.25);
|
|
width: var(--pip-expanded-max-width);
|
|
min-width: var(--pip-expanded-min-width);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.pip-wrapper:not(.experiment).hovering > .pip-expanded {
|
|
box-shadow: none;
|
|
border: var(--pip-highlight-width) var(--pip-highlight-style);
|
|
/* Remove bottom border but keep text centred with padding. */
|
|
border-bottom: none;
|
|
padding-bottom: var(--pip-highlight-width);
|
|
}
|
|
|
|
.pip-wrapper:not([small-video], [has-used], .experiment).hovering > .pip-expanded {
|
|
border-bottom-right-radius: 0;
|
|
border-bottom-left-radius: 0;
|
|
}
|
|
|
|
/* Toggle message only appears for CONTROL variant. */
|
|
.pip-wrapper:not(.experiment) > .pip-expanded > .pip-explainer {
|
|
padding: 6px 16px 8px 8px;
|
|
translate: 0;
|
|
transition: opacity 250ms, translate 190ms;
|
|
transition-timing-function: cubic-bezier(.07, .95, 0, 1);
|
|
background: rgba(12, 12, 13, 0.65);
|
|
border-bottom-right-radius: 8px;
|
|
border-bottom-left-radius: 8px;
|
|
border: var(--pip-highlight-width) var(--pip-highlight-style);
|
|
border-top: 0;
|
|
box-shadow: 0 4px 4px rgba(12, 12, 13, 0.25);
|
|
opacity: 0;
|
|
margin-inline: calc(-1 * var(--pip-highlight-width));
|
|
width: calc(100% - 24px);
|
|
word-break: break-word;
|
|
pointer-events: none;
|
|
user-select: none;
|
|
}
|
|
|
|
.videocontrols[localedir="rtl"] .pip-wrapper:not(.experiment) > .pip-explainer {
|
|
text-align: right;
|
|
direction: rtl;
|
|
}
|
|
|
|
.pip-wrapper:not(.experiment).hovering > .pip-expanded > .pip-explainer {
|
|
pointer-events: auto;
|
|
opacity: 1;
|
|
translate: 0 calc(40px - var(--pip-highlight-width));
|
|
}
|
|
|
|
|
|
/* EXPERIMENT ONLY - PIP STYLING */
|
|
|
|
/* Since we change the outline for the first-time PiP toggle VARIANT,
|
|
* override the focus outline in videocontrols.css as well so that
|
|
* there is design consistency. */
|
|
.controlsContainer.experiment {
|
|
--control-focus-outline: 2px solid #0060DF;
|
|
}
|
|
|
|
.pip-wrapper.experiment > .pip-expanded > .pip-icon-label > .pip-label {
|
|
font-size: min(16px, 1.4em);
|
|
}
|
|
|
|
/* Only the background will be set at 70% opacity. The icons and labels will remain at 100%. */
|
|
.controlsOverlay.experiment.hovering > .pip-wrapper {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* If the PiP toggle is keyboard focused, always show it and override outline set by ua.css.
|
|
* Opacity only affects the toggle icon and label, not the background, which is handled separately. */
|
|
.pip-wrapper.experiment:not([policy="hidden"]):focus-visible {
|
|
opacity: 1;
|
|
/* Wrapper size won't always match pip-small or pip-expanded, so don't apply outline on wrapper. */
|
|
outline: none;
|
|
}
|
|
|
|
/* For the regular PiP toggle, take into consideration small videos and has-used=true. */
|
|
.pip-wrapper.experiment:is([has-used], [small-video]):not([policy="hidden"]):focus-visible > .pip-small,
|
|
.pip-wrapper.experiment:not([policy="hidden"], [has-used]):focus-visible > .pip-expanded {
|
|
outline: var(--control-focus-outline);
|
|
outline-offset: var(--pip-toggle-focus-outline-offset);
|
|
}
|
|
|
|
.pip-wrapper.experiment > .pip-expanded > .pip-explainer {
|
|
display: none;
|
|
}
|
|
|
|
.pip-wrapper.experiment > .pip-small {
|
|
border-radius: var(--pip-border-radius-toggle);
|
|
transition: background-color 200ms;
|
|
}
|
|
|
|
.pip-wrapper.experiment > .pip-expanded {
|
|
transition: opacity 250ms, scale 200ms, translate 190ms, background-color 200ms;
|
|
height: var(--pip-expanded-height);
|
|
width: var(--pip-expanded-max-width);
|
|
min-width: var(--pip-expanded-min-width);
|
|
border-radius: var(--pip-border-radius-toggle);
|
|
}
|
|
|
|
.pip-wrapper.experiment > .pip-small,
|
|
.pip-wrapper.experiment > .pip-expanded {
|
|
background-color: rgba(0, 0, 0, 0.7);
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.pip-wrapper.experiment.hovering > .pip-small,
|
|
.pip-wrapper.experiment.hovering > .pip-expanded {
|
|
background-color: rgba(0, 0, 0, 1);
|
|
}
|
|
|
|
.pip-wrapper.experiment:not([policy="hidden"], :focus-visible) > .pip-small,
|
|
.pip-wrapper.experiment:not([policy="hidden"], :focus-visible) > .pip-expanded {
|
|
box-shadow: var(--pip-box-shadow-default);
|
|
}
|
|
|
|
.pip-wrapper.experiment:not([policy="hidden"], :focus-visible).hovering > .pip-small,
|
|
.pip-wrapper.experiment:not([policy="hidden"], :focus-visible).hovering > .pip-expanded {
|
|
box-shadow: var(--pip-box-shadow-hover);
|
|
}
|
|
|
|
/* Remove white box shadow if there is keyboard focus on the toggle and
|
|
* replace it with blue box shadow instead. */
|
|
.pip-wrapper.experiment:not([policy="hidden"]):focus-visible > .pip-small,
|
|
.pip-wrapper.experiment:not([policy="hidden"]):focus-visible > .pip-expanded {
|
|
box-shadow: 0 0 10px rgba(0, 96, 223, 0.9);
|
|
}
|