TimedText/CSSRequirements
Timed Text Working Group
Summary table
Style attribute | CSS support |
---|---|
backgroundClip | Direct mapping |
backgroundColor | Direct mapping |
backgroundExtent | Direct mapping |
backgroundImage | Direct mapping |
backgroundOrigin | Direct mapping |
backgroundPosition | Direct mapping |
backgroundRepeat | Direct mapping |
border | Direct mapping(s) |
bpd | Unclear mapping |
color | Direct mapping |
direction | Direct mapping |
disparity | Unsupported |
display | Direct mapping |
displayAlign | Indirect mapping |
extent | Unclear mapping |
fontFamily | Direct mapping |
fontKerning | Direct mapping |
fillLineGap | Unsupported |
fontSelectionStrategy | Unsupported |
fontShear | Unsupported |
fontSize | Partially supported |
fontStyle | Direct mapping |
fontVariant | Direct mapping |
fontWeight | Direct mapping |
inlineAreaBreak | Unsupported |
ipd | Unclear mapping |
letterSpacing | Direct mapping |
lineHeight | Direct mapping |
luminanceGain | Unsupported |
opacity | Direct mapping |
origin and position | Partially supported |
overflow | Direct mapping |
padding | Direct mapping |
ruby | Direct mapping |
rubyAlign | Partially supported |
rubyOffset | Unsupported |
rubyOverflow | Partially supported |
rubyOverhang | Partially supported |
rubyOverhangClass | Unsupported |
rubyPosition | Direct mapping |
rubyReserve | Unsupported |
showBackground | Unsupported |
textAlign | Partially supported |
textCombine | Direct mapping |
textDecoration | Direct mapping |
textEmphasis | Direct mapping |
textOrientation | Partially supported |
textOutline | Partially supported |
textShadow | Direct mapping |
unicodeBidi | Direct mapping |
visibility | Direct mapping |
wrapOption | Direct mapping |
writingMode | Partially supported |
zIndex | Direct mapping |
initial and root style inheritance | Partially supported |
linePadding | Unsupported |
multiRowAlign | Unsupported |
spurious spaces before BR | Partially supported |
TTML and IMSC styling features that are hard to reproduce in CSS
WARNING: This page is probably out of date - please see TTML2 Appendix N.2.1 for more up to date mappings
Introduction
CSS supports a wide variety of text styling features. TTML1, TTML2 and profiles such as IMSC 1 Text Profile support the set of styling features that have been found to be important for the presentation of timed text, especially in the application of subtitles and captions. Through implementation and specification work the TTWG has found that there are some TTML styling features that have no simple equivalent in CSS, and where scripting a polyfill to address this can be challenging. In other cases there are differences between the HTML and/or CSS specifications and what is actually implemented, which can cause additional difficulties when presenting TTML content using HTML, CSS and JS (ES if you prefer!).
This page lists the features for which TTWG considers that CSS styling would be helpful.
Links
- The TTML2 specification (see Appendix N.2 for attribute derivation including styling attributes)
- The IMSC 1.0.1 specification
- A number of features were identified in IMSC #218 comments
- Some features from TTML2 were identified as a strawman for inclusion in IMSC 1: TTML2-features-for-inclusion-in-IMSC2 wiki page
- TTML2 Pull Request #470 adds the CSS derivations.
Style attribute and property mapping
This document explores the mapping of semantics between TTML2 and IMSC1 style attributes and their closest equivalent CSS properties.
A "direct mapping" is possible when there is a mapping between the syntax and value space of a TTML2 style attribute and a CSS property and its values. In some cases the direct mapping is unidirectional, i.e. mapping from TTML to CSS is possible for all TTML values, but not mapping from CSS to TTML for all CSS values.
A "partial mapping" is possible when some syntax and values of a TTML2 style attribute can be mapped to a CSS property but some cannot.
A TTML style attribute is "unsupported" in CSS if its values cannot be mapped to the values of any CSS property.
Styling Features
There are many TTML style attributes, most of which derive their semantic from XSL-FO, and most of which have an identical semantic alternately defined in CSS, for example text color, background color etc.
The following selection of (newish) TTML2 (and IMSC) style attributes ideally needs to be implementable with CSS:
backgroundClip
tts:backgroundClip is used to specify a style property that determines the background painting rectangle within which the background is painted.
It maps directly to the CSS background-clip property.
backgroundColor
tts:backgroundColor is used to specify a style property that defines the background color of a region or an area generated by content flowed into a region.
It maps directly to the CSS background-color property.
backgroundExtent
tts:backgroundExtent is used to specify the extent (size) of a background image independently of the image's intrinsic extent (size).
It maps directly to the CSS background-size property.
backgroundImage
tts:backgroundImage is used to specify a style property that designates a background non-content image to be rendered as the background image of a region or an area generated by content flowed into a region.
It maps directly to the CSS background-image property.
backgroundOrigin
tts:backgroundImage is used to specify a style property that determines the background positioning rectangle within which the background is positioned.
It maps directly to the CSS background-origin property.
backgroundPosition
tts:backgroundPosition is used to specify a style property that defines whether and how a background image is positioned in a region or an area generated by content flowed into a region.
It maps directly to the CSS background-position property.
backgroundRepeat
tts:backgroundRepeat is used to specify a style property that defines whether and how a background image is repeated (tiled) into a region or an area generated by content flowed into a region.
It maps directly to the CSS background-repeat property though not all values in background-repeat are available.
border
border is used to specify a style property that defines the border of a region or an area generated by content flowed into a region.
It can be directly mapped to the following CSS properties:
- <border-thickness> maps to the CSS border-width property
- <border-style> maps to the CSS border-style property (though border-style offers options not included in TTML)
- <border-color> maps to the CSS border-color property
- <border-radii> maps to the CSS border-radius property
bpd
tts:bpd is used to specify the block progression dimension, or, more succinctly, the bpd of an area generated by content flowed into a region.
- What does this map to in CSS?
color
tts:color is used to specify a style property that defines the foreground color of marks associated with an area generated by content flowed into a region.
It maps directly to the CSS color property though not all values in color are available (e.g. no HSL expressions).
direction
tts:direction is used to specify a style property that defines the directionality of an embedding or override according to the Unicode bidirectional algorithm.
It maps directly to the CSS direction property.
disparity
tts:disparity is used to specify the binocular disparity to be applied in order to simulate stereopsis (stereoscopic depth). A disparity of zero corresponds to the plane of display; a negative value corresponds to depths in front of the plane of display; and a positive value corresponds to depths behind the plane of display.
There is no current equivalent for specifying the stereoscopic distance value for text in CSS.
Ignoring tts:disparity results in the text being presented in the "zero" plane; the impact of that depends on anything that is presented on the same device. The effect is likely to be disconcerting if it clashes with something in a stereoscopic video that appears closer to the viewer than the text.
display
display is used to specify a style property that defines whether an element is a candidate for layout and composition in a region.
It can be directly mapped to the CSS display property for the "none" and "inlineBlock" values, but:
- CSS has no obvious direct equivalent for "auto"; the initial value for CSS display is "inline" however it appears that almost all implementations treat a
<p>
in HTML as generating a block rather than an inline. In practice this is not an issue since the "auto" keyword can easily be mapped to an appropriate CSS property value.
displayAlign
displayAlign is used to specify a style property that defines the alignment of block areas in the block progression direction.
It could be mapped to justify-content in CSS equivalents but there is patchy support for that. In general CSS uses different mechanisms for achieving the functionality; another candidate is the align-self property. In general it may be preferable to use flex layout in CSS for mapping TTML regions.
extent
tts:extent is used to specify the width and height of both regions and images (overriding their intrinsic size).
- What does this map to in CSS? (it seems complicated!) The width and height properties are probably relevant, but so is the layout scheme - flex, table, grid etc that is being used...
fillLineGap
See also csswg-drafts#814 and IMSC 1.0.1 itts:fillLineGap.
This effect might in principle be achieved by setting a padding value equal to the difference between the line height and the content rectangle height, however the content rectangle height is not available and is not deterministic.
The outcome desired is that when displaying text on a contrasting background, gaps between the background areas of consecutive lines can be removed, to make the text easier to read.
There are subtleties here, for example the fact that different background colours can apply across the line area and that the background area may need to be extended in the block progression direction both ways.
CSS has no mechanism for specifying that the background areas between adjacent line areas do not have gaps between them.
fontFamily
tts:fontFamily is used to specify a style property that defines the font family from which glyphs are selected for glyph areas generated by content flowed into a region.
It maps directly to the CSS font-family property.
fontKerning
tts:fontKerning is used to specify a style property that determines whether font kerning is applied when positioning glyph areas.
It maps directly to the CSS font-kerning property.
fontSelectionStrategy
tts:fontSelectionStrategy is not-yet-fully-specified but is intended to be based on the XSL 1.1 font-selection-strategy property. This specifies whether the implementation may choose its own strategy for selecting font(s) for a run of characters or if it must select the font for each character individually.
There is no mapping in CSS for font selection strategy currently. Mozilla documentation (font-family, second note) states that each character to a suitable font individually; the @font-face rule can be used to synthesise a font, which helps to some extent. The CSS Fonts Module Level 3 font style matching algorithm suggests that matching can be done on a character by character basis without explicitly requiring it; on the other hand in that same document Character handling issues says that CSS font matching is always performed on text runs...
- What is the impact of ignoring this?
- It is possible that glyphs chosen from a non-intended font will be used.
fontShear
tts:fontShear allows shear transformations to be applied to glyphs, primarily for the purpose of providing emphasis on ideographic glyphs that do not have italicised versions.
CSS has no support for font shear currently. Ignoring this style attribute generates usable glyphs but loses the emphasis.
fontSize
tts:fontSize is used to specify a style property that defines the font size for glyphs that are selected for glyph areas generated by content flowed into a region.
It partially maps to the CSS font-size property.
- TTML supports anamorphically scaled fonts; CSS does not.
- CSS supports size keywords; TTML does not.
- CSS supports unit-less relative sizes; TTML does not.
fontStyle
tts:fontStyle is used to specify a style property that defines the font style to apply to glyphs that are selected for glyph areas generated by content flowed into a region, where the mapping from font style value to specific font face or style parameterization is not determined by this specification.
It maps directly to the CSS font-style property.
fontVariant
tts:fontVariant is used to enable the selection of typographic glyph variants.
It maps partially to the CSS font-variant property and partially to the font-variant-position property; some values in CSS are not available in TTML, which only supports "normal" | [ "super" | "sub" ] || [ "full" | "half" ] || ruby
.
fontWeight
tts:fontWeight is used to specify a style property that defines the font weight to apply to glyphs that are selected for glyph areas generated by content flowed into a region, where the mapping from font weight value to specific font face or weight parameterization is not determined by the specification.
It maps directly to the CSS font-weight property though some values in CSS are not available in TTML, which only supports "normal" | "bold"
.
inlineAreaBreak
tts:inlineAreaBreak is used to specify a style property that defines whether border and padding apply at the start and end edges of an inline area in the context of a fragmentation (break) boundary, for example, at line breaks.
This maps directly to the CSS box-decoration-break property however there is no mapping for the "cloneMostNested" value, which is needed to simulate the IMSC linePadding feature. Ignoring this style attribute generates usable text with a loss of readability when a contrasting background area is used.
- CSS issue [css-break] Consider adding clone-most-nested #1633 raised.
ipd
tts:ipd is used to specify the inline progression dimension, or, more succinctly, the ipd of an area generated by content flowed into a region.
- What does this map to in CSS?
letterSpacing
tts:letterSpacing is used to specify a style property that increases or decreases the nominal distance between glyph areas.
Direct mapping to CSS letter-spacing property.
lineHeight
tts:lineHeight is used to specify a style property that defines the inter-baseline separation between line areas generated by content flowed into a region.
It maps directly to the CSS line-height property though some units in CSS are not available in TTML, such as unit-less numbers.
luminanceGain
tts:luminanceGain is used to specify the absolute luminance of a region when its presentation requires a greater dynamic range than that provided by the sRGB color space [SRGB], and when that presentation requires an absolute luminance value.
CSS has no mechanism for specifying absolute luminance gain for mapping sRGB input colour values to high dynamic range output values as may be needed for example for the PQ HDR scheme.
opacity
tts:opacity is used to specify a style property that defines the opacity (or conversely, the transparency) of marks associated with a region or an area generated by content flowed into a region.
It maps directly to the CSS opacity property.
origin and position
tts:origin is used to specify the x and y coordinates of the origin of a region area with respect to the origin of the root container region.
It can be mapped to position - see below.
tts:position is used as a way to specify the position of a region area with respect to a positioning rectangle.
There are likely to be multiple ways to approach positioning of a region within a known rectangle such as a video window. It is not clear which should be preferred.
For example there are different layout models available, such as the basic box model layout, the flexible box layout, box alignment, Regions, and possibly others?
- Which is the best mapping for positioning and sizing regions into CSS?
overflow
tts:overflow is used to specify a style property that defines whether a region area is clipped or not if the descendant areas of the region overflow its extent.
It maps directly to the CSS overflow property however the "scroll" keyword is not available in TTML, and the TTML semantics are expressed only as SHOULD regardless of the specified value.
padding
tts:padding is used to specify padding (or inset) space on one or more sides of a region or an area generated by content flowed into a region.
In TTML2 this is extended relative to TTML1, alongside tts:inlineAreaBreak="cloneMostNested" to cover the IMSC1 case of linePadding by allowing padding to apply to <span>
elements and in that case applying the padding value to each generated line area individually.
Direct mapping to CSS padding property.
position
See origin and position above.
ruby
tts:ruby is used on a <span>
element to specify ruby semantics ruby, ruby base, ruby container, ruby text, ruby-base-container, ruby-text-container and a ruby fallback delimiter.
It can be directly mapped to the ruby-* values of the CSS display property; alternatively the markup can be mapped to HTML ruby markup.
rubyAlign
tts:rubyAlign is used to specify the position of ruby text within the inline area generated by the ruby text container annotation.
It maps directly to the CSS ruby-align property except for the values: auto, end, withBase. These values could be replaced with "space-around"
- What is the impact of using space-around?
- space-around will not be the author's intended behavior but will have minimal impact on functionality of ruby -- it won't be as pretty as the author intended but will not degrade viewer comprehension
rubyOffset
tts:rubyOffset is used to specify the offset (distance) of ruby text with respect to its associated ruby base in the block progression dimension.
It has no mapping in CSS.
- What is the impact of ignoring rubyOffset?
- will not be the author's intended behavior but will have minimal impact on functionality of ruby -- it won't be as pretty as the author intended but will not degrade viewer comprehension
rubyOverflow
tts:rubyOverflow is used to specify constraint resolution rules for handling certain edge effects involving ruby text in potential overflow scenarios. For example, if the inline progression dimension of a ruby text area exceeds the inline progression dimension of its associated base text, and that base text appears at the start or end edge of a line area, then the ruby text may potentially overflow its containing block area depending on the applicable ruby text alignment as determined by the tts:rubyAlign style property.
- tts:rubyOverflow="overflow" maps to the default CSS behaviour.
- No equivalents for shiftRuby and shiftBase?
- yes but CSS states "this level of the specification does not provide a mechanism to control this behavior"
- What is the impact if shiftRuby and shiftBase are specified but ignored?
- will not be the author's intended behavior but will have minimal impact on functionality of ruby -- it won't be as pretty as the author intended but will not degrade viewer comprehension. note that it is highly unlikely that a Japanese subtitle author wants anything but "overflow"
rubyOverhang
tts:rubyOverhang is used to specify constraint resolution rules for handling potential cases of overhang between ruby text and adjacent base text, where by adjacent base text is meant baseline aligned inline content that is immediately adjacent to the base text associated with the ruby text. In the case where the inline progression dimension of the ruby text exceeds the inline progression dimension of its associated base text, or in ruby overflow cases where the ruby text must be inset, then it is possible that the ruby text may overhang content set on the baseline that is not part of the ruby text's associated base text. In such cases, the tts:rubyOverhang attribute may be used to determine whether and how much overhang is allowed to occur.
rubyOverhang is allowed in CSS but it "does not define how much the overhang may be allowed, and under what conditions"
rubyOverhangClass
tts:rubyOverhangClass is used to provide fine-grained control over the semantics of the style property expressed by the tts:rubyOverhang attribute. In particular, it used to specify the set of base text characters which accept overhanging ruby text. If a base text character is not in this specified set, then ruby text is prevented from overhanging that character.
There is no mapping for rubyOverhangClass in CSS.
rubyPosition
tts:rubyPosition is used to specify the position of ruby text in the block progression dimension with respect to its associated ruby base.
It maps directly to the CSS ruby-position property (refer to TTML2 Table 8-2) depending on the writingMode in operation.
rubyReserve
tts:rubyReserve is used to specify additional space to apply to affected line areas in order to reserve sufficient room in the block progression dimension to contain inline areas generated by ruby text containers placed within the bounds of the line areas.
It has no mapping in CSS.
- What is the impact of ignoring rubyReserve?
- will not be the author's intended behavior but will have minimal impact on functionality of ruby -- it won't be as pretty as the author intended but will not degrade viewer comprehension
showBackground
tts:showBackground is used to specify constraints on when the background color of a region is intended to be presented.
There is no mapping from tts:showBackground to CSS currently since showBackground affects display of the region background dependent on that region's temporal activation; presumably in CSS some combination of class and (psuedo?) selector would be needed to identify the active and inactive content and modify the background color presentation as needed.
textAlign
tts:textAlign is used to specify a style property that defines how inline areas are aligned within a containing block area in the inline progression direction.
Use of tts:textAlign on nested elements is intended to replace the IMSC multiRowAlign feature.
It maps directly to the CSS text-align property for simple cases however it supports alignment of nested elements differently to CSS, see also multiRowAlign.
See ttml2#238 regarding mapping to CSS and the difference between what implementations do and what may be specified.
textCombine
tts:textCombine is used in vertical writing modes to specify a style property that determines whether and how multiple nominally non-combining characters are combined so that their glyph areas consume the nominal bounding box of a single em square of the surrounding vertical text. If a horizontal writing mode applies, then this property is ignored for the purpose of presentation processing.
- tts:textCombine maps directly to CSS text-combine-upright
textDecoration
tts:textDecoration is used to specify a style property that defines a text decoration effect to apply to glyph areas or other inline areas that are generated by content flowed into a region.
This maps directly to the CSS text-decoration property however the "blink" keyword is not available in TTML, and each separate sub-property is separately inherited.
textEmphasis
tts:textEmphasis is used to specify a style property that determines whether and how text emphasis marks are presented on affected content.
- emphasis-style maps directly to the CSS text-emphasis-style property;
- emphasis-color maps directly to the CSS text-emphasis-color property;
- emphasis-position maps directly to the CSS text-emphasis-position property (refer to TTML2 Table 8-2)
textOrientation
tts:textOrientation is used to specify a style property that defines a text orientation to apply to glyphs that are selected for glyph areas generated by content flowed into a region to which a vertical writing mode applies.
It maps directly to the CSS text-orientation property except the values: sidewaysLeft, sidewaysRight (CSS sideways-rl and sideways-lr are "at-risk and may be dropped during CR"). These values could be replaced with "mixed"
- What is the impact of replacing sidewaysLeft and sidewaysRight with "mixed"?
textOutline
tts:textOutline is used to specify a style property that defines a text outline effect to apply to glyphs that are selected for glyph areas generated by content flowed into a region.
In principle this maps to the CSS text-outline property however there is no support for that in any browser, and in practice this is in the process of being deprecated in favour of textShadow.
An alternative could be to use the CSS stroke-width property for tts:textOutline's first length component; there is no mapping of blur radius.
textShadow
tts:textShadow is used to specify a style property that defines one or more text shadow decorations to apply to glyphs that are selected for glyph areas generated by content flowed into a region.
- This maps directly to the CSS text-shadow property.
unicodeBidi
tts:unicodeBidi is used to specify a style property that defines an explicit directional embedding, override or isolate according to the Unicode bidirectional algorithm.
This maps directly to the CSS unicode-bidi property however the "isolate-override" and "plaintext" keywords are not available in TTML.
visibility
tts:visibility is used to specify a style property that defines whether generated areas are visible or not when rendered on a visual presentation medium.
This maps directly to the CSS visibility property however the "collapse" keyword is not available in TTML (table layout is not available in TTML so it is not applicable in any case).
wrapOption
tts:wrapOption is used to specify a style property that defines whether or not automatic line wrapping (breaking) applies within the context of the affected element.
When considered in combination with the xml:space
attribute this maps to the CSS white-space property. xml:space controls the collapsing of white space; tts:wrapOption controls whether lines are permitted to wrap or not. Hence there is a complex mapping.
writingMode
tts:writingMode is used to specify a style property that defines the block and inline progression directions to be used for the purpose of stacking block and inline areas within a region area.
This maps to the CSS writing-mode property however there is some variation. Whereas TTML permits the values lrtb | rltb | tbrl | tblr | lr | rl | tb
, writing-mode permits horizontal-tb | vertical-rl | vertical-lr
- clearly the inline (horizontal) inline block layout modes are not distinguished in direction by this CSS property but they are by TTML. It appears that inline block layout progression is inferred in CSS, perhaps by inspection of the text content direction or explicitly the direction property value.
zIndex
tts:zIndex is used to specify a style property that defines the front-to-back ordering of region areas in the case that they overlap.
This maps directly to the CSS z-index property.
initial and root style inheritance
The initial element is used to modify the initial value of one or more style properties, i.e, to specify use of different value(s) than the specification defined initial value(s).
This would likely be implemented in CSS by using a broad selector applying to the parent element within which the TTML content will be placed.
Additionally there is an alternate mechanism available for achieving somewhat similar results, which is to specify styles on the root element which apply via the root style inheritance algorithm.
- Need more feedback from implementors - what is the preferred mapping of initial and root style inheritance to HTML/CSS?
linePadding
This is an IMSC1 feature - see padding for the TTML2 equivalent.
This feature allows the background of every line area to be extended, in whatever colour it is at that edge, regardless of
whether line breaks were inserted manually or were generated automatically to avoid overflow in the inline direction.
Since line areas cannot be addressed directly in CSS, this is hard to achieve. box-decoration-break: clone
is insufficient
because it does not seem to work for automatically generated line breaks.
See CSS samples.
See for example of a test this TTML generating this image.
CSS cannot straightforwardly support this feature for all cases - this is the same issue as for inlineAreaBreak below.
multiRowAlign
This is an IMSC1 feature - the equivalent in TTML2 is to apply textAlign to nested elements.
multiRowAlign allows a group of lines within a <p>
to be aligned in the inline direction relative to the containing block, while each line within the group is aligned relative to each other, for example all the lines in the group left aligned with each other and the entire group centred.
multiRowAlign semantics are not supported by CSS and/or UAs when lines are automatically broken.
See thread at https://lists.w3.org/Archives/Public/public-tt/2016Dec/0021.html and codepen at https://codepen.io/palemieux/pen/yVxZWm
In a nutshell, alignment of <span>
s seem to require explicit <br>
spurious spaces before BR
See https://lists.w3.org/Archives/Public/public-tt/2017Jul/0027.html
Chrome does not suppress spaces at the end of a line before a <br>
. Firefox does do so. Is this expected from CSS or a bug in Chrome?