-
Notifications
You must be signed in to change notification settings - Fork 107
Figure
Figures provide a way to display content outside of the main flow, like an image that spans across columns.
Figures also provide a method for specifying multiple versions of content, which are filtered in based on the screen size and capabilities of browser. For example, imagine you have three different sizes for images: thumbnail, one column, and two column. Which image you show depends on how large the browser window is, and whether the design can accomodate that size image.
Play.js uses HTML5 custom data attributes to add metadata to figure content. The data-sizes
property is used to distinguish between content payloads. The markup below shows a figure with two content payloads:
<figure>
<div data-sizes="threecolumn twocolumn">
<img src="large.jpg" />
</div>
<div data-sizes="thumbnail">
<img src="thumb.jpg" />
</div>
</figure>
The data-sizes
attribute specifies one or more size names, separated by spaces. These size names are then used by template designers to select between content payloads.
Additionally, you can supply content based upon a browsers capabilities. The data-requires
property is a space-delimited list of capabilities that are required by a figure payload. For example, the following markup shows different content depending Flash supported:
<figure>
<div data-sizes="twocolumn" data-requires="flash">
<!-- Flash embed -->
</div>
<div data-sizes="twocolumn">
<!-- Non-flash content -->
</div>
</figure>
Browsers that support flash will use the first element for the twocolumn
payload, while all other browsers will use the second. Play.js always uses the first qualifying payload for a given name, ignoring all subsequent payloads that use the same name.
A figure can specify fallback content that is used whenever there is not not enough space for a figure. This is done either by specifying fallback
as one of the data-sizes
, or by not specifying the data-size
property at all.
<figure>
<div data-sizes="masthead">
<!-- content -->
</div>
<div data-sizes="fallback">
<!-- backup content in case others did not fit -->
</div>
</figure>
Imagine what happens when a browser that does not support Play.js parses the following HTML:
<figure>
<div data-sizes="huge">
<img src="huge.jpg" />
</div>
<div data-sizes="fallback">
<img src="tiny.jpg" />
</div>
</figure>
The browser end up downloading both huge.jpg
and tiny.jpg
, which is undesirable for both users and bandwidth costs. In order to make sure legacy browsers do not end up downloading multiple versions of each image, you can hide the content from older browsers as follows:
<figure>
<script type="text/html" data-sizes="huge">
<div>
<img src="huge.jpg" />
</div>
</script>
<div data-sizes="fallback">
<img src="tiny.jpg" />
</div>
</figure>
Because text/html
is an unknown script type, all browsers ignore the contents of the <script>
tag, neither attempting to execute the script nor parsing the contents as HTML. Now, legacy browsers will only parse the second <img>
element, and only download one image.
Content payloads will frequently differ only by a few key values or attributes, as in the example below:
<figure>
<script type="text/html" data-sizes="portrait">
<img src="portrait.jpg" width="300" height="400" />
<p class="caption">This is me in 1993</p>
</script>
<script type="text/html" data-sizes="landscape" data-requires="flash touchSupport">
<img src="landscape.jpg" width="400" height="300" />
<p class="caption">This is me in 1993</p>
</script>
<script type="text/html" data-sizes="thumb fallback">
<img src="thumb.jpg" width="40" height="40" />
<p class="caption">This is me in 1993</p>
</script>
</figure>
Because each payload shares similiar structure (and identical captions), we can re-use the markup by defining a template:
<figure>
<script type="text/html" data-name="photo">
<img src="{{ src }}" width="{{ width }}" height="{{ height }}" />
<p class="caption">This is me in 1993</p>
</script>
<script type="application/json" data-template="photo">
[
{
"sizes": "portrait",
"src": "portrait.jpg",
"width": 300,
"height": 400
},
{
"sizes": "landscape",
"src": "landscape.jpg",
"width": 400,
"height": 300,
"requires": "flash touchSupport"
},
{
"sizes": "thumb fallback",
"src": "thumb.jpg",
"width": 40,
"height": 40
},
]
</script>
</figure>
Just like a cloaked figure payload, the markup template is defined by using a <script>
element with the type
attribute set to text/html
(causing the contents to be ignored by browsers). However, instead of setting the data-sizes
attribute, the data-name
attribute is set, providing an identifier for the template. The template specifies variable using {{ name }}
syntax, where name
is the name of the content that will be substituted in the HTML.
The second <script>
contains JSON that declares a JavaScript Array
. Each item should have the following properties:
-
sizes
: Equivalent to thedata-sizes
attribute -
requires
: Equivalent to thedata-requires
attribute (optional)
All additional properties are treated as values that can be used for templating.
For performance reasons, Play.js does not fully-compute the layout of each content payload in a figure. This means that occasionally, a page will not have enough space to fit the figure content, leading to the figure being hidden or clipped.
In order to avoid this situation, figures can specify a sizing hint: an estimate of the minimum dimensions that will be required by the content. Some examples of sizing hints:
- Image and Caption: The dimensions of the image, plus some extra space for the image caption
- Video: The size of the video, plus any UI controls
- Pullquote: The height of the typically number of lines in the pullquote
To specify a sizing hint use the following attributes and properties:
-
Element & Cloaked:
data-minWidth
anddata-minHeight
attributes -
Templated:
minWidth
andminHeight
properties