Skip to content

Latest commit

 

History

History
495 lines (422 loc) · 13.8 KB

File metadata and controls

495 lines (422 loc) · 13.8 KB
title slug page-type browser-compat
Browser styles
Mozilla/Add-ons/WebExtensions/user_interface/Browser_styles
guide
webextensions.manifest.action
webextensions.manifest.browser_action
webextensions.manifest.page_action
webextensions.manifest.sidebar_action
webextensions.manifest.options_ui

{{AddonSidebar}}

Your extension can include user interface components - browser and page action popups, sidebars, and options pages - that are specified by:

  1. creating an HTML file defining the structure of the UI element.
  2. adding a manifest.json key (action, browser_action, page_action, sidebar_action, or options_ui) pointing to that HTML file.

You can style these elements to match the browser's style. The manifest.json keys include an optional property to help with this: browser_style. If this is included and set to true, your document gets one or more extra stylesheets that help make it look consistent with the browser's UI and with other extensions that use the browser_style property.

Note: Support for browser_style in Manifest V3 has been deprecated and, from Firefox 115, options_ui.browser_style and sidebar_action.browser_style default to false. page_action.browser_style, browser_action.browser_style, and action.browser_style already defaults to false. If your Manifest V3 extension depends on the browser_style: true styles, bundle this stylesheet in the extension: extension.css. See (Firefox bug 1827910) for more information.

When considering whether to use browser_style: true, test your extension with various themes (built-in or from AMO) to ensure that the extension UI behaves the way you expect it to.

Warning: When browser_style: true is included in your web extension's manifest, text selection in your extension's UI is disabled except in input controls. If this causes a problem, include browser_style:false instead.

Note: Google Chrome and Opera use chrome_style instead of browser_style, so you need to add both keys to support them.

In Firefox, the stylesheet can be seen at chrome://browser/content/extension.css. The extra stylesheet at chrome://browser/content/extension-mac.css is also included on macOS.

Most styles are automatically applied, but some elements require you to add the non-standard browser-style class to get their styling, as detailed in the table below:

Element Example
<button>
<button class="browser-style">Click me</button>

<select>

<select class="browser-style" name="select">
  <option value="value1">Value 1</option>
  <option value="value2" selected>Value 2</option>
  <option value="value3">Value 3</option>
</select>
<textarea>
<textarea class="browser-style">Write here</textarea>
Parent of an <input>
<div class="browser-style">
  <input type="radio" id="op1" name="choices" value="op1"/>
  <label for="op1">Option 1</label>

<input type="radio" id="op2" name="choices" value="op2"/> <label for="op2">Option 2</label> </div>

Note: See Firefox bug 1465256 for removal of this unnecessary requirement.

Browser compatibility

{{Compat}}

Firefox Panel Components

Note: This feature is non-standard and only works in Firefox.

The chrome://browser/content/extension.css stylesheet also contains the styles for the Firefox Panel Components.

The legacy Firefox Style Guide documents proper usage.

Element Example
Header
<header class="panel-section panel-section-header">
  <div class="icon-section-header"><img src="image.svg"/></div>
  <div class="text-section-header">Header</div>
</header>
Footer
<footer class="panel-section panel-section-footer">
  <button class="panel-section-footer-button">Cancel</button>
  <div class="panel-section-footer-separator"></div>
  <button class="panel-section-footer-button default">Confirm</button>
</footer>
Tabs
<div class="panel-section panel-section-tabs">
  <button class="panel-section-tabs-button selected">Tab</button>
  <div class="panel-section-tabs-separator"></div>
  <button class="panel-section-tabs-button">Tab</button>
  <div class="panel-section-tabs-separator"></div>
  <button class="panel-section-tabs-button">Tab</button>
</div>
Form
<div class="panel-section panel-section-formElements">
  <div class="panel-formElements-item">
    <label for="name01">Label:</label>
    <input type="text" value="Name" id="name01" />
  </div>
  <div class="panel-formElements-item">
    <label for="picker01">Label:</label>
    <select id="picker01">
      <option value="value1" selected="true">Dropdown</option>
      <option value="value2">List Item</option>
      <option value="value3">List Item</option>
    </select>
  </div>
  <div class="panel-formElements-item">
    <label for="placeholder01">Label:</label>
    <input type="text" placeholder="Placeholder" id="placeholder01" />
    <button name="expander" class="expander"></button>
  </div>
</div>
Menu
<div class="panel-section panel-section-list">
  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut">Ctrl-L</div>
  </div>

<div class="panel-list-item"> <div class="icon"></div> <div class="text">List Item</div> <div class="text-shortcut"></div> </div>

<div class="panel-section-separator"></div>

<div class="panel-list-item disabled"> <div class="icon"></div> <div class="text">Disabled List Item</div> <div class="text-shortcut"></div> </div>

<div class="panel-section-separator"></div>

<div class="panel-list-item"> <div class="icon"></div> <div class="text">List Item</div> <div class="text-shortcut"></div> </div>

<div class="panel-list-item"> <div class="icon"></div> <div class="text">List Item</div> <div class="text-shortcut"></div> </div> </div>

Example

HTML

<header class="panel-section panel-section-header">
  <div class="icon-section-header"><!-- An image goes here. --></div>
  <div class="text-section-header">Header</div>
</header>

<div class="panel-section panel-section-list">
  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut">Ctrl-L</div>
  </div>

  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut"></div>
  </div>

  <div class="panel-section-separator"></div>

  <div class="panel-list-item disabled">
    <div class="icon"></div>
    <div class="text">Disabled List Item</div>
    <div class="text-shortcut"></div>
  </div>

  <div class="panel-section-separator"></div>

  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut"></div>
  </div>

  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut"></div>
  </div>
</div>

<footer class="panel-section panel-section-footer">
  <button class="panel-section-footer-button">Cancel</button>
  <div class="panel-section-footer-separator"></div>
  <button class="panel-section-footer-button default">Confirm</button>
</footer>
/* Global */
html,
body {
  background: white;
  box-sizing: border-box;
  color: #222426;
  cursor: default;
  display: flex;
  flex-direction: column;
  font: caption;
  margin: 0;
  padding: 0;
  -moz-user-select: none;
}

body * {
  box-sizing: border-box;
  text-align: start;
}

button.panel-section-footer-button,
button.panel-section-tabs-button {
  color: inherit;
  background-color: unset;
  font: inherit;
  text-shadow: inherit;
  appearance: none;
  border: none;
}

/* Panel Section */
.panel-section {
  display: flex;
  flex-direction: row;
}

.panel-section-separator {
  background-color: rgba(0, 0, 0, 0.15);
  min-height: 1px;
}

/* Panel Section - Header */
.panel-section-header {
  border-bottom: 1px solid rgba(0, 0, 0, 0.15);
  padding: 16px;
}

.panel-section-header > .icon-section-header {
  background-position: center center;
  background-repeat: no-repeat;
  height: 32px;
  margin-right: 16px;
  position: relative;
  width: 32px;
}

.panel-section-header > .text-section-header {
  align-self: center;
  font-size: 1.385em;
  font-weight: lighter;
}

/* Panel Section - List */
.panel-section-list {
  flex-direction: column;
  padding: 4px 0;
}

.panel-list-item {
  align-items: center;
  display: flex;
  flex-direction: row;
  height: 24px;
  padding: 0 16px;
}

.panel-list-item:not(.disabled):hover {
  background-color: rgba(0, 0, 0, 0.06);
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}

.panel-list-item:not(.disabled):hover:active {
  background-color: rgba(0, 0, 0, 0.1);
}

.panel-list-item.disabled {
  color: #999;
}

.panel-list-item > .icon {
  flex-grow: 0;
  flex-shrink: 0;
}

.panel-list-item > .text {
  flex-grow: 10;
}

.panel-list-item > .text-shortcut {
  color: #808080;
  font-family: "Lucida Grande", caption;
  font-size: 0.847em;
  justify-content: flex-end;
}

.panel-section-list .panel-section-separator {
  margin: 4px 0;
}

/* Panel Section - Footer */
.panel-section-footer {
  background-color: rgba(0, 0, 0, 0.06);
  border-top: 1px solid rgba(0, 0, 0, 0.15);
  color: #1a1a1a;
  display: flex;
  flex-direction: row;
  height: 41px;
  margin-top: -1px;
  padding: 0;
}

.panel-section-footer-button {
  flex: 1 1 auto;
  height: 100%;
  margin: 0 -1px;
  padding: 12px;
  text-align: center;
}

.panel-section-footer-button > .text-shortcut {
  color: #808080;
  font-family: "Lucida Grande", caption;
  font-size: 0.847em;
}

.panel-section-footer-button:hover {
  background-color: rgba(0, 0, 0, 0.06);
}

.panel-section-footer-button:hover:active {
  background-color: rgba(0, 0, 0, 0.1);
}

.panel-section-footer-button.default {
  background-color: #0996f8;
  box-shadow: 0 1px 0 #0670cc inset;
  color: #fff;
}

.panel-section-footer-button.default:hover {
  background-color: #0670cc;
  box-shadow: 0 1px 0 #005bab inset;
}

.panel-section-footer-button.default:hover:active {
  background-color: #005bab;
  box-shadow: 0 1px 0 #004480 inset;
}

.panel-section-footer-separator {
  background-color: rgba(0, 0, 0, 0.1);
  width: 1px;
  z-index: 99;
}
/* Example specific – not part of chrome://browser/content/extension.css */
body {
  background: #fcfcfc;
  background-clip: padding-box;
  border: 1px solid rgba(24, 26, 27, 0.2);
  box-shadow: 0 3px 5px rgba(24, 26, 27, 0.1), 0 0 7px rgba(24, 26, 27, 0.1);
  box-sizing: content-box;
  margin: 2em auto 0.5em;
  width: 384px;
}

html {
  min-height: 100vh;
}

html > body {
  margin: auto;
}

.icon-section-header {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj48Y2lyY2xlIGZpbGw9IiMzNjM5NTkiIGN4PSIxNSIgY3k9IjE1IiByPSIxNSIvPjwvc3ZnPg==");
}

Result

{{EmbedLiveSample("Example","640","360")}}