CSS transitionsが引き起こすLayout Shift
Layout Shiftを引き起こすCSS transitionsを見つけて修正する方法を学ぶ

なぜCSS transitionsがレイアウトシフトを引き起こすのか
CSS transitionsによって引き起こされるCumulative Layout Shiftsは、多くの場合、ページの読み込みフェーズの初期段階で発生します。これらのレイアウトシフトは一貫して発生するわけではないため、デバッグが困難です。
最終レビュー: 2026年3月 Arjen Karel
Table of Contents!
transition: all の問題
transitionに関連するレイアウトシフトの最も一般的な原因は transition: all です。2022年 Web AlmanacのCSSに関する章によると、53%のページが transition: all を使用しています。これは、width、height、margin、paddingなどのレイアウトに影響を与えるものを含め、すべてのプロパティの変更がアニメーション化されることを意味します。
CSS transitionには、property、duration、timing-function、delayがあります。省略形は次のようになります:
/* property | duration | timing-function | delay */ transition: margin-right 4s ease-in-out 1s;
問題は、開発者がアニメーション化したい正確なプロパティを指定する代わりに、transition: all .3s ease と記述したときに始まります。ページの読み込み中、ナビゲーションメニューなどのファーストビューの要素は、初期状態(スタイルなし)から最終状態(スタイル適用済み、または非表示)へと遷移します。transitionのプロパティが all の場合、これには width、height、さらには visibility も含まれます。その結果、読み込み中にのみ発生し、一貫して再現することがほぼ不可能なレイアウトシフトが発生します。
どのCSSプロパティがレイアウトシフトを引き起こすのか?
すべてのCSS transitionsがレイアウトシフトを引き起こすわけではありません。要素のジオメトリや位置を変更するプロパティのみが、ブラウザのレイアウトステップをトリガーします。Googleの調査によると、レイアウトを誘発するCSSプロパティをアニメーション化しているページは、CLSの基準を満たす可能性が15%低くなります。margin や border-width をアニメーション化しているページは、ほぼ2倍の割合でCLSが不良(poor)になります。
レイアウトシフトを引き起こすプロパティ: width, height, margin, padding, top, left, right, bottom, border-width, font-size, display
安全なプロパティ (コンポジットのみ、レイアウトシフトなし): transform, opacity, filter, clip-path
安全なプロパティ (ペイントのみ、レイアウトシフトなし): background-color, color, box-shadow, outline
重要なポイント: transform と opacity は完全にブラウザのコンポジタースレッドによって処理されます。これらがレイアウトの再計算をトリガーすることは決してないため、CLSにカウントされることはありません。要素を移動する必要がある場合は、top/left の代わりに transform: translate() を使用します。視覚的にサイズを変更する必要がある場合は、width/height の代わりに transform: scale() を使用します。
以下の例をご覧ください。これは、ページの読み込みフェーズ中に発生するCSS transitionsによって引き起こされたレイアウトシフトを示しています。このパターンは頻繁に見られますが、この種の問題を見つけて修正するのは困難な場合があります。
CSS transitionsを見つけて修正する
CSS transitionsによって引き起こされるすべてのレイアウトシフトを見つけて修正するには、簡単なテストを実行する必要があります。まず、ページ上のすべてのCSS transitionsを見つけます。次に、それらのいずれかがレイアウトに影響を与えるプロパティを変更しているかどうかを確認します。最後に、それらのtransitionsを無効化または変更した場合の影響を測定し、それらがCLSを引き起こしていたことを確認します。
Core Web Vitalsのヒント: CSS transitionsによって引き起こされるCumulative Layout Shiftsは、多くの場合、ページの読み込みフェーズの初期段階で発生します。これらのレイアウトシフトは一貫して発生するわけではないため、デバッグが困難です。モバイルデバイスをエミュレートしてネットワークを遅くし、キャッシュを無効にすることで、それらを見つけやすくなります!
ステップ 1: CSS transitionsを見つける
CSS transitionsの検索は手動で行うことができます。すべてのスタイルシートを調べ、「transition」という単語を検索します。これは10分以内で終わる作業のはずですが、もっと良い方法があります!以下のスニペットをコンソールに貼り付けてEnterキーを押すだけです。
(() => {
let nodeTable = [];
let nodeArray = [];
// Get the name of the node
function getName(node) {
const name = node.nodeName;
return node.nodeType === 1
? name.toLowerCase()
: name.toUpperCase().replace(/^#/, '');
}
// Get the selector
const getSelector = (node) => {
let sel = '';
try {
while (node && node.nodeType !== 9) {
const el = node;
const part = el.id
? '#' + el.id
: getName(el) +
(el.classList &&
el.classList.value &&
el.classList.value.trim() &&
el.classList.value.trim().length
? '.' + el.classList.value.trim().replace(/\s+/g, '.')
: '');
if (sel.length + part.length > (100) - 1) return sel || part;
sel = sel ? part + '>' + sel : part;
if (el.id) break;
node = el.parentNode;
}
} catch (err) {
// Do nothing...
}
return sel;
};
const getNodesWithTransition = (node) => {
// Get the computed style
let cs = window.getComputedStyle(node);
let tp = cs['transition-property'];
let td = cs['transition-duration'];
// If there is a transition, add it to the table
if (tp !== '' && tp !== 'none' && td != '0s') {
nodeTable.push({ selector: getSelector(node), transition: cs['transition'] });
nodeArray.push(node);
}
// Recursively call this function for each child node
for (let i = 0; i < node.children.length; i++) {
getNodesWithTransition(node.children[i]);
}
}
// find all transitions
getNodesWithTransition(document.body);
// Display the results in the console
console.log('%cReadable table of selectors and their transitions', 'color: red; font-weight: bold;');
console.table(nodeTable);
console.log('%cNodeList for you to inspect (harder to read but more info)', 'color: red; font-weight: bold;');
console.log(nodeArray);
// styles to temporarity override the transitions
let selectors = nodeTable.map((item) => item.selector).join(', ');
console.log('%cSpecific CSS to disable all transitions on this page', 'color: red; font-weight: bold;');
console.log(`<style>${selectors}{transition-property: none !important;}</style>`);
console.log('%cGlobal CSS to disable all transitions on this page (not suggested on production)', 'color: red; font-weight: bold;');
console.log(`<style>*{transition-property: none !important;}</style>`);
})()
これにより、すべてのtransitions、それらが機能している要素、およびtransitionsに関する詳細を示す表が表示されます。

レイアウトシフトを見つけるには、width、height、margin、padding、top、left、display、そして特にall(all はすべての有効なtransitionプロパティを含むため)などのtransitionプロパティを探します。
ステップ 2: CSS transitionsを変更する
上記のJavaScriptスニペットは、すべてのtransitionsを表示するだけでなく、それらのtransitionsを無効にする方法のサンプルコードも提供します。簡単なテストの目的であれば、1行のシンプルなCSSコードですべてのtransitionsを無効にするという簡単な方法を取ることをお勧めします。
<style>*{transition-property: none !important;}</style>もちろん、本番環境ではもう少し工夫が必要です。セレクタごとに不要なtransition-propertiesのみを慎重に削除してください。たとえば、#button{transition: all .2s} を #button{transition: background-color .2s} に変更します。
ステップ 3: レイアウトシフトの変化を測定する
transition: all を特定のプロパティに置き換えたサイトは、CLSが平均で40%改善しました。
Transitionのベストプラクティス
- 常に正確なプロパティを指定する:
transition: allは絶対に使用しないでください。代わりにtransition: background-color .2s easeのように記述します。これにより、アニメーション化するつもりのなかったプロパティによる偶発的なレイアウトシフトを防ぐことができます。 - アニメーションにはtransformとopacityを使用する: これら2つのプロパティはコンポジターによって処理され、レイアウトをトリガーすることは決してありません。要素を移動するには
transform: translate()を、視覚的にサイズを変更するにはtransform: scale()を、フェードさせるにはopacityを使用します。これは、高パフォーマンスなアニメーションのためにGoogleが推奨していることです。 - アニメーション化する要素に明示的な寸法を設定する: 要素をtransitionさせる必要がある場合は、transitionの前後に明示的なwidthとheight(またはアスペクト比)があることを確認してください。これにより、周囲のコンテンツがシフトするのを防ぎます。詳細については、自動サイズ調整画像によって引き起こされるレイアウトシフトの修正を参照してください。
- will-changeに注意する: CSSの
will-changeプロパティは、要素を独自のコンポジターレイヤーに昇格させることで、アニメーションの準備をするようブラウザに指示します。しかし、これにはトレードオフがあります。新しいスタッキングコンテキストを作成し、GPUメモリの使用量を増やし、配置された子孫要素の包含ブロックを確立します。アニメーションが開始される直前にJavaScriptを使用して動的に適用し、アニメーションが終了したら削除してください。スタイルシートにwill-changeを永続的に残さないでください。
このような状況にもかかわらず、2025年 Web Almanacの報告によると、モバイルページの40%が依然として非コンポジットアニメーションを実行しています。良いニュースは、CLSがモバイルで81%という最も高い合格率を誇るCore Web Vitalsであることです。悪いニュースは、もしあなたのサイトが不合格の19%に含まれている場合、まだ確認していないCSS transitionsが原因である可能性があることです。

