(废话写在前面~~)前端的发展太快,感觉一周一框架的节奏,很多时候我会想怎么能跟上这样的速度,今天刚刚熟悉了一个框架, 结果明天GitHub就出了一个新的比这个更好,那我应该放弃刚熟悉的框架继续去看最新的吗?很明显这样咩有头,只会不停的得不偿失,于是想了想 还是静心下来,我们从最基本的开始,解决疑难杂症巩固好基础才能更快的上手或者说更好的去开发,找到合适于项目的技术栈才是最重要的
关于移动端H5之单位
- 关于单位的使用收集了一共有10个,分别是px,em,pt,ex,pc,in,mm,cm,vh,vw
1)px:像素(Pixel),相对于设备的长度单位,像素是相对于显示器屏幕分辨率而言的。譬如,WONDOWS的用户所使用的分辨率一般是96像素/英寸。而MAC的用户所使用的分辨率一般是72像素/英寸。
2)em:相对长度单位。相对于当前对象内文本的字体尺寸。 如当前行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。
3)pt:点(Point),绝对长度单位。
4)pc:派卡(Pica),绝对长度单位。相当于我国新四号铅字的尺寸(可以自行百度-字号与尺寸对照表)。
5)in:英寸(Inch),绝对长度单位。
6)mm:毫米(Millimeter),绝对长度单位。
7)cm:厘米(Centimeter),绝对长度单位。
8)ex:相对长度单位。相对于字符“x”的高度。此高度通常为字体尺寸的一半。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。
9)vh: 等于viewport高度的1/100.例如,如果浏览器的高是900px,1vh求得的值为9px。同理,如果显示窗口宽度为750px,1vw求得的值为7.5px。
10)vw:设置一个字体大小。这个大小将会随着浏览器的宽度按比例缩放。
其中:1in = 2.54cm = 25.4 mm = 72pt = 6pc ;
虽然收集了10个单位但是在我们开发中实际能用到的比较少,目前我所接触的项目最多的就是 px/rem
- REM的出现
说到REM就要先说说em,可能也看到了和rem 就差了一个r, em 是相对长度单位,比如 如果你在body元素上设置一个字体大小,那么在body元素内的任何子元素的em值都等于这个字体大小。
....
<style>
body{font-size: 16px;}
div p{
font-size: 1em;// 这时 p的字体大小就是 1*16 = 16px
}
</style>
<body>
<div>
<p>hello world!!</p>
</div>
</body>
上述代码表示p设置了font-size为1em。它是所继承body的字体大小的1倍,在这个例子中为16px。所以结果为16px.好处:很方便只要设置一遍body的字体大小就好了
但是,em是相对于当前对象内文本的字体尺寸,所以当我们在实际运用中 出现多层嵌套的时候
...
<style type="text/css">
body{font-size: 16px;}
div{
font-size: 2em;
}
</style>
<body>
<div class="demo1">
<p>hello world!!</p>
<div class="demo">
hello world2!!
<div class="demo2"> hello world3!! </div>
</div>
</div>
</body>
如果简单的设置了div的大小这样就会出现每一个层级字体都不一样结果如下:
第一个是216;第二个就是2216;第三个就是22216了
我们可以通过去设置每一个div的font-size来解决这个问题,但是当需求复杂时就会出现各种font-size的尺寸,就比如我们要刚才的三个嵌套都能达到同一个尺寸 2*16而又不想去设置每一个div的大小,这个时候 就出现了→
rem:基于一个唯一的度量标准来按比例缩放
简单的来说只要设置了body的font-size就可以了,页面所有的元素都是基于这个根元素的大小来改变,在大多数情况下根元素为html元素;
<style type="text/css">
body{font-size: 16px;}
div{
font-size: 2rem;
}
</style>
<body>
<div class="demo1">
<p>hello world!!</p>
<div class="demo">
hello world2!!
<div class="demo2">
hello world3!!
</div>
</div>
</div>
</body>
同样的代码修改下单位效果就改变了;
关于移动端H5之1像素边框
- 随着市场上各种手机端的出现,不同手机物理像素不同,对应的设备像素比不同,同样的1pxcss像素,转换成物理像素后,尺寸是不同的,所以导致了显示的差异,我们前端的开发工程师和UI设计的伙伴们就产生了分歧了,我们设置一个div的底部边框为 1px solid #000; 实际表现却是边框线是模糊的,或者是大于1px的。
参考:https://jinlong.github.io/2015/05/24/css-retina-hairlines/
https://juejin.im/entry/584e427361ff4b006cd22c7c
https://www.w3cplus.com/css/fix-1px-for-retina.html
http://www.html-js.com/article/Mobile-terminal-H5-mobile-terminal-HD-multi-screen-adaptation-scheme%203041
https://segmentfault.com/a/1190000007604842
方法一 0.5px 解决
在2014年的 WWDC,“设计响应的Web体验” 一讲中,Ted O’Connor 讲到关于“retina hairlines”(retina 极细的线)在retina屏上仅仅显示1物理像素的边框,开发者应该如何处理呢。 他们曾介绍到 iOS 8 和 OS X Yosemite 即将支持 0.5px 的边框:
这样有个问题:
问题是 retina 屏的浏览器可能不认识0.5px的边框,将会把它解释成0px,没有边框。包括 iOS 7 和 之前版本,OS X Mavericks 及以前版本,还有 Android 设备。
解决方案:通过JS来检测浏览器能否处理0.5px的边框
if (window.devicePixelRatio && devicePixelRatio >= 2) {
var testElem = document.createElement('div');
testElem.style.border = '.5px solid transparent';
document.body.appendChild(testElem);
if (testElem.offsetHeight == 1)
{
document.querySelector('html').classList.add('hairlines');
}
document.body.removeChild(testElem);
}
// 脚本应该放在<body>内, 如果在<head>里面运行,需要包装 $(document).ready(function() { })
然后 直接写1px即可
div {
border: 1px solid #bbb;
}
.hairlines div {
border-width: 0.5px;
}
从上面的方案来看,只要加上几行JS代码即可解决问题,但是如果要兼容安卓设备,和 iOS 8 以下设备怎么办?在这个需求上就行不通了
方法二 用图片实现 border 的
这是我认为最‘实诚’的方案,顾名思义 就是用图片来平铺得到一条线
一般会使用一张6x6的图片来通过background-image
和border-width
来实现具体我就不细说了可以直接看参考链接
这个方案最不好的地方就是 更换颜色就比较麻烦了,可能你会需要很多不同的图片来做,如果圆角需要特殊处理,并且边缘会模糊
方法三 用多背景渐变实现
.background-gradient-1px {
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;
}
/* 或者 */
.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;
}
这个的缺点 显而易见 代码太多 而且圆角也很不好弄
方法四 伪类 + transform
单条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;
}
四条boder样式设置:
.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('ul').className = 'scale-1px';
}
优点:
所有场景都能满足
支持圆角(伪类和本体类都需要加border-radius)
缺点:
对于已经使用伪类的元素(例如clearfix),可能需要多层嵌套
还有其他的方法 例如 动态改变 viewport ,借助JavaScript来动态修改meta
标签中viewport
中的initial-scale
的值,然后根据dpr
修改html
中的font-size
值,再使用rem
简称Flexible方案
总结:相对而言 伪类的方案更好用,目前我一直在用的也是这个方案,之前有搜索过各种资料包括实践,目前来说都是这种方式最好使用,兼容性也最好。(如果有看官们有好的欢迎贴码谢谢)