Le posizioni decimali in una larghezza CSS sono rispettate?


225

Qualcosa che mi chiedevo da un po 'mentre facevo la progettazione CSS.

Le posizioni decimali nelle larghezze CSS sono rispettate? O sono arrotondati?

.percentage {
  width: 49.5%;
}

o

.pixel {
  width: 122.5px;
}

Risposte:


186

Se è una larghezza percentuale, quindi sì, è rispettata . Come ha sottolineato Martin, le cose si rompono quando si arriva a pixel frazionari, ma se i valori percentuali producono un valore di pixel intero (ad esempio il 50,5% di 200 px nell'esempio) si otterrà un comportamento ragionevole e atteso.

Modifica: ho aggiornato l'esempio per mostrare cosa succede ai pixel frazionari (in Chrome i valori vengono troncati, quindi 50, 50.5 e 50.6 mostrano tutti la stessa larghezza).


7
Hai ragione sui valori percentuali che non vengono arrotondati, ma la larghezza dei pixel con le cifre decimali e il risultato finale del calcolo percentuale verranno sempre arrotondati a interi pixel :)
MartinodF

2
@MartinodF Grazie per il chiarimento. Sì, i pixel sono arrotondati, ma non è definito se in realtà arrotondano al più vicino, al pavimento o al soffitto (che è ciò che intendevo per "rottura delle cose").
Skilldrick,

1
@Skilldrick Ho provato i pixel frazionari nella tua demo su alcuni browser per motivi di curiosità: sia IE9p7 che FF4b7 arrotondano al pixel più vicino, mentre Opera 11b, Chrome 9.0.587.0 e Safari 5.0.3 troncano il valore. @andras Solo per chiarire: non sto dicendo che i valori interni siano arrotondati, ma solo i valori di rendering finali. Se si esegue lo zoom o alcuni elementi ereditano le proprietà e così via, verranno conteggiati i decimali.
MartinodF

10
Aggiornamento moderno: la mia versione 24 di Chrome arrotonda effettivamente i pixel frazionari. Visualizzazione di jsFiddle, 50.5 e 50.6 entrambi arrotondati a 51px, essendo 1 pixel più ampi del div 50px.
Michael Butler,

5
Ciò che può essere più importante notare è il modo in cui gli elementi con dimensioni pixel frazionarie si impilano uno accanto all'altro. Mentre loro fanno tutto visivamente da soli, anche loro non occupano spazio in più quando ha messo accanto ad altri elementi in frazioni dimensionati: cssdesk.com/8R2rB
Sandy Gifford

53

Anche quando il numero viene arrotondato quando viene disegnata la pagina, l'intero valore viene conservato in memoria e utilizzato per il successivo calcolo figlio. Ad esempio, se la tua scatola da 100.4999 px dipinge a 100 px, il figlio con una larghezza del 50% verrà calcolato come .5 * 100.4999 anziché .5 * 100. E così via a livelli più profondi.

Ho creato sistemi di layout della griglia profondamente nidificati in cui le larghezze dei genitori sono em e i bambini sono percentuali e l'inclusione fino a quattro punti decimali a monte ha avuto un impatto notevole.

Edge case, certo, ma qualcosa da tenere a mente.


2
La risposta accettata è più completa di questa, ma l'aneddoto in questa mi dà un'idea migliore di come si sentiranno le implicazioni tecniche. Grazie per averlo pubblicato.
Tom,

23

Sebbene i pixel frazionari possano apparire per arrotondare su singoli elementi (come dimostra molto bene @SkillDrick ) , è importante sapere che i pixel frazionari sono effettivamente rispettati nel modello box effettivo .

Ciò può essere visto meglio quando gli elementi sono impilati uno accanto all'altro (o uno sopra l'altro); in altre parole, se dovessi posizionare 400 div da 0,5 pixel fianco a fianco, avrebbero la stessa larghezza di un singolo div da 200 pixel. Se tutti effettivamente arrotondassero per eccesso a 1px (come implicano i singoli elementi) ci aspetteremmo che il div 200px sia lungo la metà.

Questo può essere visto in questo frammento di codice eseguibile:

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>


11
Per quanto riguarda il rendering: nel tuo esempio, hai due div in competizione per ogni pixel. In questi casi, il tuo browser ne sceglierà uno per renderizzare l'intero pixel, per evitare la sfocatura e altri strani artefatti. Se imposti metà dei pixel in modo che siano blu, usando :nth-child(even)o :nth-child(odd), noti che l'intera cosa è arancione o l'intera cosa è blu, non una miscela di blu e arancione (che sarebbe una vaga tonalità viola).
Daan Wilmer,

16

La larghezza verrà arrotondata a un numero intero di pixel .

Non so se ogni browser lo arrotonderà allo stesso modo però. Sembrano tutti avere una strategia diversa quando arrotondano le percentuali dei sub-pixel. Se sei interessato ai dettagli dell'arrotondamento dei sub-pixel in diversi browser, c'è un eccellente articolo su ElastiCSS .

modifica : ho provato la demo di @ Skilldrick in alcuni browser per motivi di curiosità. Quando si usano valori di pixel frazionari (non percentuali, funzionano come suggerito nell'articolo che ho collegato) IE9p7 e FF4b7 sembrano arrotondare al pixel più vicino, mentre Opera 11b, Chrome 9.0.587.0 e Safari 5.0.3 troncano le posizioni decimali. Non che sperassi che avessero qualcosa in comune dopo tutto ...


7

Sembrano arrotondare i valori all'intero più vicino; ma sto vedendo incoerenza in Chrome, Safari e Firefox.

Ad esempio, se il 33,3% viene convertito in 420,945 px

chrome e firexfox lo mostrano come 421px. mentre safari mostra il suo come 420px.

Sembra che Chrome e Firefox seguano la logica del pavimento e del soffitto mentre Safari no. Questa pagina sembra discutere lo stesso problema

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


6

Gli elementi devono dipingere su un numero intero di pixel e, come coperto dalle altre risposte, le percentuali sono effettivamente rispettate.

Una nota importante è che i pixel in questo caso significano pixel CSS , non pixel dello schermo, quindi un contenitore da 200 px con un bambino del 50,7499% verrà arrotondato a 101 pixel CSS , che verranno quindi renderizzati su 202 px su uno schermo retina, e non 400 *. 507499 ~ = 203px.

La densità dello schermo viene ignorata in questo calcolo e non c'è modo di dipingere * un elemento con dimensioni subpixel specifiche della retina. Non è possibile eseguire il rendering degli sfondi o dei bordi degli elementi con dimensioni pixel inferiori a 1 css , anche se le dimensioni effettive dell'elemento potrebbero essere inferiori a 1 pixel css, come ha dimostrato Sandy Gifford.

[*] Puoi usare alcune tecniche come 0,5 offset box-shadow, ecc., Ma le proprietà del modello box reale verranno applicate a un pixel CSS completo.


Ottima osservazione
mese di agosto
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.