ホームページ >ウェブフロントエンド >CSSチュートリアル >CSSグラデーションシャドウを取得するさまざまな方法

CSSグラデーションシャドウを取得するさまざまな方法

Lisa Kudrow
Lisa Kudrowオリジナル
2025-03-09 10:03:14435ブラウズ

Different Ways to Get CSS Gradient Shadows

私はよく質問します:固体の代わりにグラデーション色の影を作成できますか? これを達成するためのCSSには特別な特性はありません(私を信じてください、私はそれを探しました)。次にこれらのヒントのいくつかをカバーします。

しかし、最初は...グラデーションシャドウに関する別の記事はありますか?本当に?

はい、これはこのトピックに関する別の投稿ですが、違います。一緒に、私たちは限界を押し広げ、他の場所で見たことのないものをカバーするソリューションを見つけます:透明性。ほとんどのヒントは、要素が非透明な背景を持っている場合に機能しますが、透明な背景がある場合はどうでしょうか?ここでこの状況について説明します!

始める前に、グラデーションシャドウジェネレーターを紹介させてください。構成を調整するだけで、コードを取得できます。しかし、コードを生成する背後にあるすべてのロジックを理解するのに役立つので、読み続けてください。

カタログ

  • 非透明なソリューション
  • 透明なソリューション
  • 丸い角を追加
  • 要約

非透明なソリューション

一般的な状況の80%で機能するソリューションから始めましょう。最も典型的なケースは、背景を持つ要素を使用しており、グラデーションシャドウを追加する必要があることです。ここでは透明性を考慮する必要はありません。

解決策は、勾配を定義する擬似要素に依存することです。実際の要素の後ろに置き、ぼやけたフィルターを適用します。

<code>.box {
  position: relative;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px; /* 控制扩散 */
  transform: translate(10px, 8px); /* 控制偏移量 */
  z-index: -1; /* 将元素置于后面 */
  background: /* 你的渐变色在这里 */;
  filter: blur(10px); /* 控制模糊 */
}</code>

コードはたくさん見える。グラデーションの代わりに固体を使用する場合、勾配の代わりにボックスシャドウを使用する方法は次のとおりです。

<code>box-shadow: 10px 8px 10px 5px orange;</code>

これにより、最初のコードの値が何をするかについての良いアイデアが得られるはずです。 XおよびYのオフセット、ファジー半径、拡散距離があります。挿入図プロパティからの負の拡散距離値が必要であることに注意してください。

これは、クラシックなボックスシャドウと並んでグラデーションシャドウを示すデモです:

よく見ると、2つの影がわずかに異なることに気付くでしょう。特にぼやけた部分があります。これは驚くことではありません。フィルター属性のアルゴリズムがBox-Shadowのアルゴリズムとは異なると確信しているからです。最終結果は非常に似ているため、大したことではありません。

このソリューションは良好ですが、それでもZ-index:-1宣言に関連するいくつかの欠点があります。はい、そこで「スタックコンテキスト」が発生しています!

私は主な要素に変換を適用しましたが、それから影は要素の下にもなりません。これは間違いではなく、積み重ねのコンテキストの論理的な結果です。心配しないでください、私はスタッキングコンテキストの退屈な説明をし始めません(私はこれをスタックオーバーフロースレッドで行いました)が、私はまだそれを修正する方法を示します。

最初の解決策は、3D変換を使用することです。

<code>.box {
  position: relative;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px; /* 控制扩散 */
  transform: translate(10px, 8px); /* 控制偏移量 */
  z-index: -1; /* 将元素置于后面 */
  background: /* 你的渐变色在这里 */;
  filter: blur(10px); /* 控制模糊 */
}</code>

z -index:-1は使用しませんが、z軸に沿って否定的な翻訳を使用します。すべてをtranslate3d()に配置します。 Transform-Style:Preserve-3Dをメイン要素で使用することを忘れないでください。

私の知る限り、このソリューションには副作用はありません...しかし、おそらくあなたはそれを見るでしょう。もしそうなら、コメントセクションで共有して、解決策を見つけてみましょう!

何らかの理由で3D変換を使用できない場合、別の解決策は、2つの擬似要素に依存することです - ::前と::後。 1つはグラデーションシャドウを作成し、もう1つはメインの背景(および必要な他のスタイル)をコピーします。これにより、2つの擬似要素の積み重ね順序を簡単に制御できます。

<code>box-shadow: 10px 8px 10px 5px orange;</code>
にスタッキングコンテキストを作成することを強制していることに注意することが重要です。また、擬似要素がメイン要素の塗りつぶしボックスを参照として扱うことを忘れないでください。したがって、主な要素に境界がある場合、擬似要素スタイルを定義する際にこれを考慮する必要があります。メイン要素で定義されている境界線を検討するために、INSET:-2PX ON ::を使用していることに気付くでしょう。 私が言ったように、このソリューションは、透明性をサポートする必要がない限り、ほとんどの場合、勾配の影が必要な限り、十分に良いかもしれません。しかし、私たちは挑戦して制限を推進するようになりましたので、次に話したいことが必要なくても、注意を払い続けてください。他の場所で使用できる新しいCSSのヒントを学ぶことができます。 透明なソリューション

3D変換で終了するところから始めましょう。メイン要素から背景を削除します。オフセット距離と拡散距離の両方が0に等しい影から始めます。

アイデアは、外部コンテンツを保持しながら(緑色の境界内)要素の領域内にすべてを収穫または隠す方法を見つけることです。これにはクリップパスを使用します。しかし、あなたは、クリップパスをどのように要素の中にトリミングできるのか疑問に思うかもしれません

確かに、これを行う方法はありませんが、特定のポリゴンパターンでシミュレートできます。 見て!透明性をサポートするグラデーションシャドウを取得します。私たちがしたのは、前のコードにクリップパスを追加することだけでした。これは、ポリゴン部分を説明するための図です。

青い領域は、クリップパスを適用した後に表示される部分です。私は青色のみを使用して概念を説明しますが、実際には、エリア内の影のみが表示されます。ご覧のとおり、4つのポイントを定義し、それらの値は非常に大きい(b)。私の大きな価値は100VMAXですが、それはあなたが望むどんな大きな価値でもあります。アイデアは、十分な影の空間があることを確認することです。擬似要素のコーナーポイントである4つのポイントがあります。

<code>.box {
  position: relative;
  transform-style: preserve-3d;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px;
  transform: translate3d(10px, 8px, -1px); /* (X, Y, Z) */
  background: /* .. */;
  filter: blur(10px);
}</code>
矢印は、ポリゴンを定義するパスを示します。 (-b、-b)から始め、(0,0)に達するまで開始します。合計で10ポイントが必要です。 2つのポイント(-b、-b)および(0,0))がパスで2回繰り返されるため、8ポイントではありません。

また、拡散距離とオフセットを考慮する最後のことを行う必要があります。上記のデモは、これが特別なケースであるために機能します。オフセット距離と拡散距離の両方が0に等しくなります。 拡散を定義し、何が起こるかを見てみましょう。覚えておいてください、私たちはこれを行うためにネガティブ値の挿入図を使用します:

擬似要素はメイン要素よりも大きくなるため、クリップパスクリップは必要以上になります。覚えておいてください、私たちは常に

(例の緑の境界内の領域)内部のメイン要素の部分をトリミングする必要があります。クリップパスの4つのポイントの位置を調整する必要があります。

拡散距離のCSS変数-Sを定義し、ポリゴンポイントを更新しました。大きな価値を使用した場所に触れませんでした。擬似要素の角度を定義するポイントのみを更新します。すべてのゼロ値を増やし、値の100%を削減します。

<code>.box {
  position: relative;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px; /* 控制扩散 */
  transform: translate(10px, 8px); /* 控制偏移量 */
  z-index: -1; /* 将元素置于后面 */
  background: /* 你的渐变色在这里 */;
  filter: blur(10px); /* 控制模糊 */
}</code>
オフセットは同じロジックです。擬似要素を変換するとき、影は誤って整合されており、ポリゴンを再度修正して、ポイントを反対方向に移動する必要があります。

オフセットにはさらに2つの変数があります:-Xおよび-Y。それらを変換内で使用し、クリップパス値も更新しました。まだ大きな値でポリゴンポイントに触れることはありませんが、他のすべてのポイントを相殺します - X座標からXを減らし、Y座標から-Yを減らします。

<code>box-shadow: 10px 8px 10px 5px orange;</code>
ここで、勾配シャドウを制御するためにいくつかの変数を更新するだけです。これを行うときは、ファジー半径を変数に変えましょう。

3D変換スキルが必要ですか?

それはすべて国境に依存します。擬似要素の参照がフィルボックスであることを忘れないでください。したがって、メイン要素に境界線を適用すると、重複があります。 3D変換のトリックを維持するか、挿入値を更新して境界を考慮することができます。

これは、前のデモで3D変換を更新された挿入図に置き換えるために使用されるバージョンです。
これは、パディングボックスの代わりにボーダーボックスから始まるため、拡散距離がより正確になるため、より適切なアプローチだと思います。ただし、メイン要素の境界線に応じて挿入値を調整する必要があります。要素の境界線が不明である場合があり、以前のソリューションを使用する必要があります。

以前の非透明ソリューションを使用すると、積み重ねのコンテキストの問題に遭遇する可能性があります。透明なソリューションでは、国境問題に遭遇する可能性があります。これで、これらの問題を解決するオプションと方法があります。 3D変換トリックは、すべての問題を修正するため、私のお気に入りのソリューションです(オンラインジェネレーターも検討します)

丸い角を追加

私たちが開始した非透明なソリューションを使用するときに要素に境界線形を追加しようとする場合、これはかなり単純な作業です。メイン要素から同じ値を継承するだけで完了です。

国境と西欧の定義:角が丸くない場合でも、継承は良い考えです。これは、他の場所から将来または丸い角を追加したい可能性のある潜在的な丸い角を考慮します。

透明なソリューションに対処する状況は異なります。残念ながら、これは、クリップパスが曲線を処理できないため、別のソリューションを見つけることを意味します。これは、メイン要素内の領域をトリミングできないことを意味します。

ブレンドにマスク属性を追加します。

この部分は非常に退屈で、魔法の数字に依存しない一般的なソリューションを見つけるのに苦労しています。最終的には、1つの擬似要素のみを使用する非常に複雑なソリューションになりましたが、コードは混乱であり、特定の状況のみをカバーしています。この道を探索する価値はないと思います。

コードを簡素化するために、追加の要素を挿入することにしました。以下はマークです:

<code>.box {
  position: relative;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px; /* 控制扩散 */
  transform: translate(10px, 8px); /* 控制偏移量 */
  z-index: -1; /* 将元素置于后面 */
  background: /* 你的渐变色在这里 */;
  filter: blur(10px); /* 控制模糊 */
}</code>

外部CSSとの潜在的な競合を回避するために、カスタム要素を使用します。

を使用できますが、それは一般的な要素であるため、他の場所からの別のCSSルールによって簡単に配置でき、コードを破ることができます。最初のステップは、要素を見つけて、意図的にオーバーフローを作成することです。 コードは少し奇妙に見えるかもしれませんが、その背後にあるロジックを段階的に説明します。次に、
<code>box-shadow: 10px 8px 10px 5px orange;</code>
の擬似エレメントを使用して、グラデーションシャドウを作成します。

ご覧のとおり、擬似要素は以前のすべての例と同じコードを使用します。唯一の違いは、3D変換が擬似要素ではなく
<code>.box {
  position: relative;
  transform-style: preserve-3d;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px;
  transform: translate3d(10px, 8px, -1px); /* (X, Y, Z) */
  background: /* .. */;
  filter: blur(10px);
}</code>
要素に定義されることです。現在、透明度機能のないグラデーションシャドウがあります:

要素の面積は、黒い輪郭で定義されていることに注意してください。なぜ私はこれをするのですか?このため、マスクを適用して、緑の領域内の部品を隠し、影を見る必要があるあふれる部分を保持できます。

これは少し難しいことを知っていますが、Clip-Pathとは異なり、マスク属性は、コンテンツを表示および非表示にするための要素

の領域を考慮していません。そのため、「外側」の領域をシミュレートするために、余分な要素を導入する必要がありました。 また、境界線と挿入図の組み合わせを使用してエリアを定義することに注意してください。これにより、擬似要素が追加の計算を必要としないように、余分な要素のパディングボックスをメイン要素と同じに保つことができます。

追加の要素を使用することで得られるもう1つの有用なことは、要素が固定されており、擬似要素のみが動いていることです(翻訳を使用)。これにより、このトリックの最後のステップであるマスクを簡単に定義できます。

完成!グラデーションシャドウがあり、ボーダーラジウスをサポートしています!内部には多くの勾配があるが、そうではない複雑なマスク値が期待されるかもしれません!魔法を完成させるには、2つの単純な勾配とマスクコンポジットのみが必要です。 そこで何が起こっているのかを理解するために

要素を分離しましょう:
<code>.box {
  position: relative;
  z-index: 0; /* 我们强制创建一个堆叠上下文 */
}
/* 创建阴影 */
.box::before {
  content: "";
  position: absolute;
  z-index: -2;
  inset: -5px;
  transform: translate(10px, 8px);
  background: /* .. */;
  filter: blur(10px);
}
/* 复制主元素样式 */
.box::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  /* 继承在主元素上定义的所有装饰 */
  background: inherit;
  border: inherit;
  box-shadow: inherit;
}</code>

以下は、得た結果です: 内部半径が主な要素の境界線と一致する方法に注目してください。大きな境界線(150px)と、大きな境界線

プラス
<code>clip-path: polygon(-100vmax -100vmax,100vmax -100vmax,100vmax 100vmax,-100vmax 100vmax,-100vmax -100vmax,0 0,0 100%,100% 100%,100% 0,0 0)</code>
メイン要素半径に等しい境界線範囲を定義しました。外部では、150px Rに等しい半径があります。内部的には、150px r -150px = Rがあります。

内側(青)部分を隠し、境界(赤)部分がまだ表示されていることを確認する必要があります。これを行うために、2つのマスクレイヤーを定義しました。1つはコンテンツボックス領域のみをカバーし、もう1つはボーダーボックスエリアをカバーしています(デフォルト)。次に、一方を他方から除外して国境を表示します。

<code>.box {
  position: relative;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px; /* 控制扩散 */
  transform: translate(10px, 8px); /* 控制偏移量 */
  z-index: -1; /* 将元素置于后面 */
  background: /* 你的渐变色在这里 */;
  filter: blur(10px); /* 控制模糊 */
}</code>

同じ手法を使用して、勾配と境界線をサポートする境界線を作成します。アナチューダーにはマスクの複合に関する良い記事もあります。私はあなたにそれを読むことを勧めます。

この方法の欠点はありますか?

はい、これは間違いなく完璧ではありません。最初に遭遇する可能性のある問題は、メイン要素の境界線の使用に関連しています。あなたがそれを考慮しないと、これは半径のわずかな不整合につながる可能性があります。この問題は私たちの例に存在しますが、気づくのに苦労するかもしれません。

比較的簡単に修正:要素の挿入図に境界幅を追加します。

<code>box-shadow: 10px 8px 10px 5px orange;</code>

もう1つの欠点は、境界に使用する大きな値です(例では150px)。この値は、影を含めるのに十分な大きさでなければなりませんが、オーバーフローやスクロールバーの問題を避けるには大きすぎることはありません。幸いなことに、オンラインジェネレーターはすべてのパラメーターを考慮して最適な値を計算します。

私が気づいた最後の欠点は、複雑な国境帯域を使用するときです。たとえば、各コーナーに異なる半径を適用する場合は、各側の変数を定義する必要があります。これは本当の欠点ではないと思いますが、それはあなたのコードを維持するのが少し難しくなるかもしれません。

<code>.box {
  position: relative;
  transform-style: preserve-3d;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px;
  transform: translate3d(10px, 8px, -1px); /* (X, Y, Z) */
  background: /* .. */;
  filter: blur(10px);
}</code>
簡単にするために、オンラインジェネレーターは均一な半径のみを考慮しますが、複雑な半径構成を検討する場合は、コードを変更する方法を知っています。

要約

終わりに達しました!グラデーションシャドウの背後にある魔法はもはや謎ではありません。私はあなたが持っているかもしれないすべての可能性とすべての問題をカバーしようとしています。私が何かを逃した場合、または問題が見つかった場合は、コメントセクションで自由に報告してください。チェックアウトします。

再び、事実上のソリューションがあなたのユースケースのほとんどをカバーすることを考慮すると、これらの多くは冗長である可能性があります。ただし、テクニックの背後にある「なぜ」と「どのように」、その制限を克服する方法を理解することは良いことです。また、CSSの編集とマットをプレイする際に素晴らしい練習をしました。

もちろん、オンラインジェネレーターをいつでも使用してトラブルを避けることができます。

以上がCSSグラデーションシャドウを取得するさまざまな方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:動く背景次の記事:動く背景