Styling Plasmo CSUI
Plasmo CSUI's built-inRoot Container
allows extension developers to safely style their components. It ensures that for the most part:
- The exported style does not leak to the web page
- The web page's style does not influence the component's styling
Seecaveats for when it does not work.
Raw CSS Text
To style your CSUI, export agetStyle
function:
importtype { PlasmoGetStyle }from"plasmo"exportconstgetStyle:PlasmoGetStyle= ()=> {conststyle=document.createElement("style")style.textContent=` p { background-color: yellow; } `return style}
Import Stylesheet
To import CSS/LESS/SASS files, combine thegetStyle
API with thedata-text
import scheme:
import styleTextfrom"data-text:./style.scss"importtype { PlasmoGetStyle }from"plasmo"exportconstgetStyle:PlasmoGetStyle= ()=> {conststyle=document.createElement("style")style.textContent= styleTextreturn style}
CSS-in-JS
ThegetStyle
API can also be used to hydrate CSS-in-JS style cache, for example when usingwith emotion
(opens in a new tab):
import createCachefrom"@emotion/cache"import { CacheProvider }from"@emotion/react"importtype { PlasmoGetStyle }from"plasmo"conststyleElement=document.createElement("style")conststyleCache=createCache({ key:"plasmo-emotion-cache", prepend:true, container: styleElement})exportconstgetStyle:PlasmoGetStyle= ()=> styleElement
CSS Modules
To utilize CSS modules, import the stylesheet twice:
import styleTextfrom"data-text:./style.module.css"importtype { PlasmoCSConfig }from"plasmo"import*as stylefrom"./style.module.css"exportconstgetStyle= ()=> {conststyle=document.createElement("style")style.textContent= styleTextreturn style}constOverlay= ()=> <h1className={style.header}>Captain Log</h1>exportdefault Overlay
Custom Font
To use a custom font in your CSUI, you must import the font inside a CSS file and declare it in thecss
property of theconfig object. The browser does not recognize Font assets if declared inside a ShadowDOM. You have to load them in the global scope.
- Add your font in the
assets
directory (e.g/assets/Fascinate.woff2
) - Create a
font.css
file next to your content script, importing the font inline using thedata-base64
scheme:
@font-face {font-family:"Fascinate";font-style:normal;font-weight:400;font-display:swap;src:url(data-base64:~assets/Fascinate.woff2)format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
- Declare the file in the
css
property of the content script config:
exportconstconfig:PlasmoCSConfig= { matches: ["https://www.plasmo.com/*"], css: ["font.css"]}
- Once the browser registers the font, you can reference it inside your CSS style:
.hw-top {background:red;color:white;font-family:"Fascinate";}
Seewith-content-scripts-ui/contents/plasmo-overlay.tsx (opens in a new tab) for a full example.
Styling the Shadow DOM
Use the IDs#plasmo-shadow-container
andplasmo-inline
to alter theRoot Container
styles in your CSS:
#plasmo-shadow-container {z-index:99999;}#plasmo-inline {background:blue;}
SeeCaveats: Root Container Style if some stylingrules are not being overridden.
Inherit the Web Page's Style
To inherit the web page's style, override the built-inRoot Container
to mount your component directly into the web page's DOM.Click here for more details.
Caveats
There are many situations that the framework's generic style encapsulation cannot handle (yet). Here are some common gotchas:
CSS Variables
CSS Variables are shared across every frame within the same browser tab. This means that if the webpage declares some CSS variables at the:root
context, it will be prioritized over yours.
To mitigate CSS variable sharing between CSUI and the web page, you can either:
- Declare a unique prefix namespace for your CSS variables
- Hoist your CSS variable under a
:host
scope - Mount your component inside an iframe, with its own head and body
Root Container Style
If the host webpage uses a global*
specifier to style its page, it can potentially override theRoot Container
style. For example:
* {display:block;}
The above code will cause the root container to have block display. In cases like these, overriding the root container style with an inline style will help keep the container consistent.
There may exist some CSS styling declarations that cannot be overridden to alter the theRoot Container
styles. In those cases, the!important
flag can be used as a workaround.
#plasmo-shadow-container {z-index:2147483646!important;}