이것은 오래된 문제입니다. 처음에 저를 괴롭힌 사람은 UI 디자이너였습니다. 그 당시 저는 막 프론트엔드 작업실에 들어왔는데 아무것도 이해하지 못했습니다. :
디자이너가 휴대폰을 들고 왔습니다. 테두리가 두껍습니다. 제 디자인 초안은 1px입니다.
나:? ? ? ? 제가 쓴 내용은 1px입니다. 믿기지 않으시면 한번 보세요. (그가 말하면서 CSS 코드를 꺼냈습니다.
디자이너: 제 눈에는 테두리가 제가 만든 것보다 훨씬 두꺼워 보이는데요. (음, 정말 픽셀화됐네요.
나: 그럼 0.5px로 바꿔서 봐주시면 됩니다(말하면서 코드를 바꿨어요)
디자이너는 그것을 보고 고개를 끄덕였습니다. 정말 훨씬 좋아졌습니다.
나중에 일부 Android 시스템에서 동일한 코드에 문제가 있어 0.5px 라인이 보이지 않는 것으로 밝혀졌습니다.
이상하네요. 0.5px로 변경해도 문제가 해결되지 않는데, 1px 테두리가 디자인 초안보다 훨씬 두껍게 보이는 이유가 무엇인가요?
1px 테두리 성능CSS를 직접 사용하여 1px 테두리를 설정합니다.
HTML:
<ul class=hairlines> <li>1</li> <li>2</li></ul>
CSS:
* { 여백: 0; 패딩: 0; } .hairlines { 너비: 300px 자동; } .hairlines li{ 위치: 상대; -bottom: 1px solid #cccccc; // 테두리를 1px로 설정 }획득한 스크린샷은 다음과 같습니다.
디자인 초안보다 훨씬 두껍게 보입니다. 디자인 초안은 다음과 같습니다.
해결 방법 1: 의사 클래스 + 변환문제를 해결하려는 정신으로 당시에는 이유를 명확하게 생각하지 못했지만 여전히 원하는 효과를 시뮬레이션할 수 있는 테두리 이미지 또는 상자 그림자를 사용하는 방법이 언급되어 있습니다. 1px 테두리 효과는 있지만 개인적으로는 보편적이지 않고 기존의 솔루션도 아니라고 생각합니다.
최종 선택은 의사 클래스 + 변환 방법을 사용하는 것이었습니다. 원칙은 원본 요소의 테두리를 제거한 다음 :before 또는 :after를 사용하여 테두리를 다시 실행하고 변환 크기를 절반으로 줄이는 것입니다. 요소는 상대적으로 배치되고 새 테두리는 절대적으로 배치됩니다.
html 위와 동일
CSS는 다음과 같습니다 :
* { 여백: 0; } ul, li{ 목록 스타일: 없음; } .hairlines { 너비: 300px 자동; } .hairlines li{ 위치: 테두리: 없음; : 10px; } .hairlines li:after{ 내용: ''; 위치: 절대 왼쪽: 0; #cccccc; 높이: 1px; -webkit-transform: scaleY(0.5); -webkit-transform-origin: 0 0;이런 경우 실제로는 훨씬 얇아지는 선이 그려지는 경우가 있었습니다. 저는 일반적으로 1px 테두리 문제를 해결하기 위해 위의 방법을 사용했는데, 사용 후 몇 가지 문제점을 발견했습니다.
1.왜 scaleY(0.5)인가요? 0.5는 어떻게 구하셨나요? 모든 모델을 절반으로 축소해야 합니까? 즉, 보편적입니까?
2. 컨테이너의 테두리 4개를 동시에 그리려면 어떻게 해야 하나요?
3. 둥근 모서리 테두리를 지원합니까?
후자의 두 가지 문제에 대한 해결책은 위의 코드를 수정함으로써 찾을 수 있다. (효과를 보기 쉽게 하기 위해 일반적인 글쓰기로 얻은 효과와 의사 클래스를 사용하여 얻은 효과를 함께 넣어서 보기 쉽도록 했다. 차이점을 확인하려면):
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=initial-scale=1, maximum-scale=1, 최소-scale=1, 사용자 확장 가능 =no, width=device-width> <title>모바일 단말기의 1px 테두리 문제</title> <style> * { margin: 0: 0 } ul, li{ list-style: 없음; } .lines { 너비: 200px; 여백: 0 auto; } .lines li { 테두리: 1px 높이: 50px; 텍스트 정렬: 중앙; -top: 10px; } .hairlines { 너비: 200px; 여백: 0 자동; 3px; } .hairlines li{ 높이: 50px; 테두리: 없음; text-align: 위치: 상대: 여백: 10px; : 절대; 왼쪽: 0; 테두리: 1px #cccccc; 너비: 200%; 높이: 200%; -webkit-transform: scale(0.5); -webkit-transform-origin: 왼쪽 상단; ><body>굵은 선<ul class=lines> <li>1</li> <li>2</li></ul>가는 선<ul class=hairlines> <li>3</li> <li>4</li></ul></body></html>결과 렌더링은 다음과 같습니다.
아래 테두리는 훨씬 더 얇아서 디자인 초안에 더 가깝습니다.
그렇다면 1. 왜 scaleY(0.5)인가요? 0.5는 어떻게 구하셨나요? 모든 모델을 절반으로 축소해야 합니까? 즉, 보편적입니까? 이 질문에 어떻게 답해야 할까요?
이것은 문제의 본질로 다시 돌아갑니다. CSS에 1px을 썼음에도 불구하고 여전히 평소보다 훨씬 두껍게 보이는 이유는 무엇입니까?
정보를 확인해보니 CSS에 설정된 픽셀이 기기의 픽셀과 1:1로 일치하지 않는 것으로 나타났습니다. 즉, CSS에서 1px를 지정하면 휴대폰에서 보는 것과 일치하지 않을 수 있다는 뜻입니다. 점이 차지하는 너비입니다.
CSS의 픽셀은 추상적이고 상대적인 개념입니다. 다양한 장치와 환경에서 표현되는 물리적 픽셀이 다릅니다. 구형 장치에서는 화면 픽셀 밀도가 상대적으로 낮습니다. 픽셀이지만 기술은 빠르게 발전하고 있습니다. 오늘날의 휴대폰 화면은 모두 고해상도입니다. 크기가 변하지 않으면 화면이 더 많은 픽셀로 채워지게 됩니다. 이때 CSS 픽셀(보통 논리 픽셀이라고 함)이 해당됩니다. 여러 물리적 픽셀.
그렇다면 CSS 픽셀 너비는 몇 개의 실제 픽셀에 해당합니까?
이를 위해서는 devicePixelRatio(장치 픽셀 비율)를 언급해야 합니다.
devicePixelRatio = window.devicePixelRatio를 통해 얻을 수 있는 장치의 물리적 픽셀/독립 픽셀입니다. 이 픽셀 비율은 실제로 devicePixelRatio 픽셀에 해당하는 CSS의 픽셀 너비에 해당하는 실제 픽셀 수를 정확하게 설명할 수 있습니다.
뷰포트의 초기 크기 속성이 1이면 페이지 크기가 정상이지만 초기 크기가 0.5이면 페이지가 1배로 줄어듭니다. devicePixelRatio가 2인 장치는 원래 CSS 픽셀 너비가 2에 해당합니다. 물리적 픽셀 너비를 줄인 후 1 CSS 픽셀의 너비는 1 물리적 픽셀만 차지합니다. 즉, 실제 1 물리적 픽셀이 달성됩니다.
해결 방법 2: rem + 뷰포트이 시점에서 해결책은 매우 명확합니다. 런타임 시 장치의 devicePixelRatio를 가져오고 뷰포트의 초기 크기를 1/devicePixelRatio로 동적으로 변경하여 1px 너비가 실제 1 물리적 픽셀이 되도록 보장할 수 있습니다. 너비. 다른 적응에는 rem을 사용하십시오(px를 사용하면 줄어들기 때문입니다).
코드는 다음과 같습니다:
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <!--<meta name=viewport content=initial-scale=1, maximum-scale=1, Minimal-scale=1 , user-scalable=no, width=device-width>--> <title>모바일 단말기의 1px 테두리 문제</title> <script> (function () { var clientWidth = window.screen.width; var dpr = window.devicePixelRatio; var vp = document.createElement('meta'); document.documentElement.style.fontSize = clientWidth > 414 ? px'; vp.name = '뷰포트'; `초기 규모=${1.0 * 1/dpr}, 최대 규모=${1.0 * 1/dpr}, 최소 규모=${1.0 * 1/dpr}, 사용자 확장 가능=no, 너비=장치- width`; var m = document.getElementsByTagName('meta')[0] m.parentNode.insertBefore(vp, m); })(); </script> <style> * { 여백: 0; } ul, 목록 스타일: 없음 } .lines { width: 10rem; { 테두리: 1px 솔리드 #cccccc; 줄 높이: 2.5rem; 테두리 반경: 0.6rem; 여백 상단: 0.5rem; } </style></head><body><ul class=lines> <li>1</li> <li>2</li></ul></ 본문></html>얻은 효과는 아래 그림에서 볼 수 있습니다(휴대폰에서 볼 때 더 분명합니다).
위의 관점에서 이전 질문으로 돌아가서, 1. 왜 scaleY(0.5)입니까? 0.5는 어떻게 구하셨나요? 모든 모델을 절반으로 축소해야 합니까? 즉, 보편적입니까? 사실 꼭 0.5일 필요는 없습니다. dpr이 3인 기기에서는 실제로는 0.3333이어야 합니다... 휴대폰마다 dpr이 다를 수 있기 때문에 보편적이지 않습니다. 하지만 방법 1의 0.5는 일반적으로 그렇습니다. 최소 1px보다 얇아 디자이너의 요구사항을 거의 충족할 수 있습니다.
위의 내용은 이 기사의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 VeVb Wulin Network를 지지해 주시길 바랍니다.