DEMO
いつもの指定
Get started NEW Motiontext-box: trim-both cap alphabetic
Get started NEW Motionこのブラウザは text-box に未対応のため、左右が同じ見た目になります
CODE
<div class="demo-stage tbt-stage">
<div class="tbt-grid" id="tbt-grid">
<div class="tbt-col">
<p class="tbt-head">いつもの指定</p>
<span class="tbt-pill">Get started</span>
<span class="tbt-badge">NEW</span>
<span class="tbt-big">Motion</span>
</div>
<div class="tbt-col tbt-on">
<p class="tbt-head">text-box: trim-both cap alphabetic</p>
<span class="tbt-pill">Get started</span>
<span class="tbt-badge">NEW</span>
<span class="tbt-big">Motion</span>
</div>
</div>
<button type="button" class="tbt-toggle" id="tbt-toggle" aria-pressed="true">右側に trim を適用</button>
<p class="tbt-note">このブラウザは text-box に未対応のため、左右が同じ見た目になります</p>
</div>
.tbt-stage { position:relative; overflow:hidden; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1rem; padding:2rem 1.25rem; background:#0B0B10; min-height:340px; }
.tbt-grid { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:1rem; width:100%; max-width:520px; }
.tbt-col { display:flex; flex-direction:column; align-items:center; gap:.9rem; padding:1rem .5rem; border-radius:12px; background:#15151B; }
.tbt-head { margin:0; color:#A1A1AA; font-size:.72rem; text-align:center; font-family:ui-monospace,monospace; line-height:1.5; }
.tbt-pill, .tbt-badge, .tbt-big { display:inline-block; outline:1px dashed rgba(244,114,182,.7); outline-offset:0; transition: outline-color .3s; }
.tbt-pill { padding:.7rem 1.2rem; border-radius:999px; background:#D1177A; color:#fff; font-weight:600; font-size:.95rem; line-height:1.6; }
.tbt-badge { padding:.35rem .6rem; border-radius:6px; background:#EDEDED; color:#1A1A1A; font-weight:700; font-size:.72rem; letter-spacing:.12em; line-height:1.6; }
.tbt-big { color:#fff; font-family:'Oswald',sans-serif; font-size:2.6rem; font-weight:600; line-height:1.3; }
/* 右の列だけ、文字の上端(大文字の高さ)から下端(ベースライン)までに箱を切り詰める */
.tbt-on .tbt-pill, .tbt-on .tbt-badge, .tbt-on .tbt-big { text-box: trim-both cap alphabetic; }
.tbt-on.is-off .tbt-pill, .tbt-on.is-off .tbt-badge, .tbt-on.is-off .tbt-big { text-box: normal; }
.tbt-on .tbt-pill, .tbt-on .tbt-badge, .tbt-on .tbt-big { animation: tbt-flash .6s ease-out; }
.tbt-on.is-off .tbt-pill, .tbt-on.is-off .tbt-badge, .tbt-on.is-off .tbt-big { animation: tbt-flash2 .6s ease-out; }
@keyframes tbt-flash { from { outline-color:#fff; outline-offset:4px; } }
@keyframes tbt-flash2 { from { outline-color:#fff; outline-offset:4px; } }
.tbt-toggle { min-height:44px; padding:0 1.1rem; border-radius:10px; border:1px solid rgba(255,255,255,.22); background:transparent; color:#EDEDED; font:inherit; font-size:.84rem; cursor:pointer; }
.tbt-toggle::after { content:":OFF" / ""; } /* 状態は aria-pressed で伝え、見た目の ON/OFF は読み上げない */
.tbt-toggle[aria-pressed="true"] { border-color:#F472B6; color:#F9A8D4; }
.tbt-toggle[aria-pressed="true"]::after { content:":ON" / ""; }
.tbt-toggle:focus-visible { outline:2px solid #fff; outline-offset:3px; }
.tbt-note { display:none; margin:0; color:#FCD34D; font-size:.76rem; text-align:center; }
@supports not (text-box: trim-both cap alphabetic) {
.tbt-note { display:block; }
}
@media (prefers-reduced-motion: reduce) {
.tbt-on :is(.tbt-pill, .tbt-badge, .tbt-big), .tbt-on.is-off :is(.tbt-pill, .tbt-badge, .tbt-big) { animation:none; }
}
(function(){
var btn = document.getElementById('tbt-toggle');
var col = document.querySelector('.tbt-on');
if (!btn || !col) return;
btn.addEventListener('click', function(){
var off = col.classList.toggle('is-off');
btn.setAttribute('aria-pressed', String(!off)); /* ラベルは変えず、状態は aria-pressed で伝える */
});
})();
AI PROMPT
ボタンやバッジの文字が上下の真ん中からずれて見える問題を、CSS の text-box で直す比較デモを作って。2列のグリッドに、左は普通の指定、右は text-box: trim-both cap alphabetic(text-box-trim: trim-both と text-box-edge: cap alphabetic の一括指定)を付けた同じ3つの要素(角丸のボタン風の pill・小さなバッジ・大きな見出し文字)を並べる。各要素は display:inline-block にして、1px の点線の outline で箱の大きさを見えるようにする(右側は大文字の高さからベースラインまでに箱が縮み、padding が上下で同じに見える)。「右側に trim を適用」ボタン(aria-pressed を付け、ラベルの文字は変えない。ON/OFF の表示は ::after の content: ":ON" / "" のように読み上げ用の代替テキストを空にして見た目だけに出す)で右側の指定を text-box: normal と切り替え、切り替えた瞬間に outline を白く少し外側から戻す 0.6秒のアニメーションで変化を目立たせる(同じ名前のアニメーションは付け直しても再生されないので、ON と OFF で別の @keyframes 名にする)。@supports not (text-box: trim-both cap alphabetic) の時は「このブラウザは未対応」の注記を表示する。prefers-reduced-motion: reduce の時はアニメーションを無効化する。 Acceptance criteria: works with prefers-reduced-motion (animation disabled), zero console errors, zero layout shift
AIエージェントでの実装ガイド → Claude Code でWebアニメーションを実装する
BOOKS · PR · AMAZON
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
学びを止めない · AMAZONサブスク
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
CREATOR TOOLS · スクール(PR)
※本サイトはアフィリエイトリンクを含みます。リンク経由のご購入・お申し込みで運営者が紹介料を受け取る場合があります。
text-box-trim は、文字の箱の上側と下側のどちらの余白を削るかを決める CSS のプロパティで、MDN では「テキスト要素のブロックコンテナから、テキストの上端と下端のどちらを切り詰めるかを指定する」と説明されています。どこまで削るかは text-box-edge で決め、cap alphabetic なら大文字の高さからベースラインまでになります。この2つは text-box でまとめて書けます。
当サイトの Variable Font Morph は可変フォントの太さと幅を連続して変える演出、Marker Highlight Text は蛍光ペンで線を引くように文字の下へ色が走る演出、Word Pull Up は見出しの単語が1つずつ下からせり上がる演出です。本ページは文字を動かすのではなく、文字の箱の大きさを実際の文字の高さに合わせる別テーマです。
ボタン・バッジ・タグのように背景色の中に短い文字を置く部品や、画像と見出しの上端を揃えたい場面で効果がはっきり出ます。デザインツールの見た目とブラウザの表示が数ピクセルずれる原因の1つがこの余白なので、部品の共通スタイルに入れておくと調整の手間が減ります。
文字が下にずれて見えるのはなぜですか?
文字の箱には、行の高さのうち文字そのものより上と下に余白(ハーフレディング)があり、さらに大文字の上端より上の空きと、ベースラインより下の空きの大きさはフォントの設計で決まるため、上下が同じとは限りません。そのため padding を上下同じにしても、文字が上か下に寄って見えることがあります。text-box: trim-both cap alphabetic は、箱の上端を大文字の高さ、下端をベースラインに合わせて余白を削るので、padding の数値どおりの見た目で真ん中に揃います。
どのブラウザで使えますか?
MDN の互換性データ(browser-compat-data 2026-09-24 版)では、text-box・text-box-trim・text-box-edge は Chrome・Edge 133、Firefox 154、Safari 18.2 から使えます。未対応のブラウザでは指定が無視され、今までどおりの見た目になるだけなので、レイアウトが崩れることはありません。本デモは @supports not で未対応の時だけ注記を出しています。
コードは無料で使えますか?
はい。Motion LabのコードスニペットとAIプロンプトは、クレジット表記なしで自由に使えます。コピーしてそのままプロジェクトに利用できます。