@@ -850,37 +850,228 @@ CSSOM {#cssom}
850850 return the result.
851851</div>
852852
853+ The <dfn>@property</dfn> rule {#at-property-rule}
854+ =================================================
855+
856+ The ''@property'' rule provides an alternative way to register a custom property,
857+ directly in a stylesheet
858+ without having to run any JS.
859+ Valid ''@property'' rules result in a [=register a custom property|registered custom property=] ,
860+ as if {{registerProperty()}} had been called with equivalent parameters.
861+
862+ The semantics of registered properties are the same
863+ regardless of the mechanism used to perform the registration.
864+ This means that, once registered,
865+ it does not matter whether the registration originated from {{registerProperty()}} or ''@property'' :
866+ the property has the same behavior either way.
867+
868+ The syntax of ''@property'' is:
869+
870+ <pre class="prod def" nohighlight>
871+ @property <<custom-property-name>> {
872+ <<declaration-list>>
873+ }
874+ </pre>
875+
876+ ''@property'' rules require a 'syntax' and 'inherits' descriptor;
877+ if either are missing,
878+ the entire rule is invalid and must be ignored.
879+ The 'initial-value' descriptor is optional
880+ only if the syntax is the [=universal syntax descriptor=] ,
881+ otherwise the descriptor is required;
882+ if it's missing, the entire rule is invalid and must be ignored.
883+
884+ If an ''@property'' rule contains any unknown descriptors,
885+ the entire rule is invalid and must be ignored.
886+
887+ Issue(845): What happens when we have both an ''@property'' rule, and a
888+ {{registerProperty()}} call for the same property?
889+
890+ Issue(846): What happens when ''@property'' appears inside a shadow tree?
891+
892+
893+ The 'syntax' descriptor {#the-syntax-descriptor}
894+ ------------------------------------------------
895+
896+ <pre class='descdef'>
897+ Name : syntax
898+ Value : <<string>>
899+ For : @property
900+ Initial : n/a (see prose)
901+ </pre>
902+
903+ Specifies the syntax of the custom property,
904+ in the form defined by [[#syntax-strings]] .
905+ This descriptor is equivalent to the {{PropertyDescriptor/syntax|syntax}} member of {{PropertyDescriptor}} .
906+
907+ The 'syntax' descriptor is required for the ''@property'' rule to be valid;
908+ if it's missing, the ''@property'' rule is invalid.
909+
910+ If the provided string does not successfully [=consume a syntax definition|parse as a syntax definition=] ,
911+ the descriptor is invalid and must be ignored.
912+
913+
914+ The 'inherits' descriptor {#inherits-descriptor}
915+ ------------------------------------------------
916+
917+ <pre class='descdef'>
918+ Name : inherits
919+ Value : true | false
920+ For : @property
921+ Initial : n/a (see prose)
922+ </pre>
923+
924+ Specifies whether or not the custom property inherits.
925+ This is equivalent to the {{PropertyDescriptor/inherits}} member of {{PropertyDescriptor}} .
926+
927+ The inherits descriptor is required for the ''@property'' rule to be valid;
928+ if it's missing, the ''@property'' rule is invalid.
929+
930+
931+ The 'initial-value' descriptor {#initial-value-descriptor}
932+ ----------------------------------------------------------
933+
934+ <pre class='descdef'>
935+ Name : initial-value
936+ Value : <<declaration-value>>
937+ For : @property
938+ Initial : the [=guaranteed-invalid value=] (but see prose)
939+ </pre>
940+
941+ Specifies the [=initial value=] of the custom property.
942+ This is equivalent to the {{PropertyDescriptor/initialValue}} member of {{PropertyDescriptor}} .
943+
944+ If the value of the 'syntax' descriptor is the [=universal syntax descriptor=] ,
945+ then the 'initial-value' descriptor is optional.
946+ If omitted, the initial value of the property is the [=guaranteed-invalid value=] .
947+
948+ Otherwise,
949+ if the value of the 'syntax' descriptor is not the [=universal syntax descriptor=] ,
950+ the following conditions must be met for the the ''@property'' rule to be valid:
951+
952+ * The 'initial-value' descriptor must be present.
953+ * The 'initial-value' descriptor's value must [=consume a syntax definition|parse successfully=]
954+ according to the grammar specified by the [=syntax definition=] .
955+ * The 'initial-value' must be [=computationally independent=] .
956+
957+ If the above conditions are not met, the ''@property'' rule is invalid.
958+
959+
960+ Extensions to the {{CSSRule}} interface {#extensions-to-css-rule-interface}
961+ ------------------------------------------------------------------------------------
962+
963+ The {{CSSRule}} interface is extended as follows:
964+
965+ <pre class='idl'>
966+ partial interface CSSRule {
967+ const unsigned short PROPERTY_RULE = 18;
968+ };
969+ </pre>
970+
971+ The <dfn interface>CSSPropertyRule</dfn> interface {#the-css-property-rule-interface}
972+ -----------------------------------------------------------------------------
973+
974+ The {{CSSPropertyRule}} interface represents an ''@property'' rule.
975+
976+ <pre class='idl' export>
977+ [Exposed=Window]
978+ interface CSSPropertyRule : CSSRule {
979+ readonly attribute CSSOMString name;
980+ readonly attribute CSSOMString syntax;
981+ readonly attribute boolean inherits;
982+ readonly attribute CSSOMString? initialValue;
983+ };
984+ </pre>
985+
986+ <dl dfn-for=CSSPropertyRule dfn-type=attribute>
987+ <dt> <dfn>name</dfn>
988+ <dd>
989+ The custom property name associated with the ''@property'' rule.
990+
991+ <dt> <dfn>syntax</dfn>
992+ <dd>
993+ The syntax associated with the ''@property'' , exactly as specified.
994+
995+ <dt> <dfn>inherits</dfn>
996+ <dd>
997+ The inherits descriptor associated withthe ''@property'' rule.
998+
999+ <dt> <dfn>initialValue</dfn>
1000+ <dd>
1001+ The initial value associated with the ''@property'' rule,
1002+ which may not be present.
1003+ </dl>
1004+
8531005
8541006Examples {#examples}
8551007====================
8561008
8571009Example 1: Using custom properties to add animation behavior {#example-1}
8581010-------------------------------------------------------------------------
8591011
860- <pre class='lang-markup'>
861- <script>
862- CSS.registerProperty({
863- name: "--stop-color",
864- syntax: "<color>",
865- inherits: false,
866- initialValue: "rgba(0,0,0,0)"
867- });
868- </script>
869-
870- <style>
871-
872- .button {
873- --stop-color: red;
874- background: linear-gradient(var(--stop-color), black);
875- transition: --stop-color 1s;
876- }
877-
878- .button:hover {
879- --stop-color: green;
880- }
1012+ <xmp class='lang-markup'>
1013+ <script>
1014+ CSS.registerProperty({
1015+ name: "--stop-color",
1016+ syntax: "<color> ",
1017+ inherits: false,
1018+ initialValue: "rgba(0,0,0,0)"
1019+ });
1020+ </script>
8811021
882- </style>
1022+ <style>
1023+ .button {
1024+ --stop-color: red;
1025+ background: linear-gradient(var(--stop-color), black);
1026+ transition: --stop-color 1s;
1027+ }
8831028
1029+ .button:hover {
1030+ --stop-color: green;
1031+ }
1032+ </style>
1033+ </xmp>
1034+
1035+ Example 2: Using ''@property'' to register a property {#example-2}
1036+ ------------------------------------------------------------------
1037+ <xmp class='lang-markup'>
1038+ <script>
1039+ CSS.paintWorklet.addModule('circle.js' );
1040+ </script>
1041+ <style>
1042+ @property --radius {
1043+ syntax: "<length> ";
1044+ inherits: false;
1045+ initial-value: 0px;
1046+ }
1047+
1048+ div {
1049+ width: 100px;
1050+ height: 100px;
1051+ --radius: 10px;
1052+ background: paint(circle);
1053+ transition: --radius 1s;
1054+ }
1055+
1056+ div:hover {
1057+ --radius: 50px;
1058+ }
1059+ </style>
1060+ <div></div>
1061+ </xmp>
1062+
1063+ <pre class='lang-javascript'>
1064+ // circle.js
1065+ registerPaint('circle' , class {
1066+ static get inputProperties() { return ['--radius'] ; }
1067+ paint(ctx, geom, properties) {
1068+ let radius = properties.get('--radius' ).value;
1069+ ctx.fillStyle = 'black' ;
1070+ ctx.beginPath();
1071+ ctx.arc(geom.width / 2, geom.height / 2, radius, 0, 2 * Math.PI);
1072+ ctx.fill();
1073+ }
1074+ });
8841075</pre>
8851076
8861077Security Considerations {#security-considerations}
0 commit comments