754b00da42
段末行 CJK 實義字數 ≥ N(預設 2;標點/符號不計)。standalone 段落級 pass:
自段末向前數 N 個實義字,把「第 N 字起至段末」(含其間/尾隨標點)包入
<jz-orphan>(white-space:nowrap)。該整體不可斷 → 末行恒含之 ⇒ 末行實義字 ≥ N,
任意寬度/字型/瀏覽器成立,無需量測 layout。
要點:
- 邊界字定位跨 jz-jinze/行內元素攀爬:實義字落於行內元素內時綁定整個塊級
直接子(不切割 nowrap 群、revert 乾淨);僅裸文本直接子才精確切分(最小綁定)。
- 僅處理葉段落(無塊級後代);段落實義字 < N 不綁;單行段方案 C 本就無害。
- 選項 orphan?: boolean | { chars? };**預設開 chars=2**(§6.5.6 建議);
下游可 orphan:false 關閉。段落級,data-jz-level=text 子樹自動跳過。
- order=70:jinze(40)/spacing(50)/longWord(60) 後、layout pass(90/92) 前。
新增 _orphan.css(jz-orphan{white-space:nowrap});JzTag 加 jz-orphan。
9 項單元測試(末 N+尾標點、chars 選項、標點不計、實義字<N 不綁、跨 jinze、
關閉、冪等、revert、段落級閘)。共 85 測試全綠。
窄容器拖動「末行恒 ≥N」之 layout 驗證留待 demo(Step 4-5,瀏覽器)。
105 lines
2.5 KiB
CSS
105 lines
2.5 KiB
CSS
/* src/css/_normalize.css */
|
|
@supports (text-autospace: no-autospace) {
|
|
.juzhen {
|
|
text-autospace: no-autospace;
|
|
}
|
|
}
|
|
jz-char,
|
|
jz-inner,
|
|
jz-hws,
|
|
jz-cs,
|
|
jz-jinze,
|
|
jz-em {
|
|
font: inherit;
|
|
color: inherit;
|
|
text-indent: 0;
|
|
hanging-punctuation: none;
|
|
}
|
|
jz-char,
|
|
jz-jinze {
|
|
text-decoration: inherit;
|
|
}
|
|
|
|
/* src/css/_spacing.css */
|
|
jz-hws {
|
|
margin-right: 0.25em;
|
|
}
|
|
jz-hws.jz-hws-trim {
|
|
margin-right: 0;
|
|
}
|
|
|
|
/* src/css/_jiya.css */
|
|
jz-char {
|
|
display: inline-block;
|
|
vertical-align: baseline;
|
|
}
|
|
jz-inner {
|
|
display: inline;
|
|
}
|
|
[data-jz-atoms=inline] jz-char {
|
|
display: inline;
|
|
}
|
|
jz-char.jz-half jz-inner,
|
|
jz-char.jz-half-le jz-inner {
|
|
font-feature-settings: "locl" 1, "halt" 1;
|
|
-webkit-font-feature-settings: "locl" 1, "halt" 1;
|
|
}
|
|
[data-jz-halfwidth=margin] jz-char.jz-half jz-inner,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half-le jz-inner {
|
|
font-feature-settings: normal;
|
|
-webkit-font-feature-settings: normal;
|
|
}
|
|
[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-left,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-center,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-right,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-left,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-center,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-right {
|
|
width: 0.5em;
|
|
overflow: visible;
|
|
}
|
|
[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-left jz-inner,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-center jz-inner,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half.jz-ink-right jz-inner,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-left jz-inner,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-center jz-inner,
|
|
[data-jz-halfwidth=margin] jz-char.jz-half-le.jz-ink-right jz-inner {
|
|
display: inline-block;
|
|
}
|
|
[data-jz-halfwidth=margin] jz-char.jz-ink-center jz-inner {
|
|
margin-left: -0.25em;
|
|
}
|
|
[data-jz-halfwidth=margin] jz-char.jz-ink-right jz-inner {
|
|
margin-left: -0.5em;
|
|
}
|
|
[data-jz-halfwidth=margin] jz-char jz-inner {
|
|
text-decoration: inherit;
|
|
}
|
|
[data-jz-halfwidth=halt] jz-char.jz-half jz-inner,
|
|
[data-jz-halfwidth=halt] jz-char.jz-half-le jz-inner {
|
|
font-feature-settings: "locl" 1, "halt" 1;
|
|
-webkit-font-feature-settings: "locl" 1, "halt" 1;
|
|
margin-left: 0;
|
|
}
|
|
[data-jz-halfwidth=halt] jz-char.jz-half,
|
|
[data-jz-halfwidth=halt] jz-char.jz-half-le {
|
|
width: auto;
|
|
}
|
|
|
|
/* src/css/_jinze.css */
|
|
jz-jinze {
|
|
display: inline-block;
|
|
white-space: nowrap;
|
|
vertical-align: baseline;
|
|
}
|
|
[data-jz-atoms=inline] jz-jinze {
|
|
display: inline;
|
|
}
|
|
|
|
/* src/css/_orphan.css */
|
|
jz-orphan {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* src/css/juzhen.css */
|