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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Rules for everything related to XUL except scrollbars can be found in this
* file.
*
* This file should also not contain any app specific styling. Defaults for
* widgets of a particular application should be in that application's style
* sheet. For example, style definitions for browser can be found in
* browser.css.
*/
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* set default namespace to XUL */
@namespace html url("http://www.w3.org/1999/xhtml"); /* namespace for HTML elements */
* {
-moz-user-focus: ignore;
display: flex;
box-sizing: border-box;
}
/* hide the content and destroy the frame */
[hidden="true"] {
display: none;
}
/* hide the content, but don't destroy the frames */
[collapsed="true"] {
visibility: collapse;
}
/* TODO: investigate unifying these two root selectors
*/
*|*:root {
--animation-easing-function: cubic-bezier(.07, .95, 0, 1);
flex: 1;
-moz-box-collapse: legacy;
}
:root {
text-rendering: optimizeLegibility;
-moz-control-character-visibility: visible;
width: 100%;
height: 100%;
user-select: none;
}
:root:-moz-locale-dir(rtl) {
direction: rtl;
}
/* XUL doesn't show outlines by default */
:focus-visible {
outline: initial;
}
/*
* Native anonymous popups and tooltips in html are document-level, which means
* that they don't inherit from the root, so this is needed.
*/
popupgroup:-moz-native-anonymous:-moz-locale-dir(rtl),
tooltip:-moz-native-anonymous:-moz-locale-dir(rtl) {
direction: rtl;
}
/* ::::::::::
:: Rules for 'hiding' portions of the chrome for special
:: kinds of windows (not JUST browser windows) with toolbars
::::: */
*|*:root[chromehidden~="menubar"] .chromeclass-menubar,
*|*:root[chromehidden~="directories"] .chromeclass-directories,
*|*:root[chromehidden~="status"] .chromeclass-status,
*|*:root[chromehidden~="extrachrome"] .chromeclass-extrachrome,
*|*:root[chromehidden~="location"] .chromeclass-location,
*|*:root[chromehidden~="location"][chromehidden~="toolbar"] .chromeclass-toolbar,
*|*:root[chromehidden~="toolbar"] .chromeclass-toolbar-additional {
display: none;
}
/* ::::::::::
:: Rules for forcing direction for entry and display of URIs
:: or URI elements
::::: */
.uri-element {
direction: ltr !important;
}
/****** elements that have no visual representation ******/
script, data, commandset, command,
broadcasterset, broadcaster, observes,
keyset, key, toolbarpalette, template,
treeitem, treeseparator, treerow, treecell {
display: none;
}
/********** focus rules **********/
button,
checkbox,
menulist,
radiogroup,
richlistbox,
tree,
browser,
editor,
iframe,
label:is(.text-link, [onclick]),
tab[selected="true"]:not([ignorefocus="true"]) {
-moz-user-focus: normal;
}
/* Avoid losing focus on tabs by keeping them focusable, since some browser
* tests rely on this.
*
* TODO(emilio): Remove this and fix the tests / front-end code:
* * browser/base/content/test/general/browser_tabfocus.js
*/
tab:focus {
-moz-user-focus: normal;
}
/******** window & page ******/
window {
overflow: clip;
flex-direction: column;
}
/******** box *******/
vbox {
flex-direction: column;
}
/********** label **********/
label {
display: inline-block;
}
description {
display: flow-root;
}
label html|span.accesskey {
text-decoration: underline;
text-decoration-skip-ink: none;
}
description:where([value]) {
/* Preserves legacy behavior, maybe could be removed */
display: flex;
}
label:where([value]) {
/* Preserves legacy behavior, maybe could be removed */
display: inline-flex;
}
:is(label, description)[value] {
white-space: nowrap;
}
:is(label, description)[value]::before {
/* This displays the value attribute, along with the underlined
* accesskey if needed */
content: -moz-label-content;
display: block;
}
label[value=""]::before {
content: "\200b" !important; /* zwsp */
}
:is(label, description)[value][crop] {
min-width: 0;
}
:is(label, description)[value][crop]::before {
min-width: 0;
max-width: 100%;
/* This implements crop=end */
overflow: hidden;
text-overflow: ellipsis;
}
/* Invert the direction to clip at the start rather than end */
:is(label, description)[value][crop="start"]::before {
direction: rtl;
/* Mark text as ltr to preserve punctuation/numeric order */
content: "\200e" -moz-label-content;
}
:is(label, description)[value][crop="start"]:-moz-locale-dir(rtl)::before {
direction: ltr;
/* Mark text as rtl to preserve punctuation/numeric order */
content: "\200f" -moz-label-content;
}
.checkbox-label-box,
.radio-label-box {
min-width: 0;
}
/********** toolbarbutton **********/
toolbarbutton {
align-items: center;
justify-content: center;
}
toolbarbutton.tabbable {
-moz-user-focus: normal !important;
}
toolbarbutton[crop] {
min-width: 0;
}
.toolbarbutton-text {
display: block;
text-align: center;
}
toolbar[mode="icons"] .toolbarbutton-text,
toolbar[mode="text"] .toolbarbutton-icon,
html|label.toolbarbutton-badge:empty {
display: none;
}
.toolbarbutton-icon,
.toolbarbutton-text,
.toolbarbutton-badge-stack,
.toolbarbutton-menu-dropmarker,
.treecol-text,
.treecol-sortdirection,
.menubar-left,
.menubar-text,
.menu-text,
.menu-iconic-text,
.menu-iconic-highlightable-text,
.menu-iconic-left,
.menu-right,
.menu-accel-container,
.button-box {
/* Preserves legacy behavior */
pointer-events: none;
}
/********** button **********/
button {
-moz-default-appearance: button;
appearance: auto;
}
dropmarker {
-moz-default-appearance: -moz-menulist-arrow-button;
appearance: auto;
}
/******** browser, editor, iframe ********/
browser,
editor,
iframe {
display: inline;
}
/* Allow the browser to shrink below its intrinsic size, to match legacy
* behavior */
browser {
align-self: stretch;
justify-self: stretch;
min-height: 0;
min-width: 0;
contain: size;
}
/*********** popup notification ************/
popupnotification {
flex-direction: column;
}
.popup-notification-menubutton:not([label]) {
display: none;
}
/********** radio **********/
radiogroup {
flex-direction: column;
}
/******** groupbox *********/
groupbox {
flex-direction: column;
}
/******** draggable elements *********/
toolbar:not([nowindowdrag="true"], [customizing="true"]) {
-moz-window-dragging: drag;
}
/* The list below is non-comprehensive and will probably need some tweaking. */
toolbaritem,
toolbarbutton,
toolbarseparator,
button,
search-textbox,
html|input,
tab,
radio,
splitter,
menu,
menulist {
-moz-window-dragging: no-drag;
}
titlebar {
pointer-events: auto !important;
}
/******* toolbar *******/
toolbox {
flex-direction: column;
}
@media (-moz-platform: macos) {
toolbar[type="menubar"] {
min-height: 0 !important;
border: 0 !important;
}
}
toolbarspring {
flex: 1000 1000;
}
/********* menu ***********/
menubar > menu:empty {
visibility: collapse;
}
.menu-text {
flex: 1;
}
/********* menupopup, panel, & tooltip ***********/
menupopup,
panel,
tooltip {
position: fixed;
-moz-top-layer: top;
width: fit-content;
height: fit-content;
/* Make sure that popups are interactable when shown, since they escape the
* usual layering rules */
-moz-inert: none;
/* Popups can't have overflow */
contain: paint;
z-index: 2147483647;
text-shadow: none;
}
tooltip {
appearance: auto;
-moz-default-appearance: tooltip;
white-space: pre-wrap;
background-color: InfoBackground;
color: InfoText;
font: message-box;
padding: 2px 3px;
max-width: 40em;
overflow: clip;
pointer-events: none;
}
/**
* It's important that these styles are in a UA sheet, because the default
* tooltip is native anonymous content
*/
@media (-moz-platform: linux) {
tooltip {
padding: 6px 10px; /* Matches Adwaita. */
line-height: 1.4; /* For Noto Sans; note that 1.2 may clip descenders. */
}
}
@media (-moz-platform: macos) {
tooltip {
padding: 2px 6px; /* Matches native metrics. */
}
}
@media (-moz-platform: windows) {
tooltip {
appearance: none;
border: 1px solid;
}
/* TODO(emilio): Probably make InfoText/InfoBackground do the right thing and
* remove this? */
@media not (prefers-contrast) {
tooltip {
background-color: #f9f9fb;
color: black;
border-color: #67676c;
border-radius: 4px;
}
@media (prefers-color-scheme: dark) {
tooltip {
background-color: #2b2a33;
color: white;
border-color: #f9f9fb;
}
}
}
}
/******** tree ******/
treecolpicker {
order: 2147483646;
}
treechildren {
display: flex;
flex: 1;
}
tree {
flex-direction: column;
}
tree[hidecolumnpicker="true"] treecolpicker {
display: none;
}
treecol {
min-width: 16px;
/* This preserves the behavior of -moz-box-ordinal-group. To change this we'd
* need to migrate the persisted ordinal values etc. */
order: 1;
}
treecol[hidden="true"] {
visibility: collapse;
display: flex;
}
/* ::::: lines connecting cells ::::: */
tree:not([treelines="true"]) treechildren::-moz-tree-line {
visibility: hidden;
}
treechildren::-moz-tree-cell(ltr) {
direction: ltr !important;
}
/********** deck, tabpanels & stack *********/
tabpanels > *|*:not(:-moz-native-anonymous) {
/* tabpanels is special: we want to avoid displaying them, but we still want
* the hidden children to be accessible */
-moz-subtree-hidden-only-visually: 1;
}
deck > *|*:not(:-moz-native-anonymous) {
visibility: hidden;
}
tabpanels > .deck-selected,
deck > .deck-selected {
-moz-subtree-hidden-only-visually: 0;
visibility: inherit;
}
tabpanels,
deck,
stack {
display: grid;
position: relative;
}
/* We shouldn't style native anonymous children like scrollbars or what not. */
tabpanels > *|*:not(:-moz-native-anonymous),
deck > *|*:not(:-moz-native-anonymous),
stack > *|*:not(:-moz-native-anonymous) {
grid-area: 1 / 1;
z-index: 0;
/*
The default `min-height: auto` value makes grid items refuse to be smaller
than their content. This doesn't match the traditional behavior of XUL stack,
which often shoehorns tall content into a smaller stack and allows the content
to decide how to handle overflow (e.g. by scaling down if it's an image, or
by adding scrollbars if it's scrollable).
*/
min-height: 0;
}
/********** tabbox *********/
tabbox {
flex-direction: column;
min-height: 0;
}
tabpanels {
min-height: 0;
}
tabs {
flex-direction: row;
}
tab {
align-items: center;
justify-content: center;
}
/********** tooltip *********/
tooltip[titletip="true"] {
/* The width of the tooltip isn't limited on cropped <tree> cells. */
max-width: none;
}
/********** basic rule for anonymous content that needs to pass box properties through
********** to an insertion point parent that holds the real kids **************/
.box-inherit {
align-items: inherit;
justify-content: inherit;
flex-grow: inherit;
flex-shrink: inherit;
flex-direction: inherit;
}
/********** textbox **********/
search-textbox {
text-shadow: none;
}
/* Prefix with (xul|*):root to workaround HTML tests loading xul.css */
:root html|textarea:not([resizable="true"]) {
resize: none;
}
/********** autocomplete textbox **********/
.autocomplete-richlistbox {
-moz-user-focus: ignore;
overflow-x: hidden !important;
flex: 1;
}
.autocomplete-richlistitem {
flex-direction: column;
align-items: center;
overflow: clip;
}
/* The following rule is here to fix bug 96899 (and now 117952).
Somehow trees create a situation
in which a popupset flows itself as if its popup child is directly within it
instead of the placeholder child that should actually be inside the popupset.
This is a stopgap measure, and it does not address the real bug. */
.autocomplete-result-popupset {
max-width: 0px;
width: 0 !important;
min-width: 0%;
min-height: 0%;
}
/********** menulist **********/
menulist[popuponly] {
appearance: none !important;
margin: 0 !important;
height: 0 !important;
min-height: 0 !important;
border: 0 !important;
padding: 0 !important;
}
/********** splitter **********/
.tree-splitter {
margin-inline: -4px;
width: 8px;
max-width: 8px;
min-width: 8px;
appearance: none !important;
border: none !important;
background: none !important;
order: 2147483646;
z-index: 2147483646;
}
/******** scrollbar ********/
slider {
/* This is a hint to layerization that the scrollbar thumb can never leave
the scrollbar track. */
overflow: hidden;
}
/******** scrollbox ********/
scrollbox {
/* This makes it scrollable! */
overflow: hidden;
}
@media (prefers-reduced-motion: no-preference) {
scrollbox[smoothscroll=true] {
scroll-behavior: smooth;
}
}
/********** stringbundle **********/
stringbundle,
stringbundleset {
display: none;
}
/********** dialog **********/
dialog {
flex: 1;
flex-direction: column;
}
/********** wizard **********/
wizard {
flex: 1;
flex-direction: column;
contain: inline-size;
min-width: 40em;
min-height: 30em;
}
wizard > wizardpage {
grid-area: 1 / 1;
min-height: 0;
}
wizard > wizardpage:not(.selected) {
visibility: hidden;
}
wizardpage {
flex-direction: column;
overflow: auto;
}
/********** Rich Listbox ********/
richlistbox {
flex-direction: column;
overflow: auto;
min-width: 0;
min-height: 0;
}
richlistitem {
flex-shrink: 0;
}
/*********** findbar ************/
findbar {
overflow-x: hidden;
contain: inline-size;
}
/* Some elements that in HTML blocks should be inline-level by default */
button, image {
display: inline-flex;
}
.menu-iconic-highlightable-text:not([highlightable="true"]),
.menu-iconic-text[highlightable="true"] {
display: none;
}
[orient="vertical"] { flex-direction: column !important; }
[orient="horizontal"] { flex-direction: row !important; }
[align="start"] { align-items: flex-start !important; }
[align="center"] { align-items: center !important; }
[align="end"] { align-items: flex-end !important; }
[align="baseline"] { align-items: baseline !important; }
[align="stretch"] { align-items: stretch !important; }
[pack="start"] { justify-content: start !important; }
[pack="center"] { justify-content: center !important; }
[pack="end"] { justify-content: flex-end !important; }
[flex="0"] { flex: none !important; }
[flex="1"] { flex: 1 !important; }