DEMO
デザインで大切なのは、伝えたいことを1つに絞ることです。そのうえで読む順番を設計し、最後に行動をひとつだけ示します。
CODE
<div class="demo-stage mkh-stage"> <p class="mkh-p" id="mkh-p">デザインで大切なのは、<mark class="mkh">伝えたいことを1つに絞ること</mark>です。そのうえで<mark class="mkh mkh-blue" style="--d:.5s">読む順番を設計し</mark>、<mark class="mkh mkh-pink" style="--d:1s">最後に行動をひとつだけ示します</mark>。</p> <button type="button" class="mkh-replay" id="mkh-replay">REPLAY</button> </div>
.mkh-stage { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1.4rem; padding:2rem; background:#F7F5F0; min-height:280px; }
.mkh-p { max-width:420px; margin:0; font-size:1.05rem; line-height:2; color:#1A1A1A; }
.mkh {
color:inherit; padding:0 .1em;
background: linear-gradient(transparent 58%, rgba(255,214,0,.75) 58%) no-repeat left bottom / 0% 100%;
-webkit-box-decoration-break:clone; box-decoration-break:clone;
transition: background-size .9s cubic-bezier(.65,0,.35,1);
transition-delay: var(--d, 0s);
}
.mkh-blue { background-image: linear-gradient(transparent 58%, rgba(91,170,222,.55) 58%); }
.mkh-pink { background-image: linear-gradient(transparent 58%, rgba(233,27,137,.35) 58%); }
.mkh.is-on { background-size: 100% 100%; }
.mkh-replay { padding:.45rem 1rem; border:1px solid rgba(0,0,0,.25); border-radius:999px; background:transparent; color:#333; font-family:'Oswald',sans-serif; letter-spacing:.2em; font-size:.72rem; cursor:pointer; }
.mkh-replay:focus-visible { outline:2px solid #E91B89; outline-offset:2px; }
@media (prefers-reduced-motion: reduce) {
.mkh { transition:none; background-size:100% 100%; }
}
(function(){
var p = document.getElementById('mkh-p');
var btn = document.getElementById('mkh-replay');
if (!p) return;
var marks = p.querySelectorAll('.mkh');
function on(){ marks.forEach(function(m){ m.classList.add('is-on'); }); }
function off(){ marks.forEach(function(m){ m.classList.remove('is-on'); }); }
if ('IntersectionObserver' in window) {
var io = new IntersectionObserver(function(es){
if (es[0].isIntersecting) { on(); io.disconnect(); }
}, { threshold: 0.6 });
io.observe(p);
} else { on(); }
if (btn) btn.addEventListener('click', function(){
marks.forEach(function(m){ m.style.transition = 'none'; });
off();
void p.offsetWidth;
marks.forEach(function(m){ m.style.transition = ''; });
requestAnimationFrame(on);
});
})();
AI PROMPT
文章の一部に、蛍光ペンで線を引くようなマーカーを付ける演出を作って。対象は mark 要素にして、background に linear-gradient(transparent 58%, 黄色 58%) を指定し、background-repeat: no-repeat、background-position: left bottom、background-size: 0% 100% から 100% 100% へ transition .9s(cubic-bezier(.65,0,.35,1))で広げる。::after の擬似要素ではなく背景で描くのは、改行をまたいでも行ごとに線が続くようにするため。box-decoration-break: clone(-webkit- 付きも)を指定して、折り返した各行の端にも余白と背景を付ける。複数のマーカーはカスタムプロパティ --d を transition-delay に使い、.5秒ずつずらして順番に引く。段落が画面の60%以上見えたら IntersectionObserver で .is-on を付け、1回で監視をやめる。@media (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アソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
文章の大事な部分に、蛍光ペンで線を引くように色を走らせる演出です。日本語のブログやLPでは「マーカー」「黄色い下線」として昔から定番の装飾で、動きを付けると読み手の視線をその一文へ確実に運べます。
当サイトの Underline Slide Hover はホバーで細い下線が伸びるリンク装飾、SVG Squiggle Underline は手書き風の波線、Text Scroll Highlight はスクロール量に応じて文字色が変わる演出です。本ページは文字の下半分を太く塗るマーカーそのものを扱う別テーマで、記事本文の強調に向きます。
要点は背景で描くことです。改行をまたいでも行ごとに線が続き、文字色や読みやすさにも影響しません。1段落に引くのは2〜3か所までにすると、どこが大事かがぼやけません。
なぜ ::after ではなく background で線を描くのですか?
::after で線を描くと要素全体を1つの箱として扱うため、文章が2行に折り返したとき1本の四角い帯になり、行の途中に線が引けません。インライン要素の background は行ごとに描かれるので、改行をまたいでも各行の文字の下に自然に線が続きます。
box-decoration-break: clone は何のためですか?
インライン要素が折り返すと、初期値では左右の余白や背景の端が「最初の行の先頭」と「最後の行の末尾」にしか付きません。clone を指定すると各行が独立した箱として扱われ、どの行の端にも同じ余白と背景が付くため、マーカーの両端が途切れずに見えます。
コードは無料で使えますか?
はい。Motion LabのコードスニペットとAIプロンプトは、クレジット表記なしで自由に使えます。コピーしてそのままプロジェクトに利用できます。