Text and material
The bundled faces and why there is no font name, vertical setting for CJK, controlling line breaks, and how a photograph enters a document.
A closed list of faces, and no font name
font names one or more typefaces, and the list is closed: every face on it is
bundled, and the reference page for <e9-text> shows the whole list with what
each one is for.
<e9-text role="title" font="Montserrat">Autumn, together</e9-text>
<e9-text role="title" font="Montserrat, 站酷快乐体">秋天,一起</e9-text>Closed is the only unusual thing about it. font="Helvetica" is a refusal,
because a face this engine does not ship would be resolved against whatever fonts
the rendering machine happens to have — which is exactly the dependency the render
contract exists to remove. What the refusal gives back is the list of faces that
are here.
The spelling is lenient where the face is not. A face also answers to the names it
is otherwise known by — Cormorant for Cormorant Garamond, ZCOOL KuaiLe for
站酷快乐体 — and the document keeps the face's own name, so one face has one
spelling in a canonical document.
A face is drawn for the scripts it is drawn for, and the list is a fallback
order. The browser picks per glyph, first match wins, so the second name in
font="Montserrat, 站酷快乐体" is what a Chinese run is set in and the first is
what a Latin one is. Name a face for each script the design actually sets.
What you do not name is completed, never left as a hole. Any script no named
face serves falls to the shared 黑体 or 宋体 — whichever suits the first face you
did name — so font="Montserrat" still renders Chinese, in the workhorse rather
than in something chosen. A named face always outranks a completed one.
The consequence is a rule with no way around it. A character no face in the
list can draw is a check failure, not a fallback (glyph-coverage). Naming
another font cannot fix it, because there is no parameter for a font name outside
this list. What fixes it is adding a face that covers the character — the refusal
names them — rewriting the copy, or setting that text as artwork and placing it
with <e9-image>.
Coverage is a property of the face, not of the engine. The workhorses draw Latin, simplified Chinese, Korean and Japanese between them; the display faces are narrower, and some of them much narrower — a face drawn for Chinese headlines carries GB/T 2312's hanzi and no kana at all. That is why the check asks about the faces you named rather than about the bundled set as a whole.
At most two weights exist, 400 and 700, and any other value would be a weight
the browser synthesized — which renders differently across Chromium builds.
Not every face has both. Several display faces were drawn once, in one
weight, with no italic; asking one of those for a bold or a slant is refused by
name, and the refusal points at a face that has it.
italic="true" sets Latin in a bundled italic face. There is no italic Chinese
face to bundle, so a Chinese run asked to slant would be slanted by the browser
rather than drawn, and the synthesized-style check warns about that by name.
Emphasise Chinese with a different weight or face instead.
Roles before sizes
role — title, subtitle, body, caption — supplies the type scale: size,
weight and line height together. Choose the role first and override only where
the design genuinely departs from it. A set whose every text Block carries an
explicit size has flattened its own scale.
Vertical setting
For a column of Chinese or Japanese reading top to bottom, set
vertical="true" on <e9-text>. Never rotate: a rotation turns the glyphs on
their side, and it cannot make successive columns run right to left, which is
half of what vertical setting is. With vertical, the glyphs stay upright,
punctuation takes its vertical forms, and a Latin word inside the column lies on
its side — which is the convention.
Where a line breaks
Line breaks are controllable, so there is no need to binary-search max-width:
forces a break. keeps two words together.­permits a break inside a long word.wrap="balance"evens out the lines of a heading.
Material the engine does not draw
Photography, textures, brush lettering and logos are source material. The
engine never draws them. They are made or fetched outside it, added to the
Project's assets, and placed with <e9-image src="asset://…">.
The same is true of shapes the vocabulary cannot draw — arrows, curves, icons. Write the SVG, add it as an asset, place it as an image.
Two things about assets are worth knowing before the first one:
- A parameter carrying an
http,file,data,bloborjavascriptURI is refused (forbidden-uri). Material is addressed asasset://path, and anasset://that this Project does not hold is a check failure (missing-asset) rather than a hole in the picture. - Artwork that arrived baked onto its own ground — brushed lettering on white, a
paper grain — goes down with
blend="multiply", so it composites onto the page instead of covering what is beneath it as a rectangle.multiplykeeps the darker of the two, so it only erases a ground that is white: commission the asset on white, or leaveblendalone.
An SVG that draws live <text> is a warning (asset-font), not an error: an
SVG loaded as an image is an isolated document and cannot see the renderer's
bundled faces, so it resolves families against the machine's own font list. The
render is not wrong; its reproducibility is narrower than everything around it.
Placement and layout
Flowing versus absolute, what anchor and bleed are for, why paint order is document order, and when to reach for a group instead of a stack.
Conventions
The rules that are true of e9-HTML and are in no schema — published verbatim from the engine, because three blind runs found them by getting them wrong.