Skip to content

Commit eb5a900

Browse files
authored
Merge pull request #625 from IIIF/0045-css
0045 CSS in Annotations
2 parents 7addb9d + c71de54 commit eb5a900

File tree

6 files changed

+196
-5
lines changed

6 files changed

+196
-5
lines changed

_includes/links.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@
1010
[0009]: {{ site.cookbook_url | absolute_url }}/recipe/0009-book-1/ "Simple Manifest - Book"
1111
[0010]: {{ site.cookbook_url | absolute_url }}/recipe/0010-book-2-viewing-direction "Viewing direction and its effect on navigation"
1212
[0011]: {{ site.cookbook_url | absolute_url }}/recipe/0011-book-3-behavior/ "Book behavior (paging) variations"
13-
[0299]: {{ site.cookbook_url | absolute_url }}/recipe/0299-region/ "Addressing a spatial region"
1413
[0013]: {{ site.cookbook_url | absolute_url }}/recipe/0013-placeholderCanvas/ "Load a Preview Image Before the Main Content"
1514
[0202]: {{ site.cookbook_url | absolute_url }}/recipe/0202-start-canvas/ "Load Manifest Beginning with a Specific Canvas"
1615
[0014]: {{ site.cookbook_url | absolute_url }}/recipe/0014-accompanyingcanvas/ "Audio Presentation with Accompanying Image"
1716
[0015]: {{ site.cookbook_url | absolute_url }}/recipe/0015-start/ "Begin playback at a specific point - Time-based media"
1817
[0017]: {{ site.cookbook_url | absolute_url }}/recipe/0017-transcription-av/ "Providing Access to Transcript Files of A/V Content"
1918

20-
[0139]: {{ site.cookbook_url | absolute_url }}/recipe/0139-geolocate-canvas-fragment/ "Represent Canvas Fragment as a Geographic Area on a Web Map"
21-
2219
[0019]: {{ site.cookbook_url | absolute_url }}/recipe/0019-html-in-annotations/ "HTML in Annotations"
2320
[0021]: {{ site.cookbook_url | absolute_url }}/recipe/0021-tagging/ "Simple Annotation — Tagging"
2421
[0022]: {{ site.cookbook_url | absolute_url }}/recipe/0022-linking-with-a-hotspot/ "Redirecting from one Canvas to another resource (Hotspot linking)"
@@ -33,6 +30,7 @@
3330
[0031]: {{ site.cookbook_url | absolute_url }}/recipe/0031-bound-multivolume/ "Multiple Volumes in a Single Bound Volume"
3431

3532
[0040]: {{ site.cookbook_url | absolute_url }}/recipe/0040-image-rotation-service/ "Image Rotation Two Ways"
33+
[0045]: {{ site.cookbook_url | absolute_url }}/recipe/0045-css/ "CSS in an Annotation"
3634

3735
[0047]: {{ site.cookbook_url | absolute_url }}/recipe/0047-homepage/ "Linking to Web Page of an Object"
3836
[0046]: {{ site.cookbook_url | absolute_url }}/recipe/0046-rendering/ "Providing Alternative Representations"
@@ -49,7 +47,7 @@
4947
[0118]: {{ site.cookbook_url | absolute_url }}/recipe/0118-multivalue/ "Displaying Multiple Values with Language Maps"
5048

5149
[0135]: {{ site.cookbook_url | absolute_url }}/recipe/0135-annotating-point-in-canvas/ "Annotating a specific point of an image"
52-
50+
[0139]: {{ site.cookbook_url | absolute_url }}/recipe/0139-geolocate-canvas-fragment/ "Represent Canvas Fragment as a Geographic Area on a Web Map"
5351
[0154]: {{ site.cookbook_url | absolute_url }}/recipe/0154-geo-extension/ "Locate a Manifest on a Web Map"
5452

5553
[0232]: {{ site.cookbook_url | absolute_url }}/recipe/0232-image-thumbnail-canvas/ "Implementation discussion: Thumbnails on Canvases"
@@ -66,6 +64,7 @@
6664
[0266]: {{ site.cookbook_url | absolute_url }}/recipe/0266-full-canvas-annotation/ "Simplest Annotation"
6765
[0269]: {{ site.cookbook_url | absolute_url }}/recipe/0269-embedded-or-referenced-annotations/ "Embedded or Referenced Annotations"
6866
[0283]: {{ site.cookbook_url | absolute_url }}/recipe/0283-missing-image/ "Missing Images in a Sequence"
67+
[0299]: {{ site.cookbook_url | absolute_url }}/recipe/0299-region/ "Addressing a spatial region"
6968

7069
[0306]: {{ site.cookbook_url | absolute_url }}/recipe/0306-linking-annotations-to-manifests/ "Linking external Annotations targeting a Canvas to a Manifest"
7170
[0309]: {{ site.cookbook_url | absolute_url }}/recipe/0309-annotation-collection/ "Using Annotation Collections"

index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ _(leading on to segmentation examples later)_
8383
* comments - various examples (51,52,54)
8484
* [Simplest Annotation][0266]
8585
* [HTML in Annotations][0019]
86+
* [CSS in an Annotation][0045]
8687
* Fragment selectors (61)
8788
* [Simple Annotation - Tagging][0021]
8889
* [Annotation with a Non-Rectangular Polygon][0261]

recipe/0019-html-in-annotations/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"type": "AnnotationPage",
4848
"items": [
4949
{
50-
"id": "{{ id.path }}{{ id.path }}/canvas-1/annopage-2/anno-1",
50+
"id": "{{ id.path }}/canvas-1/annopage-2/anno-1",
5151
"type": "Annotation",
5252
"motivation": "commenting",
5353
"body": {

recipe/0045-css/index.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
title: CSS in an Annotation
3+
id: 45
4+
layout: recipe
5+
tags: [style]
6+
summary: "Using an external CSS stylesheet in an annotation body, annotations can be styled in limited ways"
7+
viewers:
8+
- Theseus
9+
topic:
10+
- basic
11+
code:
12+
- iiif-prezi3
13+
---
14+
15+
## Use Case
16+
17+
You have two different authors who have each made an annotation on a visual resource. You'd like to distinguish the authors visually in the presentation, putting each annotation text in a different text color.
18+
19+
## Implementation Notes
20+
21+
Using CSS in annotations is covered in the W3C Web Annotation Data Model. For a look at its approach to styles in Web Annotations, see [the W3C Web Annotation Data Model's Styles section](https://www.w3.org/TR/annotation-model/#styles). Note in particular changes needed to the `target` property if styling is intended for a IIIF Canvas.
22+
23+
Annotations can be styled using CSS in three ways. This recipe focuses on using an external stylesheet. To add CSS using an external stylesheet, insert the stylesheet's URI as the the value of a `stylesheet` property on the Annotation. The `styleClass` property can then be used to reference rules in that external stylesheet, such as in the annotation `body` or composite `target` containing a `source` as well. It is advisable to set appropriate CORS headers for the stylesheet to improve its chances of working in generic viewers.
24+
25+
Viewer behavior and the specifics of an annotation's `target` will have effects, but broadly speaking, using CSS to style the `body` of an annotation will style the content of the annotation and a CSS class in the `target` will style the annotation's highlight on a Canvas.
26+
27+
The two other methods for adding CSS to a manifest are inline CSS and an inline stylesheet. To see how to use an inline stylesheet, see [Image Rotation Two Ways][0040]. To see how to use inline CSS, see [Visible Text Resource on a Canvas][0561]. Each of these also shows styling a IIIF resource in an annotation with a `motivation` of `painting` — that is, styling content that can be expected to be visible in the content space of a viewer.
28+
29+
## Restrictions
30+
31+
See the Restrictions section of the [HTML in Annotations][0019] recipe for a brief discussion of limitations to markup in annotations. These limitations can affect, in turn, the possible selectors in your external stylesheet.
32+
33+
The CSS approach depends wholly on viewer implementation of CSS as applied to a resource. Even more broadly than with HTML, viewers have no requirement to support any particular approach to CSS styling or even to support CSS at all. Browser-based viewers may defer CSS implementation in whole or in part to the browser and may allow only a defined subset of CSS either for internal or for deferred application. Consequently, and also for reasons of accessibility, annotations should not rely on styling for semantics and should be meaningful to a human and parsable by machine without styling.
34+
35+
CSS can also be used as the vector for unethical or insecure actions. For instance, a `background` rule could include a tracking image in its value: `background: lightblue url(http://example.com/tracker/image.jpg) no-repeat fixed center;` This image could phone home data about accesses to the annotation. To be more certain of security, viewers and annotation stores that allow annotations from anonymous sources could strip any stylesheet propery entirely.
36+
37+
Even where a viewer supports CSS broadly, the intersection of IIIF and CSS can result in uncertainty. For instance, since IIIF Canvas dimensions are unit-less, using pixels for text size in CSS is valid but may be interpreted variably across viewers or other clients.
38+
39+
## Example
40+
41+
This recipe focuses on annotations with motivations other than painting and on an external CSS stylesheet. The Theseus viewer is included here for its support of styling the annotation text, but it does not currently support styling the `target`.
42+
43+
{% include manifest_links.html manifest="manifest.json" %}
44+
45+
{% include jsonviewer.html src="manifest.json" config='data-line="56,60,72,83,87,99"' %}
46+
47+
### Stylesheet
48+
{% include jsonviewer.html src="style.css" %}
49+
50+
## Related Recipes
51+
52+
* [Image Rotation Two Ways][0040], for an inline CSS stylesheet used with a IIIF resource
53+
* [HTML in Annotations][0019], a complementary recipe for markup, including a fuller discussion of markup use cautions
54+
* [Visible Text Resource on a Canvas][0561], for inline CSS used with a painted textual resource
55+
56+
{% include acronyms.md %}
57+
{% include links.md %}
58+
59+

recipe/0045-css/manifest.json

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
{
2+
"@context": "http://iiif.io/api/presentation/3/context.json",
3+
"id": "{{ id.url }}",
4+
"type": "Manifest",
5+
"label": {
6+
"en": [
7+
"Koto, chess, calligraphy, and painting"
8+
],
9+
"ja": [
10+
"琴棋書画図屏風"
11+
]
12+
},
13+
"items": [
14+
{
15+
"id": "{{ id.path }}/canvas/p1",
16+
"type": "Canvas",
17+
"height": 3966,
18+
"width": 8800,
19+
"items": [
20+
{
21+
"id": "{{ id.path }}/page/p1/1",
22+
"type": "AnnotationPage",
23+
"items": [
24+
{
25+
"id": "{{ id.path }}/annotation/p0001-image",
26+
"type": "Annotation",
27+
"motivation": "painting",
28+
"body": {
29+
"id": "https://iiif.io/api/image/3.0/example/reference/36ca0a3370db128ec984b33d71a1543d-100320001004/full/max/0/default.jpg",
30+
"type": "Image",
31+
"format": "image/jpeg",
32+
"height": 3966,
33+
"width": 8800,
34+
"service": [
35+
{
36+
"id": "https://iiif.io/api/image/3.0/example/reference/36ca0a3370db128ec984b33d71a1543d-100320001004",
37+
"profile": "level1",
38+
"type": "ImageService3"
39+
}
40+
]
41+
},
42+
"target": "{{ id.path }}/canvas/p1"
43+
}
44+
]
45+
}
46+
],
47+
"annotations": [
48+
{
49+
"id": "{{ id.path }}/page/p2/1",
50+
"type": "AnnotationPage",
51+
"items": [
52+
{
53+
"id": "{{ id.path }}/page/p2/anno-1",
54+
"type": "Annotation",
55+
"motivation": "commenting",
56+
"stylesheet": "{{ id.path }}/style.css",
57+
"body": {
58+
"id": "{{ id.path }}/body/sr1",
59+
"type": "SpecificResource",
60+
"styleClass": "author1note",
61+
"source": {
62+
"id": "{{ id.path }}/body/text1",
63+
"type": "TextualBody",
64+
"language": "en",
65+
"format": "text/html",
66+
"value": "<p>Three of the four pursuits of refined and noble men named in the screen's title are shown on this side of the screen: go, the koto, and tools for calligraphy. Each is in a container or wrapper. (GR)</p>"
67+
}
68+
},
69+
"target": {
70+
"type": "SpecificResource",
71+
"source": "{{ id.path }}/canvas/p1",
72+
"styleClass": "author2highlight",
73+
"selector": {
74+
"type": "FragmentSelector",
75+
"value": "xywh=700,1250,1850,1150"
76+
}
77+
}
78+
},
79+
{
80+
"id": "{{ id.path }}/page/p2/anno-2",
81+
"type": "Annotation",
82+
"motivation": "commenting",
83+
"stylesheet": "{{ id.path }}/style.css",
84+
"body": {
85+
"id": "{{ id.path }}/body/sr2",
86+
"type": "SpecificResource",
87+
"styleClass": "author2note",
88+
"source": {
89+
"id": "{{ id.path }}/body/text2",
90+
"type": "TextualBody",
91+
"language": "en",
92+
"format": "text/html",
93+
"value": "<p>The detail in the natural beauty of the setting could be seen as a contrast (or balance) to the manufactured pursuits of noble men. (TK)</p>"
94+
}
95+
},
96+
"target": {
97+
"type": "SpecificResource",
98+
"source": "{{ id.path }}/canvas/p1",
99+
"styleClass": "author2highlight",
100+
"selector": {
101+
"type": "FragmentSelector",
102+
"value": "xywh=170,160,2200,1000"
103+
}
104+
}
105+
}
106+
]
107+
}
108+
]
109+
}
110+
]
111+
}

recipe/0045-css/style.css

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.author1note {
2+
color: #f00;
3+
background-color: #fff;
4+
border-color: #f00;
5+
}
6+
7+
.author1highlight {
8+
color: #f00;
9+
border-color: #f00;
10+
}
11+
12+
.author2note {
13+
color: #1a1;
14+
background-color: #fff;
15+
border-color: #0f0;
16+
}
17+
18+
.author1highlight {
19+
color: #0f0;
20+
border-color: #0f0;
21+
}

0 commit comments

Comments
 (0)