W3C home > Mailing lists > Public > www-style@w3.org > February 2008

Re: [css3] Suggestion: Selector variables or “synonyms”

From: Brad Kemper <brkemper@comcast.net>
Date: Sat, 9 Feb 2008 12:16:06 -0800
Message-Id: <94B02DDA-E842-4438-8383-9A561F65F328@comcast.net>
Cc: www-style CSS <www-style@w3.org>
To: David Woolley <forums@david-woolley.me.uk>

On Feb 9, 2008, at 3:13 AM, David Woolley wrote:

> Jens Meiert wrote:
>> Apparently, Carmelo Capinpin already suggested the concept in 2006  
>> [1] (with few success, unfortunately [2]), but I may propose to  
>> consider something like “selector variables” in CSS 3 again in  
>> order to help both maintainability and style sheet efficiency.
>> The basic idea is to syntactically allow definitions like
>>   E = F;
>> … so that rules matching E would match F as well (and the other  
>> way around), while variable (or synonym) declarations could  
>> probably be located at the beginning of a style sheet or within a  
>> certain @-rule.
> Could you explain how this would interact with the cascade, in  
> particular:
> - how does it interact with !important rules;
> - what is the scope of the effect.

I know you weren't asking me, but I would like to answer based on the  
way I suggested handling this sort of thing (see quoted text below),  
in which constants are merely placeholders for other text. Thus, the  
definition of the constants would not be involved in the cascade, and  
would not be anything more than strings of text that could be later  
inserted into a rule, where they would then behave the same as any  
other text in the rule.

The constants would have to be defined before they were used.  
Constants that were used prior to being defined would be ignored.  
Thus, in the following example, "DIV" would be red with a black  
border and "SPAN" would be green with a blue border:

	DIV, SPAN { color: red; border: 2px black solid; }
	DIV { constant: mycolor; } /* used before defined, so ignored */
	@constant mycolor { color: green; border-color: blue; } /* defined */
	SPAN { constant: mycolor; } /*used */

Thus, after "color: green" and "border-color: blue" were assigned to  
the "mycolor" constant in this example, any occurrence of "constant:  
mycolor" in a rule would be interpreted as "color: green; border- 
color: blue;". Thus, the above would be exactly the same as if  
written as:

	DIV, SPAN { color: red; border: 2px black solid; }
	SPAN { color: green; border-color: blue;  }

If "!important" was part of the text of the constant, then it would  
be part of the text where the constant was used. Thus, the following:

	@constant mycolor { color: green !important;  }
	SPAN { constant: mycolor; }

	/* same as if we wrote the following: */
	SPAN { color: green !important;  }

The last value in the constant assignment will have an implied  
semicolon if it is missing. Adding "!important" to a rule as part of  
the value of the "constant" parameter would thus be ignored, in the  
following example:

	@constant mycolor { color: green  }
	SPAN { constant: mycolor !important; }

	/* same as if we wrote the following: */
	SPAN { color: green; !important;  }
	/* thus, " !important" is not part of the use of the constant */

The constant could only contain a single string of text. Thus, in the  
following example, the "myspacing' constant would contain margin, but  
not padding, as the text of the first assignment is replaced by the  
text of the second:

	/* first assignment to "myspacing" in document: */
	@constant myspacing { padding:1em; }
	/* second assignment to "myspacing" in document: */
	@constant myspacing { margin:1em; }

In this case, some might argue that "@var" and "var:" might be better  
syntax than "@constant" and "constant:". A different variation would  
be that we could say that once a constant if assigned, that it cannot  
be altered, and further attempts to re-assign text to it would be  
ignored (thus making it truly constant). If we went that route, then  
the previous example would have padding assigned to it, but not margin.

If we allow reassigning text to a constant, then it should be all or  
nothing. individual properties could not be added on. Thus, in the  
following, the second @constant completely replaces the first:

	@constant mysettings { padding:10px; }
	@constant mysettings { margin:1em; }
	/* mysettings now contains margin, but has nothing to say about  
padding anymore */

Rules assigned to a constant must be well formed and complete  
(subject to the same error handling as within rules). For instance,  
the following would assign padding, but not color:

	@constant mycolor { padding:2px; color:gr  } /* color ignored */
	DIV { constant: mycolor;  } /* picks up the padding */
	DIV { constant: mycoloreen;  } /* does not concatenate */

Constants defined in one part of a style sheet would be available for  
use in any part of the style sheet below it in the document flow, and  
to any subsequent style sheets below it, to any style sheets  
dynamically added below it after document loading (via javaScript,  
for instance), and to "style" attributes in HTML.

Constants could include other constants, provided they had been  
defined already (above them in the document flow). So, for instance,  
the following would be valid:

	@constant summer {
		background-color: gold;
		border-color: orange;
		background-image: url(leaves.png)
	@constant myCommonSettings {
		constant: summer;
		border-width: 1px;
		border-style: dotted;
		background-repeat: no-repeat;

All of the above is in reference to how "property constants" would  
work, but "selector constants" would have similar scope, which I can  
describe in a separate (but similar) posting from (and as) this one,  
if anyone wants me to. I've described the basics of each, quoted below:

> /* for groups of property/value pairs that are used in multiple  
> places: */
> @constant mycolorandfont { color: #444;  font-size: 77%;  border- 
> color;blue; }
> /* for long sequences of selectors that are used in multiple  
> places: */
> @constant navlink( #sidenav ul li a, #topnav ul li a )
> input[type="radio"] {
> 	constant:mycolorandfont;
> 	line-height:90%;
> 	 /*other settings for radio*/
> }
>  input[type="checkbox"] {
> 	constant:mycolorandfont;
> 	line-height:110%;
> 	 /*other settings for checkbox*/
> }
> navlink:link, navlink:visited { color:black; background- 
> color:yellow; }
> navlink:hover { background-color:black; color:yellow; }
> navlink:active { background-color:black; color:red; }
Received on Saturday, 9 February 2008 20:16:26 UTC

This archive was generated by hypermail 2.3.1 : Monday, 2 May 2016 14:27:33 UTC