Czy przestrzegane są miejsca dziesiętne w szerokości CSS?

225

Zastanawiam się przez chwilę, projektując CSS.

Czy przestrzegane są miejsca dziesiętne w szerokości CSS? A może są zaokrąglone?

.percentage {
  width: 49.5%;
}

lub

.pixel {
  width: 122.5px;
}
Alastair Pitts
źródło

Odpowiedzi:

186

Jeśli jest to szerokość procentowa, to tak, jest przestrzegana . Jak zauważył Martin, rzeczy ulegają rozpadowi, gdy dochodzi do pikseli ułamkowych, ale jeśli wartości procentowe dają liczbę całkowitą (np. 50,5% z 200 pikseli w przykładzie), otrzymasz rozsądne, oczekiwane zachowanie.

Edit: Mam zaktualizowany przykład, aby pokazać, co dzieje się ułamkowych pikseli (w Chrome wartości są obcinane, więc 50, 50.5 i 50.6 wszystkie wykazują taką samą szerokość).

Skilldrick
źródło
7
Masz rację, że wartości procentowe nie są zaokrąglane same, ale szerokości pikseli z miejscami dziesiętnymi, a końcowy wynik obliczenia procentowego zawsze będzie zaokrąglany do pełnych pikseli :)
MartinodF
2
@MartinodF Dziękuję za wyjaśnienie. Tak, piksele są zaokrąglone, ale nie jest określone, czy faktycznie zaokrąglają do najbliższej, podłogi czy sufitu (co mam na myśli przez „rzeczy się psują”).
Skilldrick
1
@ Skilldrick Wypróbowałem piksele ułamkowe w twojej wersji demonstracyjnej w niektórych przeglądarkach ze względu na ciekawość: zarówno IE9p7, jak i FF4b7 zaokrąglają do najbliższego piksela, podczas gdy Opera 11b, Chrome 9.0.587.0 i Safari 5.0.3 obcinają tę wartość. @andras Tylko dla wyjaśnienia: Nie mówię, że wartości wewnętrzne są zaokrąglone, tylko końcowe wartości renderowania. Jeśli powiększysz lub niektóre elementy odziedziczą właściwości itd., Miejsca dziesiętne będą się liczyć.
MartinodF,
10
Nowoczesna aktualizacja: moja wersja Chrome 24 faktycznie zaokrągla ułamkowe piksele. Wyświetlanie jsFiddle, 50.5 i 50.6, zaokrągla w górę do 51px, będąc o 1 piksel szerszy niż div 50px.
Michael Butler,
5
Najważniejsze, na co należy zwrócić uwagę, to układanie się elementów o ułamkowych wymiarach pikseli. Podczas gdy oni zrobić okrągły się wizualnie od siebie, ale także nie zajmują dodatkowego miejsca podczas umieścić obok innych elementów fractionally wymiarach: cssdesk.com/8R2rB
Sandy Gifford
53

Nawet gdy liczba jest zaokrąglana podczas malowania strony, pełna wartość jest zachowywana w pamięci i używana do późniejszych obliczeń potomnych. Na przykład, jeśli twoje pudełko o wielkości 100.4999px maluje do 100px, to dziecko o szerokości 50% zostanie obliczone jako .5 * 100.4999 zamiast .5 * 100. I tak dalej na głębsze poziomy.

Stworzyłem głęboko zagnieżdżone systemy układu siatki, w których szerokość rodziców to ems, a dzieci to procenty, a uwzględnienie do czterech miejsc po przecinku powyżej miało zauważalny wpływ.

Obudowa Edge, jasne, ale należy o tym pamiętać.

natekoechley
źródło
2
Przyjęta odpowiedź jest bardziej kompletna niż ta, ale zamieszczona w niej anegdota pozwala mi lepiej zrozumieć, w jaki sposób odczują się implikacje techniczne. Dzięki za opublikowanie.
Tom
23

Chociaż piksele ułamkowe mogą wydawać się zaokrąglać w górę na poszczególnych elementach (jak pokazuje to bardzo dobrze @SkillDrick ) , ważne jest, aby wiedzieć, że piksele ułamkowe są faktycznie przestrzegane w rzeczywistym modelu pudełkowym .

Najlepiej widać to, gdy elementy są ułożone obok siebie (lub na sobie); innymi słowy, gdybym umieścił obok siebie 400 div pikseli 0,5, miałyby taką samą szerokość jak div 200 pikseli. Jeśli wszyscy oni rzeczywiście w zaokrągleniu do 1px (jak patrząc na poszczególne elementy oznaczałoby) chcielibyśmy oczekiwać 200px div być o połowę krótszy.

Można to zobaczyć w tym fragmencie kodu:

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
źródło
11
Odnośnie renderowania: w twoim przykładzie masz dwa div div dla każdego piksela. W takich przypadkach przeglądarka wybierze jeden z nich, aby wyrenderować cały piksel - aby uniknąć rozmycia i innych dziwnych artefaktów. Jeśli ustawisz połowę pikseli na niebieską, używając :nth-child(even)lub :nth-child(odd), zauważysz, że albo cała rzecz jest pomarańczowa, albo cała rzecz jest niebieska - nie jest to mieszanina niebieskiego i pomarańczowego (który byłby jakimś niejasnym fioletowym odcieniem).
Daan Wilmer,
16

Szerokość zaokrągla się do całkowitej liczby pikseli .

Nie wiem jednak, czy każda przeglądarka dokona tego w ten sam sposób. Wszystkie wydają się mieć inną strategię przy zaokrąglaniu wartości procentowych subpikseli. Jeśli interesują Cię szczegóły zaokrąglania subpikseli w różnych przeglądarkach, znajdziesz doskonały artykuł na temat ElastiCSS .

edycja : Testowałem demo @ Skilldrick w niektórych przeglądarkach ze względu na ciekawość. Gdy używasz ułamkowych wartości pikseli (a nie wartości procentowych, działają one zgodnie z sugestią w powiązanym artykule) IE9p7 i FF4b7 wydają się zaokrąglać do najbliższego piksela, podczas gdy Opera 11b, Chrome 9.0.587.0 i Safari 5.0.3 obcinają miejsca dziesiętne. Nie dlatego, że miałem nadzieję, że mają coś wspólnego…

MartinodF
źródło
7

Wydają się zaokrąglać wartości do najbliższej liczby całkowitej; ale widzę niespójność w Chrome, Safari i Firefox.

Na przykład, jeśli 33,3% konwertuje na 420,945px

chrome i firexfox pokazują go jako 421px. podczas gdy safari pokazuje 420px.

Wygląda na to, że chrome i firefox podążają za logiką podłogi i sufitu, podczas gdy safari tego nie robi. Ta strona wydaje się omawiać ten sam problem

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

agaase
źródło
6

Elementy muszą malować do całkowitej liczby pikseli, a ponieważ inne odpowiedzi obejmują, wartości procentowe są rzeczywiście przestrzegane.

Ważną uwagą jest to, że piksele w tym przypadku oznaczają piksele css , a nie piksele ekranowe, więc pojemnik 200px z 50.7499% dzieckiem zostanie zaokrąglony do 101px pikseli css , które następnie zostaną wyrenderowane na 202px na ekranie siatkówki, a nie 400 *. 507499 ~ = 203px.

Gęstość ekranu jest pomijana w tych obliczeniach i nie ma sposobu na pomalowanie * elementu o określonych rozmiarach subpikseli siatkówki. Nie można renderować tła lub obramowań elementów w rozmiarze mniejszym niż 1 piksel css wielkości, choć rozmiar właściwy element mógłby być mniejszy niż 1 piksel css jak Sandy Gifford pokazał.

[*] Możesz użyć niektórych technik, takich jak przesunięcie pola cienia o 0,5, itp., Ale rzeczywiste właściwości modelu pola zostaną pomalowane do pełnego piksela CSS.

Olex Ponomarenko
źródło
Doskonała obserwacja
sierpień