問題:ui設(shè)計(jì)稿中邊框?yàn)?px薪鹦,在實(shí)際的前端開發(fā)扁达,移動(dòng)端設(shè)備中會(huì)出現(xiàn)設(shè)置border:1px solid #000;出現(xiàn)邊框過粗的現(xiàn)象的問題正卧。
答:因?yàn)閡i設(shè)計(jì)稿中的邊框是物理像素,而css設(shè)置的像素是邏輯像素跪解,之間存在比例關(guān)系炉旷,1px(物理像素)不等于1px(邏輯像素)
一、幾個(gè)概念
1叉讥、device pixels 即設(shè)備像素/物理像素
設(shè)備產(chǎn)品說明書上所列出的物理像素窘行,設(shè)備出廠的時(shí)候設(shè)置好的,這個(gè)值固定不變图仓,也是UI設(shè)計(jì)師設(shè)計(jì)稿中顯示的像素值
2罐盔、css pixels 即邏輯像素
Css/Js理解的像素單位,與設(shè)備像素沒有必然聯(lián)系救崔。
3惶看、dpr像素比(設(shè)備像素 / CSS像素(某一方向上))
通過window.devicePixelRatio可獲取當(dāng)前設(shè)備的dpr,或者用媒體查詢的-webkit-min-device-pixel-ratio來獲取當(dāng)比例為 1:1 時(shí)六孵,表示1個(gè)物理像素顯示一個(gè)css像素纬黎;當(dāng)比例為 2:1 時(shí),表示使用4個(gè)物理像素顯示1個(gè)邏輯像素劫窒。
4本今、rem相對(duì)單位(相對(duì)于根元素的字體大小的單位)
如果不設(shè)置根元素的字體大小,則會(huì)默認(rèn)以根元素的16px的大小計(jì)算值主巍,假設(shè)根元素設(shè)置字體大小為16px冠息,則8rem = 8 * 16px = 128px,rem和em的區(qū)別在于根據(jù)誰來計(jì)算值煤禽,em是根據(jù)使用em單位的元素的字體大小計(jì)算值,比如當(dāng)前div設(shè)置字體大小為18px岖赋,padding設(shè)置為10em檬果,那么此時(shí)padding的值就是10 * 18=180px,而rem是根據(jù)根元素大小計(jì)算值
設(shè)置根元素大小唐断,可通過js動(dòng)態(tài)添加:
根據(jù)設(shè)計(jì)稿尺寸大小修改代碼
**// rem布局的核心代碼选脊。 此例默認(rèn)UI稿按 1080 * 1920 提供**
(function(win, doc){
var docEl = doc.documentElement,
resizeEvt = 'oritationchange' in window ? 'oritationchange' : 'resize',
recalc = function(){
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if (clientWidth < 550) {
docEl.style.fontSize = 100 * (clientWidth / 1080) + 'px';
} else {
docEl.style.fontSize = 100 * (clientWidth / 1920) + 'px';
}
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DomContentLoaded', recalc, false);
})(window, document)
解決方案
1、通過修改meta中viewport的initial-scale值配合rem來進(jìn)行縮放
(1)移動(dòng)端頁面初始化頭部引入
<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no">
(2)根據(jù)當(dāng)前像素比進(jìn)行縮放脸甘,比如dpr為2的時(shí)候恳啥,initial-scale就為0.5。同時(shí)設(shè)置根元素的字體大小丹诀,用rem設(shè)置元素相對(duì)寬高
window.onload = function(){
let dpr = window.devicePixelRatio
let scale = 1/dpr
let metaNode = document.querySelector('meta[name="viewport"]')
metaNode.setAttribute('content','width=device-width, initial-scale='+scale+',user-scalable=no')
//元素的寬度高度需反向乘回來
var docEl = document.documentElement;
var fontsize = 10 * (docEl.clientWidth / 320) + 'px';
docEl.style.fontSize = fontsize;
}
2钝的、通過css的方法設(shè)置
利用偽元素:before,:after默認(rèn)設(shè)置height: 1px翁垂,transform: scale(0.5),根據(jù)媒體查詢結(jié)合transform縮放為相應(yīng)尺寸硝桩。
.border-bottom::after {
content: '';
width: 200%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid #bfbfbf;
border-radius: 4px;
-webkit-transform: scale(0.5,0.5);
transform: scale(0.5,0.5);
-webkit-transform-origin: top left;
}
/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.33);
transform: scaleY(0.33);
}
}
3沿猜、其他不常用方法
(1)box-shadow,此處顏色較難控制
box-shadow: 水平陰影位置碗脊,垂直陰影位置啼肩,模糊距離, 陰影尺寸衙伶,陰影顏色祈坠,將外部陰影改為內(nèi)部陰影;
div {
-webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5);
}
(2)border-image
通過圖片裁剪的方式
.border-image-1px {
border-width: 1px 0px;
-webkit-border-image: url("border.png") 2 0 stretch;
border-image: url("border.png") 2 0 stretch;
}
(3)background-img漸變
思路就是設(shè)置1px的漸變背景,然后50%的顏色到50%的透明的延伸矢劲,此處無法設(shè)置圓角
linear-gradient(漸變旋轉(zhuǎn)角度赦拘,漸變開始的顏色,哪個(gè)顏色到百分比的位置卧须,以此類推)
.border {
background-image:linear-gradient(180deg, red, red 50%, transparent 50%),
linear-gradient(270deg, red, red 50%, transparent 50%),
linear-gradient(0deg, red, red 50%, transparent 50%),
linear-gradient(90deg, red, red 50%, transparent 50%);
background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%;
background-repeat: no-repeat;
background-position: top, right top, bottom, left top;
padding: 10px;
}
參考資料
http://www.reibang.com/p/fa670b737a29
https://blog.csdn.net/SilenceJude/article/details/81906716