writing-mode
writing-mode
定义了文本水平或垂直排布以及在块级元素中文本的行进方向
属性值 | 说明 |
---|---|
horizontal-tb | 文本水平排版,内容从上往下排列 --- 默认值 |
vertical-lr | 文本垂直排列,从左往右进行排列 |
vertical-rl | 文本垂直排列,从右往左进行排列 |
.box {
width: 100px;
height: 100px;
background-color: skyblue;
padding: 10px;
margin: 100px auto;
writing-mode: vertical-lr;
}
pointer-events
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height: 300px;
background-color: skyblue;
}
.box {
display: flex;
justify-content: center;
align-items: center;
width: 100px;
height: 100px;
background-color: gray;
/*
pointer-events用于阻止某个元素的鼠标交互事件
默认值为auto --- 不禁止浏览器鼠标交互事件
none --- 禁止当前元素上所有的鼠标交互事件(例如点击事件,鼠标进入事件,鼠标离开事件等)
*/
pointer-events: none;
}
.btn {
/*
pointer-events属性是一个可继承属性,其会继承给子元素
所以需要在这里将pointer-events的值 进行重置
*/
pointer-events: auto;
}
</style>
</head>
<body>
<div class="container">
<div class="box">
<button class="btn">click me</button>
</div>
</div>
<script>
const containerEl = document.querySelector('.container')
const boxEl = document.querySelector('.box')
const btnEl = document.querySelector('button')
// 在本例中,boxEl的点击事件回调不会被触发,因为div.box设置了pointer-events的值为none
// 但是因为事件会冒泡,所以div.container所对应的事件处理函数仍然会被执行
containerEl.addEventListener('click', () => console.log('container click'))
boxEl.addEventListener('click', () => console.log('box click'))
// div.box对应的mouseenter事件所对应的事件处理函数,因为设置了pointer-events: none 而不会被触发
boxEl.addEventListener('mouseenter', () => console.log('box mouseenter'))
boxEl.addEventListener('mouseleave', () => console.log('box mouseleave'))
btnEl.addEventListener('click', () => console.log('button clicked'))
</script>
</script>
</body>
</html>
object-fit
object-fit 属性指定元素的内容应该如何去适应指定容器的高度与宽度
object-fit
用于替换元素
上,功能类似于background-size
object-fit 一般用于 img 和 video 标签,可以对这些元素进行保留原始比例的剪切、缩放或者直接进行拉伸等
值 | 说明 |
---|---|
fill | 默认值 ,填充容器,不保持初始比例 |
contain | 保持原有尺寸比例。保证替换内容尺寸一定可以在容器里面放得下。因此,此参数可能会在容器内留下空白对于video标签,会将object-fit的值设置为contain |
cover | 保持原有尺寸比例。保证替换内容尺寸一定大于容器尺寸,宽度和高度至少有一个和容器一致。因此,此参数可能会让替换内容(如图片)部分区域不可见 |
none | 保持原有尺寸比例。同时保持替换内容原始尺寸大小 |
scale-down | 就好像依次设置了none或contain, 最终呈现的是尺寸比较小的那个 |
如果我们需要使用具体的数值去对替换元素中的图片进行位置的调整。可以使用object-position
,用法和功能类似于background-position
安全区域
安全区域指的是一个可视窗口范围,处于安全区域的内容不受屏幕的圆角(corners)、齐刘海(sensor housing)、小黑条(Home Indicator 也就是虚拟Home键)影响
安全区域主要是针对于Iphone手机而言的,android手机并不会有影响
默认情况下,页面会因为屏幕的圆角,齐刘海和小黑条而产生页面的某一部分被裁剪,如下图所示,底部JSON的结尾大括号和固定定位的红色小方块都因为IphoneX的圆角被裁剪了
设置了安全区域后,页面会自动根据当前屏幕的齐刘海,圆角和底部小黑条大小,产生一个特殊的视口
该视口内布局的内容不会受当前屏幕的齐刘海,圆角和底部小黑条而影响
可以理解为给页面原本的视口自动加上了上下的内边距。
此时页面就不会被裁剪了
但是其实iphoneX的“刘海”为相机和其他组件留出了空间,同时在底部也留有可操作区域
所以对于web前端而言,刘海在绝大多数的场景下是可以不用处理的
因为 safari, Chrome等移动端浏览器 或客户端(微信,QQ等)的 statusBar 已经替我们抹平了顶部刘海
我们只需要关心底部的可操作区域,因为如果页面底部有按钮的话,就会被可操作区域给挡住。
由图可视,竖屏的时候,可视区域是去除底部小黑条和顶部刘海部分
而在横屏的时候,可视区域为移除页面左右部分(目的是为了避免刘海的影响,因为系统不知道刘海会位于左边还是右边,所以左右直接去除,也方便页面布局)和底部小黑条部分
值 | 说明 |
---|---|
safe-area-inset-left | 安全区域距离左边边界距离 |
safe-area-inset-right | 安全区域距离右边边界距离 |
safe-area-inset-top | 安全区域距离顶部边界距离 |
safe-area-inset-bottom | 安全区域距离底部边界距离 |
/*
设置安全区域
在原本底部50px的基础上在添加上对应安全区域的间距
*/
{
/* 兼容ios v11.2 之前版本的安全区域适配 --- constant函数现在已被废弃 */
padding-bottom: calc(constant(safe-area-inset-bottom) + 50px);
/*
ios v11.2 之后版本的安全区域适配
写在后边,以便于覆盖之前的老版本的写法
env是环境变量函数,用于在网页中加载用户代理(也就是浏览器)中定义的那些环境变量
*/
padding-bottom: calc(env(safe-area-inset-bottom) + 50px);
}
默认情况下,移动端浏览器会主动抹平手机刘海,但是这就意味着在横屏的时候,页面左右会有空白间隙
要解决左右的空白间隙,可以使用viewport-fit
属性
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, viewport-fit=cover">
viewport-fit中可选值 | 说明 |
---|---|
cover | 铺满整个屏幕 |
contain | 铺满整个安全区域 |
auto | 默认值,浏览器自主决定,一般表现形式为contain |
Ps:viewport-fit只对safari浏览器有效,对于chrome浏览器是无效的,所以并不推荐使用
如果需要移除白边,还是推荐给body设置对应的
background-color
css示例
- 网页logo的简单实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>网站logo的简单实现</title>
<style>
/* reset */
h1,
body {
margin: 0;
padding: 0;
}
a {
display: block;
}
/* css */
.logo {
margin: 100px auto;
width: 150px;
height: 150px;
background: url(./images/logo.jpg);
}
/* div.logo中的文本仅仅是为了SEO,用户并不需要看见,所以需要使其隐藏 */
.logo a {
width: 100%;
height: 100%;
text-indent: -999px;
color: transparent;
}
</style>
</head>
<body>
<h1 class="logo">
<!-- 这里放置文本的目的是为了SEO -->
<a href="#">网站logo</a>
</h1>
</body>
</html>
- 下拉列表的简单实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>下拉列表的简单实现</title>
<style>
ul, li {
margin: 0;
padding: 0;
list-style: none;
}
.dropdown {
cursor: pointer;
}
ul {
width: 100px;
padding-left: 30px;
color: #f5f5f5;
overflow: hidden;
background: gray;
/* 默认的height的值为auto,auto的值不可以作为动画的初始值,所以在这里需要进行初始化 */
height: 0;
transition: height 0.5s ease-in-out;
}
.dropdown:hover ul {
height: 110px;
}
</style>
</head>
<body>
<!--
下拉列表中的内容和触发下拉列表的元素必须有一个共同的父元素
其是通过共同的父元素的hover状态来实现对应的功能
-->
<div class="dropdown">
<span>下拉列表</span>
<ul>
<li>下拉项1</li>
<li>下拉项2</li>
<li>下拉项3</li>
<li>下拉项4</li>
<li>下拉项5</li>
</ul>
</div>
</body>
</html>