Allowing <mask>, <clipPath> etc. to target their parents

Dear all,

I have been assigned ACTION-3223, to investigate ISSUE-2431, "Consider 
allowing <mask>, <clipPath>, etc. as direct children of elements they'd 
apply to, to avoid IDs."[1]

The issue:
----------

Some elements like <mask> and <clipPath> can only be used by referring 
to them by id, e.g. mask="url(#batsignal)".

This is sub-optimal for two reasons:

1. When generating content via script, the script must generate a unique 
ID. Note that in many applications it's not sufficient to use a counter 
to generate IDs such as mask0, mask1, mask2 etc. since the generated 
content may be mashed-up with other content leading to ID collisions. 
Instead, scripts need to generate a globally unique ID which is (a) more 
complicated to generate, (b) longer, obscuring the content and 
increasing it's file size, parse time etc.

I suspect that for many authors, one of the first steps when generating 
content is to create a globally unique ID generator which seems like 
unnecessary overhead.

2. When a mask, clipPath etc. is only intended to be used once, IDs 
obscure the relationship between elements in the document. The best you 
can do is make the mask and its target, siblings.

Scope:
------

I've identified the following combinations of properties/attributes and 
target elements where ID references are currently required but where it 
might be preferable if they were not.

clip-path -> <clipPath>
cursor -> <cursor>
fill, stroke -> <linearGradient>, <radialGradient>, <pattern>
filter -> <filter>
font -> <font> ?
marker, marker-start, marker-mid, marker-end -> <marker>
mask -> <mask>
<feImage xlink:href> -> SVG content
<font-face-uri xlink:href> -> <font>
<textPath xlink:href> -> <path>

Possible solution:
------------------

It would be really nice if a mask etc. could be applied to an element 
simply by making it a child of that element. This is currently how 
animations work. An <animate> element can either refer to its target by 
xlink:href="#id" or, if no such attribute exists, it will default to 
targeting its parent element.

Using that approach, instead of:

   <filter id="myFilter">
     ...
   </filter>
   <path filter="url(#myFilter)"/>

You could have:

   <path>
     <filter>
     ...
     </filter>
   </path>

But, of course, that breaks existing content such as:

   <g>
     <filter id="MyFilter">
     ...
     </filter>
     <path filter="url(#MyFilter)"/>
     <path/>
   </g>

I think our next best option is to extend the syntax.

For properties we could have:

   clip-path: <funciri> | none | inherit | child

If it's 'child', it means "find the first child element that is a 
<clipPath> and use that."

Judging by the minutes of the previous discussion I'm pretty sure credit 
for this syntax goes to Cameron McCormack.[1]

(On that note, does CSS already have syntax for this sort of thing? And 
is it too short-sighted to limit this to the children?)

For 'xlink:href' attributes it's a bit more difficult since really all 
'xlink:href' attributes should take the same values. However, I wonder 
if for the three examples above you could get away with just allowing 
the target element to be child content in the absence of an 'xlink:href' 
attribute. feImage is probably easy, I don't really know if 
font-face-uri makes much sense, and textPath looks a little complicated:

   <text>
     <textPath>
       <path d="..."/>
       Text along path
     </textPath>
   </text>

For reference, feImage might look like:

   <filter>
     <feImage x="500" y="5">
       <path ... />
     </feImage>
   </filter>

In either case, the absence of xlink:href means, "but what about the 
children?"

As well as extending the grammar for various CSS properties, this would 
also mean changes to the permitted child content of various elements.

What do you think?

Best regards,

Brian Birtles

[1] Original discussion here: http://www.w3.org/2012/01/12-svg-minutes.html

Received on Tuesday, 21 February 2012 05:19:49 UTC