Algo que eu venho pensando há algum tempo enquanto fazia o design CSS.
As casas decimais nas larguras CSS são respeitadas? Ou eles são arredondados?
.percentage {
width: 49.5%;
}
ou
.pixel {
width: 122.5px;
}
Algo que eu venho pensando há algum tempo enquanto fazia o design CSS.
As casas decimais nas larguras CSS são respeitadas? Ou eles são arredondados?
.percentage {
width: 49.5%;
}
ou
.pixel {
width: 122.5px;
}
Respostas:
Se for uma largura percentual, sim, será respeitada . Como Martin apontou, as coisas se deterioram quando você obtém pixels fracionários, mas se seus valores de porcentagem produzirem um valor inteiro de pixels (por exemplo, 50,5% de 200px no exemplo), você terá um comportamento sensível e esperado.
Edit: Eu já atualizou o exemplo para mostrar o que acontece com pixels fracionários (em Chrome os valores são truncados, então 50, 50,5 e 50,6 todos mostram a mesma largura).
Mesmo quando o número é arredondado quando a página é pintada, o valor total é preservado na memória e usado para o cálculo filho subsequente. Por exemplo, se sua caixa de 100,4999 px for 100 px, seu filho com uma largura de 50% será calculado como 0,5 * 100,4999 em vez de 0,5 * 100. E assim por diante para níveis mais profundos.
Criei sistemas de layout de grade profundamente aninhados, onde as larguras dos pais são ems e os filhos são porcentagens, e incluir até quatro pontos decimais a montante teve um impacto notável.
Edge case, claro, mas algo para se ter em mente.
Embora os pixels fracionários pareçam arredondar para elementos individuais (como o @SkillDrick demonstra muito bem) , é importante saber que os pixels fracionais são realmente respeitados no modelo de caixa real .
Isso pode ser visto melhor quando os elementos são empilhados um ao lado do outro (ou por cima deles); em outras palavras, se eu colocasse 400 divs de 0,5 pixel lado a lado, elas teriam a mesma largura que uma única div de 200 pixels. Se todos eles realmente arredondado para 1px (como olhar para elementos individuais implicaria) que seria de esperar a 200px div a ser metade do tempo.
Isso pode ser visto neste trecho de código executável:
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>
:nth-child(even)
ou :nth-child(odd)
, notará que tudo é laranja ou tudo é azul - não uma mistura de azul e laranja (que seria um tom de roxo vago).
A largura será arredondada para um número inteiro de pixels .
Não sei se todos os navegadores irão arredondá-lo da mesma maneira. Todos eles parecem ter uma estratégia diferente ao arredondar porcentagens de sub-pixel. Se você estiver interessado nos detalhes do arredondamento de sub-pixels em diferentes navegadores, há um excelente artigo sobre o ElastiCSS .
edit : Eu testei a demo do @ Skilldrick em alguns navegadores por uma questão de curiosidade. Ao usar valores de pixels fracionários (não porcentagens, eles funcionam como sugerido no artigo que eu linkei), o IE9p7 e o FF4b7 parecem arredondar para o pixel mais próximo, enquanto o Opera 11b, o Chrome 9.0.587.0 e o Safari 5.0.3 truncam as casas decimais. Não que eu esperasse que eles tivessem algo em comum, afinal ...
Eles parecem arredondar os valores para o número inteiro mais próximo; mas estou vendo inconsistência no chrome, safari e firefox.
Por exemplo, se 33,3% se converter em 420,945px
chrome e firexfox mostram-no como 421px. enquanto o safari mostra como 420px.
Parece que o chrome e o firefox seguem a lógica do piso e do teto, enquanto o safari não. Esta página parece discutir o mesmo problema
Os elementos precisam pintar para um número inteiro de pixels e, como as outras respostas abordadas, as porcentagens são realmente respeitadas.
Uma observação importante é que pixels , nesse caso, significam pixels css , não pixels da tela; portanto, um contêiner de 200px com um filho de 50,7499% será arredondado para 101px pixels css , que serão renderizados em 202px em uma tela retina e não em 400 *. 507499 ~ = 203px.
A densidade da tela é ignorada neste cálculo e não há como pintar * um elemento para tamanhos específicos de subpixel de retina. Você não pode ter fundos ou bordas de elementos renderizados com tamanho menor que 1 css pixel , mesmo que o tamanho real do elemento possa ser menor que 1 pixel css, como mostrou Sandy Gifford.
[*] Você pode usar algumas técnicas como 0,5 sombra de caixa de deslocamento, etc., mas as propriedades reais do modelo de caixa serão pintadas em um pixel CSS completo.