騰訊雲技術社群-掘金主頁持續為大家呈現雲端計算技術文章,歡迎大家關注!
作者:link
街景wap官網中有在視網膜螢幕中實現1px border的需求.
首先,來看下面視覺給的輸出圖中的border:
從上面的視覺圖可以看到,border是一根非常細的線。這篇文章將說明如何使用border-image實現在視網膜屏中1px的border效果。
注:因為硬體條件的限制,裝置畫素比(devicePixelRatio)為1的非視網膜屏手機無法達到這樣的效果
首先準備一張符合你要求的border-image:
通常手機端的頁面設計稿都是放大一倍的,如:為適應iphone retina,設計稿會設計成640*960的解析度,圖片按照2倍大小切出來,在手機端看著就不會虛化,非常清晰。
同樣,在使用border-image時,將border設計為物理1px,如下:
樣式設定:
.border-image-1px {
border-width: 0 0 1px 0;
-webkit-border-image: url(linenew.png) 0 0 2 0 stretch;
border-image: url(linenew.png) 0 0 2 0 stretch;
}複製程式碼
上文是把border設定在邊框的底部,所以使用的圖片是2px高,上部的1px顏色為透明,下部的1px使用視覺規定的border的顏色。如果邊框底部和頂部同時需要border,可以使用下面的border-image:
樣式設定:
.border-image-1px {
border-width: 1px 0;
-webkit-border-image: url(linenew.png) 2 0 stretch;
border-image: url(linenew.png) 2 0 stretch;
}複製程式碼
到目前為止,我們已經能在iphone上展現1px border的效果了。但是我們發現這樣的方法在非視網膜屏上會出現border顯示不出來的現象,於是使用Media Query做了一些相容,樣式設定如下:
.border-image-1px {
border-bottom: 1px solid #666;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.border-image-1px {
border-bottom: none;
border-width: 0 0 1px 0;
-webkit-border-image: url(../img/linenew.png) 0 0 2 0 stretch;
border-image: url(../img/linenew.png) 0 0 2 0 stretch;
}
}複製程式碼
下面介紹一下其他方法:
- 設定viewport
直接按照設計師提供的640px寬的設計稿來重構,然後通過控制viewport的initial-scale值為0.5進行縮放,這種方案在ios下可以完美執行(淘寶就是這麼做的),但是由於android下不支援initial-scale,所以這個方案不適用於android。
<meta name="viewport" content="initial-scale=0.5,user-scalable=no"/>複製程式碼
- background-image
跟border-image的方法一樣,你要先準備一張符合你要求的圖片:
此例是準備將border設定在底部
樣式設定:
.background-image-1px {
background: url(../img/line.png) repeat-x left bottom;
-webkit-background-size: 100% 1px;
background-size: 100% 1px;
}複製程式碼
- box-shadow
.box-shadow-1px {
box-shadow: inset 0px -1px 1px -1px #c8c7cc;
}複製程式碼
使用box-shadow都會讓線有陰影,甚至顏色變淺。但是使用box-shadow與使用border類似,程式碼量少,使用方便,而且可以設定圓角矩形,在精細度要求不高的情況下可以嘗試使用這種方案。
- 漸變背景
與background-image方案類似,只是將圖片替換為css3漸變。
樣式設定:
.background-gradient-1px{
background: -webkit-gradient(linear, left top, left bottom, color-stop(.5, transparent), color-stop(.5, #c8c7cc), to(#c8c7cc)) left bottom repeat-x;
background-size: 100% 1px;
}複製程式碼
該方案不能滿足1px圓角矩形。
- 縮放
邊框由一個元素來承載,將這個元素的高度(或寬度)設定為1px,然後再將該元素縮放1倍。
樣式設定:
.scale-1px{
position: relative;
}
.scale-1px:after{
content:"";
position: absolute;
bottom:0px;
left:0px;
right:0px;
border-bottom:1px solid #c8c7cc;
-webkit-transform:scaleY(.5);
-webkit-transform-origin:0 0;
}複製程式碼
- 聽說Firefox和Safari8已經支援
0.5px
的單位了,程式碼可以像下面這樣寫:
div{
border:1px solid black;
}
@media (-webkit-min-device-pixel-ratio: 2){
div{
border-width:0.5px;
}
}複製程式碼
不過0.5px
這個單位有點過於顛覆前端開發的認識了twitter上有位哥們已經被震驚的不知所云
- 基於
border-image
和transform
使用Sass的線下解決方案:
Mixin:sass中使用@mixin宣告混合,可以傳遞引數,引數名以$符號開始,多個引數以逗號分開,也可以給引數設定預設值。宣告的@mixin通過@include來呼叫。
- 基於border-image:
_onepx.scss:
@mixin onepx($selector, $position: bottom, $color: #666, $onepxImgDirname: './img/linenew.png') {
#{$selector} {
border-#{$position}: 1px solid $color;
}
@media only screen and (-webkit-min-device-pixel-ratio:2) {
#{$selector} {
border-#{$position}: none;
@if $position == 'bottom' {
border-width: 0 0 1px 0;
-webkit-border-image: url($onepxImgDirname) 0 0 2 0 stretch;
border-image: url($onepxImgDirname) 0 0 2 0 stretch;
} @else if $position == 'top' {
border-width: 1px 0 0 0;
-webkit-border-image: url($onepxImgDirname) 2 0 0 0 stretch;
border-image: url($onepxImgDirname) 2 0 0 0 stretch;
} @else if $position == 'right' {
border-width: 0 1px 0 0;
-webkit-border-image: url($onepxImgDirname) 0 2 0 0 stretch;
border-image: url($onepxImgDirname) 0 2 0 0 stretch;
} @else if $position == 'left' {
border-width: 0 0 0 1px;
-webkit-border-image: url($onepxImgDirname) 0 0 0 2 stretch;
border-image: url($onepxImgDirname) 0 0 0 2 stretch;
}
}
}
}複製程式碼
test.scss:
@import "onepx";
.container {
@include onepx('.myonepx', 'top', '#666', './img/linenew.png');
}
@include onepx('.border-top', 'top');
@include onepx('.border-bottom');複製程式碼
執行bat檔案:
sass --scss --style expanded test.scss test.css
生成css程式碼:
.container .myonepx {
border-top: 1px solid "#666";
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.container .myonepx {
border-top: none;
border-width: 1px 0 0 0;
-webkit-border-image: url("./img/linenew.png") 2 0 0 0 stretch;
border-image: url("./img/linenew.png") 2 0 0 0 stretch;
}
}
.border-top {
border-top: 1px solid #666666;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.border-top {
border-top: none;
border-width: 1px 0 0 0;
-webkit-border-image: url("./img/linenew.png") 2 0 0 0 stretch;
border-image: url("./img/linenew.png") 2 0 0 0 stretch;
}
}
.border-bottom {
border-bottom: 1px solid #666666;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.border-bottom {
border-bottom: none;
border-width: 0 0 1px 0;
-webkit-border-image: url("./img/linenew.png") 0 0 2 0 stretch;
border-image: url("./img/linenew.png") 0 0 2 0 stretch;
}
}複製程式碼
- 基於transform的縮放:
_onpx.scss
@mixin _prefixDpr($selector, $position: 'top', $pseudo: 'before', $dpr: '2') {
@media only screen and (-webkit-min-device-pixel-ratio:$dpr) {
@if $dpr == '1.5' {
#{$selector}:#{$pseudo} {
-webkit-transform: scaleY(.7);
transform: scaleY(.7);
@if $position == 'top' {
-webkit-transform-origin: left top;
} @else if $position == 'bottom' {
-webkit-transform-origin: left bottom;
}
}
} @else if $dpr == '2' {
#{$selector}:#{$pseudo} {
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
@if $position == 'top' {
-webkit-transform-origin: left top;
} @else if $position == 'bottom' {
-webkit-transform-origin: left bottom;
}
}
} @else if $dpr == '3' {
#{$selector}:#{$pseudo} {
-webkit-transform: scaleY(.3);
transform: scaleY(.3);
@if $position == 'top' {
-webkit-transform-origin: left top;
} @else if $position == 'bottom' {
-webkit-transform-origin: left bottom;
}
}
}
}
}
@mixin onepx($selector, $position: 'top',$pseudo: 'before', $color: #666) {
#{$selector}:#{$pseudo} {
content: ' ';
display: block;
border-top: 1px solid $color;
position: absolute;
left: 0;
right: 0;
}
#{$selector} {
position: relative;
&:#{$pseudo} {
@if #{$position} == 'top'{
top: 0;
} @else if #{$position} == 'bottom' {
bottom: 0;
}
}
}
@include _prefixDpr($selector, $position, $pseudo, '1.5');
@include _prefixDpr($selector, $position, $pseudo, '2');
@include _prefixDpr($selector, $position, $pseudo, '3');
}複製程式碼
test.scss
@import "onepx";
.container {
@include onepx('.myonepx');
}
@include onepx('.hello', 'bottom', 'after', '#777');複製程式碼
執行bat檔案
sass --scss --style expanded test.scss test.css
生成css程式碼:
.container .myonepx:before {
content: ' ';
display: block;
border-top: 1px solid #666666;
position: absolute;
left: 0;
right: 0;
}
.container .myonepx {
position: relative;
}
.container .myonepx:before {
top: 0;
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
.container .myonepx:before {
-webkit-transform: scaleY(0.7);
transform: scaleY(0.7);
-webkit-transform-origin: left top;
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.container .myonepx:before {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: left top;
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 3) {
.container .myonepx:before {
-webkit-transform: scaleY(0.3);
transform: scaleY(0.3);
-webkit-transform-origin: left top;
}
}
.hello:after {
content: ' ';
display: block;
border-top: 1px solid "#777";
position: absolute;
left: 0;
right: 0;
}
.hello {
position: relative;
}
.hello:after {
top: 0;
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
.hello:after {
-webkit-transform: scaleY(0.7);
transform: scaleY(0.7);
-webkit-transform-origin: left bottom;
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.hello:after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: left bottom;
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 3) {
.hello:after {
-webkit-transform: scaleY(0.3);
transform: scaleY(0.3);
-webkit-transform-origin: left bottom;
}
}複製程式碼
好處:可以使用習慣的sass寫1px的實現方案,並且支援傳參,更加靈活。
參考:
www.topcss.org/?p=769
謝謝導師donaldyang的指導。
相關推薦
圖片流量節省大殺器:基於CDN的sharpP自適應圖片技術實踐
永珍優圖CI
頁面效能優化的利器 — Timeline
此文已由作者授權騰訊雲技術社群釋出,轉載請註明文章出處
原文連結:www.qcloud.com/community/a…
獲取更多騰訊海量技術實踐乾貨,歡迎大家前往騰訊雲技術社群