Este é um problema antigo. Quando percebi isso pela primeira vez, foi um designer de UI que veio me incomodar. Bem, eu tinha acabado de entrar no local de trabalho de front-end e não entendia nada. :
O designer veio com seu celular: Essas bordas são grossas, meu rascunho é 1px
EU:? ? ? ? O que escrevi é 1px. Se você não acredita, dê uma olhada. (Enquanto ele falava, ele tirou o código css
Designer: Isso não está certo. Aos meus olhos, a borda é muito mais grossa do que a do meu design. Parece estranho (emmm, é realmente pixelado.
Eu: Então vou mudar para 0,5px e você pode dar uma olhada (mudei o código enquanto falava
O designer olhou para ele e acenou com a cabeça, era realmente muito melhor.
Mais tarde, descobriu-se que o mesmo código era problemático em algumas máquinas Android, fazendo com que a linha de 0,5px ficasse invisível.
É estranho. Obviamente, alterá-lo para 0,5px não resolverá o problema, mas a borda de 1px parece muito mais espessa do que o rascunho do design.
Desempenho da borda de 1pxEu uso CSS diretamente para definir a borda de 1px.
HTML:
<ul class=hairlines> <li>1</li> <li>2</li></ul>
css:
* {margem: 0; preenchimento: 0; } ul, li{ estilo de lista: nenhum; .hairlines { largura: 300px; margem: 100px auto; -bottom: 1px solid #cccccc; // Defina a borda para 1px }A captura de tela obtida é a seguinte:
Parece muito mais espesso do que o rascunho do projeto. O rascunho do projeto deve ser assim.
Solução 1: pseudoclasse + transformaçãoCom a mentalidade de resolver o problema, embora não tenha pensado com clareza no motivo na época, ainda encontrei soluções relevantes alguns dos métodos citados utilizando border-image ou box-shadow, que também podem simular o efeito desejado. Efeito de borda de 1px, mas pessoalmente acho que não é universal e nem uma solução convencional.
A escolha final foi usar o método pseudo-classe + transform: o princípio é remover a borda do elemento original, depois usar :before ou :after para refazer a borda, e reduzir a escala da transformação original pela metade. o elemento está posicionado relativamente e a nova borda está posicionada absolutamente.
html igual ao acima
O css é o seguinte:
* {margem: 0; preenchimento: 0; } ul, li{ estilo de lista: nenhum; .hairlines {largura: 300px; margem: 100px auto; : 10px; } .hairlines li:after{ conteúdo: ''; posição: fundo absoluto: 0; #cccccc; largura: 100%; altura: 1px; -webkit-transformação: escalaY(0,5);Nesse caso, as linhas desenhadas são realmente muito mais finas. Geralmente usei o método acima para resolver o problema da borda de 1px por um ano, mas depois de usá-lo, descobri vários problemas:
1.Por que a escala é Y(0,5)? Como você conseguiu esse 0,5? Todos os modelos precisam ser reduzidos à metade, ou seja, são universais?
2. E se eu quiser desenhar as quatro bordas de um contêiner ao mesmo tempo?
3. Suporta bordas com cantos arredondados?
A solução para estes dois últimos problemas pode ser encontrada modificando o código acima (para facilitar a visualização do efeito, coloquei juntos o efeito obtido pela escrita normal e o efeito obtido pelo uso de pseudoclasses, para que seja mais fácil para ver a diferença):
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=initial-scale=1, escala máxima=1, escala mínima=1, escalonável pelo usuário =não, largura=largura do dispositivo> <title>problema de borda de 1px no terminal móvel</title> <style> * { margin: 0; nenhum; } .lines { largura: 200px; margem: 0 auto; .lines li { borda: 1px sólido #cccccc; -top: 10px; } .hairlines {largura: 200px; margem: 0 raio da borda: 3px; } .hairlines li{ altura: 50px; line-height: 50px; : absoluto à esquerda: 0; topo: 0; borda: 1px sólido #cccccc; 200%; altura: 200%; -webkit-transform:scale(0,5); transform:scale(0,5); ><body>Linhas grossas<ul class=lines> <li>1</li> <li>2</li></ul>Linhas finas<ul class=hairlines> <li>3</li> <li>4</li></ul></body></html>A renderização resultante é a seguinte:
A borda abaixo é obviamente muito mais fina, mais próxima do rascunho do projeto.
Então 1. Por que a escala é Y(0,5)? Como você conseguiu esse 0,5? Todos os modelos precisam ser reduzidos à metade, ou seja, são universais? Como responder a esta pergunta?
Isso nos traz de volta à essência do problema. Por que ainda parece muito mais espesso do que o normal, embora eu tenha escrito 1px no CSS?
Após verificar as informações, verifica-se que os pixels definidos no css não correspondem aos pixels do dispositivo um a um. Isso significa que se eu especificar 1px no css, o que vejo no celular pode não. ser um pixel A largura ocupada pelo ponto.
O pixel do CSS é um conceito abstrato e relativo. Em diferentes dispositivos e ambientes, os pixels físicos representados são diferentes. Em dispositivos mais antigos, a densidade de pixels da tela é relativamente baixa. pixel, mas a tecnologia está se desenvolvendo rapidamente. As telas dos telefones celulares de hoje são todas de alta resolução. Se o tamanho não mudar, uma tela será preenchida com mais pixels. Neste momento, um pixel CSS (geralmente chamado de pixel lógico). vários pixels físicos.
Então, a quantos pixels físicos corresponde uma largura de pixel CSS?
Isso requer mencionar devicePixelRatio (proporção de pixels do dispositivo)
devicePixelRatio = pixel físico/pixel independente no dispositivo, que pode ser obtido através de window.devicePixelRatio. Essa proporção de pixels pode descrever exatamente quantos pixels físicos correspondem à largura de pixels de um CSS, que na verdade corresponde aos pixels de devicePixelRatio.
Quando o atributo de escala inicial da janela de visualização é 1, o tamanho da página é normal, mas quando a escala inicial é 0,5, a página é reduzida em 1 vez. Um dispositivo com devicePixelRatio de 2 originalmente tem 1 largura de pixel CSS representando 2. larguras de pixels físicos Após a redução, a largura de 1 pixel CSS ocupa apenas 1 pixel físico, ou seja, um verdadeiro 1 pixel físico é alcançado.
Solução 2: rem + janela de visualizaçãoNeste ponto, a solução é muito clara: podemos obter o devicePixelRatio do dispositivo em tempo de execução e alterar dinamicamente a escala inicial da janela de visualização para 1/devicePixelRatio, de modo a garantir que a largura de 1px seja o real 1 pixel físico largura. Use rem para outras adaptações (porque se usar px, ele será reduzido)
O código é o seguinte:
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <!--<meta name=viewport content=initial-scale=1, escala máxima=1, escala mínima=1 , user-scalable=no, width=device-width>--> <title>Problema de borda de 1px no terminal móvel</title> <script> (function () { var clientWidth = window.screen.width; var dpr = window.devicePixelRatio; var vp = document.createElement('meta'); px'; vp.name = 'viewport'; `escala inicial = $ {1,0 * 1 / dpr}, escala máxima = $ {1,0 * 1 / dpr}, escala mínima = $ {1,0 * 1 / dpr}, escalonável pelo usuário = não, largura = dispositivo- largura`; var m = document.getElementsByTagName('meta')[0]; })(); </script> <style> * { margem: 0; preenchimento: 0; } .lines li; { borda: 1px sólido #cccccc; altura da linha: 2,5rem; 0,6rem; margem superior: 0,5rem; } </style></head><body><ul class=lines> <li>1</li> <li>2</li></ul></ corpo></html>O efeito obtido pode ser visto na imagem abaixo (é mais evidente quando visto no celular):
Do ponto de vista acima, voltando às questões anteriores, 1. Por que a escalaY(0,5)? Como você conseguiu esse 0,5? Todos os modelos precisam ser reduzidos à metade, ou seja, são universais? Na verdade, não é necessariamente 0,5. Em um dispositivo com um dpr de 3, deveria ser 0,3333... Não é universal porque o dpr de cada telefone celular pode ser diferente, no entanto, o 0,5 no método 1 é geralmente. pelo menos mais fino que 1px, então também é quase capaz de atender aos requisitos do designer.
O texto acima é todo o conteúdo deste artigo. Espero que seja útil para o estudo de todos. Também espero que todos apoiem a Rede VeVb Wulin.