browser/themes/shared/tabbrowser/content-area.css

Propagation: 18.75%

Back to Home
/* 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/. */

@namespace html url("http://www.w3.org/1999/xhtml");

:root {
  /* --tabpanel-background-color matches $in-content-page-background in newtab
     (browser/extensions/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 --background-color-canvas 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-pref("browser.privatebrowsing.felt-privacy-v1") {
      --tabpanel-background-color: linear-gradient(45deg, #722291 0%, #45278d 50%, #393473 100%) !important;
    }
  }
}

#navigator-toolbox {
  border-bottom: 0.01px solid var(--chrome-content-separator-color);

  /* stylelint-disable-next-line media-query-no-invalid */
  @media -moz-pref("sidebar.revamp") {
    /* This reserves space for the content area outline */
    border-bottom-color: var(--toolbar-bgcolor);
  }

  /* stylelint-disable-next-line media-query-no-invalid */
  @media -moz-pref("sidebar.verticalTabs") {
    border-bottom-style: none;
  }
}

/* Needed to ensure #sidebar-wrapper is full height when vertical tabs are not enabled */
#browser {
  position: relative;
}

#browser,
#tabbrowser-tabbox,
#tabbrowser-tabpanels,
.browserSidebarContainer {
  /* Allow devtools with large specified width/height to shrink */
  min-width: 0;
  min-height: 0;
}

#browser:not(.browser-toolbox-background) {
  background-color: var(--toolbar-bgcolor);
  color: var(--toolbar-color);

  :root[lwtheme] & {
    /* Ensure toolbar color displays on top of the frame/toolbox color to
    * guarantee full opacity */
    background-color: var(--lwt-accent-color);
    background-image: linear-gradient(var(--toolbar-bgcolor), var(--toolbar-bgcolor));
  }
}

#tabbrowser-tabbox {
  position: relative;
  z-index: var(--browser-area-z-index-tabbox);
  margin: 0;

  /* stylelint-disable-next-line media-query-no-invalid */
  @media -moz-pref("sidebar.revamp") {
    outline: 0.01px solid var(--chrome-content-separator-color);
    box-shadow: var(--content-area-shadow);

    /* stylelint-disable-next-line media-query-no-invalid */
    @media -moz-pref("sidebar.revamp.round-content-area") {
      :root:not([inDOMFullscreen]) &[sidebar-shown] {
        overflow: clip;
        border-start-end-radius: var(--border-radius-medium);

        /* stylelint-disable-next-line media-query-no-invalid */
        @media -moz-pref("sidebar.position_start") {
          border-start-start-radius: var(--border-radius-medium);
          border-start-end-radius: 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;
}

.sidebar-browser-stack {
  flex: 1;
}

.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-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;
    /* disabled on Windows for triggering grayscale AA (bug 659213): */
    @media not (-moz-platform: windows) {
      border-top-right-radius: 0.3em;
    }
    margin-right: 1em;
  }

  #statuspanel:not([mirror]) > &:-moz-locale-dir(rtl),
  #statuspanel[mirror] > &:-moz-locale-dir(ltr) {
    border-left-style: solid;
    /* disabled on Windows for triggering grayscale AA (bug 659213): */
    @media not (-moz-platform: windows) {
      border-top-left-radius: 0.3em;
    }
    margin-left: 1em;
  }
}

/**
 * Shortcuts
 */
#selection-shortcut-action-panel {
  --panel-subview-body-padding: 0;
}

#ai-action-button {
  --button-min-height: 34px;
  --button-size-icon: 34px;
  --button-border-radius: 7px;
  margin: 1px;
}

#ask-chat-shortcuts {
  max-width: 345px;
}

.ask-chat-shortcut-warning {
  margin: var(--arrowpanel-menuitem-margin);
  margin-bottom: var(--space-xsmall);
}

.ask-chat-shortcuts-custom-prompt {
  margin: var(--arrowpanel-menuitem-margin);
  margin-top: var(--space-small);
}

/**
 * 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 {
  min-width: 0;
  background-clip: content-box;
  display: flex;
  padding: 0;
  overflow-x: auto;
  outline: 0.5px solid var(--border-color-card);

  /* Ensure that dialog boxes are pixel-snapped, to keep their internal layout
   * consistent, regardless of whether the surrounding layout places them at a
   * fractional position. (This helps prevent arbitrary 1px shifts that could
   * otherwise appear inside of a vertically-centered dialog when the
   * viewport-height changes from being odd to even.) */
  will-change: transform;

  &:not(.spotlightBox) {
    box-shadow: var(--box-shadow-popup);
    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-color: WindowText;
  }

  &[resizable="true"] {
    resize: both;
    overflow: hidden;
    min-height: 20em;
  }

  &[sizeto="available"] {
    width: 100%;
    height: 100%;
    margin: 0;

    /* NOTE(emilio): This is a bit tricky, but basically what we want to do is
     * guarantee a size between 80% (or 90% for height) and 100% of the
     * available space, with some variable spacing when the available space is
     * over 600px. The 2 controls the growth of the margin, with a larger
     * number reaching the 80% width later, effectively. */
    --box-max-width-default: clamp(80%, 100% + (600px - 100%) / 2, 100%);
    --box-max-height-default: clamp(90%, 100% + (600px - 100%) / 2, 100%);
    max-width: var(--box-max-width-requested, var(--box-max-width-default));
    max-height: var(--box-max-height-requested, var(--box-max-height-default));
  }

  :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;
  }

  /* Spotlight dialogs are full-size on the content or window area */
  &.spotlightBox {
    max-width: none;
    max-height: none;
  }

  /* 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. */
    inset: 0;
    height: auto;
    width: auto;
    max-height: none;
    max-width: none;

    > .dialogOverlay {
      width: 100%;
      height: 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;
}
Back to Home