opacity の役割
opacity は要素がどれだけ透けて見えるかを決めます。1 は不透明 (初期値)、0 は見えず、その間の値では背景が透けて見えます。下のボックスは、透け具合がわかるようにストライプの背景の上に置いています:
最後のボックスもそこにあります。行の中の 90px の枠を取っていて、何も描かないだけです。白い数字もボックスと一緒に薄くなっていることに注目してください。opacity は要素 とその中のすべて に適用されます。
背景は透明、文字は不透明
opacity は子要素も薄くするので、「読みやすい文字の後ろに透ける背景」には向いていません。代わりにアルファチャンネル付きの背景色を使います:
2 つの白いパネルは、どちらも同じだけストライプが透けて見えます。1 つ目は文字もパネルと一緒に薄くなっています。2 つ目は背景色 (rgb(255 255 255 / 0.6)、rgba(255, 255, 255, 0.6) と同じ) だけが透明なので、文字は不透明で読みやすいままです。アルファ付きの色は 色のページ で解説しています。
子要素は親の opacity から逃れられません。親は子要素を中に含んだまま 1 つの薄いレイヤーとして描かれるので、子要素の opacity: 1 は何もしません。
値
| 値 | 結果 |
|---|---|
1 または 100% | 完全に不透明 (初期値) |
0.5 または 50% | 半透明 |
0 または 0% | 完全に透明。レイアウトに残り、クリックもできる |
1.5、-1 | 1 と 0 に収められる |
opacity は見た目では引き継がれますが、プロパティとしては継承されません。子要素の計算値の opacity は 1 のままで、薄くなった親の中に描かれているだけです。
opacity: 0 と visibility: hidden と display: none の違い
3 つとも要素を見えなくしますが、それ以外はすべて違います:
opacity: 0 | visibility: hidden | display: none | |
|---|---|---|---|
| 場所を取る | はい | はい | いいえ |
| クリックとフォーカスを受け取る | はい | いいえ | いいえ |
| スクリーンリーダーが読む | はい | いいえ | いいえ |
| transition できる | はい、なめらかに | 片方の端で切り替わり、フェードしない | いいえ |
困るのは 2 行目の違いです。opacity: 0 のボタンは、クリックも Tab での移動もできてしまいます:
表示欄は、隠した各ボタンの中の点の下にどの要素があるかをブラウザに尋ねています。opacity: 0 のボタンは「clickable」と答え、visibility: hidden のボタンは答えません。Visible のボタンは空の 150px の枠 2 つの後から始まります。場所を返したのは display: none のボタンだけだからです。フェードアウトしてから取り除くには、opacity をアニメーションさせ、最後に visibility: hidden にします。
ホバーでフェードさせる
opacity はアニメーションの負荷が一番軽いプロパティの 1 つなので、フェードイン、フェードアウトの定番の方法です。画像の上に表示されるキャプションの例です:
:focus-within で、キーボードで操作する人にもキャプションが表示されます。上の表を思い出してください。見えない間もキャプションはスクリーンリーダーに読まれますが、キャプションならそれで問題ありません。
アクセシビリティ: 薄い文字はコントラストを失う
opacity を下げるとコントラストも下がります。白地に灰色の文字を opacity: 0.5 にすると、本文に必要な 4.5:1 の比を大きく下回ることがあります。補足の文字には、濃い色を薄くするのではなく、コントラストの基準を満たす色を選びましょう。無効なコントロールでは opacity を下げるのが一般的な合図ですが、disabled 属性と組み合わせて、キーボードでも操作できず、無効として読み上げられるようにしましょう。
副作用: スタッキングコンテキスト
1 未満の opacity は、transform と同じく新しいスタッキングコンテキストを作ります。すると、z-index の大きい子要素も薄くした要素の中でしか重なり順が決まらず、外側の要素の上には出られません。薄くしたパネルの中のドロップダウンがほかの要素の下に潜り込むなら、これが原因です (重なり順は z-index のページ で解説しています)。
よくある間違い
- 背景を透明にするためにカードを薄くする。 文字も薄くなります。背景に
rgb(... / 0.5)を使いましょう。 - 子要素を不透明に戻そうとする。 親の opacity がすべての子要素を制限します。
opacity: 0だけで隠す。 要素はクリックとフォーカスを受け取ったままです。visibility: hiddenを加えるか、display: noneを使いましょう (pointer-events: noneはクリックは止めますが、キーボードのフォーカスは止めません)。opacity: 50と書く。 opacity は 0 から 1 で、50は1に収められます。0.5か50%と書きましょう。- opacity で文字のコントラストが低くなる。 元の色ではなく、結果のコントラストを確認しましょう。
よくある質問
CSS の opacity は何をしますか?
要素がどれだけ透けて見えるかを、0 (完全に透明) から 1 (完全に不透明) で指定します。文字、border、画像、すべての子要素を含む要素全体に、1 つにまとめたレイヤーとして適用されます。
文字ではなく背景だけを透明にするには?
opacity は使わず、背景にアルファ付きの色を指定します: background-color: rgb(37 99 235 / 0.5); または rgba(37, 99, 235, 0.5)。文字と子要素は不透明のままです。
子要素を親より不透明にできますか?
できません。親の opacity はグループ全体に適用されるので、子要素の opacity: 1 では打ち消せません。0.5 の親の子要素は、最大でも半分の不透明度で描かれます。代わりに透明度を親の背景色に移しましょう。
opacity: 0、visibility: hidden、display: none の違いは何ですか?
opacity: 0 は要素を隠しますが、場所を取り、クリックでき、スクリーンリーダーにも読まれます。visibility: hidden は場所を残しますが、クリックできず、読まれません。display: none はレイアウトから完全に取り除きます。
opacity にパーセントは使えますか?
使えます。現在のすべてのブラウザで opacity: 50% は opacity: 0.5 と同じです。0 未満や 1 を超える値は、その範囲に収められます。