Ini adalah masalah lama. Ketika saya pertama kali menyadarinya, itu adalah desainer UI yang mengganggu saya. Ya, saya baru saja memasuki tempat kerja front-end dan tidak mengerti apa pun :
Perancang datang dengan ponselnya: Batas ini tebal, rancangan desain saya 1 piksel
SAYA:? ? ? ? Yang saya tulis itu 1px. Kalau tidak percaya, coba lihat. (Saat dia berbicara, dia mengeluarkan kode css
Desainer: Itu tidak benar. Menurut saya, garis tepinya jauh lebih tebal daripada yang ada di desain saya. Kelihatannya aneh (emmm, pikselnya benar-benar bagus.
Saya: Lalu saya akan mengubahnya menjadi 0,5px dan Anda dapat melihatnya (saya mengubah kode sambil berbicara
Perancang melihatnya dan mengangguk, memang jauh lebih baik.
Belakangan, diketahui bahwa kode yang sama bermasalah pada beberapa mesin Android, menyebabkan garis 0,5 piksel tidak terlihat.
Aneh. Jelas mengubahnya menjadi 0.5px tidak akan menyelesaikan masalah, tapi border 1px memang terlihat jauh lebih tebal dari rancangan desain.
Kinerja batas 1pxSaya langsung menggunakan css untuk mengatur batas 1px.
html:
<ul class=garis rambut> <li>1</li> <li>2</li></ul>
css:
* { margin: 0; padding: 0; } ul, li{ gaya daftar: tidak ada; } .hairlines { lebar: 300px; margin: 100px otomatis; -bawah: 1px solid #cccccc; // Atur batas menjadi 1px }Tangkapan layar yang didapat adalah sebagai berikut:
Tampilannya jauh lebih tebal dibandingkan rancangan desain. Rancangan desain akan tampak seperti ini.
Solusi 1: Kelas semu + transformasiDengan mentalitas menyelesaikan masalah, walaupun saat itu saya belum memikirkan alasannya dengan jelas, saya tetap menemukan solusi yang relevan. Beberapa metode disebutkan menggunakan border-image atau box-shadow, yang juga dapat mensimulasikan efek yang diinginkan. Efek batas 1px, tapi menurut saya pribadi ini tidak universal dan bukan solusi konvensional.
Pilihan terakhir adalah menggunakan metode pseudo-class + transform: prinsipnya adalah menghilangkan batas elemen asli, lalu menggunakan :before atau :after untuk mengulang batas, dan mengurangi skala transformasi hingga setengahnya elemen diposisikan secara relatif, dan perbatasan baru diposisikan secara absolut.
html sama seperti di atas
Cssnya seperti berikut:
* { margin: 0; padding: 0; } ul, li{ gaya daftar: tidak ada; } .garis rambut { lebar: 300 piksel; margin: 100 piksel otomatis; : 10px; } .garis rambut li:setelah{ konten: ''; posisi: kiri: 0; bawah: 0; #cccccc; lebar: 100%; tinggi: 1 piksel; -webkit-transformasi: skalaY(0,5); transformasi: skalaY(0,5);Dalam hal ini, garis yang digambar memang jauh lebih tipis. Saya biasanya menggunakan cara di atas untuk menyelesaikan masalah batas 1px selama setahun, tetapi setelah menggunakannya, saya menemukan beberapa masalah:
1.Mengapa skalaY(0,5)? Bagaimana Anda mendapatkan 0,5 ini? Apakah semua model perlu diperkecil menjadi setengahnya, dengan kata lain, apakah model tersebut bersifat universal?
2. Bagaimana jika saya ingin menggambar empat batas sebuah wadah secara bersamaan?
3. Apakah ini mendukung batas sudut membulat?
Solusi untuk dua masalah terakhir dapat ditemukan dengan memodifikasi kode di atas (untuk memudahkan melihat efeknya, saya menggabungkan efek yang diperoleh dengan penulisan normal dan efek yang diperoleh dengan menggunakan kelas semu, sehingga lebih mudah untuk melihat perbedaannya):
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=initial-scale=1, maksimum-skala=1, minimum-skala=1, dapat diskalakan pengguna =tidak, lebar=lebar perangkat> <title>masalah batas 1px pada terminal seluler</title> <style> * { margin: 0; padding: 0; tidak ada; } .lines { lebar: 200px; margin: 0 otomatis; } .lines li { batas: 1px solid #cccccc; tinggi garis: 50px; -atas: 10 piksel; } .garis rambut { lebar: 200 piksel; margin: 0 radius batas: 3px; } .hairlines li{ tinggi: 50px; tinggi garis: 50px; batas:tidak ada; perataan teks: posisi: relatif; margin-atas: 10px; : mutlak; kiri: 0; atas: 0; batas: 1 piksel padat #cccccc; 200%; tinggi: 200%; -webkit-transform: skala(0,5); transformasi: skala(0,5); -webkit-transform-origin: kiri atas; transformasi-asal: kiri atas; ><body>Garis tebal<ul class=lines> <li>1</li> <li>2</li></ul>Garis tipis<ul class=hairlines> <li>3</li> <li>4</li></ul></body></html>Render yang dihasilkan adalah sebagai berikut:
Batas di bawahnya jelas jauh lebih tipis, lebih dekat dengan rancangan desain.
Jadi 1. Mengapa skalaY(0,5)? Bagaimana Anda mendapatkan 0,5 ini? Apakah semua model perlu diperkecil menjadi setengahnya, dengan kata lain, apakah model tersebut bersifat universal? Bagaimana menjawab pertanyaan ini?
Ini membawa kita kembali ke inti masalahnya. Mengapa masih terlihat jauh lebih tebal dari biasanya meskipun saya sudah menulis 1px di css?
Setelah dicek informasinya, ternyata piksel yang disetel di css tidak sesuai dengan piksel perangkat satu-ke-satu. Artinya jika saya menentukan 1px di css, apa yang saya lihat di ponsel mungkin tidak menjadi satu piksel. Lebar yang ditempati oleh titik.
Piksel CSS adalah konsep abstrak dan relatif. Di perangkat dan lingkungan yang berbeda, piksel fisik yang direpresentasikan berbeda. Pada perangkat lama, kerapatan piksel layar relatif rendah. Dengan cara ini, piksel 1 piksel memang merupakan piksel fisik piksel, tetapi teknologi berkembang pesat. Layar ponsel saat ini semuanya beresolusi tinggi. Jika ukurannya tidak berubah, layar akan diisi dengan lebih banyak piksel. Pada saat ini, piksel CSS (biasanya disebut piksel Logis) akan sesuai beberapa piksel fisik.
Jadi, berapa banyak piksel fisik yang sesuai dengan lebar piksel CSS?
Ini perlu menyebutkan devicePixelRatio (rasio piksel perangkat)
devicePixelRatio = piksel fisik/piksel independen pada perangkat, yang dapat diperoleh melalui window.devicePixelRatio. Rasio piksel ini dapat dengan tepat menggambarkan berapa banyak piksel fisik yang sesuai dengan lebar piksel CSS, yang sebenarnya sesuai dengan piksel devicePixelRatio.
Ketika atribut skala awal dari area pandang adalah 1, ukuran halaman normal, tetapi ketika skala awal adalah 0,5, halaman dikurangi 1 kali lipat. Perangkat dengan devicePixelRatio 2 awalnya memiliki lebar 1 piksel CSS yang berjumlah 2 lebar piksel fisik. Setelah dikurangi, lebar 1 piksel CSS hanya menempati 1 piksel fisik, yang berarti tercapai 1 piksel fisik sebenarnya.
Solusi 2: rem + area pandangPada titik ini, solusinya sangat jelas: kita bisa mendapatkan devicePixelRatio perangkat saat runtime dan secara dinamis mengubah skala awal viewport menjadi 1/devicePixelRatio, untuk memastikan bahwa lebar 1px adalah 1 piksel fisik sebenarnya lebar. Gunakan rem untuk adaptasi lainnya (karena jika menggunakan px akan berkurang)
Kodenya adalah sebagai berikut:
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <!--<meta name=viewport content=initial-scale=1, maksimum-skala=1, minimum-skala=1 , user-scalable=no, width=device-width>--> <title>masalah batas 1px di terminal seluler</title> <script> (function () { var clientWidth = jendela.layar.lebar; var dpr = jendela.devicePixelRatio; var vp = dokumen.createElement('meta'); px'; vp.nama = 'area pandang'; vp.konten = `skala awal=${1,0 * 1 / dpr}, skala maksimum=${1,0 * 1 / dpr}, skala minimum=${1,0 * 1 / dpr}, dapat diskalakan pengguna=tidak, lebar=perangkat- lebar`; var m = dokumen.getElementsByTagName('meta')[0]; m.parentNode.insertBefore(vp, m); })(); </skrip> <gaya> * { margin: 0; } ul, li{ gaya daftar: tidak ada; } .lines { lebar: 10rem; { batas: 1px solid #cccccc; tinggi: 2,5rem; tinggi garis: 2,5rem; perataan teks: radius batas: 0,6rem; margin-atas: 0,5rem; } </style></head><body><ul class=lines> <li>1</li> <li>2</li></ul></ tubuh></html>Efek yang didapat dapat dilihat pada gambar di bawah ini (lebih jelas jika dilihat di ponsel):
Dari sudut pandang di atas, kembali ke pertanyaan sebelumnya, 1. Mengapa scaleY(0.5)? Bagaimana Anda mendapatkan 0,5 ini? Apakah semua model perlu diperkecil hingga setengahnya, dengan kata lain, apakah model tersebut bersifat universal? Sebenarnya belum tentu 0,5. Di perangkat dengan dpr 3, seharusnya 0,3333.. Tidak universal karena dpr setiap ponsel mungkin berbeda. Namun, 0,5 pada metode 1 umumnya setidaknya lebih tipis dari 1px, jadi hampir dapat memenuhi persyaratan desainer.
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.