Skip to main content

编程杂记 #2

·336 words·2 mins

CSS文字与图片对齐
#

Flex布局用align-items: center就能让文字和icon居中对齐。 这里只讨论inline布局的情况。

vertical-align: middle对齐的是x-height而非cap-height,导致icon偏下。 用cap单位修正:

icon尺寸未知时,用负margin补偿x-height与cap-height的差:

1.icon {
2    vertical-align: middle;
3    margin-block-start: calc(1ex - 1cap);
4}

icon尺寸已知时,直接算vertical-align偏移量:

1.icon {
2    --size: min(2em, 10vw);
3    vertical-align: calc(0.5cap - 0.5 * var(--size));
4}

不支持cap的浏览器,用@supports回退到手动测量的em值:

 1html {
 2    /* Adjusted for Iowan Old Style */
 3    --cap: 0.704583em;
 4}
 5
 6@supports (height: 1cap) {
 7    html {
 8        --cap: 1cap;
 9    }
10}
11
12.icon {
13    vertical-align: middle;
14    margin-block-start: calc(1ex - var(--cap));
15}

Ref: Cap-Height Vertical Align by Roma Komarov

CSS中文排版text-autospacetext-spacing-trim
#

text-autospace在CJK字符和西文字母/数字之间自动插入约1/8 em的微间距,不需要在源文本里手动加空格。

text-spacing-trim处理CJK标点的宽度压缩。 CJK标点在字体里通常占一个全角宽度,但字形本身只用了半边,另外半边是空白。 两个标点相邻时(比如"」,"或"。「"),两个半宽空白叠在一起就显得松散,这个属性自动压缩多余间距。

两个属性从Chromium 120+开始支持,可以作为渐进增强使用,不支持的浏览器无副作用。

常见预装字体
#

Windows:

  • Sans-serif: Arial, Segoe UI, Verdana, Tahoma, Calibri
  • Serif: Times New Roman, Georgia, Cambria
  • Monospace: Consolas, Courier New, Cascadia Mono(Windows Terminal自带)

macOS:

  • Sans-serif: Helvetica, San Francisco(系统UI), Arial
  • Serif: Times New Roman, Georgia
  • Monospace: Menlo, Monaco, SF Mono, Courier New

Linux(取决于发行版和字体包):

  • Sans-serif: Noto Sans, DejaVu Sans
  • Serif: Noto Serif, DejaVu Serif
  • Monospace: DejaVu Sans Mono, Noto Sans Mono
  • Liberation系列(Liberation Sans/Serif/Mono)是Arial/Times New Roman/Courier New的度量兼容替代品,很多发行版预装。

Windows和macOS之间交集比较大(Arial、Times New Roman、Georgia、Courier New),Linux和它们的交集很小,主要靠Liberation和DejaVu系列覆盖。

C++有符号整数转换时的sign extension陷阱
#

将有符号转无符号再扩展宽度时,转换顺序会影响结果。

先扩展再转无符号:

1int8_t x = -1;          // 1111 1111
2uint16_t y = x;          // 先 sign extend 到 int16: 1111 1111 1111 1111
3                         // 再转 uint16: 65535

先转无符号再扩展:

1int8_t x = -1;           // 1111 1111
2uint8_t mid = x;         // 1111 1111 (255)
3uint16_t y = mid;        // zero extend: 0000 0000 1111 1111 (255)

同样的原始值-1,结果分别是65535和255。 原因是扩展时看源类型的signedness:有符号做sign extension,无符号做zero extension。

Bash set -e在条件上下文中失效
#

set -e(errexit)让脚本在任意命令失败时立即退出。 但如果命令处于||&&if的条件部分,set -e会被静默禁用,包括子shell内显式写的set -e

1#!/bin/bash
2(
3    set -e
4    false
5    echo a
6) || echo b

直觉上set -efalse应该让子shell立即退出,跳过echo a,然后||右侧的echo b执行。 实际输出是a

原因:子shell (...)处于||左侧,属于条件上下文。 Bash在这种上下文中压制errexit,即使子shell内部显式执行了set -e也不生效。 所以false返回非零但不触发退出,echo a正常执行,子shell以0退出,echo b不执行。

如果确实需要子shell在失败时退出,不要依赖set -e,显式检查退出码:

1(
2    false || exit 1
3    echo a
4) || echo b
5# 输出: b

.au域名
#

.au域名要求注册者必须是澳大利亚公民/永久居民、持有ABN/ACN的澳大利亚实体、或持有与域名完全匹配的澳大利亚注册商标的外国实体,且资格须在整个持有期间持续有效,否则域名会被直接删除且不退款。

Bun优点和兼容性问题
#

优点
#

  • 单一二进制:runtime + bundler + test runner + package manager,零配置冲突。
  • :Zig + JSC引擎,bun install / bun test冷启动体感显著快于Node生态同类工具,CI受益最大。
  • 原生TS/JSX:不依赖esbuild转译层,直接跑.ts/.tsx
  • 内置实用APIBun.serve()bun:sqliteBun.passwordBun.S3,简单后端无需额外框架。
  • Serverless友好:~20ms启动,Lambda冷启动成本直降。

兼容性问题
#

Native Addon:任何带binding.gyp的包都可能挂。 bcrypt直接报MODULE_NOT_FOUND(换bcryptjs);canvas不可用且无workaround;sharp 2026年靠WASM fallback基本能跑但需验证平台;better-sqlite3不可用(用bun:sqlite替代)。 Bun.password验证Node bcrypt生成的$2a$哈希会返回false,需手动替换前缀为$2b$

调试bun --inspect断点不可靠,await单步会迷失,sourcemap映射常错位,结束后端口不释放。 Windows上VS Code调试直接不可用(ws+unix://路径解析失败)。

Test Runner:未集成VS Code Test Explorer;monorepo下同class的instanceof断言可能误判(双重模块解析)。

Next.js:当package manager安全;当runtime需逐一验证依赖。 Bun workspaces下TS项目启动失败(hoisting差异导致@types/node丢失);有部署时SIGILL crash的报告。 Vercel 2025.10起支持Bun runtime(public beta)。

Workspace:npm的"pkg": "*"写法不被识别为workspace引用,必须写workspace:*,现有npm monorepo直接切可能坏。

bun build:不完全尊重tsconfig.json,默认把node_modules全打包,external / packages语义易混淆。