Rumah >hujung hadapan web >tutorial css >Kesan Glassmorfisme Ikon di CSS
Saya baru -baru ini melihat kesan sejuk yang dikenali sebagai Glassmorphism dalam pukulan dribble. Pemikiran pertama saya ialah saya dapat mencipta semula dengan cepat dalam beberapa minit jika saya hanya menggunakan beberapa emojis untuk ikon tanpa membuang masa untuk SVG-ing mereka.
Saya tidak mungkin lebih salah tentang "beberapa minit" - mereka akhirnya menjadi hari -hari yang marah dan kecewa menggaru gatal ini!
Ternyata, walaupun terdapat sumber-sumber bagaimana CSS kesan sedemikian, mereka semua menganggap kes yang sangat mudah di mana overlay adalah segi empat tepat atau paling banyak segi empat tepat dengan radius sempadan. Walau bagaimanapun, mendapat kesan kaca untuk bentuk yang tidak teratur seperti ikon, sama ada ikon ini adalah emojis atau SVG yang betul, jauh lebih rumit daripada yang saya harapkan, jadi saya fikir ia akan bernilai berkongsi proses, perangkap yang saya jatuh ke dalam dan perkara -perkara yang saya pelajari di sepanjang jalan. Dan juga perkara yang saya masih tidak faham.
Jawapan ringkas: Kerana SVG mengambil terlalu banyak masa. Jawapan yang panjang: Kerana saya tidak mempunyai rasa artistik hanya menariknya dalam editor imej, tetapi saya sudah biasa dengan sintaks yang cukup sehingga saya sering dapat padat SVG siap sedia saya dapati dalam talian hingga kurang dari 10% dari saiz asalnya. Jadi, saya tidak boleh menggunakannya kerana saya dapati mereka di internet - saya perlu mengulangi kod untuk menjadikannya sangat bersih dan padat. Dan ini memerlukan masa. Banyak masa kerana ia berfungsi dengan terperinci.
Dan jika semua yang saya mahukan adalah dengan cepat kod konsep menu dengan ikon, saya menggunakan emojis, memohon penapis pada mereka untuk menjadikannya sepadan dengan tema dan itu sahaja! Itulah yang saya lakukan untuk demo interaksi bar cecair ini - ikon itu semua emojis! Kesan Lembah Lancar menggunakan teknik komposit topeng.
Baiklah, jadi ini akan menjadi titik permulaan kami: menggunakan emojis untuk ikon.
Pemikiran pertama saya adalah untuk menyusun dua pseudos (dengan kandungan emoji) dari pautan navigasi, sedikit mengimbangi dan memutar bahagian bawah dengan transformasi supaya mereka hanya sebahagiannya bertindih. Kemudian, saya akan membuat satu semitransparent teratas dengan nilai opacity yang lebih kecil daripada 1, menetapkan penapis latar belakang: kabur () di atasnya, dan itu sepatutnya cukup.
Sekarang, setelah membaca intro, anda mungkin tahu bahawa tidak seperti yang dirancang, tetapi mari kita lihat apa yang kelihatan seperti dalam kod dan isu -isu yang ada dengannya.
Kami menjana bar nav dengan pug berikut:
- biarkan data = { - Rumah: {ico: '?', Hue: 200}, - Nota: {ico: '? ️', hue: 260}, - Aktiviti: {ico: '?', Hue: 320}, - Discovery: {ico: '?', Hue: 30} -}; - biarkan e = object.entries (data); - biarkan n = e.length; nav - untuk (biarkan i = 0; i> n; i) a (href = ' #' data-ico = e [i] [1] .ico style = `--hue: $ {e [i] [1] .hue} deg`) #{e [i] [0]}
Yang disusun ke HTML di bawah:
<av> <a href="'#'" data-ico="'?'" gaya="'-hue:"> rumah </a> <a href="'#'" data-ico="'?" style="'-hue:"> notes </a> <a href="'#'" data-ico="'?'" gaya="'-hue:"> aktiviti </a> <a href="'#'" data-ico="'?'" gaya="'-hue:"> iscovery </a> </av>
Kami mulakan dengan susun atur, menjadikan item grid elemen kami. Kami meletakkan NAV di tengah, memberikan pautan lebar eksplisit, meletakkan kedua-dua pseudos untuk setiap pautan di sel atas (yang menolak kandungan teks pautan ke sel bawah) dan menengah teks pautan dan pseudos.
badan, nav, a {paparan: grid; } badan { Margin: 0; Ketinggian: 100VH; } nav { grid-auto-aliran: lajur; tempat-diri: pusat; Padding: .75em 0 .375em; } { lebar: 5EM; Teks-Align: Pusat; & :: sebelum ini, & :: selepas { grid-kawasan: 1/1; Kandungan: ATTR (Data-ICO); } }
Perhatikan bahawa rupa emojis akan berbeza bergantung pada penyemak imbas yang anda gunakan melihat demo.
Kami memilih font yang boleh dibaca, membungkus saiznya, menjadikan ikon lebih besar, menetapkan latar belakang, dan warna yang lebih baik untuk setiap pautan (berdasarkan harta tanah -hue dalam atribut gaya masing -masing):
badan { / * sama seperti sebelum */ Latar Belakang: #333; } nav { / * sama seperti sebelum */ Latar Belakang: #FFF; Font: Clamp (.625em, 5vw, 1.25em)/ 1.25 Ubuntu, sans-serif; } { / * sama seperti sebelum */ Warna: HSL (var (-Hue), 100%, 50%); Teks-penyerapan: Tiada; & :: sebelum ini, & :: selepas { / * sama seperti sebelum */ saiz font: 2.5EM; } }
Di sinilah perkara mula menjadi menarik kerana kita mula membezakan antara kedua -dua lapisan emoji yang dibuat dengan pautan pseudos. Kami sedikit bergerak dan berputar :: sebelum pseudo, menjadikannya monokrom dengan sepia (1) penapis, mendapatkannya ke warna yang betul, dan membentangkan kontrasnya () - teknik lama tetapi emas dari Lea Verou. Kami juga memohon penapis: Grayscale (1) pada :: Selepas pseudo dan menjadikannya semitransparent kerana, jika tidak, kami tidak akan dapat melihat pseudo yang lain melaluinya.
{ / * sama seperti sebelum */ & :: sebelum { Transform: Terjemahan (.375em, -.25em) berputar (22.5deg); Penapis: Sepia (1) Hue-Rotate (calc (var (-hue)-50deg)) tepu (3); } & :: selepas { Opacity: .5; Penapis: Grayscale (1); } }
Setakat ini, begitu baik ... jadi apa? Langkah seterusnya, yang saya fikirkan dengan bodoh akan menjadi yang terakhir apabila saya mendapat idea untuk kod ini, melibatkan penetapan latar belakang: Blur (5px) di atas (:: selepas) lapisan.
Perhatikan bahawa Firefox masih memerlukan gfx.webrender.all dan susun atur.css.backdrop-filter.enabled bendera yang ditetapkan untuk benar dalam: config agar harta penapis latar belakang berfungsi.
Malangnya, hasilnya tidak kelihatan seperti apa yang saya harapkan. Kami mendapat semacam overlay saiz keseluruhan kotak ikon teratas, tetapi ikon bawah tidak benar -benar kabur.
Walau bagaimanapun, saya cukup yakin saya telah bermain dengan penapis latar belakang: blur () sebelum dan ia berfungsi, jadi apa yang berbulu itu berlaku di sini?
Nah, apabila anda tidak tahu apa -apa pun mengapa sesuatu tidak berfungsi, semua yang anda boleh lakukan adalah mengambil contoh kerja yang lain, mula menyesuaikannya untuk cuba mendapatkan hasil yang anda inginkan ... dan lihat di mana ia pecah!
Oleh itu, mari kita lihat versi yang dipermudahkan demo kerja yang lebih lama. HTML hanyalah artikel dalam seksyen. Dalam CSS, kami mula -mula menetapkan beberapa dimensi, maka kami menetapkan latar belakang imej pada bahagian, dan satu semitransparent pada artikel. Akhirnya, kami menetapkan harta penapis latar belakang pada artikel itu.
bahagian {latar belakang: url (cake.jpg) 50%/ cover; } artikel { Margin: 25Vmin; Ketinggian: 40VH; Latar Belakang: HSLA (0, 0%, 97%, .25); latar belakang penapis: blur (5px); }
Ini berfungsi, tetapi kami tidak mahu dua lapisan kami bersarang antara satu sama lain; Kami mahu mereka menjadi adik beradik. Oleh itu, mari kita buat kedua -dua adik -beradik artikel, menjadikannya sebahagiannya bertindih dan lihat jika kesan Glassmorphism kami masih berfungsi.
<artikel class="'asas'"> </artikel> <artikel class="'kelabu'"> </artikel>
Artikel {lebar: 66%; Ketinggian: 40VH; } .base {latar belakang: url (cake.jpg) 50%/ cover; } .Grey { Margin: -50% 0 0 33%; Latar Belakang: HSLA (0, 0%, 97%, .25); latar belakang penapis: blur (5px); }
Segala -galanya masih kelihatan baik di Chrome dan, untuk sebahagian besar, Firefox juga. Ia hanya cara kabur () ditangani di sekitar tepi di Firefox kelihatan janggal dan bukan apa yang kita mahu. Dan, berdasarkan beberapa imej dalam spec, saya percaya hasil Firefox juga tidak betul?
Saya rasa satu masalah untuk masalah Firefox dalam kes di mana kedua-dua lapisan kami duduk di latar belakang pepejal (putih dalam kes ini) adalah untuk memberikan lapisan bawah (.base) kotak bayang-bayang tanpa offset, tidak kabur, dan radius penyebaran yang dua kali ganda radius kabur yang kami gunakan untuk filter latar belakang yang digunakan pada lapisan atas (.grey). Sudah tentu, pembetulan ini seolah -olah berfungsi dalam kes tertentu.
Perkara -perkara mendapat lebih banyak lagi jika kedua -dua lapisan kami duduk di atas elemen dengan latar belakang imej yang tidak ditetapkan (dalam hal ini, kita boleh menggunakan pendekatan latar belakang berlapis untuk menyelesaikan masalah Firefox), tetapi itu bukan kes di sini, jadi kita tidak akan masuk ke dalamnya.
Namun, mari kita bergerak ke langkah seterusnya. Kami tidak mahu dua lapisan kami menjadi dua kotak persegi, kami mahu menjadi emojis, yang bermaksud kami tidak dapat memastikan semitransparency untuk yang teratas menggunakan latar belakang HSLA () - kami perlu menggunakan kelegapan.
.Grey { / * sama seperti sebelum */ Opacity: .25; Latar Belakang: HSL (0, 0%, 97%); }
Nampaknya kita dapati masalahnya! Atas sebab tertentu, menjadikan lapisan atas semitransparent menggunakan kelegapan memecahkan kesan penapis latar belakang di kedua-dua krom dan firefox. Adakah itu pepijat? Adakah itu yang sepatutnya berlaku?
MDN mengatakan perkara berikut dalam perenggan pertama di halaman penapis latar belakang:
Kerana ia terpakai kepada segala -galanya di belakang elemen, untuk melihat kesannya, anda mesti membuat elemen atau latar belakangnya sekurang -kurangnya sebahagiannya telus.
Kecuali saya tidak memahami ayat di atas, ini nampaknya menunjukkan bahawa kelegapan tidak boleh memecahkan kesannya, walaupun ia berlaku di Chrome dan Firefox.
Bagaimana dengan spesifikasi? Nah, spec adalah dinding teks yang besar tanpa banyak ilustrasi atau demo interaktif, yang ditulis dalam bahasa yang membuatnya membacanya sebagai menarik sebagai menghidu kelenjar aroma skunk. Ia mengandungi bahagian ini, yang saya rasa mungkin relevan, tetapi saya tidak pasti bahawa saya faham apa yang cuba dikatakannya-bahawa kelegapan yang ditetapkan pada elemen teratas yang kita juga mempunyai penapis latar belakang juga akan digunakan pada adik-beradik di bawahnya? Jika itu hasil yang dimaksudkan, pastinya tidak berlaku dalam amalan.
Kesan penapis latar belakang tidak akan dapat dilihat kecuali beberapa bahagian elemen B adalah separa telus. Juga ambil perhatian bahawa sebarang kelegapan yang digunakan untuk elemen B akan digunakan untuk imej latar belakang yang ditapis juga.
Walau apa pun spec yang dikatakan, hakikatnya tetap: menjadikan lapisan atas semitransparent dengan harta kelegapan memecahkan kesan Glassmorphism di kedua -dua Chrome dan Firefox. Adakah terdapat cara lain untuk membuat emoji semitransparent? Nah, kita boleh cuba penapis: opacity ()!
Pada ketika ini, saya mungkin perlu melaporkan sama ada alternatif ini berfungsi atau tidak, tetapi realiti adalah ... Saya tidak tahu! Saya menghabiskan beberapa hari di sekitar langkah ini dan dapat memeriksa ujian yang banyak kali dalam sementara itu - kadang -kadang ia berfungsi, kadang -kadang ia tidak dalam penyemak imbas yang sama, dengan hasil yang berbeza bergantung pada waktu siang. Saya juga bertanya di Twitter dan mendapat jawapan bercampur. Hanya salah satu saat ketika anda tidak dapat membantu tetapi tertanya -tanya sama ada beberapa hantu Halloween tidak menghantui, menakutkan dan menghancurkan kod anda. Untuk keabadian!
Nampaknya semua harapan telah hilang, tetapi mari kita cuba satu lagi perkara: menggantikan segi empat tepat dengan teks, yang teratas menjadi semitransparent dengan warna: hsla (). Kami mungkin tidak dapat mendapatkan kesan Glassmorphism Emoji yang sejuk selepas itu, tetapi mungkin kita boleh mendapatkan hasil sedemikian untuk teks biasa.
Oleh itu, kami menambah kandungan teks ke unsur-unsur artikel kami, menjatuhkan ukuran eksplisit mereka, menjatuhkan saiz fon mereka, menyesuaikan margin yang memberi kami pertindihan separa dan, yang paling penting, menggantikan deklarasi latar belakang dalam versi kerja terakhir dengan warna. Atas sebab aksesibiliti, kami juga menetapkan Aria-Hidden = 'True' di bahagian bawah.
<artikel class="'asas'" aria-hidden="'true'"> singa? </artikel> <artikel class="'kelabu'"> singa? </artikel>
Artikel {Font: 900 21VW/ 1 Cursive; } .base {color: #ff7a18; } .Grey { Margin: -.75em 0 0 .5em; Warna: HSLA (0, 0%, 50%, .25); latar belakang penapis: blur (5px); }
Terdapat beberapa perkara yang perlu diperhatikan di sini.
Pertama, menetapkan harta warna kepada nilai dengan alpha subuniter juga menjadikan emojis semitransparent, bukan hanya teks biasa , baik dalam Chrome dan di Firefox! Ini adalah sesuatu yang saya tidak pernah tahu sebelum ini dan saya dapati benar -benar mindblowing, memandangkan saluran lain tidak mempengaruhi emojis dalam apa cara sekalipun.
Kedua, kedua -dua Chrome dan Firefox mengaburkan seluruh kawasan teks oren dan emoji yang terdapat di bawah kotak terikat lapisan kelabu semitransparent atas, bukan hanya mengaburkan apa yang di bawah teks sebenar. Di Firefox, perkara kelihatan lebih buruk kerana kesan tepi tajam yang janggal.
Walaupun kotak kabur bukanlah apa yang kita mahu, saya tidak dapat membantu tetapi menganggapnya masuk akal kerana spesifikasi itu mengatakan yang berikut:
[...] Untuk membuat elemen "telus" yang membolehkan imej latar belakang yang ditapis penuh dapat dilihat, anda boleh menggunakan "latar belakang warna: telus;".
Oleh itu, mari kita membuat ujian untuk memeriksa apa yang berlaku apabila lapisan atas adalah satu lagi bentuk bukan kubah yang bukan teks, tetapi sebaliknya diperoleh dengan kecerunan latar belakang, laluan klip atau topeng!
Dalam kedua -dua Chrome dan Firefox, kawasan di bawah seluruh kotak lapisan atas akan kabur apabila bentuknya diperoleh dengan latar belakang: kecerunan () yang, seperti yang disebutkan dalam kes teks sebelum ini, masuk akal mengikut spesifikasi. Walau bagaimanapun, Chrome menghormati bentuk klip-laluan dan topeng, sementara Firefox tidak. Dan, dalam kes ini, saya benar -benar tidak tahu yang betul, walaupun hasil krom lebih masuk akal kepada saya.
Hasil ini dan cadangan Twitter yang saya dapat apabila saya bertanya bagaimana untuk membuat Blur menghormati tepi teks dan bukannya kotak terikatnya membawa saya ke langkah seterusnya untuk Chrome: memohon topeng yang dipotong ke teks di atas lapisan (.grey). Penyelesaian ini tidak berfungsi di Firefox kerana dua sebab: satu, teks sedih nilai-nilai mask-standard yang hanya berfungsi dalam pelayar WebKit dan, dua, seperti yang ditunjukkan oleh ujian di atas, pelekat tidak menyekat kawasan kabur ke bentuk yang dicipta oleh topeng di Firefox.
/ * sama seperti sebelum */ .Grey { / * sama seperti sebelum */ -Webkit-Mask: Teks Linear-Gradient (Merah, Merah); / * hanya berfungsi dalam pelayar webkit */ }
Baiklah, ini sebenarnya kelihatan seperti apa yang kita mahu, jadi kita boleh mengatakan kita menuju ke arah yang betul! Walau bagaimanapun, di sini kami telah menggunakan emoji jantung oren untuk lapisan bawah dan emoji jantung hitam untuk lapisan semitransparent atas. Emojis generik lain tidak mempunyai versi hitam dan putih, jadi idea seterusnya saya pada mulanya membuat kedua -dua lapisan sama, kemudian membuat satu teratas semitransparent dan menggunakan penapis: kelabu (1) di atasnya.
artikel { Warna: HSLA (25, 100%, 55%, var (-a, 1)); Font: 900 21VW/ 1.25 Cursive; } .Grey { --A: .25; Margin: -1em 0 0 .5em; Penapis: Grayscale (1); latar belakang penapis: blur (5px); -Webkit-Mask: Teks Linear-Gradient (Merah, Merah); }
Nah, itu pastinya mempunyai kesan yang kita mahu di lapisan atas. Malangnya, atas sebab yang pelik, nampaknya juga telah menjejaskan kawasan kabur lapisan di bawahnya. Momen ini adalah di mana untuk mempertimbangkan secara ringkas membuang komputer riba keluar dari tingkap ... sebelum mendapat idea menambah lapisan lain.
Ia akan seperti ini: kita mempunyai lapisan asas, sama seperti kita setakat ini, sedikit mengimbangi dari dua yang lain di atasnya. Lapisan tengah adalah "hantu" (telus) yang mempunyai penapis latar belakang yang digunakan. Dan akhirnya, yang teratas adalah semitransparent dan mendapat penapis kelabu (1).
badan {paparan: grid; } artikel { grid-kawasan: 1/1; tempat-diri: pusat; Padding: .25em; Warna: HSLA (25, 100%, 55%, var (-a, 1)); Font: 900 21VW/ 1.25 Pacifico, Z003, Skrip Segoe, komik Sans MS, kursif; } .base {margin: -.5em 0 0 -.5em; } .midl { --A: 0; latar belakang penapis: blur (5px); -Webkit-Mask: Teks Linear-Gradient (Merah, Merah); } .Grey {Filter: Grayscale (1) Opacity (.25)}
Sekarang kita mendapat tempat! Hanya ada satu perkara lagi yang perlu dilakukan: Buat lapisan asas monokrom!
/ * sama seperti sebelum */ .base { margin: -.5em 0 0 -.5em; Penapis: sepia (1) kontras hue-rotate (165deg) (1.5); }
Baiklah, ini adalah kesan yang kita mahu!
Semasa pengekodan penyelesaian Chrome, saya tidak dapat membantu tetapi berfikir kita mungkin dapat menarik hasil yang sama di Firefox kerana Firefox adalah satu -satunya penyemak imbas yang menyokong fungsi elemen (). Fungsi ini membolehkan kita mengambil elemen dan menggunakannya sebagai latar belakang untuk elemen lain.
Idea ini ialah lapisan .base dan .grey akan mempunyai gaya yang sama seperti dalam versi krom, manakala lapisan tengah akan mempunyai latar belakang yang (melalui elemen () fungsi) versi kabur lapisan kami.
Untuk membuat perkara lebih mudah, kita mulakan dengan hanya versi kabur dan lapisan tengah ini.
<artikel id="'blur'" aria-hidden="'true'"> singa? </artikel> <artikel class="'midl'"> singa? </artikel>
Kami benar -benar meletakkan versi kabur (masih mengekalkannya sekarang), menjadikannya monokrom dan kabur dan kemudian menggunakannya sebagai latar belakang untuk .midl.
#blur { Kedudukan: Mutlak; Atas: 2EM; Kanan: 0; margin: -.5em 0 0 -.5em; Penapis: Sepia (1) Hue-Rotate (165Deg) Kontras (1.5) Blur (5px); } .midl { --A: .5; Latar Belakang: -Moz -Element (#Blur); }
Kami juga telah membuat teks pada elemen .midl semitransparent supaya kita dapat melihat latar belakang melaluinya. Kami akan menjadikannya telus sepenuhnya pada akhirnya, tetapi buat masa ini, kami masih mahu melihat kedudukannya berbanding latar belakang.
Kami dapat melihat satu isu dengan segera: sementara margin berfungsi untuk mengimbangi elemen #blur sebenar, ia tidak melakukan apa -apa untuk memindahkan kedudukannya sebagai latar belakang. Untuk mendapatkan kesan sedemikian, kita perlu menggunakan harta transformasi. Ini juga boleh membantu kita jika kita mahu putaran atau sebarang transformasi lain-kerana ia dapat dilihat di bawah di mana kita telah menggantikan margin dengan transformasi: berputar (-9deg).
Baiklah, tetapi kami masih berpegang pada hanya terjemahan buat masa ini:
#blur { / * sama seperti sebelum */ Transform: Terjemahan ( -. 25em, -.25em); / * menggantikan margin */ }
Satu perkara yang perlu diperhatikan di sini adalah bahawa sedikit latar belakang kabur akan dipotong kerana ia keluar dari batas kotak padding lapisan tengah. Itu tidak penting pada langkah ini kerana langkah seterusnya kami adalah untuk klip latar belakang ke kawasan teks, tetapi ia adalah baik untuk hanya mempunyai ruang kerana lapisan .base akan diterjemahkan sejauh ini.
Oleh itu, kita akan membongkok padding dengan sedikit, walaupun, pada ketika ini, ia tidak membuat perbezaan secara visual kerana kita juga menetapkan klip latar belakang: teks pada elemen .midl kami.
artikel { / * sama seperti sebelum */ padding: .5em; } #blur { Kedudukan: Mutlak; Bawah: 100VH; Transform: Terjemahan ( -. 25em, -.25em); Penapis: Sepia (1) Hue-Rotate (165Deg) Kontras (1.5) Blur (5px); } .midl { --A: .1; Latar Belakang: -Moz -Element (#Blur); Latar Belakang: Teks; }
Kami juga telah memindahkan elemen #blur dari penglihatan dan seterusnya mengurangkan alpha warna elemen .midl, kerana kami mahu pandangan yang lebih baik di latar belakang melalui teks. Kami tidak menjadikannya telus sepenuhnya, tetapi masih dapat dilihat sekarang sehingga kita tahu kawasan yang diliputinya.
Langkah seterusnya adalah untuk menambah elemen .base dengan gaya yang sama seperti yang ada dalam kes Chrome, hanya menggantikan margin dengan transformasi.
<artikel id="'blur'" aria-hidden="'true'"> singa? </artikel> <artikel class="'asas'" aria-hidden="'true'"> singa? </artikel> <artikel class="'midl'"> singa? </artikel>
#blur { Kedudukan: Mutlak; Bawah: 100VH; Transform: Terjemahan ( -. 25em, -.25em); Penapis: Sepia (1) Hue-Rotate (165Deg) Kontras (1.5) Blur (5px); } .base { Transform: Terjemahan ( -. 25em, -.25em); Penapis: sepia (1) kontras hue-rotate (165deg) (1.5); }
Oleh kerana sebahagian daripada gaya ini adalah perkara biasa, kita juga boleh menambah kelas .base pada elemen kabur kita #blur untuk mengelakkan pertindihan dan mengurangkan jumlah kod yang kita tulis.
<artikel id="'blur'" class="'asas'" aria-hidden="'true'"> singa? </artikel> <artikel class="'asas'" aria-hidden="'true'"> singa? </artikel> <artikel class="'midl'"> singa? </artikel>
#blur { --R: 5px; Kedudukan: Mutlak; Bawah: 100VH; } .base { Transform: Terjemahan ( -. 25em, -.25em); Penapis: Sepia (1) Hue-Rotate (165Deg) Kontras (1.5) Blur (var (-r, 0)); }
Kami mempunyai masalah yang berbeza di sini. Oleh kerana lapisan .base mempunyai transformasi, ia kini berada di atas lapisan .midl walaupun perintah DOM. Pembetulan paling mudah? Tambah z-indeks: 2 pada elemen .midl!
Kami masih mempunyai satu lagi masalah yang lebih halus: elemen .base masih dapat dilihat di bawah bahagian semitransparent latar belakang kabur yang telah kami tetapkan pada elemen .midl. Kami tidak mahu melihat tepi tajam teks lapisan .base di bawahnya, tetapi kami kerana kabur menyebabkan piksel dekat dengan tepi untuk menjadi semitransparent.
Bergantung pada jenis latar belakang yang kita ada pada ibu bapa lapisan teks kami, ini adalah masalah yang dapat diselesaikan dengan sedikit atau banyak usaha.
Jika kita hanya mempunyai latar belakang yang kukuh, masalah itu dapat diselesaikan dengan menetapkan warna latar belakang pada elemen .mid kita dengan nilai yang sama. Nasib baik, ini berlaku untuk menjadi kes kita, jadi kita tidak akan membincangkan senario lain. Mungkin dalam artikel lain.
.midl { / * sama seperti sebelum */ Latar Belakang: -Moz -Element (#Blur) #FFF; Latar Belakang: Teks; }
Kami semakin dekat dengan hasil yang baik di Firefox! Apa yang perlu dilakukan ialah menambah lapisan atas. Grey dengan gaya yang sama seperti dalam versi Chrome!
.grey {filter: grayscale (1) opacity (.25); }
Malangnya, melakukan ini tidak menghasilkan hasil yang kita inginkan, yang merupakan sesuatu yang benar -benar jelas jika kita juga membuat teks lapisan tengah sepenuhnya telus (dengan menghidupkan alpha -A: 0) supaya kita hanya melihat latar belakangnya (yang menggunakan unsur kabur #blur di atas pepejal putih) yang dipotong ke kawasan teks:
Masalahnya ialah kita tidak dapat melihat lapisan .Grey! Oleh kerana menetapkan z-indeks: 2 di atasnya, lapisan tengah .midl kini berada di atas apa yang harus menjadi lapisan atas (yang .grey), walaupun perintah DOM. Pembaikan? Tetapkan z-indeks: 3 pada lapisan .Grey!
.Grey { Z-indeks: 3; Penapis: kelabu (1) opacity (.25); }
Saya tidak suka memberikan lapisan z-indeks selepas lapisan, tapi hei, usaha yang rendah dan ia berfungsi! Kami kini mempunyai penyelesaian Firefox yang bagus:
Kami mulakan dengan kod Firefox kerana hanya ada lebih banyak lagi:
<artikel id="'blur'" class="'asas'" aria-hidden="'true'"> singa? </artikel> <artikel class="'asas'" aria-hidden="'true'"> singa? </artikel> <artikel class="'midl'" aria-hidden="'true'"> singa? </artikel> <artikel class="'kelabu'"> singa? </artikel>
badan {paparan: grid; } artikel { grid-kawasan: 1/1; tempat-diri: pusat; padding: .5em; Warna: HSLA (25, 100%, 55%, var (-a, 1)); Font: 900 21VW/ 1.25 Cursive; } #blur { --R: 5px; Kedudukan: Mutlak; Bawah: 100VH; } .base { Transform: Terjemahan ( -. 25em, -.25em); Penapis: Sepia (1) Hue-Rotate (165Deg) Kontras (1.5) Blur (var (-r, 0)); } .midl { --A: 0; Z-indeks: 2; Latar Belakang: -Moz -Element (#Blur) #FFF; Latar Belakang: Teks; } .Grey { Z-indeks: 3; Penapis: kelabu (1) opacity (.25); }
Pengisytiharan z-indeks tambahan tidak memberi kesan kepada hasil krom dan tidak juga elemen #blur yang tidak dapat dilihat. Satu-satunya perkara yang hilang agar ini berfungsi di Chrome adalah penapis latar belakang dan pengisytiharan topeng pada elemen .midl:
latar belakang penapis: blur (5px); -Webkit-Mask: Teks Linear-Gradient (Merah, Merah);
Oleh kerana kita tidak mahu penapis latar belakang diterapkan di Firefox, dan kita juga tidak mahu latar belakang digunakan di Chrome, kita menggunakan @Supports:
$ r: 5px; / * sama seperti sebelum */ #blur { / * sama seperti sebelum */ --r: #{$ r}; } .midl { --A: 0; Z-indeks: 2; / * perlu menetapkan semula di dalam @supports supaya ia tidak diterapkan di Firefox */ latar belakang penapis: blur ($ r); / * Nilai tidak sah di Firefox, tidak digunakan lagi, tidak perlu menetapkan semula */ -Webkit-Mask: Teks Linear-Gradient (Merah, Merah); @Supports (latar belakang: -moz -element (#blur)) { / * untuk firefox * / Latar Belakang: -Moz -Element (#Blur) #FFF; Latar Belakang: Teks; Backdrop-filter: Tiada; } }
Ini memberi kita penyelesaian silang penyemak imbas!
Walaupun hasilnya tidak sama dalam dua pelayar, ia masih cukup serupa dan cukup baik untuk saya.
Malangnya, itu mustahil.
Mula -mula, penyelesaian Firefox memerlukan kita mempunyai sekurang -kurangnya dua elemen sejak kita menggunakan satu (dirujuk oleh IDnya) sebagai latar belakang untuk yang lain.
Kedua, sementara pemikiran pertama dengan tiga lapisan yang tinggal (yang merupakan satu -satunya yang kita perlukan untuk penyelesaian Chrome) adalah bahawa salah satu daripada mereka boleh menjadi elemen sebenar dan dua lagi pseudosnya, ia tidak begitu mudah dalam kes ini.
Untuk penyelesaian Chrome, setiap lapisan mempunyai sekurang -kurangnya satu harta yang juga tidak dapat dipengaruhi oleh mana -mana kanak -kanak dan mana -mana pseudos yang mungkin ada. Untuk lapisan .base dan .grey, itulah harta penapis. Untuk lapisan tengah, itulah harta topeng.
Oleh itu, walaupun ia tidak cukup untuk mempunyai semua unsur -unsur itu, nampaknya kita tidak mempunyai penyelesaian yang lebih baik jika kita mahu kesan Glassmorphism untuk bekerja pada emojis juga.
Jika kita hanya mahu kesan Glassmorphism pada teks biasa - tiada emojis dalam gambar - ini boleh dicapai dengan hanya dua elemen, yang hanya diperlukan untuk penyelesaian Chrome. Yang lain adalah elemen #blur, yang hanya kita perlukan di Firefox.
<artikel id="'blur'"> darah </artikel> <artikel class="'text'" aria-hidden="'true'" data-text="'darah'"> </artikel>
Kami menggunakan dua pseudos elemen .teks untuk membuat lapisan asas (dengan :: sebelum) dan gabungan dua lapisan lain (dengan :: selepas). Apa yang membantu kita di sini ialah, dengan emojis keluar dari gambar, kita tidak memerlukan penapis: kelabu (1), tetapi sebaliknya kita dapat mengawal komponen ketepuan nilai warna.
Kedua -dua pseudos ini disusun satu di atas yang lain, dengan bahagian bawah (:: sebelum) diimbangi dengan jumlah yang sama dan mempunyai warna yang sama dengan elemen #blur. Nilai warna ini bergantung kepada bendera, - -f, yang membantu kita mengawal kedua -dua ketepuan dan alpha. Untuk kedua-dua unsur #blur dan :: sebelum pseudo (--f: 1), ketepuan adalah 100% dan alpha adalah 1. Untuk :: Selepas pseudo (--f: 0), ketepuan adalah 0% dan alpha adalah .25.
$ r: 5px; %teks {// digunakan oleh #blur dan kedua -dua. --f: 1; grid-kawasan: 1/1; // stack pseudos, diabaikan untuk #base yang benar -benar diposisikan padding: .5em; warna: HSLA (345, calc (var (-f)*100%), 55%, calc (.25 .75*var (-f))); Kandungan: ATTR (data-teks); } Artikel {Font: 900 21VW/ 1.25 Cursive} #blur { Kedudukan: Mutlak; Bawah: 100VH; Penapis: Blur ($ R); } #blur, .text :: sebelum { Transform: Terjemahan ( -. 125em, -.125em); @extend %teks; } .teks { paparan: grid; & :: selepas { --f: 0; @extend %teks; Z-indeks: 2; latar belakang penapis: blur ($ r); -Webkit-Mask: Teks Linear-Gradient (Merah, Merah); @Supports (latar belakang: -moz -element (#blur)) { Latar Belakang: -Moz -Element (#Blur) #FFF; Latar Belakang: Teks; Backdrop-filter: Tiada; } } }
Berita baik di sini adalah kes penggunaan khusus kami di mana kami hanya mempunyai kesan Glassmorphism pada ikon pautan (bukan pada keseluruhan pautan termasuk teks) sebenarnya memudahkan perkara -perkara yang sedikit.
Kami menggunakan PUG berikut untuk menghasilkan struktur:
- biarkan data = { - Rumah: {ico: '?', Hue: 200}, - Nota: {ico: '? ️', hue: 260}, - Aktiviti: {ico: '?', Hue: 320}, - Discovery: {ico: '?', Hue: 30} -}; - biarkan e = object.entries (data); - biarkan n = e.length; nav - untuk (biarkan i = 0; i <n i biarkan ico="e" .ico a.item style="`--hue:" .hue deg span.icon.tint aria-hidden="'true')" span.icon.midl belakang-imej: span.icon.grey><p> Yang menghasilkan struktur HTML seperti yang di bawah:</p> <pre rel="HTML" data-line=""> <av> <a class="'item'" href="'#'" style="'-hue:"> <span class="'icon" tint id="'blur0'" aria-hidden="'true'">? </span> <span class="'icon" tint aria-hidden="'true'">? </span> <span class="'icon" midl aria-hidden="'true'" style="'latar" belakang-imej:>? </span> <span class="'ikon" kelabu aria-hidden="'true'">? </span> rumah </a> </av>
Kita mungkin boleh menggantikan sebahagian daripada rentang mereka dengan pseudos, tetapi saya rasa ia lebih konsisten dan lebih mudah seperti ini, jadi sandwic span itu!
Satu perkara yang sangat penting untuk diperhatikan ialah kita mempunyai lapisan ikon kabur yang berbeza untuk setiap item (kerana setiap item mempunyai ikon sendiri), jadi kami menetapkan latar belakang elemen .midl kepadanya dalam atribut gaya. Melakukan perkara dengan cara ini membolehkan kami mengelakkan membuat sebarang perubahan pada fail CSS jika kami menambah atau mengeluarkan entri dari objek data (dengan itu mengubah bilangan item menu).
Kami mempunyai susun atur yang hampir sama dan gaya cantik yang kami ada ketika kami mula-mula CSS-ed bar nav. Satu -satunya perbezaan ialah sekarang kita tidak mempunyai pseudos di sel atas grid item; Kami mempunyai rentang:
rentang { grid-kawasan: 1/1; / * tumpukan semua emojis di atas satu sama lain */ saiz font: 4EM; / * Bump up emoji saiz */ }
Untuk lapisan ikon emoji sendiri, kami juga tidak perlu membuat banyak perubahan dari versi silang penyemak imbas yang kami dapatkan sedikit lebih awal, walaupun terdapat beberapa orang.
Mula -mula, kami menggunakan rantai transform dan penapis yang kami pilih pada mulanya apabila kami menggunakan pseudos pautan dan bukannya rentang. Kami juga tidak memerlukan warna: HSLA () perisytiharan pada lapisan span lagi sejak, memandangkan kami hanya mempunyai emojis di sini, ia hanya saluran alfa yang penting. Lalai, yang dipelihara untuk lapisan .base dan .grey, adalah 1. Jadi, bukannya menetapkan nilai warna di mana hanya alpha, -a, saluran saluran dan kita mengubahnya ke 0 pada lapisan .midl, kita terus menetapkan warna: telus di sana. Kami juga hanya perlu menetapkan warna latar belakang pada elemen .midl dalam kes Firefox kerana kami telah menetapkan imej latar belakang dalam atribut gaya. Ini membawa kepada penyesuaian penyelesaian berikut:
.base { / * versi emoji mono * / Transform: Terjemahan (.375em, -.25em) berputar (22.5deg); penapis: sepia (1) hue-rotate (var (-hue)) tepu (3) blur (var (-r, 0)); } .midl { / * Middle, Transparan emoji versi * / warna: telus; / * jadi ia tidak kelihatan */ latar belakang penapis: blur (5px); -Webkit-Mask: Teks Linear-Gradient (Merah 0 0); @Supports (latar belakang: -moz -element (#b)) { latar belakang warna: #fff; Latar Belakang: Teks; Backdrop-filter: Tiada; } }
Dan itu sahaja - kami mempunyai kesan ikon Glassmorphism yang bagus untuk bar nav ini!
Hanya ada satu lagi perkara yang perlu dijaga - kami tidak mahu kesan ini pada setiap masa; Hanya pada: hover atau: fokus keadaan. Oleh itu, kita akan menggunakan bendera, -hl, iaitu 0 dalam keadaan biasa, dan 1 dalam: hover atau: fokus keadaan untuk mengawal kelegapan dan mengubah nilai -nilai. Ini adalah teknik yang saya terperinci dalam artikel terdahulu.
$ t: .3s; { / * sama seperti sebelum */ --hl: 0; warna: HSL (var (-hue), calc (var (-hl)*100%), 65%); Peralihan: Warna $ t; &: hover, &: focus { - -hl: 1; } } .base { Transform: terjemahan (calc (var (-hl)*. 375em), calc (var (-hl)*-25em)) berputar (calc (var (-hl)*22.5deg)); opacity: var (-hl); Peralihan: Transformasi $ t, kelegapan $ t; }
Hasilnya dapat dilihat dalam demo interaktif di bawah apabila ikon dilegakan atau fokus.
Saya secara semula jadi bertanya kepada diri sendiri soalan ini selepas semua yang diperlukan untuk mendapatkan versi CSS Emoji yang berfungsi. Bukankah cara SVG biasa lebih masuk akal daripada sandwic span, dan tidakkah lebih mudah? Nah, walaupun ia lebih masuk akal, terutamanya kerana kita tidak mempunyai emojis untuk segala -galanya, sedihnya tidak kurang kod dan ia tidak lebih mudah sama ada.
Tetapi kita akan mendapat butiran mengenai perkara itu dalam artikel lain!
Atas ialah kandungan terperinci Kesan Glassmorfisme Ikon di CSS. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!