Re: display:none and mixed SVG and HTML

On Wed, Feb 1, 2012 at 11:38 PM, Brian Birtles <bbirtles@mozilla.com> wrote:
> Dear all,
>
> I would like to clarify the expected behaviour of display:none with regards
> to mixed SVG and HTML.
>
> In HTML, display:none generally means that for the purpose of rendering the
> element and its children can be ignored (i.e. no frames are generated).
>
> In SVG, however, sometimes content marked as display:none can be rendered
> when referenced elsewhere.[1]
>
> For example:
>  - display:none does not apply to filters[2]
>  - display:none does not apply to gradients[3]
>  - display:none on clipPath has no effect (although it does on child
> elements)[4]

The key point is "when referenced elsewhere".  The elements don't
generate boxes/rendering themselves.

(I define this in a limited way in CSS Images 3, such that some
elements in HTML (img, video, canvas) and SVG (*Gradient, pattern)
have an intrinsic rendering and can thus be used with the element()
function even if they're not directly rendered.  clipPath and filters
are never rendered at all in any sense; they're purely tools for
manipulating the rendering of other elements.)


> A more detailed test case is available.[5]
>
> I'd like to clarify how this behaves when SVG and HTML are mixed through a
> series of examples.
>
> Example 0, all SVG:
>
> <svg>
>  <g style="display:none">
>    <pattern id="pattern">
>      <rect fill="blue"/>
>    </pattern>
>  </g>
>  <rect fill="url(#pattern)"/>
> </svg>
>
> Expected results: blue rect pattern is rendered.
>
> Rationale: "'pattern' elements are available for referencing even when the
> 'display' property on the 'pattern' element or any of its ancestors is set
> to none."[6]
>
> Example 1, HTML in SVG:
>
> <svg>
>  <g style="display:none">
>    <pattern id="pattern">
>      <foreignObject>
>        <body>Hi from HTML</body>
>      </foreignObject>
>    </pattern>
>  </g>
>  <rect fill="url(#pattern)"/>
> </svg>
>
> Expected results: HTML pattern is rendered.
>
> Rationale: The section from the SVG spec quoted above (Example 0) still
> applies here. We first encounter display:none in SVG mode so SVG behaviour
> applies and the pattern's children are rendered.
>
> Example 2, SVG in HTML, display:none on <p>:
>
> <html>
>  <p style="display:none">
>    <svg>
>      <pattern id="pattern">
>        <rect fill="blue"/>
>      </pattern>
>    </svg>
>  </p>
>  <svg>
>    <rect fill="url(#pattern)"/>
>  </svg>
> </html>
>
> Expected results: No pattern is rendered, i.e. the rectangle is filled
> black.
>
> Rationale: HTML rendering behaviour kicks in here. The user agent should be
> free to optimise rendering of HTML content by ignoring children of
> display:none elements for the purpose of rendering. Feel free to contest
> this, but this is my proposal here.
>
> Example 3, SVG in HTML, display:none on outer <svg>:
>
> <html>
>  <p>
>    <svg style="display:none">
>      <pattern id="pattern">
>        <rect fill="blue"/>
>      </pattern>
>    </svg>
>  </p>
>  <svg>
>    <rect fill="url(#pattern)"/>
>  </svg>
> </html>
>
> Expected results: No pattern is rendered, i.e. the rectangle is filled
> black.
>
> Rationale: As with example 2, we are still in HTML mode here when we
> encounter the outermost <svg> element. Again, feel free to contest this.
>
> So in summary:
>
> A. When display:none is first encountered on an SVG element other than the
> outermost SVG element in a document, SVG rendering behaviour applies and the
> element and its children may still be referenced and rendered elsewhere
> where permitted by SVG (e.g. patterns, filters etc.)
>
> B. When display:none is first encountered on an HTML element or an outermost
> SVG element in a compound document the whole subtree from that element
> onwards is not available for rendering. Attempts to reference content from
> that subtree will behave as if the target element was not found.
>
> The seems to more-or-less correspond with what I've observed in WebKit. For
> Gecko this is being tracked in bug 376027.[7]
>
> Your feedback would be very much appreciated! Perhaps there are other
> permutations worth clarifying?
>
> Best regards,
>
> Brian Birtles
>
> [1] http://www.w3.org/TR/SVG11/painting.html#DisplayProperty, "The ‘display’
> property only affects the direct rendering of a given element, whereas it
> does not prevent elements from being referenced by other elements."
> [2] http://www.w3.org/TR/SVG11/filters.html#FilterElement
> [3] http://www.w3.org/TR/SVG11/pservers.html#LinearGradientElement
> [4] http://www.w3.org/TR/SVG11/masking.html#ClipPathElement
> [5] https://bug376027.bugzilla.mozilla.org/attachment.cgi?id=593735
> [6] http://www.w3.org/TR/SVG11/pservers.html#PatternElement
> [7] https://bugzilla.mozilla.org/show_bug.cgi?id=376027

I disagree with this.

For one, I don't think we should be enshrining any functionality
differences between HTML and SVG unless absolutely necessary.

For two, "<p style=display:none><img id=foo></p>" will still draw the
image when you reference it with the element() function from CSS.
(This is currently only implemented in Firefox, as I specced it after
they revealed an experimental implementation.)  It's not perfect quite
yet - for example, if the image was an animated GIF, only the first
frame will show in the above example (while it would be animated if
the image was visible).  That can be considered a bug, though.  This
is basically identical to the situation you're talking about, though -
if, instead of <img>, I had <svg><pattern /></svg>, I should be able
to reference it just the same.

~TJ

Received on Thursday, 2 February 2012 10:14:02 UTC