CINXE.COM
CSS Functions and Mixins Module
<!doctype html><html lang="en"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport"> <title>CSS Functions and Mixins Module</title> <meta content="ED" name="w3c-status"> <link href="https://www.w3.org/StyleSheets/TR/2021/W3C-ED" rel="stylesheet"> <meta content="Bikeshed version b25686b9f, updated Fri Mar 14 14:15:20 2025 -0700" name="generator"> <link href="https://www.w3.org/TR/css-mixins-1/" rel="canonical"> <link href="https://drafts.csswg.org/csslogo.ico" rel="icon"> <meta content="db06191d329430e778cde143113ca1d3f4b0ed61" name="revision"> <meta content="dark light" name="color-scheme"> <link href="https://www.w3.org/StyleSheets/TR/2021/dark.css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css"> <style> /* Put nice boxes around each algorithm. */ [data-algorithm]:not(.heading) { padding: .5em; border: thin solid #ddd; border-radius: .5em; margin: .5em calc(-0.5em - 1px); } [data-algorithm]:not(.heading) > :first-child { margin-top: 0; } [data-algorithm]:not(.heading) > :last-child { margin-bottom: 0; } [data-algorithm] [data-algorithm] { margin: 1em 0; } </style> <style>/* Boilerplate: style-autolinks */ .css.css, .property.property, .descriptor.descriptor { color: var(--a-normal-text); font-size: inherit; font-family: inherit; } .css::before, .property::before, .descriptor::before { content: "‘"; } .css::after, .property::after, .descriptor::after { content: "’"; } .property, .descriptor { /* Don't wrap property and descriptor names */ white-space: nowrap; } .type { /* CSS value <type> */ font-style: italic; } pre .property::before, pre .property::after { content: ""; } [data-link-type="property"]::before, [data-link-type="propdesc"]::before, [data-link-type="descriptor"]::before, [data-link-type="value"]::before, [data-link-type="function"]::before, [data-link-type="at-rule"]::before, [data-link-type="selector"]::before, [data-link-type="maybe"]::before { content: "‘"; } [data-link-type="property"]::after, [data-link-type="propdesc"]::after, [data-link-type="descriptor"]::after, [data-link-type="value"]::after, [data-link-type="function"]::after, [data-link-type="at-rule"]::after, [data-link-type="selector"]::after, [data-link-type="maybe"]::after { content: "’"; } [data-link-type].production::before, [data-link-type].production::after, .prod [data-link-type]::before, .prod [data-link-type]::after { content: ""; } [data-link-type=element], [data-link-type=element-attr] { font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace; font-size: .9em; } [data-link-type=element]::before { content: "<" } [data-link-type=element]::after { content: ">" } [data-link-type=biblio] { white-space: pre; } @media (prefers-color-scheme: dark) { :root { --selflink-text: black; --selflink-bg: silver; --selflink-hover-text: white; } } </style> <style>/* Boilerplate: style-colors */ /* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */ :root { color-scheme: light dark; --text: black; --bg: white; --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark); --logo-bg: #1a5e9a; --logo-active-bg: #c00; --logo-text: white; --tocnav-normal-text: #707070; --tocnav-normal-bg: var(--bg); --tocnav-hover-text: var(--tocnav-normal-text); --tocnav-hover-bg: #f8f8f8; --tocnav-active-text: #c00; --tocnav-active-bg: var(--tocnav-normal-bg); --tocsidebar-text: var(--text); --tocsidebar-bg: #f7f8f9; --tocsidebar-shadow: rgba(0,0,0,.1); --tocsidebar-heading-text: hsla(203,20%,40%,.7); --toclink-text: var(--text); --toclink-underline: #3980b5; --toclink-visited-text: var(--toclink-text); --toclink-visited-underline: #054572; --heading-text: #005a9c; --hr-text: var(--text); --algo-border: #def; --del-text: red; --del-bg: transparent; --ins-text: #080; --ins-bg: transparent; --a-normal-text: #034575; --a-normal-underline: #bbb; --a-visited-text: var(--a-normal-text); --a-visited-underline: #707070; --a-hover-bg: rgba(75%, 75%, 75%, .25); --a-active-text: #c00; --a-active-underline: #c00; --blockquote-border: silver; --blockquote-bg: transparent; --blockquote-text: currentcolor; --issue-border: #e05252; --issue-bg: #fbe9e9; --issue-text: var(--text); --issueheading-text: #831616; --example-border: #e0cb52; --example-bg: #fcfaee; --example-text: var(--text); --exampleheading-text: #574b0f; --note-border: #52e052; --note-bg: #e9fbe9; --note-text: var(--text); --noteheading-text: hsl(120, 70%, 30%); --notesummary-underline: silver; --assertion-border: #aaa; --assertion-bg: #eee; --assertion-text: black; --advisement-border: orange; --advisement-bg: #fec; --advisement-text: var(--text); --advisementheading-text: #b35f00; --warning-border: red; --warning-bg: hsla(40,100%,50%,0.95); --warning-text: var(--text); --amendment-border: #330099; --amendment-bg: #F5F0FF; --amendment-text: var(--text); --amendmentheading-text: #220066; --def-border: #8ccbf2; --def-bg: #def; --def-text: var(--text); --defrow-border: #bbd7e9; --datacell-border: silver; --indexinfo-text: #707070; --indextable-hover-text: black; --indextable-hover-bg: #f7f8f9; --outdatedspec-bg: rgba(0, 0, 0, .5); --outdatedspec-text: black; --outdated-bg: maroon; --outdated-text: white; --outdated-shadow: red; --editedrec-bg: darkorange; } @media (prefers-color-scheme: dark) { :root { --text: #ddd; --bg: black; --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E"); --logo-bg: #1a5e9a; --logo-active-bg: #c00; --logo-text: white; --tocnav-normal-text: #999; --tocnav-normal-bg: var(--bg); --tocnav-hover-text: var(--tocnav-normal-text); --tocnav-hover-bg: #080808; --tocnav-active-text: #f44; --tocnav-active-bg: var(--tocnav-normal-bg); --tocsidebar-text: var(--text); --tocsidebar-bg: #080808; --tocsidebar-shadow: rgba(255,255,255,.1); --tocsidebar-heading-text: hsla(203,20%,40%,.7); --toclink-text: var(--text); --toclink-underline: #6af; --toclink-visited-text: var(--toclink-text); --toclink-visited-underline: #054572; --heading-text: #8af; --hr-text: var(--text); --algo-border: #456; --del-text: #f44; --del-bg: transparent; --ins-text: #4a4; --ins-bg: transparent; --a-normal-text: #6af; --a-normal-underline: #555; --a-visited-text: var(--a-normal-text); --a-visited-underline: var(--a-normal-underline); --a-hover-bg: rgba(25%, 25%, 25%, .2); --a-active-text: #f44; --a-active-underline: var(--a-active-text); --borderedblock-bg: rgba(255, 255, 255, .05); --blockquote-border: silver; --blockquote-bg: var(--borderedblock-bg); --blockquote-text: currentcolor; --issue-border: #e05252; --issue-bg: var(--borderedblock-bg); --issue-text: var(--text); --issueheading-text: hsl(0deg, 70%, 70%); --example-border: hsl(50deg, 90%, 60%); --example-bg: var(--borderedblock-bg); --example-text: var(--text); --exampleheading-text: hsl(50deg, 70%, 70%); --note-border: hsl(120deg, 100%, 35%); --note-bg: var(--borderedblock-bg); --note-text: var(--text); --noteheading-text: hsl(120, 70%, 70%); --notesummary-underline: silver; --assertion-border: #444; --assertion-bg: var(--borderedblock-bg); --assertion-text: var(--text); --advisement-border: orange; --advisement-bg: #222218; --advisement-text: var(--text); --advisementheading-text: #f84; --warning-border: red; --warning-bg: hsla(40,100%,20%,0.95); --warning-text: var(--text); --amendment-border: #330099; --amendment-bg: #080010; --amendment-text: var(--text); --amendmentheading-text: #cc00ff; --def-border: #8ccbf2; --def-bg: #080818; --def-text: var(--text); --defrow-border: #136; --datacell-border: silver; --indexinfo-text: #aaa; --indextable-hover-text: var(--text); --indextable-hover-bg: #181818; --outdatedspec-bg: rgba(255, 255, 255, .5); --outdatedspec-text: black; --outdated-bg: maroon; --outdated-text: white; --outdated-shadow: red; --editedrec-bg: darkorange; } /* In case a transparent-bg image doesn't expect to be on a dark bg, which is quite common in practice... */ img { background: white; } } </style> <style>/* Boilerplate: style-counters */ body { counter-reset: example figure issue; } .issue { counter-increment: issue; } .issue:not(.no-marker)::before { content: "Issue " counter(issue); } .example { counter-increment: example; } .example:not(.no-marker)::before { content: "Example " counter(example); } .invalid.example:not(.no-marker)::before, .illegal.example:not(.no-marker)::before { content: "Invalid Example" counter(example); } figcaption { counter-increment: figure; } figcaption:not(.no-marker)::before { content: "Figure " counter(figure) " "; } </style> <style>/* Boilerplate: style-dfn-panel */ :root { --dfnpanel-bg: #ddd; --dfnpanel-text: var(--text); --dfnpanel-target-bg: #ffc; --dfnpanel-target-outline: orange; } @media (prefers-color-scheme: dark) { :root { --dfnpanel-bg: #222; --dfnpanel-text: var(--text); --dfnpanel-target-bg: #333; --dfnpanel-target-outline: silver; } } .dfn-panel { position: absolute; z-index: 35; width: 20em; width: 300px; height: auto; max-height: 500px; overflow: auto; padding: 0.5em 0.75em; font: small Helvetica Neue, sans-serif, Droid Sans Fallback; background: var(--dfnpanel-bg); color: var(--dfnpanel-text); border: outset 0.2em; white-space: normal; /* in case it's moved into a pre */ } .dfn-panel:not(.on) { display: none; } .dfn-panel * { margin: 0; padding: 0; text-indent: 0; } .dfn-panel > b { display: block; } .dfn-panel a { color: var(--dfnpanel-text); } .dfn-panel a:not(:hover) { text-decoration: none !important; border-bottom: none !important; } .dfn-panel a:focus { outline: 5px auto Highlight; outline: 5px auto -webkit-focus-ring-color; } .dfn-panel > b + b { margin-top: 0.25em; } .dfn-panel ul { padding: 0 0 0 1em; list-style: none; } .dfn-panel li a { max-width: calc(300px - 1.5em - 1em); overflow: hidden; text-overflow: ellipsis; } .dfn-panel.activated { display: inline-block; position: fixed; left: 8px; bottom: 2em; margin: 0 auto; max-width: calc(100vw - 1.5em - .4em - .5em); max-height: 30vh; transition: left 1s ease-out, bottom 1s ease-out; } .dfn-panel .link-item:hover { text-decoration: underline; } .dfn-panel .link-item .copy-icon { opacity: 0; } .dfn-panel .link-item:hover .copy-icon, .dfn-panel .link-item .copy-icon:focus { opacity: 1; } .dfn-panel .copy-icon { display: inline-block; margin-right: 0.5em; width: 0.85em; height: 1em; border-radius: 3px; background-color: #ccc; cursor: pointer; } .dfn-panel .copy-icon .icon { width: 100%; height: 100%; background-color: #fff; display: flex; justify-content: center; align-items: center; position: relative; } .dfn-panel .copy-icon .icon::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 1px solid black; background-color: #ccc; opacity: 0.25; transform: translate(3px, -3px); } .dfn-panel .copy-icon:active .icon::before { opacity: 1; } .dfn-paneled[role="button"] { cursor: help; } .highlighted { animation: target-fade 3s; } @keyframes target-fade { from { background-color: var(--dfnpanel-target-bg); outline: 5px solid var(--dfnpanel-target-outline); } to { color: var(--a-normal-text); background-color: transparent; outline: transparent; } } </style> <style>/* Boilerplate: style-idl-highlighting */ pre.idl.highlight { background: var(--borderedblock-bg, var(--def-bg)); } </style> <style>/* Boilerplate: style-issues */ a[href].issue-return { float: right; float: inline-end; color: var(--issueheading-text); font-weight: bold; text-decoration: none; } </style> <style>/* Boilerplate: style-md-lists */ /* This is a weird hack for me not yet following the commonmark spec regarding paragraph and lists. */ [data-md] > :first-child { margin-top: 0; } [data-md] > :last-child { margin-bottom: 0; } </style> <style>/* Boilerplate: style-ref-hints */ :root { --ref-hint-bg: #ddd; --ref-hint-text: var(--text); } @media (prefers-color-scheme: dark) { :root { --ref-hint-bg: #222; --ref-hint-text: var(--text); } } .ref-hint { display: inline-block; position: absolute; z-index: 35; width: 20em; width: 300px; height: auto; max-height: 500px; overflow: auto; padding: 0.5em 0.5em; font: small Helvetica Neue, sans-serif, Droid Sans Fallback; background: var(--ref-hint-bg); color: var(--ref-hint-text); border: outset 0.2em; white-space: normal; /* in case it's moved into a pre */ } .ref-hint * { margin: 0; padding: 0; text-indent: 0; } .ref-hint ul { padding: 0 0 0 1em; list-style: none; } </style> <style>/* Boilerplate: style-selflinks */ :root { --selflink-text: white; --selflink-bg: gray; --selflink-hover-text: black; } .heading, .issue, .note, .example, li, dt { position: relative; } a.self-link { position: absolute; top: 0; left: calc(-1 * (3.5rem - 26px)); width: calc(3.5rem - 26px); height: 2em; text-align: center; border: none; transition: opacity .2s; opacity: .5; } a.self-link:hover { opacity: 1; } .heading > a.self-link { font-size: 83%; } .example > a.self-link, .note > a.self-link, .issue > a.self-link { /* These blocks are overflow:auto, so positioning outside doesn't work. */ left: auto; right: 0; } li > a.self-link { left: calc(-1 * (3.5rem - 26px) - 2em); } dfn > a.self-link { top: auto; left: auto; opacity: 0; width: 1.5em; height: 1.5em; background: var(--selflink-bg); color: var(--selflink-text); font-style: normal; transition: opacity .2s, background-color .2s, color .2s; } dfn:hover > a.self-link { opacity: 1; } dfn > a.self-link:hover { color: var(--selflink-hover-text); } a.self-link::before { content: "¶"; } .heading > a.self-link::before { content: "§"; } dfn > a.self-link::before { content: "#"; } </style> <style>/* Boilerplate: style-syntax-highlighting */ code.highlight { padding: .1em; border-radius: .3em; } pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; } .highlight:not(.idl) { background: rgba(0, 0, 0, .03); } c-[a] { color: #990055 } /* Keyword.Declaration */ c-[b] { color: #990055 } /* Keyword.Type */ c-[c] { color: #708090 } /* Comment */ c-[d] { color: #708090 } /* Comment.Multiline */ c-[e] { color: #0077aa } /* Name.Attribute */ c-[f] { color: #669900 } /* Name.Tag */ c-[g] { color: #222222 } /* Name.Variable */ c-[k] { color: #990055 } /* Keyword */ c-[l] { color: #000000 } /* Literal */ c-[m] { color: #000000 } /* Literal.Number */ c-[n] { color: #0077aa } /* Name */ c-[o] { color: #999999 } /* Operator */ c-[p] { color: #999999 } /* Punctuation */ c-[s] { color: #a67f59 } /* Literal.String */ c-[t] { color: #a67f59 } /* Literal.String.Single */ c-[u] { color: #a67f59 } /* Literal.String.Double */ c-[cp] { color: #708090 } /* Comment.Preproc */ c-[c1] { color: #708090 } /* Comment.Single */ c-[cs] { color: #708090 } /* Comment.Special */ c-[kc] { color: #990055 } /* Keyword.Constant */ c-[kn] { color: #990055 } /* Keyword.Namespace */ c-[kp] { color: #990055 } /* Keyword.Pseudo */ c-[kr] { color: #990055 } /* Keyword.Reserved */ c-[ld] { color: #000000 } /* Literal.Date */ c-[nc] { color: #0077aa } /* Name.Class */ c-[no] { color: #0077aa } /* Name.Constant */ c-[nd] { color: #0077aa } /* Name.Decorator */ c-[ni] { color: #0077aa } /* Name.Entity */ c-[ne] { color: #0077aa } /* Name.Exception */ c-[nf] { color: #0077aa } /* Name.Function */ c-[nl] { color: #0077aa } /* Name.Label */ c-[nn] { color: #0077aa } /* Name.Namespace */ c-[py] { color: #0077aa } /* Name.Property */ c-[ow] { color: #999999 } /* Operator.Word */ c-[mb] { color: #000000 } /* Literal.Number.Bin */ c-[mf] { color: #000000 } /* Literal.Number.Float */ c-[mh] { color: #000000 } /* Literal.Number.Hex */ c-[mi] { color: #000000 } /* Literal.Number.Integer */ c-[mo] { color: #000000 } /* Literal.Number.Oct */ c-[sb] { color: #a67f59 } /* Literal.String.Backtick */ c-[sc] { color: #a67f59 } /* Literal.String.Char */ c-[sd] { color: #a67f59 } /* Literal.String.Doc */ c-[se] { color: #a67f59 } /* Literal.String.Escape */ c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */ c-[si] { color: #a67f59 } /* Literal.String.Interpol */ c-[sx] { color: #a67f59 } /* Literal.String.Other */ c-[sr] { color: #a67f59 } /* Literal.String.Regex */ c-[ss] { color: #a67f59 } /* Literal.String.Symbol */ c-[vc] { color: #0077aa } /* Name.Variable.Class */ c-[vg] { color: #0077aa } /* Name.Variable.Global */ c-[vi] { color: #0077aa } /* Name.Variable.Instance */ c-[il] { color: #000000 } /* Literal.Number.Integer.Long */ @media (prefers-color-scheme: dark) { .highlight:not(.idl) { background: rgba(255, 255, 255, .05); } c-[a] { color: #d33682 } /* Keyword.Declaration */ c-[b] { color: #d33682 } /* Keyword.Type */ c-[c] { color: #2aa198 } /* Comment */ c-[d] { color: #2aa198 } /* Comment.Multiline */ c-[e] { color: #268bd2 } /* Name.Attribute */ c-[f] { color: #b58900 } /* Name.Tag */ c-[g] { color: #cb4b16 } /* Name.Variable */ c-[k] { color: #d33682 } /* Keyword */ c-[l] { color: #657b83 } /* Literal */ c-[m] { color: #657b83 } /* Literal.Number */ c-[n] { color: #268bd2 } /* Name */ c-[o] { color: #657b83 } /* Operator */ c-[p] { color: #657b83 } /* Punctuation */ c-[s] { color: #6c71c4 } /* Literal.String */ c-[t] { color: #6c71c4 } /* Literal.String.Single */ c-[u] { color: #6c71c4 } /* Literal.String.Double */ c-[ch] { color: #2aa198 } /* Comment.Hashbang */ c-[cp] { color: #2aa198 } /* Comment.Preproc */ c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */ c-[c1] { color: #2aa198 } /* Comment.Single */ c-[cs] { color: #2aa198 } /* Comment.Special */ c-[kc] { color: #d33682 } /* Keyword.Constant */ c-[kn] { color: #d33682 } /* Keyword.Namespace */ c-[kp] { color: #d33682 } /* Keyword.Pseudo */ c-[kr] { color: #d33682 } /* Keyword.Reserved */ c-[ld] { color: #657b83 } /* Literal.Date */ c-[nc] { color: #268bd2 } /* Name.Class */ c-[no] { color: #268bd2 } /* Name.Constant */ c-[nd] { color: #268bd2 } /* Name.Decorator */ c-[ni] { color: #268bd2 } /* Name.Entity */ c-[ne] { color: #268bd2 } /* Name.Exception */ c-[nf] { color: #268bd2 } /* Name.Function */ c-[nl] { color: #268bd2 } /* Name.Label */ c-[nn] { color: #268bd2 } /* Name.Namespace */ c-[py] { color: #268bd2 } /* Name.Property */ c-[ow] { color: #657b83 } /* Operator.Word */ c-[mb] { color: #657b83 } /* Literal.Number.Bin */ c-[mf] { color: #657b83 } /* Literal.Number.Float */ c-[mh] { color: #657b83 } /* Literal.Number.Hex */ c-[mi] { color: #657b83 } /* Literal.Number.Integer */ c-[mo] { color: #657b83 } /* Literal.Number.Oct */ c-[sa] { color: #6c71c4 } /* Literal.String.Affix */ c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */ c-[sc] { color: #6c71c4 } /* Literal.String.Char */ c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */ c-[sd] { color: #6c71c4 } /* Literal.String.Doc */ c-[se] { color: #6c71c4 } /* Literal.String.Escape */ c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */ c-[si] { color: #6c71c4 } /* Literal.String.Interpol */ c-[sx] { color: #6c71c4 } /* Literal.String.Other */ c-[sr] { color: #6c71c4 } /* Literal.String.Regex */ c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */ c-[fm] { color: #268bd2 } /* Name.Function.Magic */ c-[vc] { color: #cb4b16 } /* Name.Variable.Class */ c-[vg] { color: #cb4b16 } /* Name.Variable.Global */ c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */ c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */ c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */ } </style> <style>/* Boilerplate: style-var-click-highlighting */ /* Colors were chosen in Lab using https://nixsensor.com/free-color-converter/ D50 2deg illuminant, L in [0,100], a and b in [-128, 128] 0 = lab(85,0,85) 1 = lab(85,80,30) 2 = lab(85,-40,40) 3 = lab(85,-50,0) 4 = lab(85,5,15) 5 = lab(85,-10,-50) 6 = lab(85,35,-15) For darkmode: 0 = oklab(50% 0% 108%) 1 = oklab(50% -51% 51%) 2 = oklab(50% -64% -20%) 3 = oklab(50% 6% 19%) 4 = oklab(50% -12% -64%) 5 = oklab(50% 44% -19%) 6 = oklab(50% 102% 38%) */ [data-algorithm] var { cursor: pointer; } var[data-var-color] { background-color: var(--var-bg); box-shadow: 0 0 0 2px var(--var-bg); } var[data-var-color] { --var-bg: #F4D200; } var[data-var-color="1"] { --var-bg: #FF87A2; } var[data-var-color="2"] { --var-bg: #96E885; } var[data-var-color="3"] { --var-bg: #3EEED2; } var[data-var-color="4"] { --var-bg: #EACFB6; } var[data-var-color="5"] { --var-bg: #82DDFF; } var[data-var-color="6"] { --var-vg: #FFBCF2; } @media (prefers-color-scheme: dark) { var[data-var-color] { --var-bg: #bc1a00; } var[data-var-color="1"] { --var-bg: #007f00; } var[data-var-color="2"] { --var-bg: #008698; } var[data-var-color="3"] { --var-bg: #7f5b2b; } var[data-var-color="4"] { --var-bg: #004df3; } var[data-var-color="5"] { --var-bg: #a1248a; } var[data-var-color="6"] { --var-vg: #ff0000; } } </style> <style>/* Boilerplate: style-wpt */ :root { --wpt-border: hsl(0, 0%, 60%); --wpt-bg: hsl(0, 0%, 95%); --wpt-text: var(--text); --wptheading-text: hsl(0, 0%, 30%); } @media (prefers-color-scheme: dark) { :root { --wpt-border: hsl(0, 0%, 30%); --wpt-bg: var(--borderedblock-bg); --wpt-text: var(--text); --wptheading-text: hsl(0, 0%, 60%); } } .wpt-tests-block { list-style: none; border-left: .5em solid var(--wpt-border); background: var(--wpt-bg); color: var(--wpt-text); margin: 1em auto; padding: .5em; } .wpt-tests-block summary { color: var(--wptheading-text); font-weight: normal; text-transform: uppercase; } .wpt-tests-block summary::marker{ color: var(--wpt-border); } .wpt-tests-block summary:hover::marker{ color: var(--wpt-text); } /* The only content of a wpt test block in its closed state is the <summary>, which contains the word TESTS, and that is absolutely positioned. In that closed state, wpt test blocks are styled to have a top margin whose height is exactly equal to the height of the absolutely positioned <summary>, and no other background/padding/margin/border. The wpt test block elements will therefore allow the maring of the previous/next block elements to collapse through them; if this combined margin would be larger than its own top margin, it stays as is, and therefore the pre-existing vertical rhythm of the document is undisturbed. If that combined margin would be smaller, it is grown to that size. This means that the wpt test block ensures that there's always enough vertical space to insert the summary, without adding more than is needed. */ .wpt-tests-block:not([open]){ padding: 0; border: none; background: none; font-size: 0.75em; line-height: 1; position: relative; margin: 1em 0 0; } .wpt-tests-block:not([open]) summary { position: absolute; right: 0; bottom: 0; } /* It is possible that both the last child of a block element and the block element itself would be annotated with a <wpt> block each. If the block element has a padding or a border, that's fine, but otherwise the bottom margin of the block and of its last child would collapse and both <wpt> elements would overlap, being both placed there. To avoid that, add 1px of padding to the <wpt> element annotating the last child to prevent the bottom margin of the block and of its last child from collapsing (and as much negative margin, as wel only want to prevent margin collapsing, but are not trying to actually take more space). */ .wpt-tests-block:not([open]):last-child { padding-bottom: 1px; margin-bottom: -1px; } /* Exception to the previous rule: don't do that in non-last list items, because it's not necessary, and would therefore consume more space than strictly needed. Lists must have list items as children, not <wpt> elements, so a <wpt> element cannot be a sibling of a list item, and the collision that the previous rule avoids cannot happen. */ li:not(:last-child) > .wpt-tests-block:not([open]):last-child, dd:not(:last-child) > .wpt-tests-block:not([open]):last-child { padding-bottom: 0; margin-bottom: 0; } .wpt-tests-block:not([open]):not(:hover){ opacity: 0.5; } .wpt-tests-list { list-style: none; display: grid; margin: 0; padding: 0; grid-template-columns: 1fr max-content auto auto; grid-column-gap: .5em; } .wpt-tests-block hr:last-child { display: none; } .wpt-test { display: contents; } .wpt-test > a { text-decoration: underline; border: none; } .wpt-test > .wpt-name { grid-column: 1; } .wpt-test > .wpt-results { grid-column: 2; } .wpt-test > .wpt-live { grid-column: 3; } .wpt-test > .wpt-source { grid-column: 4; } .wpt-test > .wpt-results { display: flex; gap: .1em; } .wpt-test .wpt-result { display: inline-block; height: 1em; width: 1em; border-radius: 50%; position: relative; } </style> <body class="h-entry"> <div class="head"> <p data-fill-with="logo"><a class="logo" href="https://www.w3.org/"> <img alt="W3C" height="48" src="https://www.w3.org/StyleSheets/TR/2021/logos/W3C" width="72"> </a> </p> <h1 class="p-name no-ref" id="title">CSS Functions and Mixins Module</h1> <p id="w3c-state"><a href="https://www.w3.org/standards/types/#ED">Editor’s Draft</a>, <time class="dt-updated" datetime="2025-03-10">10 March 2025</time></p> <details open> <summary>More details about this document</summary> <div data-fill-with="spec-metadata"> <dl> <dt>This version: <dd><a class="u-url" href="https://drafts.csswg.org/css-mixins/">https://drafts.csswg.org/css-mixins/</a> <dt>Latest published version: <dd><a href="https://www.w3.org/TR/css-mixins-1/">https://www.w3.org/TR/css-mixins-1/</a> <dt>Feedback: <dd><a href="https://github.com/w3c/csswg-drafts/labels/css-mixins-1">CSSWG Issues Repository</a> <dt class="editor">Editors: <dd class="editor p-author h-card vcard" data-editor-id="117151"><a class="p-name fn u-url url" href="http://miriamsuzanne.com/contact">Miriam E. Suzanne</a> (<span class="p-org org">Invited Expert</span>) <dd class="editor p-author h-card vcard" data-editor-id="42199"><a class="p-name fn u-url url" href="http://xanthir.com/contact/">Tab Atkins-Bittner</a> (<span class="p-org org">Google</span>) <dt>Suggest an Edit for this Spec: <dd><a href="https://github.com/w3c/csswg-drafts/blob/main/css-mixins-1/Overview.bs">GitHub Editor</a> </dl> </div> </details> <div data-fill-with="warning"></div> <p class="copyright" data-fill-with="copyright"><a href="https://www.w3.org/policies/#copyright">Copyright</a> © 2025 <a href="https://www.w3.org/">World Wide Web Consortium</a>. <abbr title="World Wide Web Consortium">W3C</abbr><sup>®</sup> <a href="https://www.w3.org/policies/#Legal_Disclaimer">liability</a>, <a href="https://www.w3.org/policies/#W3C_Trademarks">trademark</a> and <a href="https://www.w3.org/copyright/software-license/" rel="license" title="W3C Software and Document License">permissive document license</a> rules apply. </p> <hr title="Separator for header"> </div> <div class="p-summary" data-fill-with="abstract"> <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2> <p>This module provides the ability to define custom functional notations.</p> <a href="https://www.w3.org/TR/CSS/">CSS</a> is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, etc. <script> const githubPrefix = "https://w3c.github.io/csswg-drafts/"; if(location.href.slice(0, githubPrefix.length) == githubPrefix) { const suffix = location.href.slice(githubPrefix.length); const draftUrl = "https://drafts.csswg.org/" + suffix; window.location.replace(draftUrl); } </script> </div> <h2 class="no-num no-toc no-ref heading settled" id="sotd"><span class="content">Status of this document</span></h2> <div data-fill-with="status"> <p> This is a public copy of the editors’ draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress. </p> <p>Please send feedback by <a href="https://github.com/w3c/csswg-drafts/issues">filing issues in GitHub</a> (preferred), including the spec code “css-mixins” in the title, like this: “[css-mixins] <i>…summary of comment…</i>”. All issues and comments are <a href="https://lists.w3.org/Archives/Public/public-css-archive/">archived</a>. Alternately, feedback can be sent to the (<a href="https://lists.w3.org/Archives/Public/www-style/">archived</a>) public mailing list <a href="mailto:www-style@w3.org?Subject=%5Bcss-mixins%5D%20PUT%20SUBJECT%20HERE">www-style@w3.org</a>. </p> <p>This document is governed by the <a href="https://www.w3.org/policies/process/20231103/" id="w3c_process_revision">03 November 2023 W3C Process Document</a>. </p> </div> <div data-fill-with="at-risk"></div> <nav data-fill-with="table-of-contents" id="toc"> <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2> <ol class="toc" role="directory"> <li><a href="#intro"><span class="secno">1</span> <span class="content">Introduction</span></a> <li> <a href="#defining-custom-functions"><span class="secno">2</span> <span class="content">Defining Custom Functions</span></a> <ol class="toc"> <li> <a href="#function-rule"><span class="secno">2.1</span> <span class="content">The <span>@function</span> Rule</span></a> <ol class="toc"> <li><a href="#function-preamble"><span class="secno">2.1.1</span> <span class="content"> The Function Preamble</span></a> <li><a href="#function-body"><span class="secno">2.1.2</span> <span class="content"> The Function Body</span></a> </ol> <li><a href="#the-result-descriptor"><span class="secno">2.2</span> <span class="content">The <span class="property">result</span> Descriptor</span></a> <li><a href="#args"><span class="secno">2.3</span> <span class="content">Arguments & Local Variables</span></a> </ol> <li> <a href="#using-custom-functions"><span class="secno">3</span> <span class="content">Using Custom Functions</span></a> <ol class="toc"> <li><a href="#evaluating-custom-functions"><span class="secno">3.1</span> <span class="content">Evaluating Custom Functions</span></a> <li><a href="#cycles"><span class="secno">3.2</span> <span class="content">Cycles</span></a> </ol> <li> <a href="#execution-model"><span class="secno">4</span> <span class="content">Execution Model of Custom Functions</span></a> <ol class="toc"> <li><a href="#conditional-rules"><span class="secno">4.1</span> <span class="content">Conditional Rules</span></a> </ol> <li> <a href="#cssom"><span class="secno">5</span> <span class="content">CSSOM</span></a> <ol class="toc"> <li><a href="#the-function-interface"><span class="secno">5.1</span> <span class="content">The <code class="idl"><span>CSSFunctionRule</span></code> Interface</span></a> <li><a href="#the-function-declarations-interface"><span class="secno">5.2</span> <span class="content">The <code class="idl"><span>CSSFunctionDeclarations</span></code> Interface</span></a> </ol> <li><a href="#privacy"><span class="secno">6</span> <span class="content">Privacy Considerations</span></a> <li><a href="#security"><span class="secno">7</span> <span class="content">Security Considerations</span></a> <li> <a href="#w3c-conformance"><span class="secno"></span> <span class="content"> Conformance</span></a> <ol class="toc"> <li><a href="#w3c-conventions"><span class="secno"></span> <span class="content"> Document conventions</span></a> <li><a href="#w3c-conformance-classes"><span class="secno"></span> <span class="content"> Conformance classes</span></a> <li> <a href="#w3c-partial"><span class="secno"></span> <span class="content"> Partial implementations</span></a> <ol class="toc"> <li><a href="#w3c-conform-future-proofing"><span class="secno"></span> <span class="content"> Implementations of Unstable and Proprietary Features</span></a> </ol> <li><a href="#w3c-testing"><span class="secno"></span> <span class="content"> Non-experimental implementations</span></a> </ol> <li> <a href="#index"><span class="secno"></span> <span class="content">Index</span></a> <ol class="toc"> <li><a href="#index-defined-here"><span class="secno"></span> <span class="content">Terms defined by this specification</span></a> <li><a href="#index-defined-elsewhere"><span class="secno"></span> <span class="content">Terms defined by reference</span></a> </ol> <li> <a href="#references"><span class="secno"></span> <span class="content">References</span></a> <ol class="toc"> <li><a href="#normative"><span class="secno"></span> <span class="content">Normative References</span></a> <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a> </ol> <li> <a href="#property-index"><span class="secno"></span> <span class="content">Property Index</span></a> <ol class="toc"> <li><a href="#function-descriptor-table"><span class="secno"></span> <span class="content"><span>@function</span> Descriptors</span></a> </ol> <li><a href="#idl-index"><span class="secno"></span> <span class="content">IDL Index</span></a> </ol> </nav> <main> <h2 class="heading settled" data-level="1" id="intro"><span class="secno">1. </span><span class="content">Introduction</span><a class="self-link" href="#intro"></a></h2> <p><em>This section is not normative.</em></p> <p class="note" role="note"><span class="marker">Note:</span> At this time, this specification only defines <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function">custom functions</a>, which operate at the level of CSS values. It is expected that it will define "mixins" later, which are functions that operate at the style rule level.</p> <p><a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property">Custom properties</a> give authors a lot of power to define useful, sometimes complex values in one place, and then re-use them across their stylesheet. They can vary across the document, or based on Media Queries or other conditionals, making them very flexible and responsive.</p> <p>However, their values are <em>fixed</em> at the point they’re defined, unable to be changed except by fully overriding their previous definition: a <a class="css" data-link-type="propdesc">--shadow: 2px 2px var(--shadow-color)</a> declaration takes its <span class="css">--shadow-color</span> value from the element it’s declared on, and later changes to <span class="css">--shadow-color</span> on descendant elements don’t alter the value of <span class="css">--shadow</span> for them; they continue to use the shadow color defined where <span class="css">--shadow</span> was defined. This is a common source of confusion for authors making heavy use of composite variables like this.</p> <p><a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function①">Custom functions</a> allow authors the same power as <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①">custom properties</a>, but <em>parameterized</em>: they have the same flexibility and conditionality as a <span id="ref-for-custom-property②">custom property</span> definition, but take values from other custom properties (or explicitly as arguments) <em>at the point of use</em>. For example, instead of a <span class="css">--shadow</span> <span id="ref-for-custom-property③">custom property</span>, a <span class="css">--shadow()</span> <span id="ref-for-custom-function②">custom function</span> could be defined instead, like:</p> <pre class="highlight"><c- n>@function</c-> <c- nf>--shadow</c-><c- p>(</c->--shadow-color <color> : inherit<c- p>)</c-> <c- p>{</c-> <c- c>/* If --shadow-color argument isn't passed,</c-> <c- c> or doesn't successfully parse as a <color>,</c-> <c- c> try to use the --shadow-color *property*</c-> <c- c> from the element instead */</c-> <c- c>/* var(--shadow-color) refers to the --shadow-color parameter,</c-> <c- c> rather than a custom property,</c-> <c- c> but can still use a fallback value as normal */</c-> result: <c- m>2</c-><c- k>px</c-> <c- m>2</c-><c- k>px</c-> <c- nf>var</c-><c- p>(</c->--shadow-color<c- p>,</c-> black<c- p>);</c-> <c- p>}</c-> .foo <c- p>{</c-> <c- k>--shadow-color</c-><c- p>:</c-> blue<c- p>;</c-> <c- k>box-shadow</c-><c- p>:</c-> <c- nf>--shadow</c-><c- p>();</c-> <c- c>/* produces a blue shadow */</c-> <c- c>/* or just */</c-> box-shadow: <c- nf>--shadow</c-><c- p>(</c->blue<c- p>);</c-> <c- p>}</c-> </pre> <h2 class="heading settled" data-level="2" id="defining-custom-functions"><span class="secno">2. </span><span class="content">Defining Custom Functions</span><a class="self-link" href="#defining-custom-functions"></a></h2> <p>A <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function③">custom function</a> can be thought of as an advanced <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property④">custom property</a>, which instead of being substituted by a single fixed value, computes its substitution value based on <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter">function parameters</a> and the value of <span id="ref-for-custom-property⑤">custom properties</span> at the point it’s invoked. Rather than the <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-variables-2/#funcdef-var" id="ref-for-funcdef-var">var()</a> syntax that <span id="ref-for-custom-property⑥">custom properties</span> use for substitution, <span id="ref-for-custom-function④">custom functions</span> are invoked by <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function"><dashed-function></a> syntax, allowing additional values to be passed as arguments.</p> <div class="example" id="example-824c03c8"> <a class="self-link" href="#example-824c03c8"></a> A simple <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function⑤">custom function</a> to negate a value can be defined as follows: <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--negative</c-><c- p>(</c->--value<c- p>)</c-> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- nf>calc</c-><c- p>(</c-><c- m>-1</c-> * <c- nf>var</c-><c- p>(</c->--value<c- p>));</c-> <c- p>}</c-> </pre> <p>Then, that function can be referenced with <span class="css">--negative()</span> in some declaration:</p> <pre class="lang-css highlight">html <c- p>{</c-> <c- k>--gap</c-><c- p>:</c-> <c- m>1</c-><c- k>em</c-><c- p>;</c-> <c- k>padding</c-><c- p>:</c-> <c- nf>--negative</c-><c- p>(</c-><c- nf>var</c-><c- p>(</c->--gap<c- p>));</c-> <c- c>/* or by passing the value explicitly, like: */</c-> padding: <c- nf>--negative</c-><c- p>(</c-><c- m>1</c-><c- k>em</c-><c- p>);</c-> <c- p>}</c-> </pre> </div> <p><a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①"><dashed-function></a>s are <a data-link-type="dfn" href="https://drafts.csswg.org/css-values-5/#arbitrary-substitution-function" id="ref-for-arbitrary-substitution-function">arbitrary substitution functions</a>, like <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-variables-2/#funcdef-var" id="ref-for-funcdef-var①">var()</a>. Their presence in a property’s value causes it to be assumed valid at parse time, and only evaluated and parsed at computed-value time, after <a data-link-type="dfn" href="https://drafts.csswg.org/css-values-5/#substitute-arbitrary-substitution-function" id="ref-for-substitute-arbitrary-substitution-function">arbitrary substitution</a> has occurred.</p> <h3 class="heading settled" data-level="2.1" id="function-rule"><span class="secno">2.1. </span><span class="content">The <dfn class="dfn-paneled css" data-dfn-type="at-rule" data-export id="at-ruledef-function">@function</dfn> Rule</span><a class="self-link" href="#function-rule"></a></h3> <p>The <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function">@function</a> rule defines a <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="custom-function">custom function</dfn>, and consists of a name, a list of <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①">parameters</a>, a <dfn class="dfn-paneled" data-dfn-for="custom function" data-dfn-type="dfn" data-noexport id="custom-function-function-body">function body</dfn>, and optionally a <dfn class="dfn-paneled" data-dfn-for="custom function" data-dfn-type="dfn" data-noexport id="custom-function-return-type">return type</dfn> described by a <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#syntax-definition" id="ref-for-syntax-definition">syntax definition</a>.</p> <p>Each <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="function-parameter">function parameter</dfn> consists of a name (<a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-variables-2/#typedef-custom-property-name" id="ref-for-typedef-custom-property-name"><custom-property-name></a>); optionally a <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="parameter-type">parameter type</dfn>, described by a <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#syntax-definition" id="ref-for-syntax-definition①">syntax definition</a>; and optionally a <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="default-value">default value</dfn>.</p> <pre class="def prod"><@function> = @function <a class="production" data-link-type="type" href="https://drafts.csswg.org/css-syntax-3/#typedef-function-token" id="ref-for-typedef-function-token"><function-token></a> <a class="production" data-link-type="type" href="#typedef-function-parameter" id="ref-for-typedef-function-parameter"><function-parameter></a><a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#mult-comma" id="ref-for-mult-comma">#</a><a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#mult-opt" id="ref-for-mult-opt">?</a> ) [ returns <a class="production" data-link-type="type" href="#typedef-css-type" id="ref-for-typedef-css-type"><css-type></a> ]<a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#mult-opt" id="ref-for-mult-opt①">?</a> { <a class="production" data-link-type="type" href="https://drafts.csswg.org/css-syntax-3/#typedef-declaration-rule-list" id="ref-for-typedef-declaration-rule-list"><declaration-rule-list></a> } <dfn class="dfn-paneled" data-dfn-type="type" data-export id="typedef-function-parameter"><a class="production" data-link-type="type" href="#typedef-function-parameter" id="ref-for-typedef-function-parameter①"><function-parameter></a></dfn> = <a class="production" data-link-type="type" href="https://drafts.csswg.org/css-variables-2/#typedef-custom-property-name" id="ref-for-typedef-custom-property-name①"><custom-property-name></a> <a class="production" data-link-type="type" href="#typedef-css-type" id="ref-for-typedef-css-type①"><css-type></a><a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#mult-opt" id="ref-for-mult-opt②">?</a> [ : <a class="production" data-link-type="type" href="https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value" id="ref-for-typedef-declaration-value"><declaration-value></a> ]<a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#mult-opt" id="ref-for-mult-opt③">?</a> <dfn class="dfn-paneled" data-dfn-type="type" data-export id="typedef-css-type"><a class="production" data-link-type="type" href="#typedef-css-type" id="ref-for-typedef-css-type②"><css-type></a></dfn> = <a class="production" data-link-type="type" href="https://drafts.csswg.org/css-values-5/#typedef-syntax-component" id="ref-for-typedef-syntax-component"><syntax-component></a> <a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#comb-one" id="ref-for-comb-one">|</a> <a class="production" data-link-type="function" href="#funcdef-function-type" id="ref-for-funcdef-function-type"><type()></a> <dfn class="dfn-paneled" data-dfn-for="@function" data-dfn-type="function" data-export data-lt="type()" id="funcdef-function-type"><type()></dfn> = type( <a class="production" data-link-type="type" href="https://drafts.csswg.org/css-values-5/#typedef-syntax" id="ref-for-typedef-syntax"><syntax></a> ) </pre> <h4 class="heading settled" data-level="2.1.1" id="function-preamble"><span class="secno">2.1.1. </span><span class="content"> The Function Preamble</span><a class="self-link" href="#function-preamble"></a></h4> <p>The <a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-syntax-3/#typedef-function-token" id="ref-for-typedef-function-token①"><function-token></a> production must start with two dashes (U+002D HYPHEN-MINUS), similar to <a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-values-4/#typedef-dashed-ident" id="ref-for-typedef-dashed-ident"><dashed-ident></a>, or else the definition is invalid.</p> <p>The name of the resulting <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function⑥">custom function</a> is given by the name of the <a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-syntax-3/#typedef-function-token" id="ref-for-typedef-function-token②"><function-token></a>, the optional <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter②">function parameters</a> are given by the <a class="production css" data-link-type="type" href="#typedef-function-parameter" id="ref-for-typedef-function-parameter②"><function-parameter></a> values (defaulting to an empty set), and the optional <a data-link-type="dfn" href="#custom-function-return-type" id="ref-for-custom-function-return-type">return type</a> is given by the <a class="production css" data-link-type="type" href="#typedef-css-type" id="ref-for-typedef-css-type③"><css-type></a> following the <span class="css">returns</span> keyword (defaulting to <span class="css">type(*)</span>).</p> <div class="example" id="example-85734fbc"> <a class="self-link" href="#example-85734fbc"></a> If the <a class="production css" data-link-type="type" href="#typedef-css-type" id="ref-for-typedef-css-type④"><css-type></a> of a <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter③">function parameter</a> or <a data-link-type="dfn" href="#custom-function-return-type" id="ref-for-custom-function-return-type①">return type</a> can be described by a single <a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-values-5/#typedef-syntax-component" id="ref-for-typedef-syntax-component①"><syntax-component></a>, then the <a class="css" data-link-type="maybe" href="#funcdef-function-type" id="ref-for-funcdef-function-type①">type()</a> function can be omitted: <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--foo</c-><c- p>(</c->--a <length><c- p>)</c-> <c- p>{</c-> <c- c>/* ... */</c-> <c- p>}</c-> <c- n>@function</c-> <c- nf>--foo</c-><c- p>(</c->--a <color><c- p>)</c-> <c- p>{</c-> <c- c>/* ... */</c-> <c- p>}</c-> <c- n>@function</c-> <c- nf>--foo</c-><c- p>(</c->--a <length>+<c- p>)</c-> <c- p>{</c-> <c- c>/* ... */</c-> <c- p>}</c-> </pre> <p>However, any <a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-values-5/#typedef-syntax" id="ref-for-typedef-syntax①"><syntax></a> that requires a <a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-values-5/#typedef-syntax-combinator" id="ref-for-typedef-syntax-combinator"><syntax-combinator></a> needs to be wrapped in the <a class="css" data-link-type="maybe" href="#funcdef-function-type" id="ref-for-funcdef-function-type②">type()</a> function:</p> <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--foo</c-><c- p>(</c->--a <c- nf>type</c-><c- p>(</c-><number> | <percentage><c- p>))</c-> <c- p>{</c-> <c- c>/* ... */</c-> <c- p>}</c-> </pre> </div> <p>The name of a <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function①">@function</a> rule is a <a data-link-type="dfn" href="https://drafts.csswg.org/css-scoping-1/#css-tree-scoped-name" id="ref-for-css-tree-scoped-name">tree-scoped name</a>. If more than one <span class="css" id="ref-for-at-ruledef-function②">@function</span> exists for a given name, then the rule in the stronger cascade layer wins, and rules defined later win within the same layer.</p> <p>If the <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter④">function parameters</a> contain the same <a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-variables-2/#typedef-custom-property-name" id="ref-for-typedef-custom-property-name②"><custom-property-name></a> more than once, then the <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function③">@function</a> rule is invalid.</p> <h4 class="heading settled" data-level="2.1.2" id="function-body"><span class="secno">2.1.2. </span><span class="content"> The Function Body</span><a class="self-link" href="#function-body"></a></h4> <p>The body of a <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function④">@function</a> rule accepts <a data-link-type="dfn" href="https://drafts.csswg.org/css-conditional-3/#conditional-group-rule" id="ref-for-conditional-group-rule">conditional group rules</a>, such as <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-conditional-3/#at-ruledef-media" id="ref-for-at-ruledef-media">@media</a>. Additionally, it accepts the following descriptors:</p> <ul> <li data-md> <p>The <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result">result</a> descriptor, which determines the result of <a data-link-type="dfn" href="#evaluate-a-custom-function" id="ref-for-evaluate-a-custom-function">evaluating the function</a>. If no <span class="property" id="ref-for-descdef-function-result①">result</span> descriptor exists, the function is valid, but always returns the <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#guaranteed-invalid-value" id="ref-for-guaranteed-invalid-value">guaranteed-invalid value</a>.</p> <li data-md> <p><a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property⑦">Custom properties</a>, providing <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="local-variables">local variables</dfn>.</p> </ul> <p>Unknown descriptors are invalid and ignored, but do not make the <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function⑤">@function</a> rule itself invalid.</p> <h3 class="heading settled" data-level="2.2" id="the-result-descriptor"><span class="secno">2.2. </span><span class="content">The <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result②">result</a> Descriptor</span><a class="self-link" href="#the-result-descriptor"></a></h3> <table class="def descdef"> <tbody> <tr> <th>Name: <td><dfn class="dfn-paneled css" data-dfn-for="@function" data-dfn-type="descriptor" data-export id="descdef-function-result">result</dfn> <tr> <th>For: <td><a class="css" data-link-type="at-rule" href="#at-ruledef-function" id="ref-for-at-ruledef-function⑥">@function</a> <tr> <th>Value: <td class="prod"><a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value" id="ref-for-typedef-declaration-value①"><declaration-value></a><a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#mult-opt" id="ref-for-mult-opt④">?</a> <tr> <th>Initial: <td>n/a (see prose) </table> <p>The <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result③">result</a> descriptor defines the result of <a data-link-type="dfn" href="#evaluate-a-custom-function" id="ref-for-evaluate-a-custom-function①">evaluating</a> the <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function⑦">custom function</a> defined by its <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function⑦">@function</a> rule. Using <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-variables-2/#funcdef-var" id="ref-for-funcdef-var②">var()</a> functions, it can reference <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter⑤">function parameters</a>, <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables">local variables</a>, as well as other <span id="ref-for-custom-function⑧">custom functions</span> via <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function②"><dashed-function></a>s.</p> <p>The <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result④">result</a> descriptor itself does not have a type, but its <a data-link-type="dfn" href="#resolve-function-styles" id="ref-for-resolve-function-styles">resolved</a> value is type-checked during the <a data-link-type="dfn" href="#substitute-a-dashed-function" id="ref-for-substitute-a-dashed-function">substitution</a> of a <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function③"><dashed-function></a>.</p> <h3 class="heading settled" data-level="2.3" id="args"><span class="secno">2.3. </span><span class="content">Arguments & Local Variables</span><a class="self-link" href="#args"></a></h3> <p><em>This section is non-normative.</em></p> <p>Within a <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function⑨">custom function’s</a> <a data-link-type="dfn" href="#custom-function-function-body" id="ref-for-custom-function-function-body">function body</a>, the <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-variables-2/#funcdef-var" id="ref-for-funcdef-var③">var()</a> function can access <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables①">local variables</a> (the <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property⑧">custom properties</a> defined in the <span id="ref-for-custom-function-function-body①">function body</span>), <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter⑥">function parameters</a> (the values passed to the function, or set to default values), and <span id="ref-for-custom-property⑨">custom properties</span> defined at the <em>call site</em> (an element, or another <span id="ref-for-custom-function①⓪">custom function</span>).</p> <p>In that list, earlier things "win" over later things of the same name—if you have a <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables②">local variable</a> named <span class="css">--foo</span>, <span class="css">var(--foo)</span> will be substituted by that <span id="ref-for-local-variables③">local variable</span>, not by an argument or a custom property defined outside. The other values can still be <em>accessed</em>, however: setting the <span class="css">--foo</span> local variable to <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-cascade-5/#valdef-all-initial" id="ref-for-valdef-all-initial">initial</a> will resolve it to the <span class="css">--foo</span> parameter, while <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-cascade-5/#valdef-all-inherit" id="ref-for-valdef-all-inherit">inherit</a> will resolve it to the <span class="css">--foo</span> custom property from the call site.</p> <div class="example" id="example-62e1620a"> <a class="self-link" href="#example-62e1620a"></a> A <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function①①">custom function</a> can access <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables④">local variables</a> and <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter⑦">function parameters</a> from functions higher up in the call stack: <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--outer</c-><c- p>(</c->--outer-arg<c- p>)</c-> <c- p>{</c-> <c- k>--outer-local</c-><c- p>:</c-> <c- m>2</c-><c- p>;</c-> <c- k>result</c-><c- p>:</c-> <c- nf>--inner</c-><c- p>();</c-> <c- p>}</c-> <c- n>@function</c-> <c- nf>--inner</c-><c- p>()</c-> returns <number> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- nf>calc</c-><c- p>(</c-><c- nf>var</c-><c- p>(</c->--outer-arg<c- p>)</c-> + <c- nf>var</c-><c- p>(</c->--outer-local<c- p>));</c-> <c- p>}</c-> div <c- p>{</c-> <c- k>z-index</c-><c- p>:</c-> <c- nf>--outer</c-><c- p>(</c-><c- m>1</c-><c- p>);</c-> <c- c>/* 3 */</c-> <c- p>}</c-> </pre> <p>Similarly, <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①⓪">custom properties</a> are implicitly available:</p> <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--double-z</c-><c- p>()</c-> returns <number> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- nf>calc</c-><c- p>(</c-><c- nf>var</c-><c- p>(</c->--z<c- p>)</c-> * <c- m>2</c-><c- p>);</c-> <c- p>}</c-> div <c- p>{</c-> <c- k>--z</c-><c- p>:</c-> <c- m>3</c-><c- p>;</c-> <c- k>z-index</c-><c- p>:</c-> <c- nf>--double-z</c-><c- p>();</c-> <c- c>/* 6 */</c-> <c- p>}</c-> </pre> <p>But <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter⑧">function parameters</a> "shadow" <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①①">custom properties</a>, and <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables⑤">local variables</a> "shadow" both:</p> <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--add-a-b-c</c-><c- p>(</c->--b<c- p>,</c-> --c<c- p>)</c-> <c- p>{</c-> <c- k>--c</c-><c- p>:</c-> <c- m>300</c-><c- p>;</c-> <c- k>result</c-><c- p>:</c-> <c- nf>calc</c-><c- p>(</c-><c- nf>var</c-><c- p>(</c->--a<c- p>)</c-> + <c- nf>var</c-><c- p>(</c->--b<c- p>)</c-> + <c- nf>var</c-><c- p>(</c->--c<c- p>));</c-> <c- c>/* uses the --a from the call site's custom property,</c-> <c- c> the --b from the function parameter,</c-> <c- c> and the --c from the local variable */</c-> <c- p>}</c-> div <c- p>{</c-> <c- k>--a</c-><c- p>:</c-> <c- m>1</c-><c- p>;</c-> <c- k>--b</c-><c- p>:</c-> <c- m>2</c-><c- p>;</c-> <c- k>--c</c-><c- p>:</c-> <c- m>3</c-><c- p>;</c-> <c- k>z-index</c-><c- p>:</c-> <c- nf>--add-a-b-c</c-><c- p>(</c-><c- m>20</c-><c- p>,</c-> <c- m>30</c-><c- p>);</c-> <c- c>/* 321 */</c-> <c- p>}</c-> </pre> </div> <h2 class="heading settled" data-level="3" id="using-custom-functions"><span class="secno">3. </span><span class="content">Using Custom Functions</span><a class="self-link" href="#using-custom-functions"></a></h2> <p>Similar to how the value of a <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①②">custom property</a> can be substituted into the value of another property with <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-variables-2/#funcdef-var" id="ref-for-funcdef-var④">var()</a>, the result of a <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function①②">custom function</a> evaluation can be substituted into the value of a property with a <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function④"><dashed-function></a>.</p> <p>A <dfn class="dfn-paneled css" data-dfn-type="type" data-export id="typedef-dashed-function"><a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function⑤"><dashed-function></a></dfn> is a <a data-link-type="dfn" href="https://drafts.csswg.org/css-values-4/#functional-notation" id="ref-for-functional-notation">functional notation</a> whose function name starts with two dashes (U+002D HYPHEN-MINUS). Its syntax is:</p> <pre class="informative prod"><dashed-function> = --<a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#mult-zero-plus" id="ref-for-mult-zero-plus">*</a>( <a class="production" data-link-type="type" href="https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value" id="ref-for-typedef-declaration-value②"><declaration-value></a><a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#mult-comma" id="ref-for-mult-comma①">#</a><a data-link-type="grammar" href="https://drafts.csswg.org/css-values-4/#mult-opt" id="ref-for-mult-opt⑤">?</a> ) </pre> <p>A <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function⑥"><dashed-function></a> can only be used where <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-variables-2/#funcdef-var" id="ref-for-funcdef-var⑤">var()</a> is allowed.</p> <p>If a property contains one or more <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function⑦"><dashed-function></a>s, the entire property’s grammar must be assumed to be valid at parse time. At computed-value time, every <span class="production" id="ref-for-typedef-dashed-function⑧"><dashed-function></span> must be <a data-link-type="dfn" href="#substitute-a-dashed-function" id="ref-for-substitute-a-dashed-function①">substituted</a> before finally being checked against the property’s grammar.</p> <p class="note" role="note"><span class="marker">Note:</span> Within the body of a <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function①③">custom function</a>, <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-variables-2/#funcdef-var" id="ref-for-funcdef-var⑥">var()</a> functions might resolve differently than on the element the <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function⑨"><dashed-function></a> is used on. See <a href="#evaluating-custom-functions">§ 3.1 Evaluating Custom Functions</a>.</p> <p>A <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①⓪"><dashed-function></a> is evaluated in some context: either in a property value on an element (or in a descriptor that is eventually treated like a property on an element, such as in <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-animations-1/#at-ruledef-keyframes" id="ref-for-at-ruledef-keyframes">@keyframes</a>), or in a descriptor in the <a data-link-type="dfn" href="#custom-function-function-body" id="ref-for-custom-function-function-body②">function body</a> of another <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function①④">custom function</a> that is being applied to a "hypothetical" element. Either way, this provides a <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="calling-context">calling context</dfn>, which contains the property or descriptor name containing the <span class="production" id="ref-for-typedef-dashed-function①①"><dashed-function></span>, and the element (or "hypothetical" element) that property/descriptor is being applied to.</p> <p>As <a data-link-type="dfn" href="#calling-context" id="ref-for-calling-context">calling contexts</a> are nested by <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①②"><dashed-function></a> evaluations <em>inside of</em> <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function①⑤">custom functions</a>, a <span id="ref-for-calling-context①">calling context’s</span> <dfn class="dfn-paneled" data-dfn-for="calling context" data-dfn-type="dfn" data-noexport id="calling-context-root-element">root element</dfn> is the real element at the root of the <span id="ref-for-calling-context②">calling context</span> stack.</p> <div class="algorithm" data-algorithm="substitute a dashed function"> To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="substitute-a-dashed-function">substitute a dashed function</dfn> in a value, with <var>dashed function</var> being a <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①③"><dashed-function></a>: <ol> <li data-md> <p>Let <var>function</var> be the result of dereferencing the <var>dashed function</var>’s name as a <a data-link-type="dfn" href="https://drafts.csswg.org/css-scoping-1/#css-tree-scoped-reference" id="ref-for-css-tree-scoped-reference">tree-scoped reference</a>. If no such name exists, return failure.</p> <li data-md> <p><a data-link-type="dfn" href="https://drafts.csswg.org/css-values-5/#substitute-arbitrary-substitution-function" id="ref-for-substitute-arbitrary-substitution-function①">Substitute</a> any <a data-link-type="dfn" href="https://drafts.csswg.org/css-values-5/#arbitrary-substitution-function" id="ref-for-arbitrary-substitution-function①">arbitrary substitution functions</a> within <var>dashed function</var>’s arguments, then parse it as <span class="css"><a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value" id="ref-for-typedef-declaration-value③"><declaration-value></a>#</span> and let <var>arguments</var> be the result (a comma-separated list of CSS values).</p> <li data-md> <p>If <var>dashed function</var> is being substituted into a property on an element, let <var>calling context</var> be a <a data-link-type="dfn" href="#calling-context" id="ref-for-calling-context③">calling context</a> with that element and that property</p> <p>Otherwise, it’s being substituted into a descriptor on a "hypothetical element", while evaluating another <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function①⑥">custom function</a>. Let <var>calling context</var> be a <a data-link-type="dfn" href="#calling-context" id="ref-for-calling-context④">calling context</a> with that "hypothetical element" and that descriptor.</p> <li data-md> <p><a data-link-type="dfn" href="#evaluate-a-custom-function" id="ref-for-evaluate-a-custom-function②">Evaluate a custom function</a>, using <var>function</var>, <var>arguments</var>, and <var>calling context</var>, and replace the <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①④"><dashed-function></a> with the <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#equivalent-token-sequence" id="ref-for-equivalent-token-sequence">equivalent token sequence</a> of the value resulting from the evaluation.</p> </ol> </div> <p>If <a data-link-type="dfn" href="#substitute-a-dashed-function" id="ref-for-substitute-a-dashed-function②">substitute a dashed function</a> fails, and the substitution is taking place on a property’s value, then the declaration containing the <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①⑤"><dashed-function></a> becomes <a data-link-type="dfn" href="https://drafts.csswg.org/css-values-5/#invalid-at-computed-value-time" id="ref-for-invalid-at-computed-value-time">invalid at computed-value time</a>.</p> <div class="example" id="example-2fcd7f28"> <a class="self-link" href="#example-2fcd7f28"></a> A <a data-link-type="dfn" href="https://drafts.csswg.org/css-values-5/#comma-containing-productions" id="ref-for-comma-containing-productions">comma-containing value</a> may be passed as a single argument by wrapping the value in curly braces, <code class="highlight"><c- p>{}</c-></code>: <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--max-plus-x</c-><c- p>(</c->--list<c- p>,</c-> --x<c- p>)</c-> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- nf>calc</c-><c- p>(</c-><c- nf>max</c-><c- p>(</c-><c- nf>var</c-><c- p>(</c->--list<c- p>))</c-> + <c- nf>var</c-><c- p>(</c->--x<c- p>));</c-> <c- p>}</c-> div <c- p>{</c-> <c- k>width</c-><c- p>:</c-> <c- nf>--max-plus-x</c-><c- p>({</c-> <c- m>1</c-><c- k>px</c-><c- p>,</c-> <c- m>7</c-><c- k>px</c-><c- p>,</c-> <c- m>2</c-><c- k>px</c-> <c- p>},</c-> <c- m>3</c-><c- k>px</c-><c- p>);</c-> <c- c>/* 10px */</c-> <c- p>}</c-> </pre> </div> <h3 class="heading settled" data-level="3.1" id="evaluating-custom-functions"><span class="secno">3.1. </span><span class="content">Evaluating Custom Functions</span><a class="self-link" href="#evaluating-custom-functions"></a></h3> <p><a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function①⑦">Custom functions</a> are evaluated by, essentially, pretending their function body is a <a data-link-type="dfn" href="https://drafts.csswg.org/css-syntax-3/#style-rule" id="ref-for-style-rule">style rule</a> being applied to a hypothetical element, resolving styles as normal, and then returning the value of the <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result⑤">result</a> descriptor on that hypothetical element. The hypothetical element "inherits" the values of all custom properties as if it were a child of its <a data-link-type="dfn" href="#calling-context" id="ref-for-calling-context⑤">calling context</a>, with its <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter⑨">function parameters</a> overriding "inherited" custom properties of the same name.</p> <div class="algorithm" data-algorithm="evaluate a custom function"> To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="evaluate-a-custom-function">evaluate a custom function</dfn> <var>custom function</var>, given a <a data-link-type="dfn" href="#calling-context" id="ref-for-calling-context⑥">calling context</a> <var>calling context</var> and a list of CSS values <var>arguments</var>, returning a CSS value: <ol> <li data-md> <p>If the number of items in <var>arguments</var> is greater than the number of <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①⓪">function parameters</a> in <var>custom function</var>, return the <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#guaranteed-invalid-value" id="ref-for-guaranteed-invalid-value①">guaranteed-invalid value</a>.</p> <li data-md> <p>Let <var>registrations</var> be an initially empty set of <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration" id="ref-for-custom-property-registration">custom property registrations</a>.</p> <li data-md> <p>For each <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①①">function parameter</a> of <var>custom function</var>, create a <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration" id="ref-for-custom-property-registration①">custom property registration</a> with the parameter’s name, a syntax of the <a data-link-type="dfn" href="#parameter-type" id="ref-for-parameter-type">parameter type</a>, an inherit flag of "true", and no initial value. Add the registration to <var>registrations</var>.</p> <li data-md> <p>If <var>custom function</var> has a <a data-link-type="dfn" href="#custom-function-return-type" id="ref-for-custom-function-return-type②">return type</a>, create a <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration" id="ref-for-custom-property-registration②">custom property registration</a> with the name "return" (violating the usual rules for what a registration’s name can be), a syntax of the <span id="ref-for-custom-function-return-type③">return type</span>, an inherit flag of "false", and no initial value. Add the registration to <var>registrations</var>.</p> <li data-md> <p>Let <var>argument rule</var> be an initially empty <a data-link-type="dfn" href="https://drafts.csswg.org/css-syntax-3/#style-rule" id="ref-for-style-rule①">style rule</a>.</p> <li data-md> <p>For each <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①②">function parameter</a> of <var>custom function</var>:</p> <ol> <li data-md> <p>Let <var>arg value</var> be the value of the corresponding argument in <var>arguments</var>, or the <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#guaranteed-invalid-value" id="ref-for-guaranteed-invalid-value②">guaranteed-invalid value</a> if there is no corresponding argument.</p> <li data-md> <p>Let <var>default value</var> be the parameter’s <a data-link-type="dfn" href="#default-value" id="ref-for-default-value">default value</a>.</p> <li data-md> <p>Add a <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①③">custom property</a> to <var>argument rule</var> with a name of the parameter’s name, and a value of <span class="css">first-valid(<var>arg value</var>, <var>default value</var>)</span>.</p> </ol> <li data-md> <p><a data-link-type="dfn" href="#resolve-function-styles" id="ref-for-resolve-function-styles①">Resolve function styles</a> using <var>argument styles</var>, <var>registrations</var>, and <var>calling context</var>. Let <var>argument styles</var> be the result.</p> <li data-md> <p>Let <var>body rule</var> be the <a data-link-type="dfn" href="#custom-function-function-body" id="ref-for-custom-function-function-body③">function body</a> of <var>custom function</var>, as a <a data-link-type="dfn" href="https://drafts.csswg.org/css-syntax-3/#style-rule" id="ref-for-style-rule②">style rule</a>.</p> <li data-md> <p>For each <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration" id="ref-for-custom-property-registration③">custom property registration</a> of <var>registrations</var>, set its initial value to the corresponding value in <var>argument styles</var>, set its syntax to the <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#universal-syntax-definition" id="ref-for-universal-syntax-definition">universal syntax definition</a>, and prepend a <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①④">custom property</a> to <var>body rule</var> with the property name and value in <var>argument styles</var>.</p> <li data-md> <p><a data-link-type="dfn" href="#resolve-function-styles" id="ref-for-resolve-function-styles②">Resolve function styles</a> using <var>body rule</var>, <var>registrations</var>, and <var>calling context</var>. Let <var>body styles</var> be the result.</p> <li data-md> <p>Return the value of the <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result⑥">result</a> property in <var>body styles</var>.</p> </ol> </div> <div class="algorithm" data-algorithm="resolve function styles"> To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="resolve-function-styles">resolve function styles</dfn>, given a style rule <var>rule</var>, a set of <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration" id="ref-for-custom-property-registration④">custom property registrations</a> <var>registrations</var>, and a <a data-link-type="dfn" href="#calling-context" id="ref-for-calling-context⑦">calling context</a> <var>calling context</var>, returning a set of <a data-link-type="dfn" href="https://drafts.csswg.org/css-cascade-5/#computed-value" id="ref-for-computed-value">computed</a> styles: <ol> <li data-md> <p>Create a "hypothetical element" <var>el</var> that acts as a child of <var>calling context</var>’s element. <var>el</var> is <a data-link-type="dfn" href="https://drafts.csswg.org/selectors-4/#featureless" id="ref-for-featureless">featureless</a>, and only <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①⑤">custom properties</a> and the <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result⑦">result</a> descriptor apply to it.</p> <li data-md> <p>Apply <var>rule</var> to <var>el</var> to the <a data-link-type="dfn" href="https://drafts.csswg.org/css-cascade-5/#specified-value" id="ref-for-specified-value">specified value</a> stage, with the following changes:</p> <ul> <li data-md> <p>Only the <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration" id="ref-for-custom-property-registration⑤">custom property registrations</a> in <var>registrations</var> are visible; all other <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①⑥">custom properties</a> are treated as unregistered.</p> <li data-md> <p>The <a data-link-type="dfn" href="https://drafts.csswg.org/css-cascade-5/#inherited-value" id="ref-for-inherited-value">inherited value</a> of <var>calling context</var>’s property is the <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#guaranteed-invalid-value" id="ref-for-guaranteed-invalid-value③">guaranteed-invalid value</a>.</p> <li data-md> <p>On custom properties, the <a data-link-type="dfn" href="https://drafts.csswg.org/css-values-4/#css-wide-keywords" id="ref-for-css-wide-keywords">CSS-wide keywords</a> <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-cascade-5/#valdef-all-initial" id="ref-for-valdef-all-initial①">initial</a> and <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-cascade-5/#valdef-all-inherit" id="ref-for-valdef-all-inherit①">inherit</a> have their usual effect; all other <span id="ref-for-css-wide-keywords①">CSS-wide keywords</span> resolve to the <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#guaranteed-invalid-value" id="ref-for-guaranteed-invalid-value④">guaranteed-invalid value</a>.</p> <p class="note" role="note"><span class="marker">Note:</span> <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-cascade-5/#valdef-all-initial" id="ref-for-valdef-all-initial②">initial</a> references the <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration" id="ref-for-custom-property-registration⑥">custom property registration</a> created from the <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①③">function parameters</a>, letting you "reset" a property to the passed value. <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-cascade-5/#valdef-all-inherit" id="ref-for-valdef-all-inherit②">inherit</a> inherits from the <a data-link-type="dfn" href="#calling-context" id="ref-for-calling-context⑧">calling context</a>’s element.\</p> <p>On <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result⑧">result</a>, all <a data-link-type="dfn" href="https://drafts.csswg.org/css-values-4/#css-wide-keywords" id="ref-for-css-wide-keywords②">CSS-wide keywords</a> are left unresolved.</p> <p class="note" role="note"><span class="marker">Note:</span> <a class="css" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result⑨">result: inherit</a>, for example, will cause the <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①⑥"><dashed-function></a> to <em>evaluate to</em> the <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-cascade-5/#valdef-all-inherit" id="ref-for-valdef-all-inherit③">inherit</a> keyword, similar to <span class="css">var(--unknown, inherit)</span>.</p> </ul> <li data-md> <p>Determine the <a data-link-type="dfn" href="https://drafts.csswg.org/css-cascade-5/#computed-value" id="ref-for-computed-value①">computed value</a> of all <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①⑦">custom properties</a> and the <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result①⓪">result</a> "property" on <var>el</var>, as defined in <a href="https://drafts.css-houdini.org/css-properties-values-api-1/#calculation-of-computed-values"><cite>CSS Properties and Values API 1</cite> § 2.4 Computed Value-Time Behavior</a>, with changes from the previous step, and the following:</p> <ul> <li data-md> <p>Aside from references to <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①⑧">custom properties</a> (which use the values on <var>el</var> as normal) and numbers/percentages (which are left unresolved in custom properties, as normal), all values which would normally refer to the element being styled instead refer to <var>calling context</var>’s <a data-link-type="dfn" href="#calling-context-root-element" id="ref-for-calling-context-root-element">root element</a>.</p> <p class="note" role="note"><span class="marker">Note:</span> For example, <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-values-5/#funcdef-attr" id="ref-for-funcdef-attr">attr()</a> in a property, or <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-conditional-5/#at-ruledef-container" id="ref-for-at-ruledef-container">@container</a> queries in the rule.</p> </ul> <li data-md> <p>Return <var>el</var>’s styles.</p> <p class="note" role="note"><span class="marker">Note:</span> Only <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property①⑨">custom properties</a> and the <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result①①">result</a> descriptor will be used from these styles.</p> </ol> </div> <h3 class="heading settled" data-level="3.2" id="cycles"><span class="secno">3.2. </span><span class="content">Cycles</span><a class="self-link" href="#cycles"></a></h3> <p>The <span class="css">result</span> descriptor and <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables⑥">local variables</a> within a <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function①⑧">custom function</a> may reference other <span id="ref-for-custom-function①⑨">custom functions</span> or <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property②⓪">custom properties</a>, and may therefore create <a href="https://drafts.csswg.org/css-variables-1/#cycles">cycles</a>.</p> <p>For each element, add a node for every specified <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function②⓪">custom function</a> to the graph described in <a href="https://drafts.csswg.org/css-variables-1/#cycles"><cite>CSS Variables 1</cite> § 2.3 Resolving Dependency Cycles</a>; add a node for each <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables⑦">local variable</a> defined within each of those functions; then, for each <span id="ref-for-custom-function②①">custom function</span> <var>func</var>, add edges as follows:</p> <ul> <li data-md> <p>From <var>func</var> to any <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function②②">custom function</a> referenced by a <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①⑦"><dashed-function></a> within <var>func</var>’s body.</p> <li data-md> <p>From <var>func</var> to any <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property②①">custom property</a> or <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables⑧">local variable</a> referenced by a <a class="css" data-link-type="maybe" href="https://drafts.csswg.org/css-variables-2/#funcdef-var" id="ref-for-funcdef-var⑦">var()</a> within <var>func</var>’s body.</p> <li data-md> <p>To <var>func</var> from any <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property②②">custom property</a> or <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables⑨">local variable</a> that references <var>func</var> using a <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①⑧"><dashed-function></a>.</p> </ul> <p>A <a class="production css" data-link-type="type" href="#typedef-dashed-function" id="ref-for-typedef-dashed-function①⑨"><dashed-function></a> referencing a <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function②③">custom function</a> which is part of a cycle makes the containing <a data-link-type="dfn" href="https://drafts.csswg.org/css-syntax-3/#declaration" id="ref-for-declaration">declaration</a> <a data-link-type="dfn" href="https://drafts.csswg.org/css-values-5/#invalid-at-computed-value-time" id="ref-for-invalid-at-computed-value-time①">invalid at computed-value time</a>.</p> <p class="note" role="note"><span class="marker">Note:</span> Cycles are disallowed even through branches that are not taken during execution.</p> <div class="example" id="example-8ff4a64d"> <a class="self-link" href="#example-8ff4a64d"></a> In the following, <code class="highlight"><c- nf>--foo</c-><c- p>()</c-></code> is in a cycle with itself, even though the media query never evaluates to "true": <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--foo</c-><c- p>(</c->--x<c- p>)</c-> <c- p>{</c-> <c- n>@media</c-> <c- p>(</c->unknown-feature<c- p>)</c-> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- nf>--foo</c-><c- p>(</c-><c- m>42</c-><c- p>);</c-> <c- p>}</c-> result: <c- m>1</c-><c- p>;</c-> <c- p>}</c-> </pre> <p>Similarly, <code class="highlight"><c- nf>--bar</c-><c- p>()</c-></code> is in a cycle with itself, even though the local variable <code class="highlight">--x</code> is never referenced:</p> <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--bar</c-><c- p>()</c-> <c- p>{</c-> <c- k>--x</c-><c- p>:</c-> <c- nf>--bar</c-><c- p>();</c-> <c- k>result</c-><c- p>:</c-> <c- m>1</c-><c- p>;</c-> <c- p>}</c-> </pre> </div> <div class="example" id="example-f0f91b6a"> <a class="self-link" href="#example-f0f91b6a"></a> The function <code class="highlight"><c- nf>--baz</c-><c- p>()</c-></code> is not in a cycle in the example below: even though <code class="highlight"><c- nf>var</c-><c- p>(</c->--x<c- p>)</c-></code> and <code class="highlight"><c- nf>var</c-><c- p>(</c->--y<c- p>)</c-></code> appear in the function body, they refer to a <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①④">function parameter</a> and <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables①⓪">local variable</a>, respectively. The <a data-link-type="dfn" href="https://drafts.csswg.org/css-variables-2/#custom-property" id="ref-for-custom-property②③">custom properties</a> <code class="highlight">--x</code> and <code class="highlight">--y</code> both reference <code class="highlight"><c- nf>--baz</c-><c- p>()</c-></code>, but that’s fine: those <span id="ref-for-custom-property②④">custom properties</span> are not referenced within <code class="highlight"><c- nf>--baz</c-><c- p>()</c-></code>. <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--baz</c-><c- p>(</c->--x<c- p>)</c-> <c- p>{</c-> <c- k>--y</c-><c- p>:</c-> <c- m>10</c-><c- k>px</c-><c- p>;</c-> <c- k>result</c-><c- p>:</c-> <c- nf>calc</c-><c- p>(</c-><c- nf>var</c-><c- p>(</c->--x<c- p>)</c-> + <c- nf>var</c-><c- p>(</c->--y<c- p>));</c-> <c- p>}</c-> div <c- p>{</c-> <c- k>--x</c-><c- p>:</c-> <c- nf>--baz</c-><c- p>(</c-><c- m>1</c-><c- k>px</c-><c- p>);</c-> <c- k>--y</c-><c- p>:</c-> <c- nf>--baz</c-><c- p>(</c-><c- m>2</c-><c- k>px</c-><c- p>);</c-> <c- k>width</c-><c- p>:</c-> <c- nf>var</c-><c- p>(</c->--x<c- p>);</c-> <c- c>/* 11px */</c-> height: <c- nf>var</c-><c- p>(</c->--y<c- p>);</c-> <c- c>/* 12px */</c-> <c- p>}</c-> </pre> </div> <h2 class="heading settled" data-level="4" id="execution-model"><span class="secno">4. </span><span class="content">Execution Model of Custom Functions</span><a class="self-link" href="#execution-model"></a></h2> <p>Like the rest of CSS, <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function②④">custom functions</a> adhere to a declarative model.</p> <p>The <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables①①">local variable</a> descriptors and <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result①②">result</a> descriptor can appear in any order, and may be provided multiple times. If this happens, then declarations appearing later win over earlier ones.</p> <div class="example" id="example-054f5eb6"> <a class="self-link" href="#example-054f5eb6"></a> <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--mypi</c-><c- p>()</c-> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- m>3</c-><c- p>;</c-> <c- k>result</c-><c- p>:</c-> <c- m>3.14</c-><c- p>;</c-> <c- p>}</c-> </pre> <p>The value of the <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result①③">result</a> descriptor of <code class="highlight">--mypi</code> is <code class="highlight"><c- m>3.14</c-></code>.</p> </div> <div class="example" id="example-55d9cff3"> <a class="self-link" href="#example-55d9cff3"></a> <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--circle-area</c-><c- p>(</c->--r<c- p>)</c-> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- nf>calc</c-><c- p>(</c->pi * <c- nf>var</c-><c- p>(</c->--r2<c- p>));</c-> <c- k>--r2</c-><c- p>:</c-> <c- nf>var</c-><c- p>(</c->--r<c- p>)</c-> * <c- nf>var</c-><c- p>(</c->--r<c- p>);</c-> <c- p>}</c-> </pre> <p><a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables①②">Local variable</a> descriptors may appear before or after they are referenced.</p> </div> <h3 class="heading settled" data-level="4.1" id="conditional-rules"><span class="secno">4.1. </span><span class="content">Conditional Rules</span><a class="self-link" href="#conditional-rules"></a></h3> <p>A <a data-link-type="dfn" href="https://drafts.csswg.org/css-conditional-3/#conditional-group-rule" id="ref-for-conditional-group-rule①">conditional group rule</a> that appears within a <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function⑧">@function</a> becomes a <a data-link-type="dfn" href="https://drafts.csswg.org/css-nesting-1/#nested-group-rules" id="ref-for-nested-group-rules">nested group rule</a>, with the additional restriction that only descriptors allowed within <span class="css" id="ref-for-at-ruledef-function⑨">@function</span> are allowed within the <span id="ref-for-nested-group-rules①">nested group rule</span>.</p> <p><a data-link-type="dfn" href="https://drafts.csswg.org/css-conditional-3/#conditional-group-rule" id="ref-for-conditional-group-rule②">Conditional group rules</a> within <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function①⓪">@function</a> are <a href="https://drafts.csswg.org/css-conditional-3/#processing">processed</a> as normal, acting as if the contents of the rule were present at the <span id="ref-for-conditional-group-rule③">conditional group rule</span>’s location when the condition is true, or acting as if nothing exists at that location otherwise.</p> <div class="example" id="example-cbe24e1b"> <a class="self-link" href="#example-cbe24e1b"></a> <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--suitable-font-size</c-><c- p>()</c-> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- m>16</c-><c- k>px</c-><c- p>;</c-> <c- n>@media</c-> <c- p>(</c->width > <c- m>1000</c-><c- k>px</c-><c- p>)</c-> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- m>20</c-><c- k>px</c-><c- p>;</c-> <c- p>}</c-> <c- p>}</c-> </pre> <p>The value of the <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result①④">result</a> descriptor is <code class="highlight"><c- m>20</c-><c- k>px</c-></code> if the media query’s condition is true, and <code class="highlight"><c- m>16</c-><c- k>px</c-></code> otherwise.</p> </div> <div class="example" id="example-77fc358f"> <a class="self-link" href="#example-77fc358f"></a> Note that due to the execution model, "early return" is not possible within a <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function①①">@function</a>: <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--suitable-font-size</c-><c- p>()</c-> <c- p>{</c-> <c- n>@media</c-> <c- p>(</c->width > <c- m>1000</c-><c- k>px</c-><c- p>)</c-> <c- p>{</c-> <c- k>result</c-><c- p>:</c-> <c- m>20</c-><c- k>px</c-><c- p>;</c-> <c- p>}</c-> result: <c- m>16</c-><c- k>px</c-><c- p>;</c-> <c- p>}</c-> </pre> <p>The value of the <a class="property" data-link-type="propdesc" href="#descdef-function-result" id="ref-for-descdef-function-result①⑤">result</a> descriptor is always <code class="highlight"><c- m>16</c-><c- k>px</c-></code> in the above example.</p> </div> <div class="example" id="example-b3ec3912"> <a class="self-link" href="#example-b3ec3912"></a> <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables①③">Local variables</a> are also valid within conditional rules: <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--suitable-font-size</c-><c- p>()</c-> <c- p>{</c-> <c- k>--size</c-><c- p>:</c-> <c- m>16</c-><c- k>px</c-><c- p>;</c-> <c- n>@media</c-> <c- p>(</c->width > <c- m>1000</c-><c- k>px</c-><c- p>)</c-> <c- p>{</c-> <c- k>--size</c-><c- p>:</c-> <c- m>20</c-><c- k>px</c-><c- p>;</c-> <c- p>}</c-> result: <c- nf>var</c-><c- p>(</c->--size<c- p>);</c-> <c- p>}</c-> </pre> </div> <h2 class="heading settled" data-level="5" id="cssom"><span class="secno">5. </span><span class="content">CSSOM</span><a class="self-link" href="#cssom"></a></h2> <h3 class="heading settled" data-level="5.1" id="the-function-interface"><span class="secno">5.1. </span><span class="content">The <code class="idl"><a data-link-type="idl" href="#cssfunctionrule" id="ref-for-cssfunctionrule">CSSFunctionRule</a></code> Interface</span><a class="self-link" href="#the-function-interface"></a></h3> <p>The <code class="idl"><a data-link-type="idl" href="#cssfunctionrule" id="ref-for-cssfunctionrule①">CSSFunctionRule</a></code> interface represents a <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function①②">@function</a> rule.</p> <pre class="idl highlight def">[<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed" id="ref-for-Exposed"><c- g>Exposed</c-></a>=<c- n>Window</c->] <c- b>interface</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="interface" data-export id="cssfunctionrule"><code class="highlight"><c- g>CSSFunctionRule</c-></code></dfn> : <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssgroupingrule" id="ref-for-cssgroupingrule"><c- n>CSSGroupingRule</c-></a> { <c- b>readonly</c-> <c- b>attribute</c-> <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring" id="ref-for-cssomstring"><c- n>CSSOMString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="CSSOMString" href="#dom-cssfunctionrule-name" id="ref-for-dom-cssfunctionrule-name"><c- g>name</c-></a>; <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence" id="ref-for-idl-sequence"><c- b>sequence</c-></a><<a data-link-type="idl-name" href="#dictdef-functionparameter" id="ref-for-dictdef-functionparameter"><c- n>FunctionParameter</c-></a>> <dfn class="dfn-paneled idl-code" data-dfn-for="CSSFunctionRule" data-dfn-type="method" data-export data-lt="getParameters()" id="dom-cssfunctionrule-getparameters"><code class="highlight"><c- g>getParameters</c-></code></dfn>(); <c- b>readonly</c-> <c- b>attribute</c-> <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring" id="ref-for-cssomstring①"><c- n>CSSOMString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="CSSOMString" href="#dom-cssfunctionrule-returntype" id="ref-for-dom-cssfunctionrule-returntype"><c- g>returnType</c-></a>; }; </pre> <dl> <dt><dfn class="dfn-paneled idl-code" data-dfn-for="CSSFunctionRule" data-dfn-type="attribute" data-export id="dom-cssfunctionrule-name"><code class="highlight">name</code></dfn>, <span> of type <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring" id="ref-for-cssomstring②">CSSOMString</a>, readonly</span> <dd> The name of the <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function②⑤">custom function</a>. <dt><dfn class="dfn-paneled idl-code" data-dfn-for="CSSFunctionRule" data-dfn-type="attribute" data-export id="dom-cssfunctionrule-returntype"><code class="highlight">returnType</code></dfn>, <span> of type <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring" id="ref-for-cssomstring③">CSSOMString</a>, readonly</span> <dd> The <a data-link-type="dfn" href="#custom-function-return-type" id="ref-for-custom-function-return-type④">return type</a> of the <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function②⑥">custom function</a>, represented as a <a href="https://drafts.css-houdini.org/css-properties-values-api-1/#syntax-strings">syntax string</a>. If the <span id="ref-for-custom-function②⑦">custom function</span> has no return type, returns <code class="highlight"><c- s>"type(*)"</c-></code>. </dl> <pre class="idl highlight def"><c- b>dictionary</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="dictionary" data-export id="dictdef-functionparameter"><code class="highlight"><c- g>FunctionParameter</c-></code></dfn> { <c- b>required</c-> <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring" id="ref-for-cssomstring④"><c- n>CSSOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="FunctionParameter" data-dfn-type="dict-member" data-export data-type="CSSOMString" id="dom-functionparameter-name"><code class="highlight"><c- g>name</c-></code></dfn>; <c- b>required</c-> <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring" id="ref-for-cssomstring⑤"><c- n>CSSOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="FunctionParameter" data-dfn-type="dict-member" data-export data-type="CSSOMString" id="dom-functionparameter-type"><code class="highlight"><c- g>type</c-></code></dfn>; <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring" id="ref-for-cssomstring⑥"><c- n>CSSOMString</c-></a>? <dfn class="dfn-paneled idl-code" data-dfn-for="FunctionParameter" data-dfn-type="dict-member" data-export data-type="CSSOMString?" id="dom-functionparameter-defaultvalue"><code class="highlight"><c- g>defaultValue</c-></code></dfn>; }; </pre> <dl> <dt>name <dd> The name of the <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①⑤">function parameter</a>. <dt>type <dd> The <a data-link-type="dfn" href="#parameter-type" id="ref-for-parameter-type①">type</a> of the <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①⑥">function parameter</a>, represented as a <a href="https://drafts.css-houdini.org/css-properties-values-api-1/#syntax-strings">syntax string</a>, or <code class="highlight"><c- s>"type(*)"</c-></code> if the <span id="ref-for-function-parameter①⑦">parameter</span> has no type. <dt>defaultValue <dd> The <a data-link-type="dfn" href="#default-value" id="ref-for-default-value①">default value</a> of the <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①⑧">function parameter</a>, or `null` if the argument does not have a default. </dl> <p>While declarations may be specified directly within a <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function①③">@function</a> rule, they are not represented as such in the CSSOM. Instead, consecutive segments of declarations appear as if wrapped in <code class="idl"><a data-link-type="idl" href="#cssfunctiondeclarations" id="ref-for-cssfunctiondeclarations">CSSFunctionDeclarations</a></code> rules.</p> <p class="note" role="note"><span class="marker">Note:</span> This also applies to the "leading" declarations in the <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function①④">@function</a> rule, i.e those that do not follow another nested rule.</p> <div class="example" id="example-7791a557"> <a class="self-link" href="#example-7791a557"></a> <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--bar</c-><c- p>()</c-> <c- p>{</c-> <c- k>--x</c-><c- p>:</c-> <c- m>42</c-><c- p>;</c-> <c- k>result</c-><c- p>:</c-> <c- nf>var</c-><c- p>(</c->--y<c- p>);</c-> <c- n>@media</c-> <c- p>(</c->width > <c- m>1000</c-><c- k>px</c-><c- p>)</c-> <c- p>{</c-> <c- c>/* ... */</c-> <c- p>}</c-> --y: <c- nf>var</c-><c- p>(</c->--x<c- p>);</c-> <c- p>}</c-> </pre> <p>The above will appear in the CSSOM as:</p> <pre class="lang-css highlight"><c- n>@function</c-> <c- nf>--bar</c-><c- p>()</c-> <c- p>{</c-> <c- c>/* CSSFunctionDeclarations { */</c-> --x: <c- m>42</c-><c- p>;</c-> <c- k>result</c-><c- p>:</c-> <c- nf>var</c-><c- p>(</c->--y<c- p>);</c-> <c- c>/* } */</c-> <c- n>@media</c-> <c- p>(</c->width > <c- m>1000</c-><c- k>px</c-><c- p>)</c-> <c- p>{</c-> <c- c>/* ... */</c-> <c- p>}</c-> <c- c>/* CSSFunctionDeclarations { */</c-> --y: <c- nf>var</c-><c- p>(</c->--x<c- p>);</c-> <c- c>/* } */</c-> <c- p>}</c-> </pre> </div> <div class="algorithm" data-algorithm="serialize a CSSFunctionRule"> To <dfn class="dfn-paneled" data-dfn-type="dfn" data-export id="serialize-a-cssfunctionrule">serialize a CSSFunctionRule</dfn>, return the concatenation of the following: <ol> <li data-md> <p>The string <code class="highlight"><c- s>"@function"</c-></code> followed by a single SPACE (U+0020).</p> <li data-md> <p>The result of performing <a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#serialize-an-identifier" id="ref-for-serialize-an-identifier">serialize an identifier</a> on the name of the <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function②⑧">custom function</a>, followed by a single LEFT PARENTHESIS (U+0028).</p> <li data-md> <p>The result of <a data-link-type="dfn" href="#serialize-a-function-parameter" id="ref-for-serialize-a-function-parameter">serialize a function parameter</a> on each of the <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function②⑨">custom function’s</a> <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter①⑨">parameters</a>, all joined by <code class="highlight"><c- s>", "</c-></code> (COMMA U+002C, followed by a single SPACE U+0020).</p> <li data-md> <p>A single RIGHT PARENTHESIS (U+0029).</p> <li data-md> <p>If the <a data-link-type="dfn" href="#custom-function" id="ref-for-custom-function③⓪">custom function</a> has <a data-link-type="dfn" href="#custom-function-return-type" id="ref-for-custom-function-return-type⑤">return type</a>, and that <span id="ref-for-custom-function-return-type⑥">return type</span> is not the <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#universal-syntax-definition" id="ref-for-universal-syntax-definition①">universal syntax definition</a> ("*"):</p> <ul> <li data-md> <p>A single SPACE (U+0020), followed by the string <code class="highlight"><c- s>"returns"</c-></code>, followed by a single SPACE (U+0020).</p> <li data-md> <p>The result of performing <a data-link-type="dfn" href="#serialize-a-css-type" id="ref-for-serialize-a-css-type">serialize a CSS type</a> on that <a data-link-type="dfn" href="#custom-function-return-type" id="ref-for-custom-function-return-type⑦">type</a>, followed by a single SPACE (U+0020).</p> </ul> <li data-md> <p>A single LEFT CURLY BRACKET (U+007B), followed by a SPACE (U+0020).</p> <li data-md> <p>The result of performing <a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#serialize-a-css-rule" id="ref-for-serialize-a-css-rule">serialize a CSS rule</a> on each rule in cssRules, filtering out empty strings, all joined by a single SPACE (U+0020).</p> <p class="note" role="note"><span class="marker">Note:</span> <a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#serialize-a-css-rule" id="ref-for-serialize-a-css-rule①">Serialize a CSS rule</a> can return an empty string when serializing an empty <code class="idl"><a data-link-type="idl" href="#cssfunctiondeclarations" id="ref-for-cssfunctiondeclarations①">CSSFunctionDeclarations</a></code> rule.</p> <li data-md> <p>A single SPACE (U+0020), followed by a single RIGHT CURLY BRACKET (U+007D).</p> </ol> </div> <div class="algorithm" data-algorithm="serialize a function parameter"> To <dfn class="dfn-paneled" data-dfn-type="dfn" data-export id="serialize-a-function-parameter">serialize a function parameter</dfn>, return the concatenation of the following: <ol> <li data-md> <p>The result of performing <a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#serialize-an-identifier" id="ref-for-serialize-an-identifier①">serialize an identifier</a> on the name of the <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter②⓪">function parameter</a>.</p> <li data-md> <p>If the <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter②①">function parameter</a> has a <a data-link-type="dfn" href="#parameter-type" id="ref-for-parameter-type②">type</a>, and that <span id="ref-for-parameter-type③">type</span> is not the <a data-link-type="dfn" href="https://drafts.css-houdini.org/css-properties-values-api-1/#universal-syntax-definition" id="ref-for-universal-syntax-definition②">universal syntax definition</a>:</p> <ul> <li data-md> <p>A single SPACE (U+0020), followed by the result of performing <a data-link-type="dfn" href="#serialize-a-css-type" id="ref-for-serialize-a-css-type①">serialize a CSS type</a> on that <a data-link-type="dfn" href="#parameter-type" id="ref-for-parameter-type④">type</a>.</p> </ul> <li data-md> <p>If the <a data-link-type="dfn" href="#function-parameter" id="ref-for-function-parameter②②">function parameter</a> has a <a data-link-type="dfn" href="#default-value" id="ref-for-default-value②">default value</a>:</p> <ul> <li data-md> <p>A single COLON (U+003A), followed by a single SPACE (U+0020), followed by the result of performing <a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#serialize-a-css-value" id="ref-for-serialize-a-css-value">serialize a CSS value</a> on that value.</p> </ul> </ol> </div> <div class="algorithm" data-algorithm="serialize a CSS type"> To <dfn class="dfn-paneled" data-dfn-type="dfn" data-export id="serialize-a-css-type">serialize a CSS type</dfn>, return the concatenation of the following: <ol> <li data-md> <p>If the <a class="production css" data-link-type="type" href="#typedef-css-type" id="ref-for-typedef-css-type⑤"><css-type></a> consists of a single <a class="production css" data-link-type="type" href="https://drafts.csswg.org/css-values-5/#typedef-syntax-component" id="ref-for-typedef-syntax-component②"><syntax-component></a>, return the corresponding <a href="https://drafts.css-houdini.org/css-properties-values-api-1/#syntax-strings">syntax string</a>.</p> <li data-md> <p>Otherwise, return the concatenation of the following:</p> <ul> <li data-md> <p>The string <code class="highlight"><c- s>"type("</c-></code>, i.e. <code class="highlight"><c- s>"type"</c-></code> followed by a single LEFT PARENTHESIS (U+0028).</p> <li data-md> <p>The corresponding <a href="https://drafts.css-houdini.org/css-properties-values-api-1/#syntax-strings">syntax string</a>.</p> <li data-md> <p>The string <code class="highlight"><c- s>")"</c-></code>, i.e. a single RIGHT PARENTHESIS (U+0029).</p> </ul> </ol> </div> <h3 class="heading settled" data-level="5.2" id="the-function-declarations-interface"><span class="secno">5.2. </span><span class="content">The <code class="idl"><a data-link-type="idl" href="#cssfunctiondeclarations" id="ref-for-cssfunctiondeclarations②">CSSFunctionDeclarations</a></code> Interface</span><a class="self-link" href="#the-function-declarations-interface"></a></h3> <p>The <code class="idl"><a data-link-type="idl" href="#cssfunctiondeclarations" id="ref-for-cssfunctiondeclarations③">CSSFunctionDeclarations</a></code> interface represents a run of consecutive <a data-link-type="dfn" href="https://drafts.csswg.org/css-syntax-3/#declaration" id="ref-for-declaration①">declarations</a> within a <a class="css" data-link-type="maybe" href="#at-ruledef-function" id="ref-for-at-ruledef-function①⑤">@function</a> rule.</p> <pre class="idl highlight def">[<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed" id="ref-for-Exposed①"><c- g>Exposed</c-></a>=<c- n>Window</c->] <c- b>interface</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="interface" data-export id="cssfunctiondescriptors"><code class="highlight"><c- g>CSSFunctionDescriptors</c-></code></dfn> : <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssstyledeclaration" id="ref-for-cssstyledeclaration"><c- n>CSSStyleDeclaration</c-></a> { <c- b>attribute</c-> [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#LegacyNullToEmptyString" id="ref-for-LegacyNullToEmptyString"><c- g>LegacyNullToEmptyString</c-></a>] <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring" id="ref-for-cssomstring⑦"><c- n>CSSOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="CSSFunctionDescriptors" data-dfn-type="attribute" data-export data-type="CSSOMString" id="dom-cssfunctiondescriptors-result"><code class="highlight"><c- g>result</c-></code></dfn>; }; [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed" id="ref-for-Exposed②"><c- g>Exposed</c-></a>=<c- n>Window</c->] <c- b>interface</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="interface" data-export id="cssfunctiondeclarations"><code class="highlight"><c- g>CSSFunctionDeclarations</c-></code></dfn> : <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssrule" id="ref-for-cssrule"><c- n>CSSRule</c-></a> { [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#SameObject" id="ref-for-SameObject"><c- g>SameObject</c-></a>, <a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#PutForwards" id="ref-for-PutForwards"><c- g>PutForwards</c-></a>=<a class="idl-code" data-link-type="attribute"><c- n>cssText</c-></a>] <c- b>readonly</c-> <c- b>attribute</c-> <a data-link-type="idl-name" href="#cssfunctiondescriptors" id="ref-for-cssfunctiondescriptors"><c- n>CSSFunctionDescriptors</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="CSSFunctionDescriptors" href="#dom-cssfunctiondeclarations-style" id="ref-for-dom-cssfunctiondeclarations-style"><c- g>style</c-></a>; }; </pre> <div class="algorithm" data-algorithm="style" data-algorithm-for="CSSFunctionDeclarations"> The <dfn class="dfn-paneled idl-code" data-dfn-for="CSSFunctionDeclarations" data-dfn-type="attribute" data-export id="dom-cssfunctiondeclarations-style"><code class="highlight">style</code></dfn> attribute must return a <code class="idl"><a data-link-type="idl" href="#cssfunctiondescriptors" id="ref-for-cssfunctiondescriptors①">CSSFunctionDescriptors</a></code> object for the rule, with the following properties: <dl> <dt data-md><a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#cssstyledeclaration-computed-flag" id="ref-for-cssstyledeclaration-computed-flag">computed flag</a> <dd data-md> <p>Unset</p> <dt data-md><a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#cssstyledeclaration-readonly-flag" id="ref-for-cssstyledeclaration-readonly-flag">readonly flag</a> <dd data-md> <p>Unset</p> <dt data-md><a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#cssstyledeclaration-declarations" id="ref-for-cssstyledeclaration-declarations">declarations</a> <dd data-md> <p>The declared declarations in the rule, in <a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#concept-declarations-specified-order" id="ref-for-concept-declarations-specified-order">specified order</a>. <span class="note">This includes any <a data-link-type="dfn" href="#local-variables" id="ref-for-local-variables①④">local variables</a>.</span></p> <dt data-md><a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#cssstyledeclaration-parent-css-rule" id="ref-for-cssstyledeclaration-parent-css-rule">parent CSS rule</a> <dd data-md> <p><a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this">this</a></p> <dt data-md><a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#cssstyledeclaration-owner-node" id="ref-for-cssstyledeclaration-owner-node">owner node</a> <dd data-md> <p>Null</p> </dl> </div> <p>The <code class="idl"><a data-link-type="idl" href="#cssfunctiondeclarations" id="ref-for-cssfunctiondeclarations④">CSSFunctionDeclarations</a></code> rule, like <code class="idl"><a data-link-type="idl" href="https://drafts.csswg.org/css-nesting-1/#cssnesteddeclarations" id="ref-for-cssnesteddeclarations">CSSNestedDeclarations</a></code>, <a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#serialize-a-css-rule" id="ref-for-serialize-a-css-rule②">serializes</a> as if its <a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#css-declaration-block" id="ref-for-css-declaration-block">declaration block</a> had been <a data-link-type="dfn" href="https://drafts.csswg.org/cssom-1/#serialize-a-css-declaration-block" id="ref-for-serialize-a-css-declaration-block">serialized</a> directly.</p> <h2 class="heading settled" data-level="6" id="privacy"><span class="secno">6. </span><span class="content">Privacy Considerations</span><a class="self-link" href="#privacy"></a></h2> <p>The constructs defined by this specification are defined and used entirely within CSS; they expose no new information.</p> <h2 class="heading settled" data-level="7" id="security"><span class="secno">7. </span><span class="content">Security Considerations</span><a class="self-link" href="#security"></a></h2> <p>No issues have been opened against this specification.</p> </main> <h2 class="no-ref no-num heading settled" id="w3c-conformance"><span class="content"> Conformance</span><a class="self-link" href="#w3c-conformance"></a></h2> <h3 class="no-ref heading settled" id="w3c-conventions"><span class="content"> Document conventions</span><a class="self-link" href="#w3c-conventions"></a></h3> <p>Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification. </p> <p>All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. <a data-link-type="biblio" href="#biblio-rfc2119" title="Key words for use in RFCs to Indicate Requirement Levels">[RFC2119]</a></p> <p>Examples in this specification are introduced with the words “for example” or are set apart from the normative text with <code class="highlight">class=<c- s>"example"</c-></code>, like this: </p> <div class="example" id="w3c-example"> <a class="self-link" href="#w3c-example"></a> <p>This is an example of an informative example.</p> </div> <p>Informative notes begin with the word “Note” and are set apart from the normative text with <code class="highlight">class=<c- s>"note"</c-></code>, like this: </p> <p class="note" role="note">Note, this is an informative note.</p> <p>Advisements are normative sections styled to evoke special attention and are set apart from other normative text with <code class="highlight"><strong class=<c- s>"advisement"</c->></code>, like this: <strong class="advisement"> UAs MUST provide an accessible alternative. </strong></p> <details class="wpt-tests-block" dir="ltr" lang="en" open> <summary>Tests</summary> <p>Tests relating to the content of this specification may be documented in “Tests” blocks like this one. Any such block is non-normative.</p> <ul class="wpt-tests-list"></ul> <hr> </details> <h3 class="no-ref heading settled" id="w3c-conformance-classes"><span class="content"> Conformance classes</span><a class="self-link" href="#w3c-conformance-classes"></a></h3> <p>Conformance to this specification is defined for three conformance classes: </p> <dl> <dt>style sheet <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#style-sheet">CSS style sheet</a>. <dt>renderer <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#user-agent">UA</a> that interprets the semantics of a style sheet and renders documents that use them. <dt>authoring tool <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#user-agent">UA</a> that writes a style sheet. </dl> <p>A style sheet is conformant to this specification if all of its statements that use syntax defined in this module are valid according to the generic CSS grammar and the individual grammars of each feature defined in this module. </p> <p>A renderer is conformant to this specification if, in addition to interpreting the style sheet as defined by the appropriate specifications, it supports all the features defined by this specification by parsing them correctly and rendering the document accordingly. However, the inability of a UA to correctly render a document due to limitations of the device does not make the UA non-conformant. (For example, a UA is not required to render color on a monochrome monitor.) </p> <p>An authoring tool is conformant to this specification if it writes style sheets that are syntactically correct according to the generic CSS grammar and the individual grammars of each feature in this module, and meet all other conformance requirements of style sheets as described in this module. </p> <h3 class="no-ref heading settled" id="w3c-partial"><span class="content"> Partial implementations</span><a class="self-link" href="#w3c-partial"></a></h3> <p>So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers <strong>must</strong> treat as invalid (and <a href="http://www.w3.org/TR/CSS21/conform.html#ignore">ignore as appropriate</a>) any at-rules, properties, property values, keywords, and other syntactic constructs for which they have no usable level of support. In particular, user agents <strong>must not</strong> selectively ignore unsupported component values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.</p> <h4 class="heading settled" id="w3c-conform-future-proofing"><span class="content"> Implementations of Unstable and Proprietary Features</span><a class="self-link" href="#w3c-conform-future-proofing"></a></h4> <p>To avoid clashes with future stable CSS features, the CSSWG recommends <a href="http://www.w3.org/TR/CSS/#future-proofing">following best practices</a> for the implementation of <a href="http://www.w3.org/TR/CSS/#unstable">unstable</a> features and <a href="http://www.w3.org/TR/CSS/#proprietary-extension">proprietary extensions</a> to CSS. </p> <h3 class="no-ref heading settled" id="w3c-testing"><span class="content"> Non-experimental implementations</span><a class="self-link" href="#w3c-testing"></a></h3> <p>Once a specification reaches the Candidate Recommendation stage, non-experimental implementations are possible, and implementors should release an unprefixed implementation of any CR-level feature they can demonstrate to be correctly implemented according to spec. </p> <p>To establish and maintain the interoperability of CSS across implementations, the CSS Working Group requests that non-experimental CSS renderers submit an implementation report (and, if necessary, the testcases used for that implementation report) to the W3C before releasing an unprefixed implementation of any CSS features. Testcases submitted to W3C are subject to review and correction by the CSS Working Group. </p> <p>Further information on submitting testcases and implementation reports can be found from on the CSS Working Group’s website at <a href="http://www.w3.org/Style/CSS/Test/">http://www.w3.org/Style/CSS/Test/</a>. Questions should be directed to the <a href="http://lists.w3.org/Archives/Public/public-css-testsuite">public-css-testsuite@w3.org</a> mailing list.</p> <script src="https://www.w3.org/scripts/TR/2021/fixup.js"></script> <h2 class="no-num no-ref heading settled" id="index"><span class="content">Index</span><a class="self-link" href="#index"></a></h2> <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="content">Terms defined by this specification</span><a class="self-link" href="#index-defined-here"></a></h3> <ul class="index"> <li><a href="#calling-context">calling context</a><span>, in § 3</span> <li><a href="#cssfunctiondeclarations">CSSFunctionDeclarations</a><span>, in § 5.2</span> <li><a href="#cssfunctiondescriptors">CSSFunctionDescriptors</a><span>, in § 5.2</span> <li><a href="#cssfunctionrule">CSSFunctionRule</a><span>, in § 5.1</span> <li><a href="#typedef-css-type"><css-type></a><span>, in § 2.1</span> <li><a href="#custom-function">custom function</a><span>, in § 2.1</span> <li><a href="#typedef-dashed-function"><dashed-function></a><span>, in § 3</span> <li><a href="#default-value">default value</a><span>, in § 2.1</span> <li><a href="#dom-functionparameter-defaultvalue">defaultValue</a><span>, in § 5.1</span> <li><a href="#evaluate-a-custom-function">evaluate a custom function</a><span>, in § 3.1</span> <li><a href="#at-ruledef-function">@function</a><span>, in § 2.1</span> <li><a href="#custom-function-function-body">function body</a><span>, in § 2.1</span> <li><a href="#typedef-function-parameter"><function-parameter></a><span>, in § 2.1</span> <li><a href="#function-parameter">function parameter</a><span>, in § 2.1</span> <li><a href="#dictdef-functionparameter">FunctionParameter</a><span>, in § 5.1</span> <li><a href="#dom-cssfunctionrule-getparameters">getParameters()</a><span>, in § 5.1</span> <li><a href="#local-variables">local variables</a><span>, in § 2.1.2</span> <li> name <ul> <li><a href="#dom-cssfunctionrule-name">attribute for CSSFunctionRule</a><span>, in § 5.1</span> <li><a href="#dom-functionparameter-name">dict-member for FunctionParameter</a><span>, in § 5.1</span> </ul> <li><a href="#parameter-type">parameter type</a><span>, in § 2.1</span> <li><a href="#resolve-function-styles">resolve function styles</a><span>, in § 3.1</span> <li> result <ul> <li><a href="#dom-cssfunctiondescriptors-result">attribute for CSSFunctionDescriptors</a><span>, in § 5.2</span> <li><a href="#descdef-function-result">descriptor for @function</a><span>, in § 2.2</span> </ul> <li><a href="#custom-function-return-type">return type</a><span>, in § 2.1</span> <li><a href="#dom-cssfunctionrule-returntype">returnType</a><span>, in § 5.1</span> <li><a href="#calling-context-root-element">root element</a><span>, in § 3</span> <li><a href="#serialize-a-cssfunctionrule">serialize a CSSFunctionRule</a><span>, in § 5.1</span> <li><a href="#serialize-a-css-type">serialize a CSS type</a><span>, in § 5.1</span> <li><a href="#serialize-a-function-parameter">serialize a function parameter</a><span>, in § 5.1</span> <li><a href="#dom-cssfunctiondeclarations-style">style</a><span>, in § 5.2</span> <li><a href="#substitute-a-dashed-function">substitute a dashed function</a><span>, in § 3</span> <li><a href="#dom-functionparameter-type">type</a><span>, in § 5.1</span> <li><a href="#funcdef-function-type">type()</a><span>, in § 2.1</span> </ul> <h3 class="no-num no-ref heading settled" id="index-defined-elsewhere"><span class="content">Terms defined by reference</span><a class="self-link" href="#index-defined-elsewhere"></a></h3> <ul class="index"> <li> <a data-link-type="biblio">[CSS-ANIMATIONS-1]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="fa19c68e">@keyframes</span> </ul> <li> <a data-link-type="biblio">[CSS-CASCADE-5]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="9cd25054">computed value</span> <li><span class="dfn-paneled" id="c388d253">inherit</span> <li><span class="dfn-paneled" id="d309d3f4">inherited value</span> <li><span class="dfn-paneled" id="4d7d3dcd">initial</span> <li><span class="dfn-paneled" id="1cf918c1">specified value</span> </ul> <li> <a data-link-type="biblio">[CSS-CONDITIONAL-3]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="5f1b7f60">@media</span> <li><span class="dfn-paneled" id="bf3ca8a7">conditional group rule</span> </ul> <li> <a data-link-type="biblio">[CSS-CONDITIONAL-5]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="4ecd1e40">@container</span> </ul> <li> <a data-link-type="biblio">[CSS-NESTING-1]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="cccedd30">CSSNestedDeclarations</span> <li><span class="dfn-paneled" id="ec52b7f5">nested group rules</span> </ul> <li> <a data-link-type="biblio">[CSS-PROPERTIES-VALUES-API-1]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="d1c0f823">custom property registration</span> <li><span class="dfn-paneled" id="b8de3fe5">equivalent token sequence</span> <li><span class="dfn-paneled" id="cfb5cfc9">syntax definition</span> <li><span class="dfn-paneled" id="983c572a">universal syntax definition</span> </ul> <li> <a data-link-type="biblio">[CSS-SCOPING-1]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="778f8dbd">tree-scoped name</span> <li><span class="dfn-paneled" id="c304f669">tree-scoped reference</span> </ul> <li> <a data-link-type="biblio">[CSS-SYNTAX-3]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="4bcd07f8"><declaration-rule-list></span> <li><span class="dfn-paneled" id="8144e597"><declaration-value></span> <li><span class="dfn-paneled" id="af50aa62"><function-token></span> <li><span class="dfn-paneled" id="dfd120f7">declaration</span> <li><span class="dfn-paneled" id="5a58bbb0">style rule</span> </ul> <li> <a data-link-type="biblio">[CSS-VALUES-4]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="68487d22">#</span> <li><span class="dfn-paneled" id="68150e76">*</span> <li><span class="dfn-paneled" id="8a427103"><dashed-ident></span> <li><span class="dfn-paneled" id="537cf076">?</span> <li><span class="dfn-paneled" id="358fd6ff">CSS-wide keywords</span> <li><span class="dfn-paneled" id="8ca32f09">functional notation</span> <li><span class="dfn-paneled" id="6ec67710">|</span> </ul> <li> <a data-link-type="biblio">[CSS-VALUES-5]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="04215a8e"><syntax-combinator></span> <li><span class="dfn-paneled" id="eb374cfb"><syntax-component></span> <li><span class="dfn-paneled" id="0200fc07"><syntax></span> <li><span class="dfn-paneled" id="4c50974c">arbitrary substitution</span> <li><span class="dfn-paneled" id="346d2bb2">arbitrary substitution function</span> <li><span class="dfn-paneled" id="57699934">attr()</span> <li><span class="dfn-paneled" id="f70b2903">comma-containing productions</span> <li><span class="dfn-paneled" id="54fd6ed6">invalid at computed-value time</span> <li><span class="dfn-paneled" id="c1c3d423">substitute arbitrary substitution function</span> </ul> <li> <a data-link-type="biblio">[CSS-VARIABLES-2]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="e55dd7f2"><custom-property-name></span> <li><span class="dfn-paneled" id="198f1537">custom property</span> <li><span class="dfn-paneled" id="eb7e3851">guaranteed-invalid value</span> <li><span class="dfn-paneled" id="dbba942a">var()</span> </ul> <li> <a data-link-type="biblio">[CSSOM-1]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="2485e0d1">CSSGroupingRule</span> <li><span class="dfn-paneled" id="5fced98b">CSSOMString</span> <li><span class="dfn-paneled" id="ebaeb088">CSSRule</span> <li><span class="dfn-paneled" id="a82a20ef">CSSStyleDeclaration</span> <li><span class="dfn-paneled" id="29c3f2fe">computed flag</span> <li><span class="dfn-paneled" id="a06e5a78">CSS declaration block</span> <li><span class="dfn-paneled" id="e4ffca7f">declarations</span> <li><span class="dfn-paneled" id="eab73120">owner node</span> <li><span class="dfn-paneled" id="8056dead">parent CSS rule</span> <li><span class="dfn-paneled" id="6eabcb67">readonly flag</span> <li><span class="dfn-paneled" id="2c2c4b46">serialize a CSS declaration block</span> <li><span class="dfn-paneled" id="8c57eaed">serialize a CSS rule</span> <li><span class="dfn-paneled" id="5fdd1729">serialize a CSS value</span> <li><span class="dfn-paneled" id="f96aa907">serialize an identifier</span> <li><span class="dfn-paneled" id="c475bc01">specified order</span> </ul> <li> <a data-link-type="biblio">[SELECTORS-4]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="3a1154bf">featureless</span> </ul> <li> <a data-link-type="biblio">[WEBIDL]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="889e932f">Exposed</span> <li><span class="dfn-paneled" id="2c4af168">LegacyNullToEmptyString</span> <li><span class="dfn-paneled" id="21ecf38f">PutForwards</span> <li><span class="dfn-paneled" id="a5c91173">SameObject</span> <li><span class="dfn-paneled" id="9cce47fd">sequence</span> <li><span class="dfn-paneled" id="4013a022">this</span> </ul> </ul> <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2> <h3 class="no-num no-ref heading settled" id="normative"><span class="content">Normative References</span><a class="self-link" href="#normative"></a></h3> <dl> <dt id="biblio-css-animations-1">[CSS-ANIMATIONS-1] <dd>David Baron; et al. <a href="https://drafts.csswg.org/css-animations/"><cite>CSS Animations Level 1</cite></a>. URL: <a href="https://drafts.csswg.org/css-animations/">https://drafts.csswg.org/css-animations/</a> <dt id="biblio-css-cascade-5">[CSS-CASCADE-5] <dd>Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. <a href="https://drafts.csswg.org/css-cascade-5/"><cite>CSS Cascading and Inheritance Level 5</cite></a>. URL: <a href="https://drafts.csswg.org/css-cascade-5/">https://drafts.csswg.org/css-cascade-5/</a> <dt id="biblio-css-conditional-3">[CSS-CONDITIONAL-3] <dd>Chris Lilley; David Baron; Elika Etemad. <a href="https://drafts.csswg.org/css-conditional-3/"><cite>CSS Conditional Rules Module Level 3</cite></a>. URL: <a href="https://drafts.csswg.org/css-conditional-3/">https://drafts.csswg.org/css-conditional-3/</a> <dt id="biblio-css-nesting-1">[CSS-NESTING-1] <dd>Tab Atkins Jr.; Adam Argyle. <a href="https://drafts.csswg.org/css-nesting/"><cite>CSS Nesting Module</cite></a>. URL: <a href="https://drafts.csswg.org/css-nesting/">https://drafts.csswg.org/css-nesting/</a> <dt id="biblio-css-properties-values-api-1">[CSS-PROPERTIES-VALUES-API-1] <dd>Tab Atkins Jr.; Alan Stearns; Greg Whitworth. <a href="https://drafts.css-houdini.org/css-properties-values-api-1/"><cite>CSS Properties and Values API Level 1</cite></a>. URL: <a href="https://drafts.css-houdini.org/css-properties-values-api-1/">https://drafts.css-houdini.org/css-properties-values-api-1/</a> <dt id="biblio-css-scoping-1">[CSS-SCOPING-1] <dd>Tab Atkins Jr.; Elika Etemad. <a href="https://drafts.csswg.org/css-scoping/"><cite>CSS Scoping Module Level 1</cite></a>. URL: <a href="https://drafts.csswg.org/css-scoping/">https://drafts.csswg.org/css-scoping/</a> <dt id="biblio-css-syntax-3">[CSS-SYNTAX-3] <dd>Tab Atkins Jr.; Simon Sapin. <a href="https://drafts.csswg.org/css-syntax/"><cite>CSS Syntax Module Level 3</cite></a>. URL: <a href="https://drafts.csswg.org/css-syntax/">https://drafts.csswg.org/css-syntax/</a> <dt id="biblio-css-values-4">[CSS-VALUES-4] <dd>Tab Atkins Jr.; Elika Etemad. <a href="https://drafts.csswg.org/css-values-4/"><cite>CSS Values and Units Module Level 4</cite></a>. URL: <a href="https://drafts.csswg.org/css-values-4/">https://drafts.csswg.org/css-values-4/</a> <dt id="biblio-css-values-5">[CSS-VALUES-5] <dd>Tab Atkins Jr.; Elika Etemad; Miriam Suzanne. <a href="https://drafts.csswg.org/css-values-5/"><cite>CSS Values and Units Module Level 5</cite></a>. URL: <a href="https://drafts.csswg.org/css-values-5/">https://drafts.csswg.org/css-values-5/</a> <dt id="biblio-css-variables-1">[CSS-VARIABLES-1] <dd>Tab Atkins Jr.. <a href="https://drafts.csswg.org/css-variables/"><cite>CSS Custom Properties for Cascading Variables Module Level 1</cite></a>. URL: <a href="https://drafts.csswg.org/css-variables/">https://drafts.csswg.org/css-variables/</a> <dt id="biblio-css-variables-2">[CSS-VARIABLES-2] <dd><a href="https://drafts.csswg.org/css-variables-2/"><cite>CSS Custom Properties for Cascading Variables Module Level 2</cite></a>. Editor's Draft. URL: <a href="https://drafts.csswg.org/css-variables-2/">https://drafts.csswg.org/css-variables-2/</a> <dt id="biblio-cssom-1">[CSSOM-1] <dd>Daniel Glazman; Emilio Cobos Álvarez. <a href="https://drafts.csswg.org/cssom/"><cite>CSS Object Model (CSSOM)</cite></a>. URL: <a href="https://drafts.csswg.org/cssom/">https://drafts.csswg.org/cssom/</a> <dt id="biblio-rfc2119">[RFC2119] <dd>S. Bradner. <a href="https://datatracker.ietf.org/doc/html/rfc2119"><cite>Key words for use in RFCs to Indicate Requirement Levels</cite></a>. March 1997. Best Current Practice. URL: <a href="https://datatracker.ietf.org/doc/html/rfc2119">https://datatracker.ietf.org/doc/html/rfc2119</a> <dt id="biblio-selectors-4">[SELECTORS-4] <dd>Elika Etemad; Tab Atkins Jr.. <a href="https://drafts.csswg.org/selectors/"><cite>Selectors Level 4</cite></a>. URL: <a href="https://drafts.csswg.org/selectors/">https://drafts.csswg.org/selectors/</a> <dt id="biblio-webidl">[WEBIDL] <dd>Edgar Chen; Timothy Gu. <a href="https://webidl.spec.whatwg.org/"><cite>Web IDL Standard</cite></a>. Living Standard. URL: <a href="https://webidl.spec.whatwg.org/">https://webidl.spec.whatwg.org/</a> </dl> <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3> <dl> <dt id="biblio-css-conditional-5">[CSS-CONDITIONAL-5] <dd>Chris Lilley; et al. <a href="https://drafts.csswg.org/css-conditional-5/"><cite>CSS Conditional Rules Module Level 5</cite></a>. URL: <a href="https://drafts.csswg.org/css-conditional-5/">https://drafts.csswg.org/css-conditional-5/</a> </dl> <h2 class="no-num no-ref heading settled" id="property-index"><span class="content">Property Index</span><a class="self-link" href="#property-index"></a></h2> <p>No properties defined.</p> <h3 class="no-num no-ref heading settled" id="function-descriptor-table"><span class="content"><a class="css" data-link-type="at-rule" href="#at-ruledef-function" id="ref-for-at-ruledef-function①⑥">@function</a> Descriptors</span><a class="self-link" href="#function-descriptor-table"></a></h3> <div class="big-element-wrapper"> <table class="index"> <thead> <tr> <th scope="col">Name <th scope="col">Value <th scope="col">Initial <tbody> <tr> <th scope="row"><a class="css" data-link-type="descriptor" href="#descdef-function-result" id="ref-for-descdef-function-result①⑥">result</a> <td><declaration-value>? <td>n/a (see prose) </table> </div> <h2 class="no-num no-ref heading settled" id="idl-index"><span class="content">IDL Index</span><a class="self-link" href="#idl-index"></a></h2> <pre class="idl highlight def">[<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed"><c- g>Exposed</c-></a>=<c- n>Window</c->] <c- b>interface</c-> <a href="#cssfunctionrule"><code class="highlight"><c- g>CSSFunctionRule</c-></code></a> : <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssgroupingrule"><c- n>CSSGroupingRule</c-></a> { <c- b>readonly</c-> <c- b>attribute</c-> <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring"><c- n>CSSOMString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="CSSOMString" href="#dom-cssfunctionrule-name"><c- g>name</c-></a>; <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence"><c- b>sequence</c-></a><<a data-link-type="idl-name" href="#dictdef-functionparameter"><c- n>FunctionParameter</c-></a>> <a href="#dom-cssfunctionrule-getparameters"><code class="highlight"><c- g>getParameters</c-></code></a>(); <c- b>readonly</c-> <c- b>attribute</c-> <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring"><c- n>CSSOMString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="CSSOMString" href="#dom-cssfunctionrule-returntype"><c- g>returnType</c-></a>; }; <c- b>dictionary</c-> <a href="#dictdef-functionparameter"><code class="highlight"><c- g>FunctionParameter</c-></code></a> { <c- b>required</c-> <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring"><c- n>CSSOMString</c-></a> <a data-type="CSSOMString" href="#dom-functionparameter-name"><code class="highlight"><c- g>name</c-></code></a>; <c- b>required</c-> <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring"><c- n>CSSOMString</c-></a> <a data-type="CSSOMString" href="#dom-functionparameter-type"><code class="highlight"><c- g>type</c-></code></a>; <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring"><c- n>CSSOMString</c-></a>? <a data-type="CSSOMString?" href="#dom-functionparameter-defaultvalue"><code class="highlight"><c- g>defaultValue</c-></code></a>; }; [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed"><c- g>Exposed</c-></a>=<c- n>Window</c->] <c- b>interface</c-> <a href="#cssfunctiondescriptors"><code class="highlight"><c- g>CSSFunctionDescriptors</c-></code></a> : <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssstyledeclaration"><c- n>CSSStyleDeclaration</c-></a> { <c- b>attribute</c-> [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#LegacyNullToEmptyString"><c- g>LegacyNullToEmptyString</c-></a>] <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssomstring"><c- n>CSSOMString</c-></a> <a data-type="CSSOMString" href="#dom-cssfunctiondescriptors-result"><code class="highlight"><c- g>result</c-></code></a>; }; [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed"><c- g>Exposed</c-></a>=<c- n>Window</c->] <c- b>interface</c-> <a href="#cssfunctiondeclarations"><code class="highlight"><c- g>CSSFunctionDeclarations</c-></code></a> : <a data-link-type="idl-name" href="https://drafts.csswg.org/cssom-1/#cssrule"><c- n>CSSRule</c-></a> { [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#SameObject"><c- g>SameObject</c-></a>, <a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#PutForwards"><c- g>PutForwards</c-></a>=<a class="idl-code" data-link-type="attribute"><c- n>cssText</c-></a>] <c- b>readonly</c-> <c- b>attribute</c-> <a data-link-type="idl-name" href="#cssfunctiondescriptors"><c- n>CSSFunctionDescriptors</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="CSSFunctionDescriptors" href="#dom-cssfunctiondeclarations-style"><c- g>style</c-></a>; }; </pre> <script>/* Boilerplate: script-dom-helper */ "use strict"; function query(sel) { return document.querySelector(sel); } function queryAll(sel) { return [...document.querySelectorAll(sel)]; } function iter(obj) { if(!obj) return []; var it = obj[Symbol.iterator]; if(it) return it; return Object.entries(obj); } function mk(tagname, attrs, ...children) { const el = document.createElement(tagname); for(const [k,v] of iter(attrs)) { if(k.slice(0,3) == "_on") { const eventName = k.slice(3); el.addEventListener(eventName, v); } else if(k[0] == "_") { // property, not attribute el[k.slice(1)] = v; } else { if(v === false || v == null) { continue; } else if(v === true) { el.setAttribute(k, ""); continue; } else { el.setAttribute(k, v); } } } append(el, children); return el; } /* Create shortcuts for every known HTML element */ [ "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "label", "legend", "li", "link", "main", "map", "mark", "meta", "meter", "nav", "nobr", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "pre", "progress", "q", "s", "samp", "script", "section", "select", "small", "source", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "u", "ul", "var", "video", "wbr", "xmp", ].forEach(tagname=>{ mk[tagname] = (...args) => mk(tagname, ...args); }); function* nodesFromChildList(children) { for(const child of children.flat(Infinity)) { if(child instanceof Node) { yield child; } else { yield new Text(child); } } } function append(el, ...children) { for(const child of nodesFromChildList(children)) { if(el instanceof Node) el.appendChild(child); else el.push(child); } return el; } function insertAfter(el, ...children) { for(const child of nodesFromChildList(children)) { el.parentNode.insertBefore(child, el.nextSibling); } return el; } function clearContents(el) { el.innerHTML = ""; return el; } function parseHTML(markup) { if(markup.toLowerCase().trim().indexOf('<!doctype') === 0) { const doc = document.implementation.createHTMLDocument(""); doc.documentElement.innerHTML = markup; return doc; } else { const el = mk.template({}); el.innerHTML = markup; return el.content; } }</script> <script>/* Boilerplate: script-dfn-panel */ "use strict"; { let dfnPanelData = { "0200fc07": {"dfnID":"0200fc07","dfnText":"<syntax>","external":true,"refSections":[{"refs":[{"id":"ref-for-typedef-syntax"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-typedef-syntax\u2460"}],"title":"2.1.1. \nThe Function Preamble"}],"url":"https://drafts.csswg.org/css-values-5/#typedef-syntax"}, "04215a8e": {"dfnID":"04215a8e","dfnText":"<syntax-combinator>","external":true,"refSections":[{"refs":[{"id":"ref-for-typedef-syntax-combinator"}],"title":"2.1.1. \nThe Function Preamble"}],"url":"https://drafts.csswg.org/css-values-5/#typedef-syntax-combinator"}, "198f1537": {"dfnID":"198f1537","dfnText":"custom property","external":true,"refSections":[{"refs":[{"id":"ref-for-custom-property"},{"id":"ref-for-custom-property\u2460"},{"id":"ref-for-custom-property\u2461"},{"id":"ref-for-custom-property\u2462"}],"title":"1. Introduction"},{"refs":[{"id":"ref-for-custom-property\u2463"},{"id":"ref-for-custom-property\u2464"},{"id":"ref-for-custom-property\u2465"}],"title":"2. Defining Custom Functions"},{"refs":[{"id":"ref-for-custom-property\u2466"}],"title":"2.1.2. \nThe Function Body"},{"refs":[{"id":"ref-for-custom-property\u2467"},{"id":"ref-for-custom-property\u2468"},{"id":"ref-for-custom-property\u2460\u24ea"},{"id":"ref-for-custom-property\u2460\u2460"}],"title":"2.3. Arguments & Local Variables"},{"refs":[{"id":"ref-for-custom-property\u2460\u2461"}],"title":"3. Using Custom Functions"},{"refs":[{"id":"ref-for-custom-property\u2460\u2462"},{"id":"ref-for-custom-property\u2460\u2463"},{"id":"ref-for-custom-property\u2460\u2464"},{"id":"ref-for-custom-property\u2460\u2465"},{"id":"ref-for-custom-property\u2460\u2466"},{"id":"ref-for-custom-property\u2460\u2467"},{"id":"ref-for-custom-property\u2460\u2468"}],"title":"3.1. Evaluating Custom Functions"},{"refs":[{"id":"ref-for-custom-property\u2461\u24ea"},{"id":"ref-for-custom-property\u2461\u2460"},{"id":"ref-for-custom-property\u2461\u2461"},{"id":"ref-for-custom-property\u2461\u2462"},{"id":"ref-for-custom-property\u2461\u2463"}],"title":"3.2. Cycles"}],"url":"https://drafts.csswg.org/css-variables-2/#custom-property"}, "1cf918c1": {"dfnID":"1cf918c1","dfnText":"specified value","external":true,"refSections":[{"refs":[{"id":"ref-for-specified-value"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-cascade-5/#specified-value"}, "21ecf38f": {"dfnID":"21ecf38f","dfnText":"PutForwards","external":true,"refSections":[{"refs":[{"id":"ref-for-PutForwards"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://webidl.spec.whatwg.org/#PutForwards"}, "2485e0d1": {"dfnID":"2485e0d1","dfnText":"CSSGroupingRule","external":true,"refSections":[{"refs":[{"id":"ref-for-cssgroupingrule"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"https://drafts.csswg.org/cssom-1/#cssgroupingrule"}, "29c3f2fe": {"dfnID":"29c3f2fe","dfnText":"computed flag","external":true,"refSections":[{"refs":[{"id":"ref-for-cssstyledeclaration-computed-flag"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-computed-flag"}, "2c2c4b46": {"dfnID":"2c2c4b46","dfnText":"serialize a CSS declaration block","external":true,"refSections":[{"refs":[{"id":"ref-for-serialize-a-css-declaration-block"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#serialize-a-css-declaration-block"}, "2c4af168": {"dfnID":"2c4af168","dfnText":"LegacyNullToEmptyString","external":true,"refSections":[{"refs":[{"id":"ref-for-LegacyNullToEmptyString"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://webidl.spec.whatwg.org/#LegacyNullToEmptyString"}, "346d2bb2": {"dfnID":"346d2bb2","dfnText":"arbitrary substitution function","external":true,"refSections":[{"refs":[{"id":"ref-for-arbitrary-substitution-function"}],"title":"2. Defining Custom Functions"},{"refs":[{"id":"ref-for-arbitrary-substitution-function\u2460"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-values-5/#arbitrary-substitution-function"}, "358fd6ff": {"dfnID":"358fd6ff","dfnText":"CSS-wide keywords","external":true,"refSections":[{"refs":[{"id":"ref-for-css-wide-keywords"},{"id":"ref-for-css-wide-keywords\u2460"},{"id":"ref-for-css-wide-keywords\u2461"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-values-4/#css-wide-keywords"}, "3a1154bf": {"dfnID":"3a1154bf","dfnText":"featureless","external":true,"refSections":[{"refs":[{"id":"ref-for-featureless"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/selectors-4/#featureless"}, "4013a022": {"dfnID":"4013a022","dfnText":"this","external":true,"refSections":[{"refs":[{"id":"ref-for-this"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://webidl.spec.whatwg.org/#this"}, "4bcd07f8": {"dfnID":"4bcd07f8","dfnText":"<declaration-rule-list>","external":true,"refSections":[{"refs":[{"id":"ref-for-typedef-declaration-rule-list"}],"title":"2.1. The @function Rule"}],"url":"https://drafts.csswg.org/css-syntax-3/#typedef-declaration-rule-list"}, "4c50974c": {"dfnID":"4c50974c","dfnText":"arbitrary substitution","external":true,"refSections":[{"refs":[{"id":"ref-for-substitute-arbitrary-substitution-function"}],"title":"2. Defining Custom Functions"},{"refs":[{"id":"ref-for-substitute-arbitrary-substitution-function\u2460"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-values-5/#substitute-arbitrary-substitution-function"}, "4d7d3dcd": {"dfnID":"4d7d3dcd","dfnText":"initial","external":true,"refSections":[{"refs":[{"id":"ref-for-valdef-all-initial"}],"title":"2.3. Arguments & Local Variables"},{"refs":[{"id":"ref-for-valdef-all-initial\u2460"},{"id":"ref-for-valdef-all-initial\u2461"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-cascade-5/#valdef-all-initial"}, "4ecd1e40": {"dfnID":"4ecd1e40","dfnText":"@container","external":true,"refSections":[{"refs":[{"id":"ref-for-at-ruledef-container"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-conditional-5/#at-ruledef-container"}, "537cf076": {"dfnID":"537cf076","dfnText":"?","external":true,"refSections":[{"refs":[{"id":"ref-for-mult-opt"},{"id":"ref-for-mult-opt\u2460"},{"id":"ref-for-mult-opt\u2461"},{"id":"ref-for-mult-opt\u2462"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-mult-opt\u2463"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-mult-opt\u2464"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-values-4/#mult-opt"}, "54fd6ed6": {"dfnID":"54fd6ed6","dfnText":"invalid at computed-value time","external":true,"refSections":[{"refs":[{"id":"ref-for-invalid-at-computed-value-time"}],"title":"3. Using Custom Functions"},{"refs":[{"id":"ref-for-invalid-at-computed-value-time\u2460"}],"title":"3.2. Cycles"}],"url":"https://drafts.csswg.org/css-values-5/#invalid-at-computed-value-time"}, "57699934": {"dfnID":"57699934","dfnText":"attr()","external":true,"refSections":[{"refs":[{"id":"ref-for-funcdef-attr"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-values-5/#funcdef-attr"}, "5a58bbb0": {"dfnID":"5a58bbb0","dfnText":"style rule","external":true,"refSections":[{"refs":[{"id":"ref-for-style-rule"},{"id":"ref-for-style-rule\u2460"},{"id":"ref-for-style-rule\u2461"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-syntax-3/#style-rule"}, "5f1b7f60": {"dfnID":"5f1b7f60","dfnText":"@media","external":true,"refSections":[{"refs":[{"id":"ref-for-at-ruledef-media"}],"title":"2.1.2. \nThe Function Body"}],"url":"https://drafts.csswg.org/css-conditional-3/#at-ruledef-media"}, "5fced98b": {"dfnID":"5fced98b","dfnText":"CSSOMString","external":true,"refSections":[{"refs":[{"id":"ref-for-cssomstring"},{"id":"ref-for-cssomstring\u2460"},{"id":"ref-for-cssomstring\u2461"},{"id":"ref-for-cssomstring\u2462"},{"id":"ref-for-cssomstring\u2463"},{"id":"ref-for-cssomstring\u2464"},{"id":"ref-for-cssomstring\u2465"}],"title":"5.1. The CSSFunctionRule Interface"},{"refs":[{"id":"ref-for-cssomstring\u2466"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#cssomstring"}, "5fdd1729": {"dfnID":"5fdd1729","dfnText":"serialize a CSS value","external":true,"refSections":[{"refs":[{"id":"ref-for-serialize-a-css-value"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"https://drafts.csswg.org/cssom-1/#serialize-a-css-value"}, "68150e76": {"dfnID":"68150e76","dfnText":"*","external":true,"refSections":[{"refs":[{"id":"ref-for-mult-zero-plus"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-values-4/#mult-zero-plus"}, "68487d22": {"dfnID":"68487d22","dfnText":"#","external":true,"refSections":[{"refs":[{"id":"ref-for-mult-comma"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-mult-comma\u2460"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-values-4/#mult-comma"}, "6eabcb67": {"dfnID":"6eabcb67","dfnText":"readonly flag","external":true,"refSections":[{"refs":[{"id":"ref-for-cssstyledeclaration-readonly-flag"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-readonly-flag"}, "6ec67710": {"dfnID":"6ec67710","dfnText":"|","external":true,"refSections":[{"refs":[{"id":"ref-for-comb-one"}],"title":"2.1. The @function Rule"}],"url":"https://drafts.csswg.org/css-values-4/#comb-one"}, "778f8dbd": {"dfnID":"778f8dbd","dfnText":"tree-scoped name","external":true,"refSections":[{"refs":[{"id":"ref-for-css-tree-scoped-name"}],"title":"2.1.1. \nThe Function Preamble"}],"url":"https://drafts.csswg.org/css-scoping-1/#css-tree-scoped-name"}, "8056dead": {"dfnID":"8056dead","dfnText":"parent CSS rule","external":true,"refSections":[{"refs":[{"id":"ref-for-cssstyledeclaration-parent-css-rule"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-parent-css-rule"}, "8144e597": {"dfnID":"8144e597","dfnText":"<declaration-value>","external":true,"refSections":[{"refs":[{"id":"ref-for-typedef-declaration-value"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-typedef-declaration-value\u2460"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-typedef-declaration-value\u2461"},{"id":"ref-for-typedef-declaration-value\u2462"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value"}, "889e932f": {"dfnID":"889e932f","dfnText":"Exposed","external":true,"refSections":[{"refs":[{"id":"ref-for-Exposed"}],"title":"5.1. The CSSFunctionRule Interface"},{"refs":[{"id":"ref-for-Exposed\u2460"},{"id":"ref-for-Exposed\u2461"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://webidl.spec.whatwg.org/#Exposed"}, "8a427103": {"dfnID":"8a427103","dfnText":"<dashed-ident>","external":true,"refSections":[{"refs":[{"id":"ref-for-typedef-dashed-ident"}],"title":"2.1.1. \nThe Function Preamble"}],"url":"https://drafts.csswg.org/css-values-4/#typedef-dashed-ident"}, "8c57eaed": {"dfnID":"8c57eaed","dfnText":"serialize a CSS rule","external":true,"refSections":[{"refs":[{"id":"ref-for-serialize-a-css-rule"},{"id":"ref-for-serialize-a-css-rule\u2460"}],"title":"5.1. The CSSFunctionRule Interface"},{"refs":[{"id":"ref-for-serialize-a-css-rule\u2461"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#serialize-a-css-rule"}, "8ca32f09": {"dfnID":"8ca32f09","dfnText":"functional notation","external":true,"refSections":[{"refs":[{"id":"ref-for-functional-notation"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-values-4/#functional-notation"}, "983c572a": {"dfnID":"983c572a","dfnText":"universal syntax definition","external":true,"refSections":[{"refs":[{"id":"ref-for-universal-syntax-definition"}],"title":"3.1. Evaluating Custom Functions"},{"refs":[{"id":"ref-for-universal-syntax-definition\u2460"},{"id":"ref-for-universal-syntax-definition\u2461"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"https://drafts.css-houdini.org/css-properties-values-api-1/#universal-syntax-definition"}, "9cce47fd": {"dfnID":"9cce47fd","dfnText":"sequence","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-sequence"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"https://webidl.spec.whatwg.org/#idl-sequence"}, "9cd25054": {"dfnID":"9cd25054","dfnText":"computed value","external":true,"refSections":[{"refs":[{"id":"ref-for-computed-value"},{"id":"ref-for-computed-value\u2460"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-cascade-5/#computed-value"}, "a06e5a78": {"dfnID":"a06e5a78","dfnText":"CSS declaration block","external":true,"refSections":[{"refs":[{"id":"ref-for-css-declaration-block"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#css-declaration-block"}, "a5c91173": {"dfnID":"a5c91173","dfnText":"SameObject","external":true,"refSections":[{"refs":[{"id":"ref-for-SameObject"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://webidl.spec.whatwg.org/#SameObject"}, "a82a20ef": {"dfnID":"a82a20ef","dfnText":"CSSStyleDeclaration","external":true,"refSections":[{"refs":[{"id":"ref-for-cssstyledeclaration"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration"}, "af50aa62": {"dfnID":"af50aa62","dfnText":"<function-token>","external":true,"refSections":[{"refs":[{"id":"ref-for-typedef-function-token"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-typedef-function-token\u2460"},{"id":"ref-for-typedef-function-token\u2461"}],"title":"2.1.1. \nThe Function Preamble"}],"url":"https://drafts.csswg.org/css-syntax-3/#typedef-function-token"}, "at-ruledef-function": {"dfnID":"at-ruledef-function","dfnText":"@function","external":false,"refSections":[{"refs":[{"id":"ref-for-at-ruledef-function"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-at-ruledef-function\u2460"},{"id":"ref-for-at-ruledef-function\u2461"},{"id":"ref-for-at-ruledef-function\u2462"}],"title":"2.1.1. \nThe Function Preamble"},{"refs":[{"id":"ref-for-at-ruledef-function\u2463"},{"id":"ref-for-at-ruledef-function\u2464"}],"title":"2.1.2. \nThe Function Body"},{"refs":[{"id":"ref-for-at-ruledef-function\u2465"},{"id":"ref-for-at-ruledef-function\u2466"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-at-ruledef-function\u2467"},{"id":"ref-for-at-ruledef-function\u2468"},{"id":"ref-for-at-ruledef-function\u2460\u24ea"},{"id":"ref-for-at-ruledef-function\u2460\u2460"}],"title":"4.1. Conditional Rules"},{"refs":[{"id":"ref-for-at-ruledef-function\u2460\u2461"},{"id":"ref-for-at-ruledef-function\u2460\u2462"},{"id":"ref-for-at-ruledef-function\u2460\u2463"}],"title":"5.1. The CSSFunctionRule Interface"},{"refs":[{"id":"ref-for-at-ruledef-function\u2460\u2464"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"#at-ruledef-function"}, "b8de3fe5": {"dfnID":"b8de3fe5","dfnText":"equivalent token sequence","external":true,"refSections":[{"refs":[{"id":"ref-for-equivalent-token-sequence"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.css-houdini.org/css-properties-values-api-1/#equivalent-token-sequence"}, "bf3ca8a7": {"dfnID":"bf3ca8a7","dfnText":"conditional group rule","external":true,"refSections":[{"refs":[{"id":"ref-for-conditional-group-rule"}],"title":"2.1.2. \nThe Function Body"},{"refs":[{"id":"ref-for-conditional-group-rule\u2460"},{"id":"ref-for-conditional-group-rule\u2461"},{"id":"ref-for-conditional-group-rule\u2462"}],"title":"4.1. Conditional Rules"}],"url":"https://drafts.csswg.org/css-conditional-3/#conditional-group-rule"}, "c1c3d423": {"dfnID":"c1c3d423","dfnText":"substitute arbitrary substitution function","external":true,"refSections":[{"refs":[{"id":"ref-for-substitute-arbitrary-substitution-function"}],"title":"2. Defining Custom Functions"},{"refs":[{"id":"ref-for-substitute-arbitrary-substitution-function\u2460"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-values-5/#substitute-arbitrary-substitution-function"}, "c304f669": {"dfnID":"c304f669","dfnText":"tree-scoped reference","external":true,"refSections":[{"refs":[{"id":"ref-for-css-tree-scoped-reference"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-scoping-1/#css-tree-scoped-reference"}, "c388d253": {"dfnID":"c388d253","dfnText":"inherit","external":true,"refSections":[{"refs":[{"id":"ref-for-valdef-all-inherit"}],"title":"2.3. Arguments & Local Variables"},{"refs":[{"id":"ref-for-valdef-all-inherit\u2460"},{"id":"ref-for-valdef-all-inherit\u2461"},{"id":"ref-for-valdef-all-inherit\u2462"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-cascade-5/#valdef-all-inherit"}, "c475bc01": {"dfnID":"c475bc01","dfnText":"specified order","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-declarations-specified-order"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#concept-declarations-specified-order"}, "calling-context": {"dfnID":"calling-context","dfnText":"calling context","external":false,"refSections":[{"refs":[{"id":"ref-for-calling-context"},{"id":"ref-for-calling-context\u2460"},{"id":"ref-for-calling-context\u2461"},{"id":"ref-for-calling-context\u2462"},{"id":"ref-for-calling-context\u2463"}],"title":"3. Using Custom Functions"},{"refs":[{"id":"ref-for-calling-context\u2464"},{"id":"ref-for-calling-context\u2465"},{"id":"ref-for-calling-context\u2466"},{"id":"ref-for-calling-context\u2467"}],"title":"3.1. Evaluating Custom Functions"}],"url":"#calling-context"}, "calling-context-root-element": {"dfnID":"calling-context-root-element","dfnText":"root element","external":false,"refSections":[{"refs":[{"id":"ref-for-calling-context-root-element"}],"title":"3.1. Evaluating Custom Functions"}],"url":"#calling-context-root-element"}, "cccedd30": {"dfnID":"cccedd30","dfnText":"CSSNestedDeclarations","external":true,"refSections":[{"refs":[{"id":"ref-for-cssnesteddeclarations"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/css-nesting-1/#cssnesteddeclarations"}, "cfb5cfc9": {"dfnID":"cfb5cfc9","dfnText":"syntax definition","external":true,"refSections":[{"refs":[{"id":"ref-for-syntax-definition"},{"id":"ref-for-syntax-definition\u2460"}],"title":"2.1. The @function Rule"}],"url":"https://drafts.css-houdini.org/css-properties-values-api-1/#syntax-definition"}, "cssfunctiondeclarations": {"dfnID":"cssfunctiondeclarations","dfnText":"CSSFunctionDeclarations","external":false,"refSections":[{"refs":[{"id":"ref-for-cssfunctiondeclarations"},{"id":"ref-for-cssfunctiondeclarations\u2460"}],"title":"5.1. The CSSFunctionRule Interface"},{"refs":[{"id":"ref-for-cssfunctiondeclarations\u2461"},{"id":"ref-for-cssfunctiondeclarations\u2462"},{"id":"ref-for-cssfunctiondeclarations\u2463"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"#cssfunctiondeclarations"}, "cssfunctiondescriptors": {"dfnID":"cssfunctiondescriptors","dfnText":"CSSFunctionDescriptors","external":false,"refSections":[{"refs":[{"id":"ref-for-cssfunctiondescriptors"},{"id":"ref-for-cssfunctiondescriptors\u2460"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"#cssfunctiondescriptors"}, "cssfunctionrule": {"dfnID":"cssfunctionrule","dfnText":"CSSFunctionRule","external":false,"refSections":[{"refs":[{"id":"ref-for-cssfunctionrule"},{"id":"ref-for-cssfunctionrule\u2460"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#cssfunctionrule"}, "custom-function": {"dfnID":"custom-function","dfnText":"custom function","external":false,"refSections":[{"refs":[{"id":"ref-for-custom-function"},{"id":"ref-for-custom-function\u2460"},{"id":"ref-for-custom-function\u2461"}],"title":"1. Introduction"},{"refs":[{"id":"ref-for-custom-function\u2462"},{"id":"ref-for-custom-function\u2463"},{"id":"ref-for-custom-function\u2464"}],"title":"2. Defining Custom Functions"},{"refs":[{"id":"ref-for-custom-function\u2465"}],"title":"2.1.1. \nThe Function Preamble"},{"refs":[{"id":"ref-for-custom-function\u2466"},{"id":"ref-for-custom-function\u2467"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-custom-function\u2468"},{"id":"ref-for-custom-function\u2460\u24ea"},{"id":"ref-for-custom-function\u2460\u2460"}],"title":"2.3. Arguments & Local Variables"},{"refs":[{"id":"ref-for-custom-function\u2460\u2461"},{"id":"ref-for-custom-function\u2460\u2462"},{"id":"ref-for-custom-function\u2460\u2463"},{"id":"ref-for-custom-function\u2460\u2464"},{"id":"ref-for-custom-function\u2460\u2465"}],"title":"3. Using Custom Functions"},{"refs":[{"id":"ref-for-custom-function\u2460\u2466"}],"title":"3.1. Evaluating Custom Functions"},{"refs":[{"id":"ref-for-custom-function\u2460\u2467"},{"id":"ref-for-custom-function\u2460\u2468"},{"id":"ref-for-custom-function\u2461\u24ea"},{"id":"ref-for-custom-function\u2461\u2460"},{"id":"ref-for-custom-function\u2461\u2461"},{"id":"ref-for-custom-function\u2461\u2462"}],"title":"3.2. Cycles"},{"refs":[{"id":"ref-for-custom-function\u2461\u2463"}],"title":"4. Execution Model of Custom Functions"},{"refs":[{"id":"ref-for-custom-function\u2461\u2464"},{"id":"ref-for-custom-function\u2461\u2465"},{"id":"ref-for-custom-function\u2461\u2466"},{"id":"ref-for-custom-function\u2461\u2467"},{"id":"ref-for-custom-function\u2461\u2468"},{"id":"ref-for-custom-function\u2462\u24ea"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#custom-function"}, "custom-function-function-body": {"dfnID":"custom-function-function-body","dfnText":"function body","external":false,"refSections":[{"refs":[{"id":"ref-for-custom-function-function-body"},{"id":"ref-for-custom-function-function-body\u2460"}],"title":"2.3. Arguments & Local Variables"},{"refs":[{"id":"ref-for-custom-function-function-body\u2461"}],"title":"3. Using Custom Functions"},{"refs":[{"id":"ref-for-custom-function-function-body\u2462"}],"title":"3.1. Evaluating Custom Functions"}],"url":"#custom-function-function-body"}, "custom-function-return-type": {"dfnID":"custom-function-return-type","dfnText":"return type","external":false,"refSections":[{"refs":[{"id":"ref-for-custom-function-return-type"},{"id":"ref-for-custom-function-return-type\u2460"}],"title":"2.1.1. \nThe Function Preamble"},{"refs":[{"id":"ref-for-custom-function-return-type\u2461"},{"id":"ref-for-custom-function-return-type\u2462"}],"title":"3.1. Evaluating Custom Functions"},{"refs":[{"id":"ref-for-custom-function-return-type\u2463"},{"id":"ref-for-custom-function-return-type\u2464"},{"id":"ref-for-custom-function-return-type\u2465"},{"id":"ref-for-custom-function-return-type\u2466"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#custom-function-return-type"}, "d1c0f823": {"dfnID":"d1c0f823","dfnText":"custom property registration","external":true,"refSections":[{"refs":[{"id":"ref-for-custom-property-registration"},{"id":"ref-for-custom-property-registration\u2460"},{"id":"ref-for-custom-property-registration\u2461"},{"id":"ref-for-custom-property-registration\u2462"},{"id":"ref-for-custom-property-registration\u2463"},{"id":"ref-for-custom-property-registration\u2464"},{"id":"ref-for-custom-property-registration\u2465"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration"}, "d309d3f4": {"dfnID":"d309d3f4","dfnText":"inherited value","external":true,"refSections":[{"refs":[{"id":"ref-for-inherited-value"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-cascade-5/#inherited-value"}, "dbba942a": {"dfnID":"dbba942a","dfnText":"var()","external":true,"refSections":[{"refs":[{"id":"ref-for-funcdef-var"},{"id":"ref-for-funcdef-var\u2460"}],"title":"2. Defining Custom Functions"},{"refs":[{"id":"ref-for-funcdef-var\u2461"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-funcdef-var\u2462"}],"title":"2.3. Arguments & Local Variables"},{"refs":[{"id":"ref-for-funcdef-var\u2463"},{"id":"ref-for-funcdef-var\u2464"},{"id":"ref-for-funcdef-var\u2465"}],"title":"3. Using Custom Functions"},{"refs":[{"id":"ref-for-funcdef-var\u2466"}],"title":"3.2. Cycles"}],"url":"https://drafts.csswg.org/css-variables-2/#funcdef-var"}, "default-value": {"dfnID":"default-value","dfnText":"default value","external":false,"refSections":[{"refs":[{"id":"ref-for-default-value"}],"title":"3.1. Evaluating Custom Functions"},{"refs":[{"id":"ref-for-default-value\u2460"},{"id":"ref-for-default-value\u2461"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#default-value"}, "descdef-function-result": {"dfnID":"descdef-function-result","dfnText":"result","external":false,"refSections":[{"refs":[{"id":"ref-for-descdef-function-result"},{"id":"ref-for-descdef-function-result\u2460"}],"title":"2.1.2. \nThe Function Body"},{"refs":[{"id":"ref-for-descdef-function-result\u2461"},{"id":"ref-for-descdef-function-result\u2462"},{"id":"ref-for-descdef-function-result\u2463"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-descdef-function-result\u2464"},{"id":"ref-for-descdef-function-result\u2465"},{"id":"ref-for-descdef-function-result\u2466"},{"id":"ref-for-descdef-function-result\u2467"},{"id":"ref-for-descdef-function-result\u2468"},{"id":"ref-for-descdef-function-result\u2460\u24ea"},{"id":"ref-for-descdef-function-result\u2460\u2460"}],"title":"3.1. Evaluating Custom Functions"},{"refs":[{"id":"ref-for-descdef-function-result\u2460\u2461"},{"id":"ref-for-descdef-function-result\u2460\u2462"}],"title":"4. Execution Model of Custom Functions"},{"refs":[{"id":"ref-for-descdef-function-result\u2460\u2463"},{"id":"ref-for-descdef-function-result\u2460\u2464"}],"title":"4.1. Conditional Rules"}],"url":"#descdef-function-result"}, "dfd120f7": {"dfnID":"dfd120f7","dfnText":"declaration","external":true,"refSections":[{"refs":[{"id":"ref-for-declaration"}],"title":"3.2. Cycles"},{"refs":[{"id":"ref-for-declaration\u2460"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/css-syntax-3/#declaration"}, "dictdef-functionparameter": {"dfnID":"dictdef-functionparameter","dfnText":"FunctionParameter","external":false,"refSections":[{"refs":[{"id":"ref-for-dictdef-functionparameter"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#dictdef-functionparameter"}, "dom-cssfunctiondeclarations-style": {"dfnID":"dom-cssfunctiondeclarations-style","dfnText":"style","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-cssfunctiondeclarations-style"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"#dom-cssfunctiondeclarations-style"}, "dom-cssfunctiondescriptors-result": {"dfnID":"dom-cssfunctiondescriptors-result","dfnText":"result","external":false,"refSections":[],"url":"#dom-cssfunctiondescriptors-result"}, "dom-cssfunctionrule-getparameters": {"dfnID":"dom-cssfunctionrule-getparameters","dfnText":"getParameters","external":false,"refSections":[],"url":"#dom-cssfunctionrule-getparameters"}, "dom-cssfunctionrule-name": {"dfnID":"dom-cssfunctionrule-name","dfnText":"name","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-cssfunctionrule-name"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#dom-cssfunctionrule-name"}, "dom-cssfunctionrule-returntype": {"dfnID":"dom-cssfunctionrule-returntype","dfnText":"returnType","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-cssfunctionrule-returntype"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#dom-cssfunctionrule-returntype"}, "dom-functionparameter-defaultvalue": {"dfnID":"dom-functionparameter-defaultvalue","dfnText":"defaultValue","external":false,"refSections":[],"url":"#dom-functionparameter-defaultvalue"}, "dom-functionparameter-name": {"dfnID":"dom-functionparameter-name","dfnText":"name","external":false,"refSections":[],"url":"#dom-functionparameter-name"}, "dom-functionparameter-type": {"dfnID":"dom-functionparameter-type","dfnText":"type","external":false,"refSections":[],"url":"#dom-functionparameter-type"}, "e4ffca7f": {"dfnID":"e4ffca7f","dfnText":"declarations","external":true,"refSections":[{"refs":[{"id":"ref-for-cssstyledeclaration-declarations"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-declarations"}, "e55dd7f2": {"dfnID":"e55dd7f2","dfnText":"<custom-property-name>","external":true,"refSections":[{"refs":[{"id":"ref-for-typedef-custom-property-name"},{"id":"ref-for-typedef-custom-property-name\u2460"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-typedef-custom-property-name\u2461"}],"title":"2.1.1. \nThe Function Preamble"}],"url":"https://drafts.csswg.org/css-variables-2/#typedef-custom-property-name"}, "eab73120": {"dfnID":"eab73120","dfnText":"owner node","external":true,"refSections":[{"refs":[{"id":"ref-for-cssstyledeclaration-owner-node"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-owner-node"}, "eb374cfb": {"dfnID":"eb374cfb","dfnText":"<syntax-component>","external":true,"refSections":[{"refs":[{"id":"ref-for-typedef-syntax-component"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-typedef-syntax-component\u2460"}],"title":"2.1.1. \nThe Function Preamble"},{"refs":[{"id":"ref-for-typedef-syntax-component\u2461"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"https://drafts.csswg.org/css-values-5/#typedef-syntax-component"}, "eb7e3851": {"dfnID":"eb7e3851","dfnText":"guaranteed-invalid value","external":true,"refSections":[{"refs":[{"id":"ref-for-guaranteed-invalid-value"}],"title":"2.1.2. \nThe Function Body"},{"refs":[{"id":"ref-for-guaranteed-invalid-value\u2460"},{"id":"ref-for-guaranteed-invalid-value\u2461"},{"id":"ref-for-guaranteed-invalid-value\u2462"},{"id":"ref-for-guaranteed-invalid-value\u2463"}],"title":"3.1. Evaluating Custom Functions"}],"url":"https://drafts.csswg.org/css-variables-2/#guaranteed-invalid-value"}, "ebaeb088": {"dfnID":"ebaeb088","dfnText":"CSSRule","external":true,"refSections":[{"refs":[{"id":"ref-for-cssrule"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"https://drafts.csswg.org/cssom-1/#cssrule"}, "ec52b7f5": {"dfnID":"ec52b7f5","dfnText":"nested group rules","external":true,"refSections":[{"refs":[{"id":"ref-for-nested-group-rules"},{"id":"ref-for-nested-group-rules\u2460"}],"title":"4.1. Conditional Rules"}],"url":"https://drafts.csswg.org/css-nesting-1/#nested-group-rules"}, "evaluate-a-custom-function": {"dfnID":"evaluate-a-custom-function","dfnText":"evaluate a custom function","external":false,"refSections":[{"refs":[{"id":"ref-for-evaluate-a-custom-function"}],"title":"2.1.2. \nThe Function Body"},{"refs":[{"id":"ref-for-evaluate-a-custom-function\u2460"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-evaluate-a-custom-function\u2461"}],"title":"3. Using Custom Functions"}],"url":"#evaluate-a-custom-function"}, "f70b2903": {"dfnID":"f70b2903","dfnText":"comma-containing productions","external":true,"refSections":[{"refs":[{"id":"ref-for-comma-containing-productions"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-values-5/#comma-containing-productions"}, "f96aa907": {"dfnID":"f96aa907","dfnText":"serialize an identifier","external":true,"refSections":[{"refs":[{"id":"ref-for-serialize-an-identifier"},{"id":"ref-for-serialize-an-identifier\u2460"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"https://drafts.csswg.org/cssom-1/#serialize-an-identifier"}, "fa19c68e": {"dfnID":"fa19c68e","dfnText":"@keyframes","external":true,"refSections":[{"refs":[{"id":"ref-for-at-ruledef-keyframes"}],"title":"3. Using Custom Functions"}],"url":"https://drafts.csswg.org/css-animations-1/#at-ruledef-keyframes"}, "funcdef-function-type": {"dfnID":"funcdef-function-type","dfnText":"<type()>","external":false,"refSections":[{"refs":[{"id":"ref-for-funcdef-function-type"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-funcdef-function-type\u2460"},{"id":"ref-for-funcdef-function-type\u2461"}],"title":"2.1.1. \nThe Function Preamble"}],"url":"#funcdef-function-type"}, "function-parameter": {"dfnID":"function-parameter","dfnText":"function parameter","external":false,"refSections":[{"refs":[{"id":"ref-for-function-parameter"}],"title":"2. Defining Custom Functions"},{"refs":[{"id":"ref-for-function-parameter\u2460"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-function-parameter\u2461"},{"id":"ref-for-function-parameter\u2462"},{"id":"ref-for-function-parameter\u2463"}],"title":"2.1.1. \nThe Function Preamble"},{"refs":[{"id":"ref-for-function-parameter\u2464"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-function-parameter\u2465"},{"id":"ref-for-function-parameter\u2466"},{"id":"ref-for-function-parameter\u2467"}],"title":"2.3. Arguments & Local Variables"},{"refs":[{"id":"ref-for-function-parameter\u2468"},{"id":"ref-for-function-parameter\u2460\u24ea"},{"id":"ref-for-function-parameter\u2460\u2460"},{"id":"ref-for-function-parameter\u2460\u2461"},{"id":"ref-for-function-parameter\u2460\u2462"}],"title":"3.1. Evaluating Custom Functions"},{"refs":[{"id":"ref-for-function-parameter\u2460\u2463"}],"title":"3.2. Cycles"},{"refs":[{"id":"ref-for-function-parameter\u2460\u2464"},{"id":"ref-for-function-parameter\u2460\u2465"},{"id":"ref-for-function-parameter\u2460\u2466"},{"id":"ref-for-function-parameter\u2460\u2467"},{"id":"ref-for-function-parameter\u2460\u2468"},{"id":"ref-for-function-parameter\u2461\u24ea"},{"id":"ref-for-function-parameter\u2461\u2460"},{"id":"ref-for-function-parameter\u2461\u2461"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#function-parameter"}, "local-variables": {"dfnID":"local-variables","dfnText":"local variables","external":false,"refSections":[{"refs":[{"id":"ref-for-local-variables"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-local-variables\u2460"},{"id":"ref-for-local-variables\u2461"},{"id":"ref-for-local-variables\u2462"},{"id":"ref-for-local-variables\u2463"},{"id":"ref-for-local-variables\u2464"}],"title":"2.3. Arguments & Local Variables"},{"refs":[{"id":"ref-for-local-variables\u2465"},{"id":"ref-for-local-variables\u2466"},{"id":"ref-for-local-variables\u2467"},{"id":"ref-for-local-variables\u2468"},{"id":"ref-for-local-variables\u2460\u24ea"}],"title":"3.2. Cycles"},{"refs":[{"id":"ref-for-local-variables\u2460\u2460"},{"id":"ref-for-local-variables\u2460\u2461"}],"title":"4. Execution Model of Custom Functions"},{"refs":[{"id":"ref-for-local-variables\u2460\u2462"}],"title":"4.1. Conditional Rules"},{"refs":[{"id":"ref-for-local-variables\u2460\u2463"}],"title":"5.2. The CSSFunctionDeclarations Interface"}],"url":"#local-variables"}, "parameter-type": {"dfnID":"parameter-type","dfnText":"parameter type","external":false,"refSections":[{"refs":[{"id":"ref-for-parameter-type"}],"title":"3.1. Evaluating Custom Functions"},{"refs":[{"id":"ref-for-parameter-type\u2460"},{"id":"ref-for-parameter-type\u2461"},{"id":"ref-for-parameter-type\u2462"},{"id":"ref-for-parameter-type\u2463"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#parameter-type"}, "resolve-function-styles": {"dfnID":"resolve-function-styles","dfnText":"resolve function styles","external":false,"refSections":[{"refs":[{"id":"ref-for-resolve-function-styles"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-resolve-function-styles\u2460"},{"id":"ref-for-resolve-function-styles\u2461"}],"title":"3.1. Evaluating Custom Functions"}],"url":"#resolve-function-styles"}, "serialize-a-css-type": {"dfnID":"serialize-a-css-type","dfnText":"serialize a CSS type","external":false,"refSections":[{"refs":[{"id":"ref-for-serialize-a-css-type"},{"id":"ref-for-serialize-a-css-type\u2460"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#serialize-a-css-type"}, "serialize-a-cssfunctionrule": {"dfnID":"serialize-a-cssfunctionrule","dfnText":"serialize a CSSFunctionRule","external":false,"refSections":[],"url":"#serialize-a-cssfunctionrule"}, "serialize-a-function-parameter": {"dfnID":"serialize-a-function-parameter","dfnText":"serialize a function parameter","external":false,"refSections":[{"refs":[{"id":"ref-for-serialize-a-function-parameter"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#serialize-a-function-parameter"}, "substitute-a-dashed-function": {"dfnID":"substitute-a-dashed-function","dfnText":"substitute a dashed function","external":false,"refSections":[{"refs":[{"id":"ref-for-substitute-a-dashed-function"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-substitute-a-dashed-function\u2460"},{"id":"ref-for-substitute-a-dashed-function\u2461"}],"title":"3. Using Custom Functions"}],"url":"#substitute-a-dashed-function"}, "typedef-css-type": {"dfnID":"typedef-css-type","dfnText":"<css-type>","external":false,"refSections":[{"refs":[{"id":"ref-for-typedef-css-type"},{"id":"ref-for-typedef-css-type\u2460"},{"id":"ref-for-typedef-css-type\u2461"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-typedef-css-type\u2462"},{"id":"ref-for-typedef-css-type\u2463"}],"title":"2.1.1. \nThe Function Preamble"},{"refs":[{"id":"ref-for-typedef-css-type\u2464"}],"title":"5.1. The CSSFunctionRule Interface"}],"url":"#typedef-css-type"}, "typedef-dashed-function": {"dfnID":"typedef-dashed-function","dfnText":"<dashed-function>","external":false,"refSections":[{"refs":[{"id":"ref-for-typedef-dashed-function"},{"id":"ref-for-typedef-dashed-function\u2460"}],"title":"2. Defining Custom Functions"},{"refs":[{"id":"ref-for-typedef-dashed-function\u2461"},{"id":"ref-for-typedef-dashed-function\u2462"}],"title":"2.2. The result Descriptor"},{"refs":[{"id":"ref-for-typedef-dashed-function\u2463"},{"id":"ref-for-typedef-dashed-function\u2464"},{"id":"ref-for-typedef-dashed-function\u2465"},{"id":"ref-for-typedef-dashed-function\u2466"},{"id":"ref-for-typedef-dashed-function\u2467"},{"id":"ref-for-typedef-dashed-function\u2468"},{"id":"ref-for-typedef-dashed-function\u2460\u24ea"},{"id":"ref-for-typedef-dashed-function\u2460\u2460"},{"id":"ref-for-typedef-dashed-function\u2460\u2461"},{"id":"ref-for-typedef-dashed-function\u2460\u2462"},{"id":"ref-for-typedef-dashed-function\u2460\u2463"},{"id":"ref-for-typedef-dashed-function\u2460\u2464"}],"title":"3. Using Custom Functions"},{"refs":[{"id":"ref-for-typedef-dashed-function\u2460\u2465"}],"title":"3.1. Evaluating Custom Functions"},{"refs":[{"id":"ref-for-typedef-dashed-function\u2460\u2466"},{"id":"ref-for-typedef-dashed-function\u2460\u2467"},{"id":"ref-for-typedef-dashed-function\u2460\u2468"}],"title":"3.2. Cycles"}],"url":"#typedef-dashed-function"}, "typedef-function-parameter": {"dfnID":"typedef-function-parameter","dfnText":"<function-parameter>","external":false,"refSections":[{"refs":[{"id":"ref-for-typedef-function-parameter"},{"id":"ref-for-typedef-function-parameter\u2460"}],"title":"2.1. The @function Rule"},{"refs":[{"id":"ref-for-typedef-function-parameter\u2461"}],"title":"2.1.1. \nThe Function Preamble"}],"url":"#typedef-function-parameter"}, }; document.addEventListener("DOMContentLoaded", ()=>{ genAllDfnPanels(); document.body.addEventListener("click", (e) => { // If not handled already, just hide all dfn panels. hideAllDfnPanels(); }); }); window.addEventListener("resize", () => { // Pin any visible dfn panel queryAll(".dfn-panel.on, .dfn-panel.activated").forEach(el=>positionDfnPanel(el)); }); function genAllDfnPanels() { for(const panelData of Object.values(dfnPanelData)) { const dfnID = panelData.dfnID; const dfn = document.getElementById(dfnID); if(!dfn) { console.log(`Can't find dfn#${dfnID}.`, panelData); continue; } dfn.panelData = panelData; insertDfnPopupAction(dfn); } } function genDfnPanel(dfn, { dfnID, url, dfnText, refSections, external }) { const dfnPanel = mk.aside({ class: "dfn-panel on", id: `infopanel-for-${dfnID}`, "data-for": dfnID, "aria-labelled-by":`infopaneltitle-for-${dfnID}`, }, mk.span({id:`infopaneltitle-for-${dfnID}`, style:"display:none"}, `Info about the '${dfnText}' ${external?"external":""} reference.`), mk.a({href:url, class:"dfn-link"}, url), refSections.length == 0 ? [] : mk.b({}, "Referenced in:"), mk.ul({}, ...refSections.map(section=> mk.li({}, ...section.refs.map((ref, refI)=> [ mk.a({ href: `#${ref.id}` }, (refI == 0) ? section.title : `(${refI + 1})` ), " ", ] ), ), ), ), genLinkingSyntaxes(dfn), ); dfnPanel.addEventListener('click', (event) => { if (event.target.nodeName == 'A') { scrollToTargetAndHighlight(event); pinDfnPanel(dfnPanel); } event.stopPropagation(); refocusOnTarget(event); }); dfnPanel.addEventListener('keydown', (event) => { if(event.keyCode == 27) { // Escape key hideDfnPanel({dfnPanel}); event.stopPropagation(); event.preventDefault(); } }); dfnPanel.dfn = dfn; dfn.dfnPanel = dfnPanel; return dfnPanel; } function hideAllDfnPanels() { // Delete the currently-active dfn panel. queryAll(".dfn-panel").forEach(dfnPanel=>hideDfnPanel({dfnPanel})); } function showDfnPanel(dfn) { hideAllDfnPanels(); // Only display one at a time. dfn.setAttribute("aria-expanded", "true"); const dfnPanel = genDfnPanel(dfn, dfn.panelData); // Give the dfn a unique tabindex, and then // give all the tabbable panel bits successive indexes. let tabIndex = 100; dfn.tabIndex = tabIndex++; const tabbable = dfnPanel.querySelectorAll(":is(a, button)"); for (const el of tabbable) { el.tabIndex = tabIndex++; } append(document.body, dfnPanel); positionDfnPanel(dfnPanel); } function positionDfnPanel(dfnPanel) { const dfn = dfnPanel.dfn; const dfnPos = getBounds(dfn); dfnPanel.style.top = dfnPos.bottom + "px"; dfnPanel.style.left = dfnPos.left + "px"; const panelPos = dfnPanel.getBoundingClientRect(); const panelMargin = 8; const maxRight = document.body.parentNode.clientWidth - panelMargin; if (panelPos.right > maxRight) { const overflowAmount = panelPos.right - maxRight; const newLeft = Math.max(panelMargin, dfnPos.left - overflowAmount); dfnPanel.style.left = newLeft + "px"; } } function pinDfnPanel(dfnPanel) { // Switch it to "activated" state, which pins it. dfnPanel.classList.add("activated"); dfnPanel.style.position = "fixed"; dfnPanel.style.left = null; dfnPanel.style.top = null; } function hideDfnPanel({dfn, dfnPanel}) { if(!dfnPanel) dfnPanel = dfn.dfnPanel; if(!dfn) dfn = dfnPanel.dfn; dfn.dfnPanel = undefined; dfnPanel.dfn = undefined; dfn.setAttribute("aria-expanded", "false"); dfn.tabIndex = undefined; dfnPanel.remove() } function toggleDfnPanel(dfn) { if(dfn.dfnPanel) { hideDfnPanel(dfn); } else { showDfnPanel(dfn); } } function insertDfnPopupAction(dfn) { dfn.setAttribute('role', 'button'); dfn.setAttribute('aria-expanded', 'false') dfn.tabIndex = 0; dfn.classList.add('has-dfn-panel'); dfn.addEventListener('click', (event) => { toggleDfnPanel(dfn); event.stopPropagation(); }); dfn.addEventListener('keypress', (event) => { const kc = event.keyCode; // 32->Space, 13->Enter if(kc == 32 || kc == 13) { toggleDfnPanel(dfn); event.stopPropagation(); event.preventDefault(); } }); } function refocusOnTarget(event) { const target = event.target; setTimeout(() => { // Refocus on the event.target element. // This is needed after browser scrolls to the destination. target.focus(); }); } // TODO: shared util // Returns the root-level absolute position {left and top} of element. function getBounds(el, relativeTo=document.body) { const relativeRect = relativeTo.getBoundingClientRect(); const elRect = el.getBoundingClientRect(); const top = elRect.top - relativeRect.top; const left = elRect.left - relativeRect.left; return { top, left, bottom: top + elRect.height, right: left + elRect.width, } } function scrollToTargetAndHighlight(event) { let hash = event.target.hash; if (hash) { hash = decodeURIComponent(hash.substring(1)); const dest = document.getElementById(hash); if (dest) { dest.classList.add('highlighted'); setTimeout(() => dest.classList.remove('highlighted'), 1000); } } } // Functions, divided by link type, that wrap an autolink's // contents with the appropriate outer syntax. // Alternately, a string naming another type they format // the same as. function needsFor(type) { switch(type) { case "descriptor": case "value": case "element-attr": case "attr-value": case "element-state": case "method": case "constructor": case "argument": case "attribute": case "const": case "dict-member": case "event": case "enum-value": case "stringifier": case "serializer": case "iterator": case "maplike": case "setlike": case "state": case "mode": case "context": case "facet": return true; default: return false; } } function refusesFor(type) { switch(type) { case "property": case "element": case "interface": case "namespace": case "callback": case "dictionary": case "enum": case "exception": case "typedef": case "http-header": case "permission": return true; default: return false; } } function linkFormatterFromType(type) { switch(type) { case 'scheme': case 'permission': case 'dfn': return (text) => `[=${text}=]`; case 'abstract-op': return (text) => `[\$${text}\$]`; case 'function': case 'at-rule': case 'selector': case 'value': return (text) => `''${text}''`; case 'http-header': return (text) => `[:${text}:]`; case 'interface': case 'constructor': case 'method': case 'argument': case 'attribute': case 'callback': case 'dictionary': case 'dict-member': case 'enum': case 'enum-value': case 'exception': case 'const': case 'typedef': case 'stringifier': case 'serializer': case 'iterator': case 'maplike': case 'setlike': case 'extended-attribute': case 'event': case 'idl': return (text) => `{{${text}}}`; case 'element-state': case 'element-attr': case 'attr-value': case 'element': return (element) => `<{${element}}>`; case 'grammar': return (text) => `${text} (within a <pre class=prod>)`; case 'type': return (text)=> `<<${text}>>`; case 'descriptor': case 'property': return (text) => `'${text}'`; default: return; }; }; function genLinkingSyntaxes(dfn) { if(dfn.tagName != "DFN") return; const type = dfn.getAttribute('data-dfn-type'); if(!type) { console.log(`<dfn> doesn't have a data-dfn-type:`, dfn); return []; } // Return a function that wraps link text based on the type const linkFormatter = linkFormatterFromType(type); if(!linkFormatter) { console.log(`<dfn> has an unknown data-dfn-type:`, dfn); return []; } let ltAlts; if(dfn.hasAttribute('data-lt')) { ltAlts = dfn.getAttribute('data-lt') .split("|") .map(x=>x.trim()); } else { ltAlts = [dfn.textContent.trim()]; } if(type == "type") { // lt of "<foo>", but "foo" is the interior; // <<foo/bar>> is how you write it with a for, // not <foo/<bar>> or whatever. for(var i = 0; i < ltAlts.length; i++) { const lt = ltAlts[i]; const match = /<(.*)>/.exec(lt); if(match) { ltAlts[i] = match[1]; } } } let forAlts; if(dfn.hasAttribute('data-dfn-for')) { forAlts = dfn.getAttribute('data-dfn-for') .split(",") .map(x=>x.trim()); } else { forAlts = ['']; } let linkingSyntaxes = []; if(!needsFor(type)) { for(const lt of ltAlts) { linkingSyntaxes.push(linkFormatter(lt)); } } if(!refusesFor(type)) { for(const f of forAlts) { linkingSyntaxes.push(linkFormatter(`${f}/${ltAlts[0]}`)) } } return [ mk.b({}, 'Possible linking syntaxes:'), mk.ul({}, ...linkingSyntaxes.map(link => { const copyLink = async () => await navigator.clipboard.writeText(link); return mk.li({}, mk.div({ class: 'link-item' }, mk.button({ class: 'copy-icon', title: 'Copy', type: 'button', _onclick: copyLink, tabindex: 0, }, mk.span({ class: 'icon' }) ), mk.span({}, link) ) ); }) ) ]; } } </script> <script>/* Boilerplate: script-ref-hints */ "use strict"; { let refsData = { "#at-ruledef-function": {"displayText":"@function","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"@function","type":"at-rule","url":"#at-ruledef-function"}, "#calling-context": {"displayText":"calling context","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"calling context","type":"dfn","url":"#calling-context"}, "#calling-context-root-element": {"displayText":"root element","export":true,"for_":["calling context"],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"root element","type":"dfn","url":"#calling-context-root-element"}, "#cssfunctiondeclarations": {"displayText":"CSSFunctionDeclarations","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"CSSFunctionDeclarations","type":"interface","url":"#cssfunctiondeclarations"}, "#cssfunctiondescriptors": {"displayText":"CSSFunctionDescriptors","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"CSSFunctionDescriptors","type":"interface","url":"#cssfunctiondescriptors"}, "#cssfunctionrule": {"displayText":"CSSFunctionRule","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"CSSFunctionRule","type":"interface","url":"#cssfunctionrule"}, "#custom-function": {"displayText":"custom function","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"custom function","type":"dfn","url":"#custom-function"}, "#custom-function-function-body": {"displayText":"function body","export":true,"for_":["custom function"],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"function body","type":"dfn","url":"#custom-function-function-body"}, "#custom-function-return-type": {"displayText":"return type","export":true,"for_":["custom function"],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"return type","type":"dfn","url":"#custom-function-return-type"}, "#default-value": {"displayText":"default value","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"default value","type":"dfn","url":"#default-value"}, "#descdef-function-result": {"displayText":"result","export":true,"for_":["@function"],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"result","type":"descriptor","url":"#descdef-function-result"}, "#dictdef-functionparameter": {"displayText":"FunctionParameter","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"FunctionParameter","type":"dictionary","url":"#dictdef-functionparameter"}, "#dom-cssfunctiondeclarations-style": {"displayText":"style","export":true,"for_":["CSSFunctionDeclarations"],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"style","type":"attribute","url":"#dom-cssfunctiondeclarations-style"}, "#dom-cssfunctionrule-name": {"displayText":"name","export":true,"for_":["CSSFunctionRule"],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"name","type":"attribute","url":"#dom-cssfunctionrule-name"}, "#dom-cssfunctionrule-returntype": {"displayText":"returnType","export":true,"for_":["CSSFunctionRule"],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"returnType","type":"attribute","url":"#dom-cssfunctionrule-returntype"}, "#evaluate-a-custom-function": {"displayText":"evaluate a custom function","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"evaluate a custom function","type":"dfn","url":"#evaluate-a-custom-function"}, "#funcdef-function-type": {"displayText":"type()","export":true,"for_":["@function"],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"type()","type":"function","url":"#funcdef-function-type"}, "#function-parameter": {"displayText":"function parameter","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"function parameter","type":"dfn","url":"#function-parameter"}, "#local-variables": {"displayText":"local variables","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"local variables","type":"dfn","url":"#local-variables"}, "#parameter-type": {"displayText":"parameter type","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"parameter type","type":"dfn","url":"#parameter-type"}, "#resolve-function-styles": {"displayText":"resolve function styles","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"resolve function styles","type":"dfn","url":"#resolve-function-styles"}, "#serialize-a-css-type": {"displayText":"serialize a css type","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"serialize a css type","type":"dfn","url":"#serialize-a-css-type"}, "#serialize-a-function-parameter": {"displayText":"serialize a function parameter","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"serialize a function parameter","type":"dfn","url":"#serialize-a-function-parameter"}, "#substitute-a-dashed-function": {"displayText":"substitute a dashed function","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"substitute a dashed function","type":"dfn","url":"#substitute-a-dashed-function"}, "#typedef-css-type": {"displayText":"<css-type>","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"<css-type>","type":"type","url":"#typedef-css-type"}, "#typedef-dashed-function": {"displayText":"<dashed-function>","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"<dashed-function>","type":"type","url":"#typedef-dashed-function"}, "#typedef-function-parameter": {"displayText":"<function-parameter>","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-mixins","spec":"css-mixins-1","status":"local","text":"<function-parameter>","type":"type","url":"#typedef-function-parameter"}, "https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration": {"displayText":"custom property registration","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-properties-values-api","spec":"css-properties-values-api-1","status":"current","text":"custom property registration","type":"dfn","url":"https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration"}, "https://drafts.css-houdini.org/css-properties-values-api-1/#equivalent-token-sequence": {"displayText":"equivalent token sequence","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-properties-values-api","spec":"css-properties-values-api-1","status":"current","text":"equivalent token sequence","type":"dfn","url":"https://drafts.css-houdini.org/css-properties-values-api-1/#equivalent-token-sequence"}, "https://drafts.css-houdini.org/css-properties-values-api-1/#syntax-definition": {"displayText":"syntax definition","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-properties-values-api","spec":"css-properties-values-api-1","status":"current","text":"syntax definition","type":"dfn","url":"https://drafts.css-houdini.org/css-properties-values-api-1/#syntax-definition"}, "https://drafts.css-houdini.org/css-properties-values-api-1/#universal-syntax-definition": {"displayText":"universal syntax definition","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-properties-values-api","spec":"css-properties-values-api-1","status":"current","text":"universal syntax definition","type":"dfn","url":"https://drafts.css-houdini.org/css-properties-values-api-1/#universal-syntax-definition"}, "https://drafts.csswg.org/css-animations-1/#at-ruledef-keyframes": {"displayText":"@keyframes","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-animations","spec":"css-animations-1","status":"current","text":"@keyframes","type":"at-rule","url":"https://drafts.csswg.org/css-animations-1/#at-ruledef-keyframes"}, "https://drafts.csswg.org/css-cascade-5/#computed-value": {"displayText":"computed value","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-cascade","spec":"css-cascade-5","status":"current","text":"computed value","type":"dfn","url":"https://drafts.csswg.org/css-cascade-5/#computed-value"}, "https://drafts.csswg.org/css-cascade-5/#inherited-value": {"displayText":"inherited value","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-cascade","spec":"css-cascade-5","status":"current","text":"inherited value","type":"dfn","url":"https://drafts.csswg.org/css-cascade-5/#inherited-value"}, "https://drafts.csswg.org/css-cascade-5/#specified-value": {"displayText":"specified value","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-cascade","spec":"css-cascade-5","status":"current","text":"specified value","type":"dfn","url":"https://drafts.csswg.org/css-cascade-5/#specified-value"}, "https://drafts.csswg.org/css-cascade-5/#valdef-all-inherit": {"displayText":"inherit","export":true,"for_":["all"],"level":"5","normative":true,"shortname":"css-cascade","spec":"css-cascade-5","status":"current","text":"inherit","type":"value","url":"https://drafts.csswg.org/css-cascade-5/#valdef-all-inherit"}, "https://drafts.csswg.org/css-cascade-5/#valdef-all-initial": {"displayText":"initial","export":true,"for_":["all"],"level":"5","normative":true,"shortname":"css-cascade","spec":"css-cascade-5","status":"current","text":"initial","type":"value","url":"https://drafts.csswg.org/css-cascade-5/#valdef-all-initial"}, "https://drafts.csswg.org/css-conditional-3/#at-ruledef-media": {"displayText":"@media","export":true,"for_":[],"level":"3","normative":true,"shortname":"css-conditional","spec":"css-conditional-3","status":"current","text":"@media","type":"at-rule","url":"https://drafts.csswg.org/css-conditional-3/#at-ruledef-media"}, "https://drafts.csswg.org/css-conditional-3/#conditional-group-rule": {"displayText":"conditional group rule","export":true,"for_":[],"level":"3","normative":true,"shortname":"css-conditional","spec":"css-conditional-3","status":"current","text":"conditional group rule","type":"dfn","url":"https://drafts.csswg.org/css-conditional-3/#conditional-group-rule"}, "https://drafts.csswg.org/css-conditional-5/#at-ruledef-container": {"displayText":"@container","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-conditional","spec":"css-conditional-5","status":"current","text":"@container","type":"at-rule","url":"https://drafts.csswg.org/css-conditional-5/#at-ruledef-container"}, "https://drafts.csswg.org/css-nesting-1/#cssnesteddeclarations": {"displayText":"CSSNestedDeclarations","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-nesting","spec":"css-nesting-1","status":"current","text":"CSSNestedDeclarations","type":"interface","url":"https://drafts.csswg.org/css-nesting-1/#cssnesteddeclarations"}, "https://drafts.csswg.org/css-nesting-1/#nested-group-rules": {"displayText":"nested group rules","export":true,"for_":[],"level":"1","normative":true,"shortname":"css-nesting","spec":"css-nesting-1","status":"current","text":"nested group rules","type":"dfn","url":"https://drafts.csswg.org/css-nesting-1/#nested-group-rules"}, "https://drafts.csswg.org/css-scoping-1/#css-tree-scoped-name": {"displayText":"tree-scoped name","export":true,"for_":["CSS"],"level":"1","normative":true,"shortname":"css-scoping","spec":"css-scoping-1","status":"current","text":"tree-scoped name","type":"dfn","url":"https://drafts.csswg.org/css-scoping-1/#css-tree-scoped-name"}, "https://drafts.csswg.org/css-scoping-1/#css-tree-scoped-reference": {"displayText":"tree-scoped reference","export":true,"for_":["CSS"],"level":"1","normative":true,"shortname":"css-scoping","spec":"css-scoping-1","status":"current","text":"tree-scoped reference","type":"dfn","url":"https://drafts.csswg.org/css-scoping-1/#css-tree-scoped-reference"}, "https://drafts.csswg.org/css-syntax-3/#declaration": {"displayText":"declaration","export":true,"for_":["CSS"],"level":"3","normative":true,"shortname":"css-syntax","spec":"css-syntax-3","status":"current","text":"declaration","type":"dfn","url":"https://drafts.csswg.org/css-syntax-3/#declaration"}, "https://drafts.csswg.org/css-syntax-3/#style-rule": {"displayText":"style rule","export":true,"for_":[],"level":"3","normative":true,"shortname":"css-syntax","spec":"css-syntax-3","status":"current","text":"style rule","type":"dfn","url":"https://drafts.csswg.org/css-syntax-3/#style-rule"}, "https://drafts.csswg.org/css-syntax-3/#typedef-declaration-rule-list": {"displayText":"<declaration-rule-list>","export":true,"for_":[],"level":"3","normative":true,"shortname":"css-syntax","spec":"css-syntax-3","status":"current","text":"<declaration-rule-list>","type":"type","url":"https://drafts.csswg.org/css-syntax-3/#typedef-declaration-rule-list"}, "https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value": {"displayText":"<declaration-value>","export":true,"for_":[],"level":"3","normative":true,"shortname":"css-syntax","spec":"css-syntax-3","status":"current","text":"<declaration-value>","type":"type","url":"https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value"}, "https://drafts.csswg.org/css-syntax-3/#typedef-function-token": {"displayText":"<function-token>","export":true,"for_":[],"level":"3","normative":true,"shortname":"css-syntax","spec":"css-syntax-3","status":"current","text":"<function-token>","type":"type","url":"https://drafts.csswg.org/css-syntax-3/#typedef-function-token"}, "https://drafts.csswg.org/css-values-4/#comb-one": {"displayText":"|","export":true,"for_":[],"level":"4","normative":true,"shortname":"css-values","spec":"css-values-4","status":"current","text":"|","type":"grammar","url":"https://drafts.csswg.org/css-values-4/#comb-one"}, "https://drafts.csswg.org/css-values-4/#css-wide-keywords": {"displayText":"CSS-wide keywords","export":true,"for_":[],"level":"4","normative":true,"shortname":"css-values","spec":"css-values-4","status":"current","text":"css-wide keywords","type":"dfn","url":"https://drafts.csswg.org/css-values-4/#css-wide-keywords"}, "https://drafts.csswg.org/css-values-4/#functional-notation": {"displayText":"functional notation","export":true,"for_":[],"level":"4","normative":true,"shortname":"css-values","spec":"css-values-4","status":"current","text":"functional notation","type":"dfn","url":"https://drafts.csswg.org/css-values-4/#functional-notation"}, "https://drafts.csswg.org/css-values-4/#mult-comma": {"displayText":"#","export":true,"for_":[],"level":"4","normative":true,"shortname":"css-values","spec":"css-values-4","status":"current","text":"#","type":"grammar","url":"https://drafts.csswg.org/css-values-4/#mult-comma"}, "https://drafts.csswg.org/css-values-4/#mult-opt": {"displayText":"?","export":true,"for_":[],"level":"4","normative":true,"shortname":"css-values","spec":"css-values-4","status":"current","text":"?","type":"grammar","url":"https://drafts.csswg.org/css-values-4/#mult-opt"}, "https://drafts.csswg.org/css-values-4/#mult-zero-plus": {"displayText":"*","export":true,"for_":[],"level":"4","normative":true,"shortname":"css-values","spec":"css-values-4","status":"current","text":"*","type":"grammar","url":"https://drafts.csswg.org/css-values-4/#mult-zero-plus"}, "https://drafts.csswg.org/css-values-4/#typedef-dashed-ident": {"displayText":"<dashed-ident>","export":true,"for_":[],"level":"4","normative":true,"shortname":"css-values","spec":"css-values-4","status":"current","text":"<dashed-ident>","type":"type","url":"https://drafts.csswg.org/css-values-4/#typedef-dashed-ident"}, "https://drafts.csswg.org/css-values-5/#arbitrary-substitution-function": {"displayText":"arbitrary substitution function","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-values","spec":"css-values-5","status":"current","text":"arbitrary substitution function","type":"dfn","url":"https://drafts.csswg.org/css-values-5/#arbitrary-substitution-function"}, "https://drafts.csswg.org/css-values-5/#comma-containing-productions": {"displayText":"comma-containing productions","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-values","spec":"css-values-5","status":"current","text":"comma-containing productions","type":"dfn","url":"https://drafts.csswg.org/css-values-5/#comma-containing-productions"}, "https://drafts.csswg.org/css-values-5/#funcdef-attr": {"displayText":"attr()","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-values","spec":"css-values-5","status":"current","text":"attr()","type":"function","url":"https://drafts.csswg.org/css-values-5/#funcdef-attr"}, "https://drafts.csswg.org/css-values-5/#invalid-at-computed-value-time": {"displayText":"invalid at computed-value time","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-values","spec":"css-values-5","status":"current","text":"invalid at computed-value time","type":"dfn","url":"https://drafts.csswg.org/css-values-5/#invalid-at-computed-value-time"}, "https://drafts.csswg.org/css-values-5/#substitute-arbitrary-substitution-function": {"displayText":"arbitrary substitution","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-values","spec":"css-values-5","status":"current","text":"arbitrary substitution","type":"dfn","url":"https://drafts.csswg.org/css-values-5/#substitute-arbitrary-substitution-function"}, "https://drafts.csswg.org/css-values-5/#typedef-syntax": {"displayText":"<syntax>","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-values","spec":"css-values-5","status":"current","text":"<syntax>","type":"type","url":"https://drafts.csswg.org/css-values-5/#typedef-syntax"}, "https://drafts.csswg.org/css-values-5/#typedef-syntax-combinator": {"displayText":"<syntax-combinator>","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-values","spec":"css-values-5","status":"current","text":"<syntax-combinator>","type":"type","url":"https://drafts.csswg.org/css-values-5/#typedef-syntax-combinator"}, "https://drafts.csswg.org/css-values-5/#typedef-syntax-component": {"displayText":"<syntax-component>","export":true,"for_":[],"level":"5","normative":true,"shortname":"css-values","spec":"css-values-5","status":"current","text":"<syntax-component>","type":"type","url":"https://drafts.csswg.org/css-values-5/#typedef-syntax-component"}, "https://drafts.csswg.org/css-variables-2/#custom-property": {"displayText":"custom property","export":true,"for_":[],"level":"2","normative":true,"shortname":"css-variables","spec":"css-variables-2","status":"current","text":"custom property","type":"dfn","url":"https://drafts.csswg.org/css-variables-2/#custom-property"}, "https://drafts.csswg.org/css-variables-2/#funcdef-var": {"displayText":"var()","export":true,"for_":[],"level":"2","normative":true,"shortname":"css-variables","spec":"css-variables-2","status":"current","text":"var()","type":"function","url":"https://drafts.csswg.org/css-variables-2/#funcdef-var"}, "https://drafts.csswg.org/css-variables-2/#guaranteed-invalid-value": {"displayText":"guaranteed-invalid value","export":true,"for_":[],"level":"2","normative":true,"shortname":"css-variables","spec":"css-variables-2","status":"current","text":"guaranteed-invalid value","type":"dfn","url":"https://drafts.csswg.org/css-variables-2/#guaranteed-invalid-value"}, "https://drafts.csswg.org/css-variables-2/#typedef-custom-property-name": {"displayText":"<custom-property-name>","export":true,"for_":[],"level":"2","normative":true,"shortname":"css-variables","spec":"css-variables-2","status":"current","text":"<custom-property-name>","type":"type","url":"https://drafts.csswg.org/css-variables-2/#typedef-custom-property-name"}, "https://drafts.csswg.org/cssom-1/#concept-declarations-specified-order": {"displayText":"specified order","export":false,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"specified order","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#concept-declarations-specified-order"}, "https://drafts.csswg.org/cssom-1/#css-declaration-block": {"displayText":"CSS declaration block","export":true,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"css declaration block","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#css-declaration-block"}, "https://drafts.csswg.org/cssom-1/#cssgroupingrule": {"displayText":"CSSGroupingRule","export":true,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"CSSGroupingRule","type":"interface","url":"https://drafts.csswg.org/cssom-1/#cssgroupingrule"}, "https://drafts.csswg.org/cssom-1/#cssomstring": {"displayText":"CSSOMString","export":true,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"CSSOMString","type":"interface","url":"https://drafts.csswg.org/cssom-1/#cssomstring"}, "https://drafts.csswg.org/cssom-1/#cssrule": {"displayText":"CSSRule","export":true,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"CSSRule","type":"interface","url":"https://drafts.csswg.org/cssom-1/#cssrule"}, "https://drafts.csswg.org/cssom-1/#cssstyledeclaration": {"displayText":"CSSStyleDeclaration","export":true,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"CSSStyleDeclaration","type":"interface","url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration"}, "https://drafts.csswg.org/cssom-1/#cssstyledeclaration-computed-flag": {"displayText":"computed flag","export":true,"for_":["CSSStyleDeclaration"],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"computed flag","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-computed-flag"}, "https://drafts.csswg.org/cssom-1/#cssstyledeclaration-declarations": {"displayText":"declarations","export":true,"for_":["CSSStyleDeclaration"],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"declarations","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-declarations"}, "https://drafts.csswg.org/cssom-1/#cssstyledeclaration-owner-node": {"displayText":"owner node","export":true,"for_":["CSSStyleDeclaration"],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"owner node","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-owner-node"}, "https://drafts.csswg.org/cssom-1/#cssstyledeclaration-parent-css-rule": {"displayText":"parent CSS rule","export":true,"for_":["CSSStyleDeclaration"],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"parent css rule","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-parent-css-rule"}, "https://drafts.csswg.org/cssom-1/#cssstyledeclaration-readonly-flag": {"displayText":"readonly flag","export":true,"for_":["CSSStyleDeclaration"],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"readonly flag","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#cssstyledeclaration-readonly-flag"}, "https://drafts.csswg.org/cssom-1/#serialize-a-css-declaration-block": {"displayText":"serialize a CSS declaration block","export":true,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"serialize a css declaration block","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#serialize-a-css-declaration-block"}, "https://drafts.csswg.org/cssom-1/#serialize-a-css-rule": {"displayText":"serialize a CSS rule","export":true,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"serialize a css rule","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#serialize-a-css-rule"}, "https://drafts.csswg.org/cssom-1/#serialize-a-css-value": {"displayText":"serialize a CSS value","export":true,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"serialize a css value","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#serialize-a-css-value"}, "https://drafts.csswg.org/cssom-1/#serialize-an-identifier": {"displayText":"serialize an identifier","export":true,"for_":[],"level":"1","normative":true,"shortname":"cssom","spec":"cssom-1","status":"current","text":"serialize an identifier","type":"dfn","url":"https://drafts.csswg.org/cssom-1/#serialize-an-identifier"}, "https://drafts.csswg.org/selectors-4/#featureless": {"displayText":"featureless","export":true,"for_":[],"level":"4","normative":true,"shortname":"selectors","spec":"selectors-4","status":"current","text":"featureless","type":"dfn","url":"https://drafts.csswg.org/selectors-4/#featureless"}, "https://webidl.spec.whatwg.org/#Exposed": {"displayText":"Exposed","export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"Exposed","type":"extended-attribute","url":"https://webidl.spec.whatwg.org/#Exposed"}, "https://webidl.spec.whatwg.org/#LegacyNullToEmptyString": {"displayText":"LegacyNullToEmptyString","export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"LegacyNullToEmptyString","type":"extended-attribute","url":"https://webidl.spec.whatwg.org/#LegacyNullToEmptyString"}, "https://webidl.spec.whatwg.org/#PutForwards": {"displayText":"PutForwards","export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"PutForwards","type":"extended-attribute","url":"https://webidl.spec.whatwg.org/#PutForwards"}, "https://webidl.spec.whatwg.org/#SameObject": {"displayText":"SameObject","export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"SameObject","type":"extended-attribute","url":"https://webidl.spec.whatwg.org/#SameObject"}, "https://webidl.spec.whatwg.org/#idl-sequence": {"displayText":"sequence","export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"sequence","type":"dfn","url":"https://webidl.spec.whatwg.org/#idl-sequence"}, "https://webidl.spec.whatwg.org/#this": {"displayText":"this","export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"this","type":"dfn","url":"https://webidl.spec.whatwg.org/#this"}, }; function mkRefHint(link, ref) { const linkText = link.textContent; let dfnTextElements = ''; if (ref.displayText.toLowerCase() != linkText.toLowerCase()) { // Give the original term if it's being displayed in a different way. // But allow casing differences, they're insignificant. dfnTextElements = mk.li({}, mk.b({}, "Term: "), mk.span({}, ref.displayText) ); } const forList = ref.for_; let forListElements; if(forList.length == 0) { forListElements = []; } else if(forList.length == 1) { forListElements = mk.li({}, mk.b({}, "For: "), mk.span({}, forList[0]), ); } else { forListElements = mk.li({}, mk.b({}, "For: "), mk.ul({}, ...forList.map(forItem => mk.li({}, mk.span({}, forItem) ), ), ), ); } const url = ref.url; const safeUrl = encodeURIComponent(url); const hintPanel = mk.aside({ class: "ref-hint", id: `ref-hint-for-${safeUrl}`, "data-for": url, "aria-labelled-by": `ref-hint-for-${safeUrl}`, }, mk.ul({}, dfnTextElements, mk.li({}, mk.b({}, "URL: "), mk.a({ href: url, class: "ref" }, url), ), mk.li({}, mk.b({}, "Type: "), mk.span({}, `${ref.type}`), ), mk.li({}, mk.b({}, "Spec: "), mk.span({}, `${ref.spec ? ref.spec : ''}`), ), forListElements ), ); hintPanel.forLink = link; setupRefHintEventListeners(link, hintPanel); return hintPanel; } function hideAllRefHints() { queryAll(".ref-hint").forEach(el=>hideRefHint(el)); } function hideRefHint(refHint) { const link = refHint.forLink; link.setAttribute("aria-expanded", "false"); if(refHint.teardownEventListeners) { refHint.teardownEventListeners(); } refHint.remove(); } function showRefHint(link) { if(link.classList.contains("dfn-link")) return; const url = link.getAttribute("href"); const refHintKey = link.getAttribute("data-refhint-key"); let key = url; if(refHintKey) { key = refHintKey + "_" + url; } const ref = refsData[key]; if(!ref) return; hideAllRefHints(); // Only display one at this time. const refHint = mkRefHint(link, ref); append(document.body, refHint); link.setAttribute("aria-expanded", "true"); positionRefHint(refHint); } function setupRefHintEventListeners(link, refHint) { if (refHint.teardownEventListeners) return; // Add event handlers to hide the refHint after the user moves away // from both the link and refHint, if not hovering either within one second. let timeout = null; const startHidingRefHint = (event) => { if (timeout) { clearTimeout(timeout); } timeout = setTimeout(() => { hideRefHint(refHint); }, 1000); } const resetHidingRefHint = (event) => { if (timeout) clearTimeout(timeout); timeout = null; }; link.addEventListener("mouseleave", startHidingRefHint); link.addEventListener("mouseenter", resetHidingRefHint); link.addEventListener("blur", startHidingRefHint); link.addEventListener("focus", resetHidingRefHint); refHint.addEventListener("mouseleave", startHidingRefHint); refHint.addEventListener("mouseenter", resetHidingRefHint); refHint.addEventListener("blur", startHidingRefHint); refHint.addEventListener("focus", resetHidingRefHint); refHint.teardownEventListeners = () => { // remove event listeners resetHidingRefHint(); link.removeEventListener("mouseleave", startHidingRefHint); link.removeEventListener("mouseenter", resetHidingRefHint); link.removeEventListener("blur", startHidingRefHint); link.removeEventListener("focus", resetHidingRefHint); refHint.removeEventListener("mouseleave", startHidingRefHint); refHint.removeEventListener("mouseenter", resetHidingRefHint); refHint.removeEventListener("blur", startHidingRefHint); refHint.removeEventListener("focus", resetHidingRefHint); }; } function positionRefHint(refHint) { const link = refHint.forLink; const linkPos = getBounds(link); refHint.style.top = linkPos.bottom + "px"; refHint.style.left = linkPos.left + "px"; const panelPos = refHint.getBoundingClientRect(); const panelMargin = 8; const maxRight = document.body.parentNode.clientWidth - panelMargin; if (panelPos.right > maxRight) { const overflowAmount = panelPos.right - maxRight; const newLeft = Math.max(panelMargin, linkPos.left - overflowAmount); refHint.style.left = newLeft + "px"; } } // TODO: shared util // Returns the root-level absolute position {left and top} of element. function getBounds(el, relativeTo=document.body) { const relativeRect = relativeTo.getBoundingClientRect(); const elRect = el.getBoundingClientRect(); const top = elRect.top - relativeRect.top; const left = elRect.left - relativeRect.left; return { top, left, bottom: top + elRect.height, right: left + elRect.width, } } function showRefHintListener(e) { // If the target isn't in a link (or is a link), // just ignore it. let link = e.target.closest("a"); if(!link) return; // If the target is in a ref-hint panel // (aka a link in the already-open one), // also just ignore it. if(link.closest(".ref-hint")) return; // Otherwise, show the panel for the link. showRefHint(link); } function hideAllHintsListener(e) { // If the click is inside a ref-hint panel, ignore it. if(e.target.closest(".ref-hint")) return; // Otherwise, close all the current panels. hideAllRefHints(); } document.addEventListener("DOMContentLoaded", () => { document.body.addEventListener("mousedown", showRefHintListener); document.body.addEventListener("focus", showRefHintListener); document.body.addEventListener("click", hideAllHintsListener); }); window.addEventListener("resize", () => { // Hide any open ref hint. hideAllRefHints(); }); } </script> <script>/* Boilerplate: script-var-click-highlighting */ "use strict"; { /* Color-choosing design: * Colors are ordered by goodness. * On clicking a var, give it the earliest color with the lowest usage in the algorithm. * On re-clicking, re-use the var's most recent color if that's not currently being used elsewhere. */ const COLOR_COUNT = 7; document.addEventListener("click", e=>{ if(e.target.nodeName == "VAR") { highlightSameAlgoVars(e.target); } }); function highlightSameAlgoVars(v) { // Find the algorithm container. let algoContainer = findAlgoContainer(v); // Not highlighting document-global vars, // too likely to be unrelated. if(algoContainer == null) return; const varName = nameFromVar(v); if(!v.hasAttribute("data-var-color")) { const newColor = chooseHighlightColor(algoContainer, v); for(const el of algoContainer.querySelectorAll("var")) { if(nameFromVar(el) == varName) { el.setAttribute("data-var-color", newColor); el.setAttribute("data-var-last-color", newColor); } } } else { for(const el of algoContainer.querySelectorAll("var")) { if(nameFromVar(el) == varName) { el.removeAttribute("data-var-color"); } } } } function findAlgoContainer(el) { while(el != document.body) { if(el.hasAttribute("data-algorithm")) return el; el = el.parentNode; } return null; } function nameFromVar(el) { return el.textContent.replace(/(\s|\xa0)+/g, " ").trim(); } function colorCountsFromContainer(container) { const namesFromColor = Array.from({length:COLOR_COUNT}, x=>new Set()); for(let v of container.querySelectorAll("var[data-var-color]")) { let color = +v.getAttribute("data-var-color"); namesFromColor[color].add(nameFromVar(v)); } return namesFromColor.map(x=>x.size); } function leastUsedColor(colors) { // Find the earliest color with the lowest count. let minCount = Infinity; let minColor = null; for(var i = 0; i < colors.length; i++) { if(colors[i] < minCount) { minColor = i; minCount = colors[i]; } } return minColor; } function chooseHighlightColor(container, v) { const colorCounts = colorCountsFromContainer(container); if(v.hasAttribute("data-var-last-color")) { let color = +v.getAttribute("data-var-last-color"); if(colorCounts[color] == 0) return color; } return leastUsedColor(colorCounts); } } </script>