Search code examples
csscss-selectorscss-variablescss-paged-media

Using custom properties with @page rules


I'm trying to use css custom properties together with @page rules, but it does not seem to work. It kind of make sense since css variables cascade and the :root selector and the @page rule don't have a child/parent relationship.

Below is a typical example of what I'd like to do:

:root {
    --page-width: 148.5mm;
    --page-height: 210mm;
}

@page  {
    size: var(--page-width) var(--page-height);
}

Is there any way I could use variables with @page rules?


Solution

  • css variables cascade and the :root selector and the @page rule don't have a child/parent relationship.

    @page rules cascade, too. And the page context does actually inherit from the root element, which means not only do @page rules cascade, but they participate in the same cascade as style rules. But since this wasn't in the spec a decade ago, implementations where the page context doesn't inherit from the root element are still conformant to the spec.

    While this means you shouldn't rely on @page rules inheriting custom properties from :root, it does also mean that @page itself accepts custom properties, essentially making inheritance a non-issue. So, the following is expected to work, but it doesn't — it seems that every browser fails to create the custom properties:

    @page {
        --page-width: 148.5mm;
        --page-height: 210mm;
        size: var(--page-width) var(--page-height);
    }
    

    Interestingly, Firefox and Chrome have no trouble parsing and computing var() expressions with fallback values in @page style declarations, while Microsoft Edge fails to do so, which means the following will result in each page having 25mm margins in Firefox and Chrome:

    @page {
        --page-margin: 50mm;
        margin: var(--page-margin, 25mm);
    }
    

    So, in short, custom properties in @page rules don't work — not because the spec doesn't allow it, but because every browser's implementation of custom properties is incomplete.