¿Se respetan los decimales en un ancho CSS?

Resuelto Alastair Pitts asked hace 13 años • 6 respuestas

Algo que me he estado preguntando durante un tiempo mientras hacía diseño CSS.

¿Se respetan los decimales en los anchos de CSS? ¿O son redondeados?

.percentage {
  width: 49.5%;
}

o

.pixel {
  width: 122.5px;
}
Alastair Pitts avatar Nov 30 '10 06:11 Alastair Pitts
Aceptado

Si es un ancho porcentual, entonces sí, se respeta:

#outer {
    width: 200px;
}

#first {
    width: 50%;
    height: 20px;
    background-color: red;
}

#second {
    width: 50.5%;
    height: 20px;
    background-color:green;
}

#third {
    width: 51%;
    height: 20px;
    background-color:blue;
}
<div id="outer">
    <div id="first">&nbsp;</div>
    <div id="second">&nbsp;</div>
    <div id="third">&nbsp;</div>
</div>
Expandir fragmento

Como señaló Martin, las cosas se descomponen cuando llegas a píxeles fraccionarios, pero si tus valores porcentuales arrojan un valor de píxel entero (por ejemplo, 50,5% de 200 px en el ejemplo), obtendrás el comportamiento esperado y sensato.

Editar: actualicé el ejemplo para mostrar lo que sucede con los píxeles fraccionarios (en Chrome los valores están truncados, por lo que 50, 50,5 y 50,6 muestran el mismo ancho).

#percentage {
    width: 200px;
    color: white;
}

#percentage .first {
    width: 50%;
    height: 20px;
    background-color: red;
}

#percentage .second {
    width: 50.5%;
    height: 20px;
    background-color:green;
}

#percentage .third {
    width: 51%;
    height: 20px;
    background-color:blue;
}

#pixels {
    color: white;
}

#pixels .first {
    width: 50px;
    height: 20px;
    background-color: red;
}

#pixels .second {
    width: 50.5px;
    height: 20px;
    background-color:green;
}

#pixels .third {
    width: 50.6px;
    height: 20px;
    background-color:blue;
}

#pixels .fourth {
    width: 51px;
    height: 20px;
    background-color:red;
}
<div id="percentage">
    <div class="first">50%=100px</div>
    <div class="second">50.5%=101px</div>
    <div class="third">51%=102px</div>
</div>
<br />
<div id="pixels">
    <div class="first">50px</div>
    <div class="second">50.5px</div>
    <div class="third">50.6px</div>
    <div class="fourth">51px</div>
</div>
Expandir fragmento

Skilldrick avatar Nov 29 '2010 23:11 Skilldrick

Incluso cuando el número se redondea al pintar la página, el valor completo se conserva en la memoria y se utiliza para cálculos secundarios posteriores. Por ejemplo, si su cuadro de 100.4999px se pinta en 100px, su hijo con un ancho del 50% se calculará como .5*100.4999 en lugar de .5*100. Y así sucesivamente hasta niveles más profundos.

He creado sistemas de diseño de cuadrícula profundamente anidados donde los anchos de los padres son ems y los hijos son porcentajes, e incluir hasta cuatro puntos decimales en sentido ascendente tuvo un impacto notable.

Caso Edge, claro, pero algo a tener en cuenta.

natekoechley avatar Nov 29 '2010 23:11 natekoechley

Aunque puede parecer que los píxeles fraccionarios se redondean en elementos individuales (como lo demuestra muy bien @SkillDrick ), es importante saber que los píxeles fraccionarios en realidad se respetan en el modelo de caja real .

Esto se puede ver mejor cuando los elementos se apilan uno al lado del otro (o encima de él); en otras palabras, si colocara 400 divs de 0,5 píxeles uno al lado del otro, tendrían el mismo ancho que un único div de 200 píxeles. Si todos realmente se redondearan a 1 px (como implicaría mirar elementos individuales), esperaríamos que el div de 200 px fuera la mitad de largo.

Esto se puede ver en este fragmento de código ejecutable:

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>
Expandir fragmento

Sandy Gifford avatar Apr 09 '2014 21:04 Sandy Gifford

El ancho se redondeará a un número entero de píxeles .

Sin embargo, no sé si todos los navegadores lo redondearán de la misma manera. Todos parecen tener una estrategia diferente al redondear los porcentajes de subpíxeles. Si está interesado en los detalles del redondeo de subpíxeles en diferentes navegadores, hay un excelente artículo sobre ElastiCSS .

editar : Probé la demostración de @Skilldrick en algunos navegadores por curiosidad. Cuando se utilizan valores de píxeles fraccionarios (no porcentajes, funcionan como se sugiere en el artículo que vinculé), IE9p7 y FF4b7 parecen redondear al píxel más cercano, mientras que Opera 11b, Chrome 9.0.587.0 y Safari 5.0.3 truncan los lugares decimales. No es que esperara que tuvieran algo en común después de todo...

MartinodF avatar Nov 29 '2010 23:11 MartinodF

Parecen redondear los valores al número entero más cercano; pero veo inconsistencia en Chrome, Safari y Firefox.

Por ejemplo, si el 33,3% se convierte a 420,945 px

Chrome y Firefox lo muestran como 421px. mientras que Safari muestra que es de 420 px.

Parece que Chrome y Firefox siguen la lógica del piso y el techo, mientras que Safari no. Esta página parece discutir el mismo problema.

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

agaase avatar Aug 19 '2013 12:08 agaase