Rumah >hujung hadapan web >tutorial css >Cara yang berbeza untuk mendapatkan bayang -bayang kecerunan CSS

Cara yang berbeza untuk mendapatkan bayang -bayang kecerunan CSS

Lisa Kudrow
Lisa Kudrowasal
2025-03-09 10:03:14433semak imbas

Different Ways to Get CSS Gradient Shadows

Saya sering mengemukakan soalan:

Bolehkah saya membuat bayang -bayang dengan warna kecerunan dan bukannya warna pepejal? Tidak ada sifat khas dalam CSS untuk mencapai ini (percayalah, saya telah mencarinya), dan mana -mana jawatan blog yang anda dapati tentang ini pada dasarnya adalah beberapa helah CSS kecerunan yang sama. Kami akan merangkumi beberapa petua ini seterusnya.

Tetapi pertama ... Adakah artikel lain mengenai bayang -bayang kecerunan? Betul?

Ya, ini adalah satu lagi jawatan mengenai topik ini, tetapi ia berbeza. Bersama -sama, kita akan menolak had dan mencari penyelesaian yang meliputi sesuatu yang tidak pernah saya lihat di tempat lain:

Transparency . Kebanyakan petua berfungsi apabila elemen mempunyai latar belakang yang tidak telus, tetapi bagaimana jika kita mempunyai latar belakang yang telus? Kami akan membincangkan keadaan ini di sini!

Sebelum kita memulakan, izinkan saya memperkenalkan penjana bayangan kecerunan saya. Anda hanya perlu menyesuaikan konfigurasi dan anda boleh mendapatkan kod tersebut. Tetapi terus membaca kerana saya akan membantu anda memahami semua logik di belakang menghasilkan kod.

katalog

    penyelesaian bukan telus
  • penyelesaian telus
  • Tambah sudut bulat
  • Ringkasan
penyelesaian bukan telus

mari kita mulakan dengan penyelesaian yang berfungsi untuk 80% situasi biasa. Kes yang paling tipikal ialah anda menggunakan elemen dengan latar belakang dan anda perlu menambah bayangan kecerunan kepadanya. Tidak perlu mempertimbangkan ketelusan di sini.

Penyelesaiannya adalah bergantung kepada elemen pseudo yang mentakrifkan kecerunan. Anda meletakkannya di belakang elemen sebenar dan memohon penapis kabur kepadanya.

<code>.box {
  position: relative;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px; /* 控制扩散 */
  transform: translate(10px, 8px); /* 控制偏移量 */
  z-index: -1; /* 将元素置于后面 */
  background: /* 你的渐变色在这里 */;
  filter: blur(10px); /* 控制模糊 */
}</code>
Kod kelihatan banyak, kerana ia mempunyai banyak. Berikut adalah cara menggunakan bayang-bayang kotak bukan kecerunan jika kita menggunakan warna pepejal dan bukannya kecerunan.

<code>box-shadow: 10px 8px 10px 5px orange;</code>
Ini harus memberi anda idea yang baik tentang nilai dalam kod pertama kod. Kami mempunyai offset X dan Y, jejari kabur, dan jarak penyebaran. Perhatikan bahawa kita memerlukan nilai jarak penyebaran negatif dari harta inset.

Ini adalah demo yang menunjukkan bayang-bayang kecerunan bersebelahan dengan kotak kotak klasik:

Jika anda melihat dengan teliti, anda akan melihat bahawa kedua -dua bayang -bayang itu sedikit berbeza, terutama bahagian kabur. Ini tidak menghairankan, kerana saya cukup yakin algoritma untuk atribut penapis adalah berbeza daripada bayang-bayang kotak. Ia bukan masalah besar, kerana hasil akhirnya sangat serupa.

Penyelesaian ini baik, tetapi masih mempunyai beberapa kelemahan yang berkaitan dengan Z-indeks: -1 pengisytiharan. Ya, ada "konteks timbunan" yang berlaku di sana!

Saya menggunakan transformasi ke elemen utama, dan kemudian bayang -bayang tidak lagi di bawah elemen. Ini bukan kesilapan, tetapi hasil logik konteks menyusun. Jangan risau, saya tidak akan mula memberikan penjelasan yang membosankan mengenai konteks menyusun (saya telah melakukan ini dalam benang limpahan stack), tetapi saya masih akan menunjukkan kepada anda bagaimana untuk memperbaikinya.

penyelesaian pertama yang saya cadangkan adalah menggunakan penukaran 3D:

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

Kami tidak menggunakan z -indeks: -1, tetapi gunakan terjemahan negatif di sepanjang paksi z. Kami meletakkan segala -galanya dalam terjemahan3d (). Jangan lupa menggunakan gaya transformasi: Preserve-3D pada elemen utama;

sejauh yang saya tahu, penyelesaian ini tidak mempunyai kesan sampingan ... tetapi mungkin anda akan melihatnya. Jika ya, sila kongsi di bahagian komen dan mari cuba mencari penyelesaian!

Jika atas sebab tertentu, anda tidak boleh menggunakan penukaran 3D, penyelesaian lain adalah bergantung kepada dua elemen pseudo-:: sebelum dan :: selepas. Satu mencipta bayangan kecerunan, yang lain memasuki latar belakang utama (dan gaya lain yang anda perlukan). Dengan cara ini, kita dapat dengan mudah mengawal susunan dua elemen pseudo.

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

Adalah penting untuk diperhatikan bahawa kita memaksa untuk membuat konteks penyusunan dengan mengisytiharkan z-indeks: 0 di atasnya atau mana-mana atribut lain yang sama. Juga, jangan lupa bahawa pseudo-element merawat kotak mengisi elemen utama sebagai rujukan. Oleh itu, jika elemen utama mempunyai sempadan, ini perlu dipertimbangkan ketika menentukan gaya pseudo-elemen. Anda akan melihat bahawa saya menggunakan inset: -2px pada :: Selepas mempertimbangkan sempadan yang ditakrifkan pada elemen utama.

Seperti yang saya katakan, penyelesaian ini mungkin cukup baik dalam kebanyakan kes selagi anda tidak perlu menyokong ketelusan, anda mahu bayangan kecerunan. Tetapi kami datang untuk mencabar dan menolak had, jadi walaupun anda tidak memerlukan apa yang anda ingin bicarakan seterusnya, sila terus memberi perhatian. Anda boleh mempelajari petua CSS baru yang boleh anda gunakan di tempat lain.

penyelesaian telus

Mari kita mulakan di mana kita berakhir dalam transformasi 3D dan keluarkan latar belakang dari elemen utama. Saya akan mulakan dengan bayang -bayang di mana kedua -dua jarak offset dan penyebaran adalah sama dengan 0.

Ideanya adalah untuk mencari jalan untuk menanam atau menyembunyikan segala -galanya di dalam kawasan elemen (dalam sempadan hijau) sambil mengekalkan kandungan luaran. Kami akan menggunakan laluan klip untuk ini. Tetapi anda mungkin tertanya-tanya bagaimana laluan klip boleh dipotong di dalam elemen

. Sesungguhnya, tidak ada cara untuk melakukan ini, tetapi kita boleh mensimulasikannya dengan corak poligon tertentu:

Lihat! Kami mendapat bayangan kecerunan yang menyokong ketelusan. Apa yang kami lakukan ialah menambah laluan klip ke kod sebelumnya. Berikut adalah gambarajah untuk menggambarkan bahagian poligon.
<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>

Kawasan biru adalah bahagian yang dapat dilihat selepas memohon laluan klip. Saya hanya menggunakan biru untuk menggambarkan konsep ini, tetapi pada hakikatnya, kita hanya melihat bayang -bayang di dalam kawasan itu. Seperti yang anda lihat, kami menentukan empat mata, dan nilai mereka sangat besar (b). Nilai besar saya adalah 100Vmax, tetapi ia boleh menjadi nilai besar yang anda mahukan. Idea ini adalah untuk memastikan kami mempunyai ruang bayangan yang cukup. Kami mempunyai empat mata lagi yang merupakan titik sudut elemen pseudo.

anak panah menunjukkan jalan yang mentakrifkan poligon. Kami bermula dari (-b, -b) dan sehingga kami mencapai (0,0). Secara keseluruhan, kita memerlukan 10 mata. Bukan 8 mata, kerana kedua-dua mata ((-b, -b) dan (0,0)) diulang dua kali di jalan.

kita juga perlu melakukan perkara terakhir , yang harus mempertimbangkan jarak penyebaran dan mengimbangi. Demonstrasi di atas berfungsi semata -mata kerana ini adalah kes khas, kedua -dua jarak offset dan penyebaran adalah sama dengan 0.

mari kita tentukan penyebaran dan lihat apa yang berlaku. Ingat, kami menggunakan inset nilai negatif untuk melakukan ini:

Pseudo-element kini lebih besar daripada elemen utama, jadi klip klip-laluan lebih daripada yang kita perlukan. Ingat, kita sentiasa perlu menanam bahagian elemen utama

di dalam (kawasan di dalam sempadan hijau dalam contoh). Kita perlu menyesuaikan kedudukan empat mata dalam laluan klip.

<code>.box {
  position: relative;
}
.box::before {
  content: "";
  position: absolute;
  inset: -5px; /* 控制扩散 */
  transform: translate(10px, 8px); /* 控制偏移量 */
  z-index: -1; /* 将元素置于后面 */
  background: /* 你的渐变色在这里 */;
  filter: blur(10px); /* 控制模糊 */
}</code>
Kami menentukan pembolehubah CSS -untuk jarak penyebaran dan mengemas kini mata poligon. Saya tidak menyentuh di mana saya menggunakan nilai besar. Saya hanya mengemas kini mata yang menentukan sudut elemen pseudo. Saya meningkatkan semua nilai sifar-dan mengurangkan 100% nilai-.

Offset adalah logik yang sama. Apabila kita menukar unsur-unsur pseudo, bayang-bayang tidak disengajakan dan kita perlu membetulkan poligon sekali lagi dan memindahkan mata ke arah yang bertentangan.

<code>box-shadow: 10px 8px 10px 5px orange;</code>
Terdapat dua lagi pembolehubah untuk offset: --x dan --y. Kami menggunakannya di dalam Transform dan kami juga mengemas kini nilai klip-laluan. Kami masih tidak menyentuh mata poligon dengan nilai yang besar, tetapi kami mengimbangi semua perkara lain -kami mengurangkan --x dari koordinat x, dan -dari koordinat y.

Sekarang kita hanya perlu mengemas kini beberapa pembolehubah untuk mengawal bayangan kecerunan. Apabila kita melakukan ini, mari kita juga menghidupkan radius kabur menjadi pembolehubah:

Adakah kita masih memerlukan kemahiran penukaran 3D?

semuanya bergantung pada sempadan. Jangan lupa bahawa rujukan untuk elemen pseudo adalah kotak mengisi, jadi jika anda memohon sempadan ke elemen utama, anda akan bertindih. Anda boleh menyimpan helah penukaran 3D atau mengemas kini nilai inset untuk mempertimbangkan sempadan.

Ini adalah versi yang digunakan untuk menggantikan penukaran 3D dengan nilai inset yang dikemas kini dalam demonstrasi sebelumnya:

Saya fikir ini adalah pendekatan yang lebih sesuai, kerana jarak penyebaran akan lebih tepat, kerana ia bermula dengan kotak sempadan bukan kotak padding. Tetapi anda perlu menyesuaikan nilai inset mengikut sempadan elemen utama. Kadang -kadang sempadan elemen tidak diketahui dan anda perlu menggunakan penyelesaian sebelumnya.

Menggunakan penyelesaian bukan telus sebelumnya, anda mungkin menghadapi masalah konteks menyusun. Dengan penyelesaian telus, anda mungkin menghadapi isu sempadan. Sekarang anda mempunyai pilihan dan cara untuk menyelesaikan masalah ini. Trik Penukaran 3D adalah penyelesaian kegemaran saya kerana ia membetulkan semua isu (penjana dalam talian akan menganggapnya juga)

Tambah sudut bulat

Jika anda cuba menambah radius sempadan ke unsur-unsur apabila menggunakan penyelesaian yang tidak telus yang kami mulakan, ini adalah tugas yang agak mudah. Anda hanya perlu mewarisi nilai yang sama dari elemen utama dan anda selesai.

Menentukan Radius Sempadan: Idea adalah idea yang baik walaupun anda tidak mempunyai sudut bulat. Ini menganggap mana -mana sudut bulat berpotensi yang anda mungkin mahu menambah di sudut masa depan atau bulat dari tempat lain.

Keadaan menangani penyelesaian telus adalah berbeza. Malangnya, ini bermakna mencari penyelesaian lain kerana laluan klip tidak dapat mengendalikan lengkung. Ini bermakna kita tidak akan dapat menanam kawasan di dalam elemen utama.

Kami menambah atribut topeng ke campuran.

Bahagian ini sangat membosankan dan saya mempunyai masa yang sukar untuk mencari penyelesaian umum yang tidak bergantung pada nombor sihir. Saya berakhir dengan penyelesaian yang sangat kompleks yang hanya menggunakan satu elemen pseudo, tetapi kod itu adalah kekacauan dan hanya meliputi beberapa situasi tertentu. Saya tidak fikir ia bernilai meneroka jalan ini.

Untuk memudahkan kod, saya memutuskan untuk memasukkan elemen tambahan. Berikut adalah tanda:

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

Saya menggunakan elemen tersuai untuk mengelakkan sebarang konflik yang berpotensi dengan CSS luaran. Saya boleh menggunakan

, tetapi kerana ia adalah elemen yang sama, mudah untuk diposisikan oleh peraturan CSS yang lain dari tempat lain, yang boleh memecahkan kod kami. Langkah pertama adalah mencari elemen dan sengaja membuat limpahan:
<code>box-shadow: 10px 8px 10px 5px orange;</code>
Kod mungkin kelihatan sedikit pelik, tetapi kami akan menerangkan logik di belakangnya langkah demi langkah. Seterusnya, kami menggunakan pseudo-elemen

untuk membuat bayangan kecerunan.

<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>
Seperti yang anda lihat, pseudo-elemen menggunakan kod yang sama seperti semua contoh sebelumnya. Satu-satunya perbezaan ialah transformasi 3D ditakrifkan pada elemen

, bukan pada elemen pseudo. Pada masa ini, kami mempunyai bayangan kecerunan tanpa fungsi ketelusan: Sila ambil perhatian bahawa kawasan elemen

ditakrifkan dengan garis besar hitam. Mengapa saya melakukan ini? Kerana ini, saya boleh memohon topeng di atasnya untuk menyembunyikan bahagian -bahagian di dalam kawasan hijau dan menyimpan bahagian yang melimpah di mana kita perlu melihat bayangan.

Saya tahu ini agak rumit, tetapi tidak seperti Clip-Path, atribut Mask tidak mengambil kira kawasan elemen

di luar

untuk menunjukkan dan menyembunyikan kandungan. Itulah sebabnya saya perlu memperkenalkan elemen tambahan - untuk mensimulasikan kawasan "luar". Juga, ambil perhatian bahawa saya menggunakan gabungan sempadan dan inset untuk menentukan kawasan tersebut. Ini membolehkan saya menyimpan kotak padding elemen tambahan sama seperti elemen utama supaya elemen pseudo tidak memerlukan pengiraan tambahan.

Satu lagi perkara berguna yang mendapat dari menggunakan unsur-unsur tambahan ialah unsur-unsur tetap dan hanya unsur-unsur pseudo bergerak (menggunakan terjemahan). Ini akan membolehkan saya dengan mudah menentukan topeng, yang merupakan langkah terakhir helah ini.

selesai! Kami mempunyai bayang-bayang kecerunan, dan ia menyokong radius sempadan! Anda mungkin mengharapkan nilai topeng yang kompleks dengan banyak kecerunan di dalam, tetapi tidak! Kami hanya memerlukan dua kecerunan mudah dan komposit topeng untuk melengkapkan sihir.

mari kita mengasingkan elemen
<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>
untuk memahami apa yang berlaku di sana:

Berikut adalah hasil yang kami dapat:

Perhatikan bagaimana jejari dalaman sepadan dengan radius sempadan elemen utama. Saya menentukan sempadan besar (150px) dan radius sempadan sama dengan sempadan besar
<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>
ditambah

radius elemen utama. Secara luaran, saya mempunyai radius yang sama dengan 150px R. Secara dalaman, saya mempunyai 150px R - 150px = R.

kita perlu menyembunyikan bahagian dalaman (biru) dan pastikan bahagian sempadan (merah) masih dapat dilihat. Untuk melakukan ini, saya menentukan dua lapisan topeng-satu yang meliputi hanya kawasan kotak kandungan dan yang lain yang meliputi kawasan kotak sempadan (lalai). Saya kemudian mengecualikan satu dari yang lain untuk menunjukkan sempadan.

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

Saya menggunakan teknik yang sama untuk membuat sempadan yang menyokong kecerunan dan radius sempadan. Ana Tudor juga mempunyai artikel yang baik mengenai pengkompaunan topeng, dan saya menjemput anda untuk membacanya.

Adakah terdapat kelemahan kaedah ini?

Ya, ini pasti tidak sempurna. Masalah pertama yang mungkin anda hadapi berkaitan dengan menggunakan sempadan pada elemen utama. Jika anda tidak menganggapnya, ini boleh menyebabkan sedikit misalignment radius. Masalah ini wujud dalam contoh kami, tetapi anda mungkin mengalami kesukaran memerhatikannya.

Tetap agak mudah: Tambah lebar sempadan ke inset elemen .

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

Kelemahan lain adalah nilai besar yang kita gunakan untuk sempadan (150px dalam contoh). Nilai ini harus cukup besar untuk mengandungi bayang -bayang, tetapi tidak terlalu besar untuk mengelakkan masalah limpahan dan scrollbar. Nasib baik, penjana dalam talian akan mengambil semua parameter untuk mengira nilai optimum.

Kelemahan terakhir yang saya sedar adalah apabila anda menggunakan radius sempadan kompleks. Sebagai contoh, jika anda ingin memohon jejari yang berbeza ke setiap sudut, anda perlu menentukan pembolehubah untuk setiap sisi. Ini bukan kelemahan sebenar, saya fikir, tetapi ia boleh menjadikan kod anda sedikit lebih sukar untuk dikekalkan.

<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>

Untuk kesederhanaan, penjana dalam talian hanya menganggap radius seragam, tetapi anda kini tahu bagaimana untuk mengubah suai kod jika anda ingin mempertimbangkan konfigurasi radius kompleks.

Ringkasan

Kami telah sampai ke akhir! Keajaiban di belakang Shadow Gradien tidak lagi menjadi misteri. Saya cuba menampung semua kemungkinan dan sebarang isu yang mungkin anda miliki. Sekiranya saya terlepas sesuatu atau anda mendapati sebarang masalah, jangan lepaskannya di bahagian komen dan saya akan menyemaknya.

Sekali lagi, memandangkan penyelesaian de facto akan meliputi kebanyakan kes penggunaan anda, kebanyakannya mungkin berlebihan. Walau bagaimanapun, adalah baik untuk memahami "mengapa" dan "bagaimana" di belakang teknik dan bagaimana untuk mengatasi batasannya. Juga, kami mendapat amalan hebat dalam bermain penyuntingan dan matte CSS.

Sudah tentu, anda boleh menggunakan penjana dalam talian untuk mengelakkan masalah.

Atas ialah kandungan terperinci Cara yang berbeza untuk mendapatkan bayang -bayang kecerunan CSS. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Latar belakang bergerakArtikel seterusnya:Latar belakang bergerak