项目里做一些活动h5页面全屏展示的时候,针对这些刘海屏反复测试和试用,总结了部分可实用性的方案:
兼容 iOS < 11.2
@supports (top: constant(safe-area-inset-top)) {
body{
padding-top: constant(safe-area-inset-top);
}
}
@supports (bottom: constant(safe-area-inset-bottom)) {
.fixedFooter {
padding-bottom: constant(safe-area-inset-bottom);
}
}
兼容 iOS >= 11.2
X、XR:375*814
(全屏刘海+吸底,两者都需要添加)
(非全屏,只有吸底按钮,需要单独给底部按钮加吸底安全距离)
先要加:
<meta name="viewport" content="width=device-width, viewport-fit=cover”>
Body,html{
min-height: 100vh; //保证底部按钮固定在底部
}
contain: 可视窗口完全包含网页内容(左图)
cover:网页内容完全覆盖可视窗口(右图)
auto:默认值,跟 contain 表现一致
>注意:当 viewport-fit=contain 时 env() 是不起作用的,必须要配合 viewport-fit=cover 使用。对于不支持env() 的浏览器,浏览器将会忽略它。
(2-1)、底部吸顶按钮安全距离
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.fixedFooter {
padding-bottom: env(safe-area-inset-bottom);
}
}
(2-2)、头部安全距离处理+底部有吸顶按钮:
@supports (top: constant(safe-area-inset-top)) or (top: env(safe-area-inset-top)) {
body {
padding-top: constant(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
}
}
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
body {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}
>注意:env() 跟 constant() 需要同时存在,而且顺序不能换
padding-bottom: constant(safe-area-inset-bottom); /* 兼容 iOS < 11.2 */
padding-bottom: env(safe-area-inset-bottom); /* 兼容 iOS >= 11.2 */
Android刘海屏:
/*html: 最顶部加入两个盒子*/
<div class="safe-top"></div>
<div class="nav-bar"></div>
/*css: @baseSize: 75; //设计稿是2倍图时*/
.nav-bar {
height: 148rem/@baseSize;
}
解决ios和Android两个端刘海屏:
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
body {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
.safe-top {
height: calc(constant(safe-area-inset-top) - 148rem/@baseSize);
height: calc(env(safe-area-inset-top) - 148rem/@baseSize);
}
}
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.fixedFooter {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}
以下拓展:
3-1、env()和constant()
iOS11 新增特性,Webkit 的一个 CSS 函数,用于设定安全区域与边界的距离,有四个预定义的变量:
safe-area-inset-left:安全区域距离左边边界距离;
safe-area-inset-right:安全区域距离右边边界距离;
safe-area-inset-top:安全区域距离顶部边界距离;
safe-area-inset-bottom:安全区域距离底部边界距离 (小黑条的高度,横竖屏时值不一样);
3-2、fixed 元素的适配
(1)、可以通过加内边距 padding 扩展高度:
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
button {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}
(2)、或者通过计算函数 calc 覆盖原来高度:
{ height: calc(60px(假设值) + constant(safe-area-inset-bottom));
height: calc(60px(假设值) + env(safe-area-inset-bottom));
}
(3)、可以通过新增一个新的元素(空的颜色块,主要用于小黑条高度的占位),然后吸底元素可以不改变高度只需要调整位置,像这样:
{ margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
}
(4)、空的颜色
.empty{
position: fixed;
bottom: 0;
width: 100%;
height: constant(safe-area-inset-bottom);
height: env(safe-area-inset-bottom);
background-color: #fff;
}
fixed 非完全吸底元素(bottom ≠ 0),比如 “返回顶部”、“侧边广告” 等:
(1)、只是位置需要对应向上调整,可以仅通过外边距 margin 来处理:
{
margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
}
(2)、也可以通过计算函数 calc 覆盖原来 bottom 值:
{
bottom: calc(50px(假设值) + constant(safe-area-inset-bottom));
bottom: calc(50px(假设值) + env(safe-area-inset-bottom));
}
日常常用iPhone机型配置:
型号 | 分辨率(宽*高) | 屏幕尺寸 | 布局尺寸 | PPI(像素密度) | DPI(打印密度) |
iPhone5 | 640*1136 | 4英寸 | 320*568 | 326 ppi | |
iPhone 5S | 640*1136 | 4英寸 | 320*568 | 326 ppi | |
iPhone 5C | 640*1136 | 4英寸 | 320*568 | 326 ppi | |
iPhone 6 | 750*1334 | 4.7英寸 | 375*667 | 326 ppi | |
iPhone 6 Plus | 1080*1920 | 5.5英寸 | 414*736 | 401 ppi | |
iPhone 6S | 750*1334 | 4.7英寸 | 375*667 | 326 ppi | |
iPhone 6S Plus | 1080*1920 | 5.5英寸 | 414*736 | 401 ppi | |
iPhone SE | 640*1136 | 4英寸 | 320*568 | 326 ppi | |
iPhone 7 | 750*1334 | 4.7英寸 | 375*667 | 326 ppi | |
iPhone 7 Plus | 1080*1920 | 5.5英寸 | 414*736 | 401 ppi | |
iPhone 8 | 750*1334 | 4.7英寸 | 375*667 | 326 ppi | |
iPhone 8 Plus | 1080*1920 | 5.5英寸 | 414*736 | 401 ppi | |
iPhone X | 1125 * 2436 | 5.8英寸 | 375*812 | 458 ppi | |
iPhone XS | 1125 * 2436 | 5.8英寸 | 375*812 | 458 ppi | |
iPhone XR | 828*1792 | 6.1英寸 | 414*896 | 326 ppi | |
iPhone XS Max | 1242 * 2688 | 6.5英寸 | 414*896 | 458 ppi | |
iPhone 11 | 828*1792 | 6.1英寸 | 414*896 | 326 ppi | |
iPhone 11 Pro | 1125 * 2436 | 5.8英寸 | 375*812 | 458 ppi | |
iPhone 11 Pro Max | 1242 * 2688 | 6.5英寸 | 414*896 | 458 ppi | |
感谢大家的耐心阅读,如果有任何问题或者建议,或者有扩展更深层次的小伙伴,欢迎留言补充,如有错误欢迎指导,欢迎在评论区留言。