布局視口 layout viewport:
手機一般為了容納為桌面瀏覽器設計的網站,默認布局viewport寬度遠大於屏幕的寬度,為了讓用戶看到網站全貌,縮小網站。例如,apple一般將viewport寬度定為980px。主要意義是手機廠商不至於讓自家手機變得可笑,在打開大於980寬度的頁面的時候可以橫向拖動,而不至於擠成一團。可以通過
document.documentElement.clientWidth來獲取。視覺視口 visual viewport:
屏幕的可視區域,即物理像素尺寸,可以通過window.innerWidth來獲取。對於iPhone 6 Plus來說,在加了著名代碼前提下,值是414px,不加的話,值是980px,著名代碼如果改一改
width=device-width, initial-scale=1.5,這時值是276px。所以它是一個可變的值。理想視口 ideal viewport:
最適合移動設備的viewport,ideal viewport的寬度等於移動設備的屏幕寬度
為了讓viewport能夠等於ideal viewport,一般我們會添加meta標簽。
width=device-width,initial-scale=1.0的時候,視覺視口的大小。對於iPhone 6 Plus來說,是固定值414px。所以,理想視口就等於設備寬度。
1、什么是1px問題
移動端css設置1px(如border:1px solid #000;),實際上邊框的寬度比設置的1px要寬
2、移動端1px變寬原因
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
這句話定義了本頁面的viewport的寬度為設備寬度,初始縮放值和最大縮放值都為1,並禁止了用戶縮放. viewport通俗的講是瀏覽器上可用來顯示頁面的區域, 這個區域是可能比屏幕大的.
3、1px解決方案
(1) 用小數寫1px
//這是css方式
.border { border: 1px solid #999 } @media screen and (-webkit-min-device-pixel-ratio: 2) { .border { border: 0.5px solid #999 } } @media screen and (-webkit-min-device-pixel-ratio: 3) { .border { border: 0.333333px solid #999 } }
//如果使用less/sass的話只是加了1句mixin
//缺點: IOS8下已經支持帶小數的px值,安卓與低版本IOS不適用, 這個或許是未來的標准寫法, 現在不做指望
//這是JavaScript方式
<body> <div id="main" style="border: 1px solid #000000;"></div> </body> <script type="text/javascript"> if (window.devicePixelRatio && devicePixelRatio >= 2) { var main = document.getElementById('main'); main.style.border = '.5px solid #000000'; } </script>
//優點: 簡單
//缺點: 兼容性差,目前之余IOS8+才支持,在IOS7及其以下、安卓系統都是顯示0px。
(2)使用border-image(但要注意這個屬性的兼容性):不推薦
//第一種寫法 使用媒體查詢 @media screen and (-webkit-min-device-pixel-ratio: 2){ .border{ border: 1px solid transparent; border-image: url(border.gif) 2 repeat; } } //第二種寫法 直接用類名 .border { border-width: 1px 0px; -webkit-border-image: url(border.png) 2 0 stretch; border-image: url(border.png) 2 0 stretch; }
(3)使用background漸變(但要注意這個屬性的兼容性)設置1px的漸變背景,50%有顏色,50%透明--->背景漸變, 漸變在透明色和邊框色中間分割
//第一種方式:媒體查詢
@media screen and (-webkit-min-device-pixel-ratio: 2){ .border{ background-position: left top; background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0.5,transparent),color-stop(0.5,#e0e0e0),to(#e0e0e0)); } }
//缺點: 代碼量大, 而且需要針對不同邊框結構,而且這只是背景, 這樣做出來的邊框實際是在原本的border空間內部的, 如果元素背景色有變化的樣式, 邊框線也會消失;不適應圓角樣式
//第二種方式:直接類名
.border { background: linear-gradient(180deg, black, black 50%, transparent 50%) top left / 100% 1px no-repeat, linear-gradient(90deg, black, black 50%, transparent 50%) top right / 1px 100% no-repeat, linear-gradient(0, black, black 50%, transparent 50%) bottom right / 100% 1px no-repeat, linear-gradient(-90deg, black, black 50%, transparent 50%) bottom left / 1px 100% no-repeat; }
(4)會用 :before , :after 與 transform(推薦使用)
原理:把原先元素的 border 去掉,然后利用 :before 或者 :after 重做 border ,並 transform 的 scale 縮小一半,原先的元素相對定位,新做的 border 絕對定位。
//第一種方法
//構建1個偽元素, 將它的長寬放大到2倍, 邊框寬度設置為1px, 再以transform縮放到50%
.radius-border{ position: relative; } @media screen and (-webkit-min-device-pixel-ratio: 2){ .radius-border:before{ content: ""; pointer-events: none; /* 防止點擊觸發 */ box-sizing: border-box; position: absolute; width: 200%; height: 200%; left: 0; top: 0; border-radius: 8px; border:1px solid #999; -webkit-transform(scale(0.5)); -webkit-transform-origin: 0 0; transform(scale(0.5)); transform-origin: 0 0; } }
//需要注意<input type="button">是沒有:before, :after偽元素的
//優點: 其實不止是圓角, 其他的邊框也可以這樣做出來
//缺點: 代碼量也很大, 占據了偽元素, 容易引起沖突
//第二種方式 //單條border樣式設置: .scale-1px{ position: relative; border:none; } .scale-1px:after{ content: ''; position: absolute; bottom: 0; background: #000; width: 100%; height: 1px; -webkit-transform: scaleY(0.5); transform: scaleY(0.5); -webkit-transform-origin: 0 0; transform-origin: 0 0; } //四條border樣式設置: .scale-1px{ position: relative; margin-bottom: 20px; border:none; } .scale-1px:after{ content: ''; position: absolute; top: 0; left: 0; border: 1px solid #000; -webkit-box-sizing: border-box; box-sizing: border-box; width: 200%; height: 200%; -webkit-transform: scale(0.5); transform: scale(0.5); -webkit-transform-origin: left top; transform-origin: left top; } //結合js來代碼來判斷是否是Retina屏 if(window.devicePixelRatio && devicePixelRatio >= 2){ document.querySelector('div').className = 'scale-1px'; } //優點:所有場景都能滿足 支持圓角 //缺點:對於已經使用偽類的元素,可能需要多層嵌套
(5)使用flexible.js(https://github.com/amfe/lib-flexible)
原理:viewport寬度設置為實際的設備物理寬度,
(6)使用CSS3 box-shadow
.shadow { -webkit-box-shadow:0 1px 1px -1px rgba(255, 0, 0, 0.5); box-shadow:0 1px 1px -1px rgba(255, 0, 0, 0.5); } //不好用,不推薦
(7)viewport結合rem
//devicePixelRatio=2設置meta <meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
//devicePixelRatio=3設置meta <meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">
參考文獻:
https://www.cnblogs.com/lunarorbitx/p/5287309.html
https://blog.csdn.net/xuexizhe88/article/details/80566552
本文為自己知識點搜索整理,若有侵權麻煩聯系我,刪除本文章。謝謝(* ̄︶ ̄)
