JavaScript implementation of CSS.
const {
CSSPseudoElement,
CSSStyleProperties,
CSSStyleSheet,
StyleSheetList,
install,
matchElementAgainstSelectors,
matchTreesAgainstSelectors,
parseGrammar,
parseListGrammar,
} = require('@cdoublev/css')
// Install CSSOM interfaces on the global object
install()
// Create a CSSStyleSheet or CSSStyleProperties wrapper
const stylesheet = CSSStyleSheet.create(myGlobalObject, undefined, privateData)
const style = CSSStyleProperties.create(myGlobalObject, undefined, privateData)
// Parse something according to a CSS grammar
const selectors = parseGrammar('div', '<selector-list>')
// Parse a comma-separated list according to a CSS grammar
const list = parseListGrammar('(width < 30rem), (orientation: portrait)', '<media-query-list>')
// Match a tree against a complex selector list
const elements = matchTreesAgainstSelectors([document], selectors)install() accepts two optional arguments:
-
a window-like global object (default:
globalThis) that must have the following properties:document,Array,Object,Number,String,TypeError -
an object defining the user agent, system, and preferences (default: see below)
Property Default Affected values agent.colorSchemes['light', 'dark']@media/*-color-schemeagent.navigation['back']@media/nav-controlsagent.scripting'enabled'@media/scriptingagent.type'screen'@media(<media-type>)agent.viewport.interfaces.*{ expanded: false, value: 0 }*dv*and*sv*length valuesagent.viewport.overflow['scroll', 'scroll']@media/overflow-*agent.viewport.resizabletrue@media/resizableagent.viewport.state'normal'@media/display-statemanifestundefined @media/display-modesystem.display.blending'opaque'@media/environment-blendingsystem.display.colorIndex0@media/color-indexsystem.display.graphicModetrue@media/gridsystem.display.hdrfalse@media/*-dynamic-rangesystem.display.interlacedfalse@media/scansystem.display.monochrome0@media/monochromesystem.display.segments[1, 1]@media/*-segmentssystem.display.shape'rect'@media/shapesystem.display.update'fast'@media/updatesystem.pointersSee below @media/*-hover,@media/*-pointeruser.colorScheme'light'@media/*-color-scheme,<system-color>user.forcedColorsundefined @media/forced-colors,@media/prefers-color-scheme,@media/prefers-contrast,<system-color>user.highContrastfalse@media/prefers-contrastuser.fontFamilymonospacefont-familyuser.fontSize16font-sizeuser.invertedColorsfalse@media/inverted-colorsuser.reducedDatafalse@media/prefers-reduced-datauser.reducedMotionfalse@media/prefers-reduced-motionuser.reducedTransparencyfalse@media/prefers-reduced-transparencyuser.voiceFamilyfemalevoice-familyagent.colorSchemesrepresents the color schemes supported by the user agent, with the first entry representing the default color scheme.user.colorSchemerepresents the user's preferred color scheme, which is assumed to be included inagent.colorSchemes.agent.viewport.interfacesmust be an object with the propertiesbottom,left,right,top, assigned{ expanded: Boolean, value: Number }. It represents the user agent interfaces affecting the viewport area when expanded.agent.viewport.overflowrepresents the overflow behavior in the inline and block direction, respectively.manifest(parsed JSON) must be defined only when emulating a Web application environment.system.display.segmentsrepresents the number of horizontal and vertical segments, respectively.system.pointersmust be a list of pointer definitions as{ motionable: Boolean, precision: 'coarse|fine' }. The first entry represents the primary pointer, which defaults to{ motionable: true, precision: 'fine' }.user.forcedColorsmust be an object mapping a<system-color>keyword in lowercase to a resolved legacy<rgb()>. It represents the colors from the high contrast mode in Windows or Firefox. When it is defined,user.highContrastmust not be defined: it will be evaluated based on the WCAG contrast ratio betweencanvasandcanvastext, which are assumed to always be defined.user.highContrastcorresponds to the high contrast mode in macOS, which does not activate the forced color mode, souser.forcedColorsis assumed to be undefined.
CSSPseudoElement, CSSStyleSheet, CSSStyleProperties, StyleSheetList, are webidl2js wrappers intended to implement:
DocumentOrShadowRoot.styleSheets- create a CSS style sheet: when processing the content of
HTMLStyleElementor the resource referenced byHTMLLinkElementor an HTTPLinkheader withrel="stylesheet" ElementCSSInlineStyle.styleElement.pseudo()andWindow.getComputedStyle()
CSSPseudoElement accepts privateProperties that correspond to its attributes.
CSSStyleSheet accepts the following privateProperties:
- CSS rules:
rules(StringorReadableStream) - alternate flag:
alternate(Boolean, optional, default:false) - disabled flag:
disabled(Boolean, optional, default:false) - location:
location(String, optional, default:null) - media:
media(StringorMediaList) - origin-clean flag:
originClean(Boolean) - owner CSS rule:
ownerRule(CSSRule, optional, default:null) - owner node:
ownerNode(HTMLElement) - parent CSS style sheet:
parentStyleSheet(CSSStyleSheet, optional, default:null) - title:
title(String, optional, default:'')
CSSStyleProperties accepts the following privateProperties:
- computed flag:
computed(Boolean, optional, default:false) - declarations:
declarations([Declaration], optional, default:[]) - owner node:
ownerNode(HTMLElement, optional, default:null) - parent CSS rule:
parentRule(CSSRule, optional, default:null)
Declaration must be a plain object with the following properties:
name:Stringvalue:Object|[Object](parsed value)important:Boolean(optional, default:false)
parseGrammar() and parseListGrammar() are implementations of parse something according to a CSS grammar and parse a comma-separated list according to a CSS grammar, which take 3 arguments:
input:Stringdefinition:String(a CSS value definition)context:Element(optional)
matchElementAgainstSelectors() and matchTreesAgainstSelectors() are intended to implement:
element.closest()withmatchElementAgainstSelectors(ancestor, selectors, { scopes: { inclusive: true, roots: [element] } })element.matches()withmatchElementAgainstSelectors(element, selectors, { scopes: { inclusive: true, roots: [element] } })element.querySelector()withmatchTreesAgainstSelectors([document], selectors, { scopes: { roots: [element] } }, { first: true })element.querySelectorAll()withmatchTreesAgainstSelectors([document], selectors, { scopes: { roots: [element] } })
selectors is expected to be a <complex-selector-list> or <complex-real-selector-list>.