Source code
Revision control
Copy as Markdown
Other Tools
/* 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
:root {
/* --tabpanel-background-color matches $in-content-page-background in newtab
(browser/components/newtab/content-src/styles/_variables.scss) */
--tabpanel-background-color: #F9F9FB;
@media (-moz-content-prefers-color-scheme: dark) {
--tabpanel-background-color: #2B2A33;
}
&[privatebrowsingmode=temporary] {
/* Value for --in-content-page-background in aboutPrivateBrowsing.css.
!important overrides the direct setting of this variable in
ThemeVariableMap.sys.mjs when the user has a theme that defines
ntp_background. */
--tabpanel-background-color: #25003e !important;
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.privatebrowsing.felt-privacy-v1") {
--tabpanel-background-color: linear-gradient(45deg, #722291 0%, #45278D 50%, #393473 100%) !important;
}
}
}
#browser,
#tabbrowser-tabbox,
#tabbrowser-tabpanels,
.browserSidebarContainer {
/* Allow devtools with large specified width/height to shrink */
min-width: 0;
min-height: 0;
}
/* We set large flex on both containers to allow the devtools toolbox to
* set a flex value itself. We don't want the toolbox to actually take up free
* space, but we do want it to collapse when the window shrinks, and with
* flex: 0 it can't.
*
* When the toolbox is on the bottom it's a sibling of browserStack, and when
* it's on the side it's a sibling of browserContainer.
*/
.browserContainer {
flex: 10000 10000;
/* To contain the status panel */
position: relative;
/* .browserContainer only contains the devtools when docked horizontally */
min-height: 0;
}
.browserStack {
flex: 10000 10000;
/* Prevent shrinking the page content to 0 height and width */
min-height: 25px;
min-width: 25px;
}
#tabbrowser-tabpanels {
appearance: none;
padding: 0;
color-scheme: unset;
background: var(--tabpanel-background-color);
&[pendingpaint] {
background-image: url("chrome://global/skin/icons/pendingpaint.png");
background-repeat: no-repeat;
background-position: center center;
background-size: 30px;
}
browser:is([blank], [pendingpaint]) {
opacity: 0;
}
browser[type=content] {
color-scheme: env(-moz-content-preferred-color-scheme);
}
browser[tabDialogShowing] {
-moz-user-focus: none !important;
}
}
/* Status panel */
#statuspanel {
&:not([hidden]) {
max-width: calc(100% - 5px);
pointer-events: none;
/* Take a bit more space vertically for the mouse tracker to hit us more
* easily */
padding-top: 2em;
position: absolute;
bottom: 0;
left: 0;
}
&:not([mirror]):-moz-locale-dir(rtl),
&[mirror]:-moz-locale-dir(ltr) {
left: auto;
right: 0;
}
&[sizelimit] {
max-width: 50%;
}
&[type=status] {
min-width: min(23em, 33%);
}
&[type=overLink] {
transition: opacity 120ms ease-out, visibility 120ms;
}
&:is([type=overLink], [inactive][previoustype=overLink]) {
direction: ltr;
}
&[inactive],
:root[inDOMFullscreen] &:not([type=overLink]) {
transition: none;
opacity: 0;
visibility: hidden;
&[previoustype=overLink] {
transition: opacity 200ms ease-out, visibility 200ms;
}
}
/* stylelint-disable-next-line media-query-no-invalid */
@media (-moz-bool-pref: "browser.tabs.hideStatusPanel") {
visibility: hidden;
}
}
#statuspanel-label {
color-scheme: env(-moz-content-preferred-color-scheme);
margin: 0;
padding: 2px 4px;
background-color: -moz-dialog;
border: 1px none ThreeDShadow;
border-top-style: solid;
color: -moz-dialogText;
text-shadow: none;
@media (not (prefers-contrast)) and (not (-moz-platform: linux)) {
background-color: light-dark(#f9f9fa, hsl(240,1%,20%));
border-color: light-dark(#ddd, hsl(240,1%,40%));
color: light-dark(#444, rgb(249,249,250));
}
#statuspanel:not([mirror]) > &:-moz-locale-dir(ltr),
#statuspanel[mirror] > &:-moz-locale-dir(rtl) {
border-right-style: solid;
@media not (-moz-platform: windows) {
border-top-right-radius: .3em;
}
margin-right: 1em;
}
#statuspanel:not([mirror]) > &:-moz-locale-dir(rtl),
#statuspanel[mirror] > &:-moz-locale-dir(ltr) {
border-left-style: solid;
@media not (-moz-platform: windows) {
border-top-left-radius: .3em;
}
margin-left: 1em;
}
}
/**
* Shortcuts
*/
.content-shortcuts {
--shortcuts-left: calc(var(--shortcuts-x) + var(--shortcuts-offset));
--shortcuts-offset: 10px;
--shortcuts-top: calc(var(--shortcuts-y) + var(--shortcuts-offset));
background: var(--toolbar-bgcolor) url(chrome://mozapps/skin/extensions/category-discover.svg) center / 16px no-repeat;
border: 1px solid var(--arrowpanel-border-color);
border-radius: var(--arrowpanel-border-radius);
color: var(--arrowpanel-color);
-moz-context-properties: fill;
fill: currentColor;
height: 28px;
left: clamp(0px, var(--shortcuts-left), calc(100% - 28px));
position: absolute;
top: clamp(0px, var(--shortcuts-top), calc(100% - 28px));
width: 28px;
&:-moz-locale-dir(rtl) {
--shortcuts-left: calc(var(--shortcuts-x) - var(--shortcuts-offset) - 28px);
}
&[active] {
color: var(--color-accent-primary);
}
&:not([shown]) {
display: none;
}
}
/**
* Dialogs
*/
.dialogStack {
z-index: var(--browser-stack-z-index-dialog-stack);
position: absolute;
inset: 0;
/* Hide tab-modal dialogs when a window-modal one is up. */
:root[window-modal-open] .browserStack > &,
/* For some printing use cases we need to visually hide the dialog before
* actually closing it / make it disappear from the frame tree. */
&.temporarilyHidden {
visibility: hidden;
}
}
.dialogOverlay {
align-items: center;
visibility: hidden;
&[topmost="true"] {
z-index: 1;
}
.content-prompt-dialog > & {
display: grid;
align-items: unset;
place-content: center;
/* 90% for 5% top/bottom margins, the document height so that
* smaller dialogs don't become too big. */
grid-auto-rows: min(90%, var(--doc-height-px));
}
}
.dialogBox {
background-clip: content-box;
display: flex;
margin: 0 3vw;
padding: 0;
overflow-x: auto;
&:not(.spotlightBox) {
box-shadow: 0 2px 14px 0 rgba(0, 0, 0, 0.2);
border-radius: 8px;
}
/*
* In High Contrast Mode, this prevents a dialog from visually bleeding into
* the window behind it, which looks jarring.
*/
@media (prefers-contrast) {
outline: 1px solid WindowText;
}
&[resizable="true"] {
resize: both;
overflow: hidden;
min-height: 20em;
}
&[sizeto="available"] {
--box-top-px: 0px; /* Overridden using inline style */
--box-inline-margin: 4px;
--box-block-margin: 4px;
--box-ideal-width: 1000;
--box-ideal-height: 650;
--box-max-width-margin: calc(100vw - 2 * var(--box-inline-margin));
--box-max-height-margin: calc(100vh - var(--box-top-px) - var(--box-block-margin));
--box-max-width-ratio: 70vw;
--box-max-height-ratio: calc(var(--box-ideal-height) / var(--box-ideal-width) * var(--box-max-width-ratio));
--box-max-height-requested: 100vh;
--box-max-width-requested: 100vw;
--box-max-height-remaining: calc(100vh - var(--box-top-px));
width: 100vw;
height: 100vh;
margin: 0;
@media (min-width: 550px) {
--box-inline-margin: min(calc(4px + (100vw - 550px) / 4), 16px);
}
@media (min-width: 800px) {
--box-inline-margin: min(calc(16px + (100vw - 800px) / 4), 32px);
}
@media (min-height: 350px) {
--box-block-margin: min(calc(4px + (100vh - 350px) / 4), 16px);
}
@media (min-height: 550px) {
--box-block-margin: min(calc(16px + (100vh - 550px) / 4), 32px);
}
&:not(.spotlightBox) {
max-width: min(max(var(--box-ideal-width) * 1px, var(--box-max-width-ratio)), var(--box-max-width-margin), var(--box-max-width-requested));
max-height: min(max(var(--box-ideal-height) * 1px, var(--box-max-height-ratio)), var(--box-max-height-margin), var(--box-max-height-requested), var(--box-max-height-remaining));
}
.dialogStack &.spotlightBox {
/* Tab modal: subtract the navigator toolbox height from the dialog height. */
height: calc(100vh - var(--box-top-px));
}
}
:not(.content-prompt-dialog) > .dialogOverlay > &:not(.spotlightBox) {
/* Make dialogs overlap with upper chrome UI. Not necessary for Spotlight
dialogs that are intended to be centered above the window or content area. */
margin-top: -5px;
}
/* For window-modal dialogs, we allow overlapping the urlbar if the window is
* small enough. */
#window-modal-dialog > .dialogOverlay > &:not(.spotlightBox) {
/* Do not go below 3px (as otherwise the top of the dialog would be
* adjacent to or clipped by the top of the window), or above the window
* size. */
margin-top: clamp(
3px,
var(--chrome-offset, 20px) - 5px,
calc(100vh - var(--subdialog-inner-height) - 5px)
);
}
}
#window-modal-dialog {
overflow: visible;
padding: 0;
/* Override default <html:dialog> styles */
border-width: 0;
background-color: transparent;
/* This makes the dialog top-aligned by default (the dialog box will move via
* margin-top above) */
bottom: auto;
/* When showModal() is called on a <dialog>, the <dialog> itself will be
* focused when there's no content, hence the focus ring. However, this
* focus ring is not needed because we always setup the content of the dialog
* after its opened and manually focus an element within it.
*/
outline: none;
&.spotlight {
/* Spotlight window modal dialogs should be equal in size to the window. */
bottom: revert;
max-height: 100%;
max-width: 100%;
}
}
.dialogFrame {
margin: 0;
flex: 1;
/* Default dialog dimensions */
width: 34em;
}
.dialogOverlay[topmost="true"],
#window-modal-dialog::backdrop {
background-color: rgba(28, 27, 34, 0.45);
}
.dialogOverlay[hideContent="true"][topmost="true"] {
background-color: var(--tabpanel-background-color);
}
/* For the window-modal dialog, the background is supplied by the HTML dialog
* backdrop, so the dialogOverlay background above "double backgrounds" - so
* we remove it here: */
#window-modal-dialog > .dialogOverlay[topmost="true"] {
background-color: transparent;
}