¿Se respetan los lugares decimales en un ancho CSS?

225

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

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

.percentage {
  width: 49.5%;
}

o

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

Respuestas:

186

Si es un ancho porcentual, entonces sí, se respeta . Como señaló Martin, las cosas se descomponen cuando se llega a píxeles fraccionarios, pero si sus valores porcentuales producen un valor de píxel entero (por ejemplo, 50.5% de 200 px en el ejemplo) obtendrá un comportamiento esperado y sensible.

Editar: he actualizado el ejemplo para mostrar lo que sucede con los píxeles fraccionarios (en Chrome los valores se truncan, por lo que 50, 50.5 y 50.6 muestran el mismo ancho).

Drilldrick
fuente
77
Tienes razón acerca de que los valores de porcentaje no se redondean, pero los anchos de píxeles con decimales y el resultado final del cálculo de porcentaje siempre se redondearán a píxeles completos :)
MartinodF
2
@MartinodF Gracias por la aclaración. Sí, los píxeles son redondeados, pero no se define si realmente se redondean al piso, al techo o al más cercano (que es lo que quiero decir con "las cosas se descomponen").
Skilldrick
1
@Skilldrick Probé los píxeles fraccionarios en su demo en algunos navegadores por curiosidad: tanto IE9p7 como FF4b7 redondean al píxel más cercano, mientras que Opera 11b, Chrome 9.0.587.0 y Safari 5.0.3 truncan el valor. @andras Solo para aclarar: no estoy diciendo que los valores internos sean redondeados, solo los valores de renderización final. Si hace zoom, o algunos elementos heredan propiedades, etc., esos decimales contarán.
MartinodF
10
Actualización moderna: mi versión 24 de Chrome en realidad redondea los píxeles fraccionales. Al ver jsFiddle, 50.5 y 50.6 se redondean hasta 51px, siendo 1 píxel más ancho que el div de 50px.
Michael Butler
55
Lo más importante a tener en cuenta es cómo los elementos con dimensiones de píxeles fraccionales se apilan uno al lado del otro. Mientras que hacen ronda visualmente por sí mismos, sino que también no ocupan espacio adicional cuando se puso junto a otros elementos dimensionados fraccionada: cssdesk.com/8R2rB
arena Gifford
53

Incluso cuando el número se redondea cuando se pinta la página, el valor completo se conserva en la memoria y se utiliza para el cálculo secundario posterior. Por ejemplo, si su caja de 100.4999px pinta a 100px, su hijo con un ancho del 50% se calculará como .5 * 100.4999 en lugar de .5 * 100. Y así sucesivamente a 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 aguas arriba tuvo un impacto notable.

Estuche de borde, claro, pero algo a tener en cuenta.

natekoechley
fuente
2
La respuesta aceptada es más completa que esta, pero la anécdota en esta me da una mejor idea de cómo se harán sentir las implicaciones técnicas. Gracias por publicarlo.
Tom
23

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

Esto se puede ver mejor cuando los elementos se apilan uno al lado del otro (o encima); en otras palabras, si tuviera que colocar 400 divisiones de 0.5 píxeles una al lado de la otra, tendrían el mismo ancho que una sola división de 200 píxeles. Si todos realmente se redondearon a 1px (como implicaría mirar elementos individuales) esperaríamos que el div de 200px sea 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>

Sandy Gifford
fuente
11
Con respecto a la representación: en su ejemplo, tiene dos divs que compiten por cada píxel. En estos casos, su navegador elegirá uno de ellos para representar el píxel completo, para evitar el desenfoque y otros artefactos extraños. Si configura la mitad de los píxeles para que sean azules, usando :nth-child(even)o :nth-child(odd), notará que todo es naranja o que todo es azul, no una mezcla de azul y naranja (lo que sería un vago tono púrpura).
Daan Wilmer
16

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

Sin embargo, no sé si cada navegador lo redondeará 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 usan valores fraccionales de píxeles (no porcentajes, funcionan como se sugirió en el artículo que vinculé) IE9p7 y FF4b7 parecen redondearse 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
fuente
7

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

Por ejemplo, si 33.3% se convierte a 420.945px

Chrome y Firexfox lo muestran como 421px. mientras que safari muestra sus 420px.

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

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

agaase
fuente
6

Los elementos tienen que pintar a un número entero de píxeles, y como las otras respuestas cubren, los porcentajes se respetan.

Una nota importante es que los píxeles en este caso significan píxeles css , no píxeles de pantalla, por lo que un contenedor de 200 píxeles con un 50.7499% secundario se redondeará a 101 píxeles píxeles css , que luego se renderizarán en 202 píxeles en una pantalla de retina, y no en 400 *. 507499 ~ = 203px.

La densidad de la pantalla se ignora en este cálculo, y no hay forma de pintar * un elemento a tamaños específicos de subpíxeles de retina. No puede hacer que los fondos o bordes de los elementos se representen con un tamaño de píxel inferior a 1 css , aunque el tamaño real del elemento podría ser inferior a 1 píxel css, como lo mostró Sandy Gifford.

[*] Puedes usar algunas técnicas como 0.5 offset box-shadow, etc., pero las propiedades reales del modelo de caja pintarán a un píxel CSS completo.

Olex Ponomarenko
fuente
Excelente observación
agosto