Apakah tempat desimal dalam lebar CSS dihormati?

225

Sesuatu yang saya sudah bertanya-tanya untuk sementara saat melakukan desain CSS.

Apakah tempat desimal dalam lebar CSS dihormati? Atau apakah mereka bulat?

.percentage {
  width: 49.5%;
}

atau

.pixel {
  width: 122.5px;
}
Alastair Pitts
sumber

Jawaban:

186

Jika itu persentase lebar, maka ya, itu dihormati . Seperti yang Martin tunjukkan, hal-hal rusak ketika Anda mencapai piksel fraksional, tetapi jika nilai persentase Anda menghasilkan nilai piksel bilangan bulat (misalnya 50,5% dari 200px dalam contoh) Anda akan mendapatkan perilaku yang masuk akal dan diharapkan.

Sunting: Saya telah memperbarui contoh untuk menunjukkan apa yang terjadi pada piksel fraksional (di Chrome nilainya terpotong, jadi 50, 50,5 dan 50,6 semuanya menunjukkan lebar yang sama).

Skilldrick
sumber
7
Anda benar tentang nilai persentase yang tidak dibulatkan sendiri, tetapi lebar piksel dengan tempat desimal dan hasil akhir dari perhitungan persentase akan selalu dibulatkan ke seluruh piksel :)
MartinodF
2
@MartinodF Terima kasih atas klarifikasi. Ya, pikselnya bulat, tetapi tidak ditentukan apakah benar-benar membulatkan ke terdekat, lantai atau langit-langit (yang saya maksud dengan "hal-hal rusak").
Skilldrick
1
@ Skilldrick Saya mencoba piksel fraksional dalam demo Anda di beberapa browser demi rasa ingin tahu: baik IE9p7 dan FF4b7 membulatkan ke piksel terdekat, sementara Opera 11b, Chrome 9.0.587.0 dan Safari 5.0.3 memotong nilainya. @ andras Hanya untuk memperjelas: Saya tidak mengatakan bahwa nilai internal dibulatkan, hanya nilai render akhir yang. Jika Anda memperbesar, atau beberapa elemen mewarisi properti dan sebagainya, tempat desimal itu akan dihitung.
MartinodF
10
Pembaruan modern: Chrome versi 24 saya sebenarnya menangkap piksel fraksional. Melihat jsFiddle, 50,5 dan 50,6 keduanya membulatkan hingga 51px, menjadi 1 piksel lebih lebar dari div 50px.
Michael Butler
5
Apa yang mungkin paling penting untuk diperhatikan adalah bagaimana elemen dengan dimensi piksel fraksional saling bertumpuk. Sementara mereka lakukan putaran up visual sendiri, mereka juga tidak mengambil ruang ekstra ketika menempatkan sebelah elemen fraksional dimensioned lainnya: cssdesk.com/8R2rB
Sandy Gifford
53

Bahkan ketika angka dibulatkan saat halaman dicat, nilai penuh disimpan dalam memori dan digunakan untuk perhitungan anak berikutnya. Misalnya, jika kotak Anda dari 100,4999px cat ke 100px, itu anak dengan lebar 50% akan dihitung sebagai 0,5 * 100,4999 bukan 0,5 * 100. Dan seterusnya ke level yang lebih dalam.

Saya telah membuat sistem tata letak grid bersarang di mana lebar orang tua adalah ems, dan anak-anak adalah persen, dan termasuk hingga empat titik desimal di bagian hulu memiliki dampak yang nyata.

Kasing tepi, tentu saja, tetapi sesuatu yang perlu diingat.

natekoechley
sumber
2
Jawaban yang diterima lebih lengkap daripada yang ini, tetapi anekdot dalam yang satu ini memberi saya perasaan yang lebih baik tentang bagaimana implikasi teknis akan membuat diri mereka terasa. Terima kasih telah mempostingnya.
Tom
23

Meskipun piksel fraksional mungkin tampak cocok pada elemen individual (seperti yang ditunjukkan oleh @SkillDrick dengan baik) , penting untuk mengetahui bahwa piksel fraksional benar-benar dihormati dalam model kotak yang sebenarnya .

Ini paling baik dilihat ketika elemen-elemen ditumpuk di samping (atau di atas) satu sama lain; dengan kata lain, jika saya menempatkan 400 0,5 pixel div secara berdampingan, mereka akan memiliki lebar yang sama dengan div 200 pixel tunggal. Jika mereka semua benar - benar dibulatkan hingga 1px (seperti yang terlihat pada elemen individual akan menyiratkan) kita akan mengharapkan div 200px menjadi setengah panjang.

Ini dapat dilihat dalam cuplikan kode runnable ini:

body {
  color:            white;
  font-family:      sans-serif;
  font-weight:      bold;
  background-color: #334;
}

.div_house div {
  height:           10px;
  background-color: orange;
  display:          inline-block;
}

div#small_divs div {
  width:            0.5px;
}

div#large_div div {
  width:            200px;
}
<div class="div_house" id="small_divs">
  <p>0.5px div x 400</p>
  <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<br>
<div class="div_house" id="large_div">
  <p>200px div x 1</p>
  <div></div>
</div>

Sandy Gifford
sumber
11
Berkenaan dengan rendering: dalam contoh Anda, Anda memiliki dua div yang bersaing untuk setiap piksel. Dalam kasus ini, browser Anda akan memilih salah satunya untuk membuat seluruh piksel - untuk menghindari kabur dan artefak aneh lainnya. Jika Anda menetapkan setengah piksel menjadi biru, menggunakan :nth-child(even)atau :nth-child(odd), Anda perhatikan bahwa semuanya berwarna oranye atau seluruhnya berwarna biru - bukan campuran warna biru dan oranye (yang akan menjadi warna ungu yang samar-samar).
Daan Wilmer
16

Lebar akan dibulatkan ke angka integer piksel .

Saya tidak tahu apakah setiap browser akan memutarnya dengan cara yang sama. Mereka semua tampaknya memiliki strategi yang berbeda ketika membulatkan persentase sub-pixel. Jika Anda tertarik dengan detail pembulatan sub-pixel di berbagai browser, ada artikel bagus tentang ElastiCSS .

sunting : Saya menguji demo @ Skilldrick di beberapa browser demi rasa ingin tahu. Ketika menggunakan nilai piksel fraksional (bukan persentase, mereka berfungsi seperti yang disarankan dalam artikel yang saya tautkan) IE9p7 dan FF4b7 tampaknya membulatkan ke piksel terdekat, sementara Opera 11b, Chrome 9.0.587.0 dan Safari 5.0.3 memotong tempat desimal. Bukannya aku berharap mereka memiliki kesamaan ...

MartinodF
sumber
7

Mereka tampaknya mengumpulkan nilai ke integer terdekat; tapi saya melihat ketidakkonsistenan dalam chrome, safari dan firefox.

Misalnya, jika 33,3% dikonversi ke 420,945px

chrome dan firexfox menunjukkannya sebagai 421px. sementara safari menunjukkan sebagai 420px.

Sepertinya chrome dan firefox mengikuti logika lantai dan langit-langit sementara safari tidak. Halaman ini tampaknya membahas masalah yang sama

http://ejohn.org/blog/sub-pixel-problems-in-css/

agaase
sumber
6

Elemen harus melukis ke jumlah integer piksel, dan sebagai jawaban lain yang dibahas, persentase memang dihormati.

Catatan penting adalah bahwa piksel dalam hal ini berarti piksel css , bukan piksel layar, sehingga wadah 200px dengan anak 50,7499% akan dibulatkan menjadi piksel piksel 101px , yang kemudian dirender ke 202px pada layar retina, dan tidak 400 *. 507499 ~ = 203px.

Kepadatan layar diabaikan dalam perhitungan ini, dan tidak ada cara untuk melukis * elemen ke ukuran subpiksel retina tertentu. Anda tidak dapat memiliki latar belakang atau batas elemen yang diberikan kurang dari 1 css piksel , meskipun ukuran elemen sebenarnya bisa kurang dari 1 css piksel seperti yang ditunjukkan Sandy Gifford.

[*] Anda dapat menggunakan beberapa teknik seperti 0,5 offset kotak-bayangan, dll, tetapi properti model kotak yang sebenarnya akan melukis ke piksel CSS penuh.

Olex Ponomarenko
sumber
Baik pengamatan
Agustus