
本文介绍一种精准控制打字光标显示位置的方案:仅在当前正在输入的段落末尾显示闪烁光标,已输入完成的段落(除最后一行外)不显示光标,避免多光标堆叠问题。
本文介绍一种精准控制打字光标显示位置的方案:仅在当前正在输入的段落末尾显示闪烁光标,已输入完成的段落(除最后一行外)不显示光标,避免多光标堆叠问题。
实现逐行打字动画时,一个常见痛点是光标(caret)无法“跟随”当前输入位置——若直接给 元素设置 border-right 动画,光标会占据整行宽度、错位到行尾,且所有段落同时显示光标,破坏视觉节奏。
核心解法在于分离内容与光标:不将光标作为段落自身样式,而是通过 ::after 伪元素动态附加在“活跃段落”末尾,并利用 CSS 选择器精准控制其出现时机。
✅ 正确的 CSS 逻辑
#str p:not(:empty):not(.complete:not(:last-child)):after {
content: "";
display: inline-block;
height: 1em;
border-right: 0.15em solid orange;
vertical-align: bottom;
animation: blink-caret 0.5s step-end infinite;
}
@keyframes blink-caret {
from, to { border-color: transparent; }
50% { border-color: orange; }
}
关键选择器解析:
-
:not(:empty)→ 排除空段落(尚未开始输入),避免初始光标漂浮; -
:not(.complete:not(:last-child))→ 双重否定逻辑:- 若段落已加
complete类(即输入完毕),且不是最后一行 → 不显示光标; - 若是最后一行(
:last-child),即使有complete类,仍保留光标(符合用户预期:最终停留在结尾); - 若未加
complete类(正在输入中),无论是否最后一行,均显示光标。
- 若段落已加
✅ JavaScript 配合逻辑
在打字完成时为当前 添加 complete 类,触发 CSS 规则切换:
::after










