iPhone X 后时代的CSS hack
2018年12月14新增 iPhone XS、iPhone XS Max、iPhone XR 相关的内容。
以下不说明 why,只说 how。
常规方式
常规方式采用 CSS 方式,适用于包括如下但不限于如下的情形:头部或尾部有 fix 元素、需要照顾竖屏的情况
viewport 的改进
确保存在viewport-fit=cover
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,viewport-fit=cover">
CSS 中的 safe-area-inset-*
变量
env()
和constant()
是iOS11 新增特性,Webkit 的一个 CSS 函数,用于设定安全区域与边界的距离,有四个预定义的变量:
safe-area-inset-left
:安全区域距离左边边界距离
safe-area-inset-right
:安全区域距离右边边界距离
safe-area-inset-top
:安全区域距离顶部边界距离
safe-area-inset-bottom
:安全区域距离底部边界距离
使用实例
结合CSS的 @support
新特征来使用。
实例:
源代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>iPhone X 后时代的 CSS 兼容</title>
<!-- viewport 的 viewport-fit=cover 不可少 -->
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,viewport-fit=cover">
<style type="text/css">
/* CSS Reset 实际业务中建议用 Normalize */
* {padding: 0; margin: 0}
/* Comment Start */
/* 当内容不足一屏的时候,可以用这个确保也能保持100% 高度,
当然,直接简单粗暴的`body:100vh` 也可以的
*/
html {
position: relative;
}
html,body {
height: 100%;
}
/* Comment End */
body {
background: #272822;
color: #FFF;
text-align: center;
}
.heightDiv {
background:#EEE;
height:900px;
color: #000;
}
.fixedDiv {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 9999;
background-color: #555;
}
.fixedDiv_btn {
margin: 10px 20px;
background-color: #356aa0;
color: #FFF;
height: 30px;
line-height: 30px;
border-radius: 4px;
display: block;
text-decoration: none;
}
/* constant(): (iOS 11.0-11.2) */
@supports (padding-bottom: constant(safe-area-inset-bottom)) {
.fixedDiv_btn {
--safe-area-inset-var: constant(safe-area-inset-bottom);
margin-bottom: calc(10px + var(--safe-area-inset-var));
}
}
/* env(): (iOS 11.2+) */
@supports (padding-bottom: env(safe-area-inset-bottom)) {
.fixedDiv_btn {
--safe-area-inset-var: env(safe-area-inset-bottom);
margin-bottom: calc(10px + var(--safe-area-inset-var));
}
}
/* IPhone X 后时代的兼容,善用CSS3 的`calc()`函数 */
.bottomDiv_inner {
background-color: #dd4b39;
color: #FFF;
font-size: 20px;
padding: 40px 0;
}
/* 可以用 CSS4 的变量(如前面的 fixedDiv ),也可以直接写,看实际情况*/
@supports (padding-bottom: constant(safe-area-inset-bottom)) {
.bottomDiv {
padding-bottom: constant(safe-area-inset-bottom);
}
}
@supports (padding-bottom: env(safe-area-inset-bottom)) {
.bottomDiv {
padding-bottom: env(safe-area-inset-bottom);
}
}
</style>
</head>
<body>
<p>第一行文字哈哈哈哈</p>
<p>!!注意,body 区域是黑色的!!</p>
<p>请右键查看源代码查看说明</p>
<p></p>
<p></p>
<p></p>
<div class="heightDiv">灰色区域撑开自然高度</div>
<div class="fixedDiv">
<a href="javascript:;" class="fixedDiv_btn">我是 Fixed 的元素按钮</div>
</div>
<div class="bottomDiv">
<p class="bottomDiv_inner">我是自然末尾的元素</p>
</div>
</body>
</html>
粗暴版本(不推荐,仅作备份)
通过媒体查询的方式,目前不怎么推荐这种方式了。
/*
iPhoneX / XS 竖屏
所有针对iPhone X竖屏情况下的hack样式都写这里面
*/
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) and (orientation: portrait){
body {
height: 100vh;
}
.help_container {
margin-left: constant(safe-area-inset-left);
margin-left: env(safe-area-inset-left);
margin-right: constant(safe-area-inset-left);
margin-right: env(safe-area-inset-left);
}
.help_feedback .weui-cell{
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}
/*
iPhoneX / XS 横屏
*/
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) and (orientation: landscape){}
/*
iPhoneXR
*/
/* 1792x828px at 326ppi */
@media only screen
and (device-width : 414px)
and (device-height : 896px)
and (-webkit-device-pixel-ratio : 2) { }
/*
iPhone XS Max
*/
/* 2688x1242px at 458ppi */
@media only screen
and (device-width : 414px)
and (device-height : 896px)
and (-webkit-device-pixel-ratio : 3) { }
其它说明
iPhone X 后时代的CSS 兼容,善用CSS3 的
calc()
函数。当你的页面自然高度不满屏的时候,有些第三方客户端的 webview 会自作聪明地帮你加个底部的 safe area margin bottom。有洁癖的设计师可能会要求你去掉,如果要去掉,有如下两种方式:
(1)直接一句
body {height:100vh;}
撑大高度,简单粗暴。(2)传统的撑高高度的样式。
html { position: relative; } html,body { height: 100%; }
附录
Apple 官方文档:https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/
英文资料:https://webkit.org/blog/7929/designing-websites-for-iphone-x/ , https://medium.com/@draganeror/iphone-x-layout-features-with-css-environment-variables-d57423433dec
外部页面介绍:https://aotu.io/notes/2017/11/27/iphonex/index.html (注意该文最后一段 @support 的说法有问题,不一定只有iPhone 支持)