Skip to main content
Deno 2 is finally here 🎉️
Learn more
Module

x/bundler/deps.ts>postcss.Container

A Bundler with the web in mind.
Go to Latest
class postcss.Container
extends Node
Re-export
Abstract
import { postcss } from "https://deno.land/x/bundler@0.6.5/deps.ts";
const { Container } = postcss;

The Root, AtRule, and Rule container nodes inherit some common methods to help work with their children.

Note that all containers can store any content. If you write a rule inside a rule, PostCSS will parse it.

Properties

readonly
first: ChildNode | undefined

The container’s first child.

rule.first === rules.nodes[0]
readonly
last: ChildNode | undefined

The container’s last child.

rule.last === rule.nodes[rule.nodes.length - 1]
nodes: ChildNode[]

An array containing the container’s children.

const root = postcss.parse('a { color: black }')
root.nodes.length           //=> 1
root.nodes[0].selector      //=> 'a'
root.nodes[0].nodes[0].prop //=> 'color'

Methods

append(...nodes: (
| Node
| Node[]
| string
| string[]
)[]
): this

Inserts new nodes to the end of the container.

const decl1 = new Declaration({ prop: 'color', value: 'black' })
const decl2 = new Declaration({ prop: 'background-color', value: 'white' })
rule.append(decl1, decl2)

root.append({ name: 'charset', params: '"UTF-8"' })  // at-rule
root.append({ selector: 'a' })                       // rule
rule.append({ prop: 'color', value: 'black' })       // declaration
rule.append({ text: 'Comment' })                     // comment

root.append('a {}')
root.first.append('color: black; z-index: 1')
each(callback: (node: ChildNode, index: number) => false | void): false | undefined

Iterates through the container’s immediate children, calling callback for each child.

Returning false in the callback will break iteration.

This method only iterates through the container’s immediate children. If you need to recursively iterate through all the container’s descendant nodes, use Container#walk.

Unlike the for {}-cycle or Array#forEach this iterator is safe if you are mutating the array of child nodes during iteration. PostCSS will adjust the current index to match the mutations.

const root = postcss.parse('a { color: black; z-index: 1 }')
const rule = root.first

for (const decl of rule.nodes) {
  decl.cloneBefore({ prop: '-webkit-' + decl.prop })
  // Cycle will be infinite, because cloneBefore moves the current node
  // to the next index
}

rule.each(decl => {
  decl.cloneBefore({ prop: '-webkit-' + decl.prop })
  // Will be executed only for color and z-index
})
every(condition: (
node: ChildNode,
index: number,
nodes: ChildNode[],
) => boolean
): boolean

Returns true if callback returns true for all of the container’s children.

const noPrefixes = rule.every(i => i.prop[0] !== '-')
index(child: ChildNode | number): number

Returns a child’s index within the Container#nodes array.

rule.index( rule.nodes[2] ) //=> 2
insertAfter(oldNode: ChildNode | number, newNode:
| string
| string[]
): this

Insert new node after old node within the container.

insertBefore(oldNode: ChildNode | number, newNode:
| string
| string[]
): this

Insert new node before old node within the container.

rule.insertBefore(decl, decl.clone({ prop: '-webkit-' + decl.prop }))
prepend(...nodes: (
| Node
| Node[]
| string
| string[]
)[]
): this

Inserts new nodes to the start of the container.

const decl1 = new Declaration({ prop: 'color', value: 'black' })
const decl2 = new Declaration({ prop: 'background-color', value: 'white' })
rule.prepend(decl1, decl2)

root.append({ name: 'charset', params: '"UTF-8"' })  // at-rule
root.append({ selector: 'a' })                       // rule
rule.append({ prop: 'color', value: 'black' })       // declaration
rule.append({ text: 'Comment' })                     // comment

root.append('a {}')
root.first.append('color: black; z-index: 1')
push(child: ChildNode): this

Add child to the end of the node.

rule.push(new Declaration({ prop: 'color', value: 'black' }))
removeAll(): this

Removes all children from the container and cleans their parent properties.

rule.removeAll()
rule.nodes.length //=> 0
removeChild(child: ChildNode | number): this

Removes node from the container and cleans the parent properties from the node and its children.

rule.nodes.length  //=> 5
rule.removeChild(decl)
rule.nodes.length  //=> 4
decl.parent        //=> undefined
replaceValues(
pattern: string | RegExp,
options: ValueOptions,
replaced: string | { (substring: string, ...args: any[]): string; },
): this

Passes all declaration values within the container that match pattern through callback, replacing those values with the returned result of callback.

This method is useful if you are using a custom unit or function and need to iterate through all values.

root.replaceValues(/\d+rem/, { fast: 'rem' }, string => {
  return 15 * parseInt(string) + 'px'
})
replaceValues(pattern: string | RegExp, replaced: string | { (substring: string, ...args: any[]): string; }): this
some(condition: (
node: ChildNode,
index: number,
nodes: ChildNode[],
) => boolean
): boolean

Returns true if callback returns true for (at least) one of the container’s children.

const hasPrefix = rule.some(i => i.prop[0] === '-')
walk(callback: (node: ChildNode, index: number) => false | void): false | undefined

Traverses the container’s descendant nodes, calling callback for each node.

Like container.each(), this method is safe to use if you are mutating arrays during iteration.

If you only need to iterate through the container’s immediate children, use Container#each.

root.walk(node => {
  // Traverses all descendant nodes.
})
walkAtRules(nameFilter: string | RegExp, callback: (atRule: AtRule, index: number) => false | void): false | undefined

Traverses the container’s descendant nodes, calling callback for each at-rule node.

If you pass a filter, iteration will only happen over at-rules that have matching names.

Like Container#each, this method is safe to use if you are mutating arrays during iteration.

root.walkAtRules(rule => {
  if (isOld(rule.name)) rule.remove()
})

let first = false
root.walkAtRules('charset', rule => {
  if (!first) {
    first = true
  } else {
    rule.remove()
  }
})
walkAtRules(callback: (atRule: AtRule, index: number) => false | void): false | undefined
walkComments(callback: (comment: Comment, indexed: number) => false | void): false | undefined

Traverses the container’s descendant nodes, calling callback for each comment node.

Like Container#each, this method is safe to use if you are mutating arrays during iteration.

root.walkComments(comment => {
  comment.remove()
})
walkComments(callback: (comment: Comment, indexed: number) => false | void): false | undefined
walkDecls(propFilter: string | RegExp, callback: (decl: Declaration, index: number) => false | void): false | undefined

Traverses the container’s descendant nodes, calling callback for each declaration node.

If you pass a filter, iteration will only happen over declarations with matching properties.

root.walkDecls(decl => {
  checkPropertySupport(decl.prop)
})

root.walkDecls('border-radius', decl => {
  decl.remove()
})

root.walkDecls(/^background/, decl => {
  decl.value = takeFirstColorFromGradient(decl.value)
})

Like Container#each, this method is safe to use if you are mutating arrays during iteration.

walkDecls(callback: (decl: Declaration, index: number) => false | void): false | undefined
walkRules(selectorFilter: string | RegExp, callback: (atRule: Rule, index: number) => false | void): false | undefined

Traverses the container’s descendant nodes, calling callback for each rule node.

If you pass a filter, iteration will only happen over rules with matching selectors.

Like Container#each, this method is safe to use if you are mutating arrays during iteration.

const selectors = []
root.walkRules(rule => {
  selectors.push(rule.selector)
})
console.log(`Your CSS uses ${ selectors.length } selectors`)
walkRules(callback: (atRule: Rule, index: number) => false | void): false | undefined