前言
我们在做直播场景,这个场景有以下要求:
- 宽高是16:9,因为视频流是这么大,所有的内容都在这个区域内
- 这个区域要尽量占满空间并居中,如果周围有空白则用黑色填充用以凸显直播部分
- 因为浏览器可以随便改变大小,所以保证这个区域至少960x540,防止太小导致里面的内容错乱
clamp
看着上面的需求挺复杂,但是其实关键就是16:9并且最小960x540,那么如何实现这个布局?
我们使用css的clamp函数即可。
clamp函数需要传入3个参数,一个最小值,一个默认值,一个最大值,用于处理边界值,当默认值大于最大值时,取最大值,小于最小值时,取最小值,介于最小与最大之间时,取默认值。
clamp(MIN,DEFAULT,MAX)就相当于max(MIN,min(DEFAULT,MAX))
先来看宽度,默认值是窗口宽度来满足尽量占满空间,最小值是960,最大值则是 高度16/9,因为如果 宽度 小于 高度16/9,那么直播区域的宽度要比窗口宽度小,这样左右两边留出黑边即可。所以:
width: clamp(960px, 100vw, 177.78vh);
同理可以得到高度:
height: clamp(540px, 100vh, 56.25vw);
这样就满足了直播区域的要求。
居中
满足直播区域的要求后,解决居中问题即可,这个很简单,完整代码如下:
.page-container {
display: flex;
justify-content: center;
align-items: center;
min-width: 960px;
background-color: black;
.live-container {
position: relative;
background-color: white;
width: clamp(960px, 100vw, 177.78vh);
height: clamp(540px, 100vh, 56.25vw);
}
...
}
live-container就是直播区域,它在page-container的中间,留白为黑色。如果窗口小于960,则宽度固定960,在外层进行滚动即可。
css计算函数
这里面我们用到了css的clamp函数,css的函数有不少,其中用于计算数值相关的有以下几个:
- calc():进行加减乘除计算
- min():取最小值,可以有多个参数
- max():取最大值,可以有多个参数
- clamp():在区间内取合适的值
移动端
移动端用上面的方法有很多问题:
- android:尺寸没问题,但是当弹出键盘的时候100vh就会变小,在横屏的情况下会导致直播区域变得非常小。其实我们希望它可以不改变尺寸,键盘应该是覆盖在上面的。
- ios:ios上100vh不是可见高度,而是包括地址栏,这就导致直播区域底部有一部分不可见,需要滑动才可以。
目前这两个问题还没找到很好的解决方法,所以如果适配移动端的话,还是建议通过js动态计算再设置live-container的style吧。
js获取宽高:
const windowWidth = document.documentElement.clientWidth || document.body.clientWidth;
const windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
虽然在android上弹出键盘还是会导致高度变小,但是我们在一开始获取正常的高度一次性设置完即可。