SS 过去只有四个你需要知道的视口单元,它们几乎可以涵盖所有可以想象的用例。 然而,随着时间的推移和技术的变化,这四个视口单元不再足以处理所有用例。 由于CSS 增加了 20 个视口单元,这听起来很多,但它们被分解为六个主要的视口单元,并带有三个独特的修饰符,总共有 24 种组合。
主要的4种视口单元
主要的 CSS 视口单位是 vw、vh、vmin 和 vmax。 您以前可能使用过或看过这些单位,所以我在解释它们时会尽量简短。
VW
vw 代表 Viewport Width,代表视口宽度的百分比。 放置在 vw 之前的数字是视口宽度的百分比。 例如,如果您写了 10vw,那么这将代表视口宽度的 10% 的长度。
视口代表你屏幕的大小,如果你在一个宽度为 1920 像素的大桌面上,10vw 将代表 192 像素。 如果您使用的是宽度为 300px 的手机,那么 10vw 将只有 30px。
VH
vh 代表视口高度,与 vw 完全相同,但它代表高度而不是宽度。 这两个单元可以组合使用,以轻松地使元素填满屏幕的整个大小。
VMIN 和 VMAX
vmin 和 vmax 表示最大和最小视口尺寸。 例如,如果您使用的是 300 像素宽和 800 像素高的手机,则 vmin 将代表视口的宽度,而 vmax 将代表设备的高度。 如果您需要根据屏幕的最小/最大尺寸调整元素的大小,这些单位非常有用。 例如,下面的 CSS 将创建一个尽可能大的正方形,而不会在任何方向溢出,因为它永远不会大于最小屏幕尺寸的 100%。
两个新的视口单位
CSS 一直在尝试从严格的顶部/底部、左/右、高度/宽度模型转变为更动态的开始/结束、块/内联模型。 此更改的主要原因是它可以让你更容易地采用不同的编写方向。 如果您的整个应用程序从水平书写方向切换到垂直书写方向,则顶部/底部或宽度/高度的概念不一定意味着相同的事情,因为如果您想在文本上方和下方添加填充,这将被表示 作为垂直书写系统中的左右填充,而不是填充顶部和底部。 这就是 CSS 添加 vi 和 vb 视口单元的原因。
VI
vi 代表 Viewport Inline,代表文档的内联方向。 在水平书写方向上,这对应于视口的宽度,而在垂直书写方向上,这表示视口的高度。 记住 inline 方向的简单方法是记住它与文本的方向相同。 另一种记住这一点的方法是,如果您有两个彼此相邻的内联元素(例如两个跨度),那么它们堆叠的方向就是您的内联方向。
VB
vb 代表 Viewport Block,代表文档的块方向。 这与 vi 相反,因此在水平书写方向上,这将对应于视口高度,在垂直文档中,这将表示视口的宽度。 如果你很难记住这个单元,请记住块方向始终是块元素(例如两个 div)相互堆叠的方向。
视口单位修饰符
到目前为止,我们已经介绍了六种主要类型的视口单元,但是当您的视口可以改变大小时,您可以将三种不同的修改器添加到单元中以使它们表现不同。例如,当您在手机上浏览网页时,您可能会注意到向下滚动时 URL 栏会消失。发生这种情况时,您的视口在技术上会更改大小,因为现在 URL 栏不再占据您的视口的一部分。当前的 CSS 单元无法处理视口大小的这种变化,这就是添加这些修饰符的原因。
这些修饰符是 s、l 和 d。为了使用修饰符,您只需将修饰符放在数字之后和单位之前,例如 10svw。这为 6 个视口单元中的每一个提供了 4 个总组合。大众、svw、lvw 和 dvw。
到目前为止,我们在本文中介绍的所有内容都没有使用完全有效的修饰符。当您在单元上不使用修饰符时,例如 10vw 或 10vh,浏览器将自动默认使用基于浏览器实现的 3 个修饰符之一。
s修饰符
s 修饰符代表 Small 并表示可能的最小视口。 在我们的手机示例中,这将是显示 URL 栏时视口的大小。 如果您将一个元素设置为 100svh,它将占据屏幕高度的 100%,具体取决于显示 URL 栏时的屏幕大小。 URL 栏是否可见无关紧要,此单元将始终根据显示 URL 栏时的视口大小来确定其大小。
l修饰符
l 修饰符代表Large,代表最大可能的视口。 这几乎与 s 修饰符相反。 在我们的手机示例中,这将是没有显示 URL 栏时的视口大小。 如果您将元素设置为 100lvh,则当 URL 栏不显示时,它会根据屏幕大小占据屏幕高度的 100%。 URL 栏是否可见无关紧要,如果 URL 栏未显示,此单元将始终根据视口的大小确定其大小,这意味着如果您将元素设置为 100lvh 并且 URL 栏显示它在技术上将 比屏幕大。
d修饰符
d 修饰符代表动态,代表当前视口大小。 这就像 s 和 l 修饰符的组合。 在我们的手机示例中,无论 URL 栏是否显示,这始终是当前视口的大小。 如果我们的 URL 栏正在显示,则 d 修饰符与 s 修饰符大小相同,而如果 URL 栏未显示 d 修饰符与 l 修饰符大小相同。
在显示和隐藏 URL 栏之间的过渡期间,此单元将动态缩放大小,因此它始终会填满所有可用空间。 如果您需要确保元素始终根据视口调整大小,这很好,但可能会很费力,因为随着大小的不断变化,它会导致大量重绘。
浏览器支持
对于每一个很酷的 CSS 功能,您总是需要考虑浏览器支持,不幸的是,浏览器对这些新视口单元的支持不是很好。 目前,这些新单元的支持率为 15.2%,并且实际上仅在 Safari 和 Firefox 中得到支持。 缺乏支持的原因是该提案仍处于工作草案阶段,这意味着它还处于生命周期的早期阶段,距离成为官方 CSS 还很远。
结论
虽然 24 个单位可能听起来很多,但实际上只有 6 个单位和三个相对简单的修饰符。 然而,这些简单的组合给了我们构建完美 CSS 布局的强大能力。
来混,那些混过去的,迟早是要还的 ( ̄Д  ̄)┍ 。
让我们来解决几个问题:
1. 什么是 viewport ? 它的的作用是啥?
提到 viewport,之前总感觉挺突兀的,但是当我最近做移动端项目时,突然关注到一直被忽略的 meta 标签的时候,才恍然大悟(o(╯□╰)o)。那么,首先让我们来了解一下 meta 标签☛一直被忽略的meta标签了解一下,之后再去看 viewport,就很容易记住了,不就是 meta 标签中 name 属性的一个值嘛。
那么, 它的作用是啥呢?要了解它具体的作用,我们需要先来了解一些相关的基本知识。
视口类型
viewport 指浏览器的窗口,即浏览器上用来显示网页的那部分区域,是用户网页的可视区域。
viewport 的功能在于控制你网站的最高块状(block)容器:<html>元素。可以理解为 viewport 是容纳 <html> 元素的元素。<html> 元素的宽度为浏览器的宽度,即为 viewport 宽度的100%。(原文)
在移动端和pc端,视口是不同的。pc端的视口是浏览器窗口区域,而在移动端则有三个不同的视口概念:布局视口、视觉视口、理想视口。
( viewport移动端适配、关于移动端适配,你必须要知道的)
viewport 的设置不会对 PC 页面产生影响,但对于移动页面却很重要。
属性介绍
属性 含义 取值 width 定义视口的宽度,单位为像素 正整数或设备宽度device-width height 定义视口的高度,单位为像素 正整数或device-height initial-scale 定义初始缩放值 整数或小数 minimum-scale 定义缩小最小比例,它必须小于或等于maximum-scale设置 整数或小数 maximum-scale 定义放大最大比例,它必须大于或等于minimum-scale设置 整数或小数 user-scalable 定义是否允许用户手动缩放页面,默认值yes yes/no 基本用法和作用
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> 复制代码
上面这个基本的设置:
viewport 属性的作用,就是让 布局视口 通过缩放来适配屏幕宽度,width=device.width 仅仅是让 布局视口 初始大小等于设备宽度,后面设置的initial-scale 是用来缩放 布局视口 大小,而且默认是 布局视口 初始大小等于设备宽度,也就是所谓的 理想视口。
2. 什么是 rem?它的布局原理是什么?
rem(font size of the root element):是指相对于根元素的字体大小的单位,其布局的本质是等比缩放,一般是基于宽度。
将设计稿转化为手机屏幕上的内容,就类似于画地图,按照一定的比例进行缩小绘制:
3. 为什么要进行 scale 缩放?scale 与 dpr 的关系?
dpr ( device pixel ratio):设备像素比,即设备物理像素与逻辑像素(css像素)的比例。
window.devicePixelRatio 复制代码
【设计稿】:设计师给的 750px 宽的设计稿是根据设备像素(device pixel,物理像素)为单位制作的设计稿。
【web页面编写】:前端工程师在编码 web 页面时所写的 CSS 像素 则需要根据 设备像素比 来进行换算。
设备像素比(DPR) = 设备像素个数 / 理想视口CSS像素个数(device-width) ,则:
CSS像素 = 设计稿像素/dpr。
缩放会影响 布局视口 的大小,当我们在移动端对页面进行放大和缩小时,实际上是在改变 CSS 像素的大小,而 scale 缩放的目的就是为了使 CSS 像素适应移动端的设备像素,而这个缩放是通过两个关键的元素设置来实现的:
width=device-width,initial-scale=1/dpr
做的事情就是先把布局视口放大dpr倍,然后再整体缩放相应倍数以适应设备尺寸,这样就能够使css像素和设备物理像素一对一了。
var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; if (isIPhone) { // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其他设备下,仍旧使用1倍的方案 dpr = 1; } scale = 1 / dpr; 复制代码
rem 是为了解决不同机型不同宽度的问题,scale是为了解决dpr的问题。移动端自适应与dpr是无关的。
淘宝方案中采用了dpr用于解决1px的问题,而网易方案并没有引入dpr,布局视口没有放大,整个页面也没有缩放,但是并不影响与设计图的比例。
➹ 真的,移动端尺寸自适应与dpr无关
➹ 详解适配相关概念
明白了上述几个问题了之后,我们就掌握了移动端自适应的精髓,从而可以进行实战开发了。
拿到设计稿,该怎么下手?
通过上面的 rem 换算,我们能够知道,如何把视觉稿(750px)中元素的 px 转换成 rem。
(1)设置 html font-size,如将手机屏幕分成10份:
<script> var dpr = window.devicePixelRatio; var meta = document.createElement('meta'); // dpr meta.setAttribute('content', 'initial-scale=' + 1 / dpr + ', maximum-scale=' + 1 / dpr + ', minimum-scale=' + 1 / dpr + ', user-scalable=no'); document.getElementsByTagName('head')[0].appendChild(meta); // rem document.addEventListener('DOMContentLoaded', function (e) { document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px'; }, false); </script> 复制代码
(2)假设元素宽度为 300px,则元素宽度:
可以通过以下的方案来实现自动转换:
✔ Scss 方案
$ue-width: 750; /* ue图的宽度 */ @function px2rem($px) { @return #{$px/$ue-width*10}rem; } p { width: px2rem(100); } 复制代码
✔ vscode 中进行 px 到 rem 的转换:vscode-cssrem
✔ postcss-pxtorem 方案
// postcss.config.js const pxtorem = require('postcss-pxtorem'); const pxtoremOpts = { rootValue: 16, // 根字体大小,默认16 unitPrecision: 5, // 精度 propList: ['font', 'font-size', 'line-height', 'letter-spacing'], // 可以将px转换成rem的属性 selectorBlackList: [], // 选择器忽略并保留px replace: true, // 替换包含rems的规则 mediaQuery: false, // 是否允许在媒体查询中转换px minPixelValue: 2 // 设置要替换的最小像素值 }; module.exports = { plugins: [ pxtorem(pxtoremOpts), ], }; 复制代码
5. 常见移动端分辨率
常,我们希望限制元素相对于其父元素的宽度,同时使其具有动态性。因此,有一个基础宽度或高度的能力,使其扩展的基础上,可用的空间。比如说,我们有一个按钮,它的宽度应该是最小的,不应该低于它的宽度。这就是最大和最小属性变得方便的地方。
在本文中,我们将详细介绍CSS的最大和最小宽度和高度属性,并使用可能的用例和技巧详细解释每一个属性。
首先要讨论的是与宽度相关的属性。我们有min-width和max-width,它们中的每一个都很重要,都有自己的用例。
设置min-width的值时,其好处在于防止width属性使用的值变得小于min-width的指定值。 请注意,min-width的默认值是auto,它解析为0。
让我们举一个基本的例子来说明这一点。
我们有一个按钮,里面有一个变化的文本。文本的范围可能从一个单词到多个单词。为了确保即使只有一个单词,它也有最小宽度,应该使用min-width。
最小宽度为100px,这样即使按钮的内容很短,比如Done,或者只有一个图标,它仍然足够大,可以被注意到。在使用阿拉伯语等多语言网站时,这一点非常重要。 考虑以下来自Twitter的示例:
在以前的情况下,按钮上带有单词“تم”,表示完成。 按钮的宽度太小,因此在后面的案例中,我增加了它的最小宽度。
在内容较长的情况下,min-width可以扩展按钮的宽度,而水平方向上的padding应该被添加,以实现一个合适的外观按钮。
在设置max-width值时,它的好处在于防止width属性使用的值超过max-width的指定值。max-width的默认值是none。
max-width的常见且简单的用例是将其与图像一起使用。 考虑以下示例:
图像比它的父元素大。通过使用max-width: 100%,图像的宽度不会超过其父图像的宽度。如果图像比父图像小,则max-width: 100%不会对图像产生实际影响,因为它比父图像小。
当min-width和max-width都用于一个元素时,它们中的哪一个将覆盖另一个?换句话说,哪个优先级更高?
html
<div class="wrapper">
<div class="sub"></div>
</div>
css
.sub {
width: 100px;
min-width: 50%;
max-width: 100%;
}
初始width值为100px,并在其上加上min-width和max-width值。 结果是元素宽度未超过其包含的块/父元素的50%。
除了最小和最大宽度属性外,我们还具有与高度相同的属性。
设置min-height的值时,其好处在于防止使用的height属性值变得小于min-height的指定值。 请注意,最小高度的默认值为auto,它解析为0。
我们用一个简单的例子来演示一下。
我们有一个带有描述文本的部分。目标是为section设置一个最小高度,这样它就可以处理短或长内容。考虑下面的基本情况
.sub {
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
min-height: 100px;
color: #fff;
background: #3c78dB;
}
最小高度为100px,使用flexbox时,内容水平和垂直居中。 如果内容更长,会发生什么? 例如一段?
是的,你猜对了!section的高度将展开以包含新内容。有了它,我们就可以构建灵活的组件,并对其内容做出响应。
事例源码:https://codepen.io/shadeed/pen/cfb600cf30acdae9cf6f9cb5347a37cf
在设置max-height值时,它的好处在于防止height属性使用的值超过max-height的指定值。注意,max-height的默认值是none。
考虑下面的示例,其中我为内容设置了max-height。 但是,因为它大于指定的空间,所以会发生溢出。 因此,文本超出了其父边界。
我们将介绍min-width,min-height,max-width和max-height的一些常见和不常见的用例。
当有一个标签列表时,建议限制一个标签的最小宽度,这样如果它的内容很短,它的外观就不会受到影响。
通过具有这种灵活性,无论内容有多短,标签都将看起来不错。 但是,如果内容作者输入了一个非常长的标签名称,而他使用的内容管理系统没有标签的最大字符长度,将会发生什么情况呢? 我们也可以使用max-width。
.c-tag {
display: inline-block;
min-width: 100px;
max-width: 250px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
/*Other styles*/
}
通过使用max-width,标签宽度将被限制为特定值。 但是,这还不够,标签名称应被截断。
事例地址:https://codepen.io/shadeed/pen/320e42b7ad75c438a9e633417d737d16
对于按钮的最小值和最大值有不同的用例,因为按钮组件有多种变体。考虑下面的图:
请注意,按钮的“Get”宽度太小。 如果不设置最小宽度,则由于任何原因而没有文本时,情况可能会变得更糟。 在这种情况下,设置最小宽度很重要。
min-width的默认值是auto,它被计算为0。当一个元素是一个flex项时,min-width的值不会计算为零。flex 项目的最小大小等于其内容的大小。
根据CSSWG:
默认情况下,flex项目不会缩小到它们的最小内容大小(最长单词或固定大小元素的长度)以下。要更改此设置,请设置min-width或 min-height属性。
考虑下面的例子
这个人的名字有一个很长的单词,这导致了溢出和水平滚动。尽管如此,我还是在标题中添加了下面的CSS来截断它
.c-person__name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
由于title是flex项目,因此解决方案是重置min-width并将其强制为零。
.c-person__name {
/*Other styles*/
min-width: 0;
}
下面是修复后的样子
根据CSSWG:
在弹性项目的主轴上可见溢出的项目上,当在弹性项目的主轴min-size属性中指定时,指定自动最小尺寸。
意味着,将overflow设置为visible值以外的值会导致min-width被计算为0,这解决了我们不设置min-width: 0的问题。
事例源码:https://codepen.io/shadeed/pen/398ccffcd437a2fb042f5ce3bdd68c57
虽然与min-width相比,这是一个不太常见的问题,但是它可能发生。 只是为了确认,问题与不能少于其内容的弹性项目有关。 结果min-height值被设置为与内容一样长。
考虑以下示例:
用红色表示的文本应该在父文本中裁剪。因为面板主体是一个flex项目,所以它的min-height与它的内容相等。为了防止这种情况,我们应该重新设置最小高度值。看看HTML和CSS是怎么样的。
HTML
<div class="c-panel">
<h2 class="c-panel__title"><!-- Title --></h2>
<div class="c-panel__body">
<div class="c-panel__content"><!-- Content --></div>
</div>
</div>
CSS
.c-panel {
display: flex;
flex-direction: column;
height: 180px;
}
.c-panel__body {
min-height: 0;
}
.c-panel__content {
overflow-y: scroll;
height: 100%;
}
通过向面板主体添加min-height: 0,这将重置该属性,并且现在应该可以正常工作。
事例源码:https://codepen.io/shadeed/pen/dea75b84b1fcfd03e5c21173a40afc20?editors=0100
在某些情况下,我们有一个最小宽度的元素,但同时,它没有最大宽度。这可能会导致组件太宽,而我们并不想这样做。考虑以下示例
由于宽度是以像素为单位定义的,因此不能保证上面的方法适用于移动视口。为了解决这个问题,我们可以使用百分比来代替像素作为最小和最大属性。考虑下面这个具有article主体的示例。
我为图像添加了以下CSS:
img {
min-width: 35%;
max-width: 70%;
}
事例源码:https://codepen.io/shadeed/pen/11f49fd1a35ad06ce241bee17c3d3124
#### 页面包装器/容器
最常用的`max-width`用例之一是页面包装器或容器。通过向页面添加最大宽度,我们可以确保内容对用户来说是可读的、易于浏览的。
下面是一个包装器的例子,它是居中的,左右两边有水平的填充。
.wrapper {
max-width: 1170px;
padding-left: 16px;
padding-right: 16px;
margin-left: auto;
margin-right: auto;
}
ch 是一个相对于数字0的大小,1ch 就是数字 0 的宽度。如定义一个3ch的宽度,那么就只能装下 3个0。
<!-- HTML代码 -->
<div>0000</div>
/* CSS代码 */
div {
width: 3ch;
background: powderblue;
}
在前面的wrapper元素示例中,我们可以利用ch单元,因为它是一个article 主体。
.wrapper {
max-width: 70ch;
/* Other styles */
}
在某些情况下,我们面临着使手风琴或移动菜单具有意想不到的内容高度的挑战。在这种情况下,max-height可能是一个很好的解决方案。
请考虑以下示例:
单击菜单按钮后,菜单应随动画从上到下滑动。 如果没有固定的高度(不建议这样做),除非使用JavaScript,否则这是不可能的。 但是,对于max-height,这是可能的。 想法是为高度添加一个较大的值,例如max-height:20rem,可能无法达到,然后我们可以使用动画从max-height: 0变换到max-height: 20rem。
.c-nav {
max-height: 0;
overflow: hidden;
transition: 0.3s linear;
}
.c-nav.is-active {
max-height: 22rem;
}
点击菜单按钮可以看到动画的运行。
事例源码:https://codepen.io/shadeed/pen/164c7ef67f5d4541bddb8bc12b2772da
一般来说,我不喜欢给元素添加固定的高度。我觉得这样做,会破坏流式布局的结构。但有些情况设置固定高度却很有用。
考虑下面的例子,在这里我们有一个设置了固定高度的hero部分。
是,当内容较长时,它会溢出并离开hero包装器,这可不太好。
为了预先解决这个问题,我们可以使用min-height来代替height。我们可以用这种方式先解决问题,尽管这可能会导致页面看起来很奇怪,但是我认为应该首先防止内容管理系统(CMS)中发生这样的事情。这样,问题就解决了,看起来也不错。
内容溢出的问题不仅在于内容是否大于固定的hero 高度。它可以发生在屏幕大小调整作为文本换行的结果。
如果改用min-height,则上述情况根本不会发生。
对于模态组件,它需要最小和最大宽度,以便可以适应移动设备到PC的屏幕上的适应。
思路1
.c-modal__body {
width: 600px;
max-width: 100%;
}
思路2
.c-modal__body {
width: 100%;
max-width: 600px;
}
对于我来说,我更喜欢第二个思路,因为我只需要定义max-width: 600px。modal是一个<div>元素,因此它已经具有其父元素的100%宽度,对吗?
考虑下面为模态设计简化的测试案例。 请注意,如果可用视口空间不足,则宽度如何更改为其父级的100%。
事例源码:https://codepen.io/shadeed/pen/5dcb1c4c6773cc3a97a766c327c36443
当一个网站的内容不够长,它希望看到页脚粘到底部。让我们用一个可视化的例子来更好地展示这一点。
请注意,页脚未粘贴在浏览器窗口的末尾。 那是因为内容不足以达到浏览器窗口高度的长度。 修复后,其外观应如下所示:
首先,将body元素作为flexbox容器,然后将其最小高度设置为视口高度的100%。
事例源码:https://codepen.io/shadeed/pen/aeb14f2819b9cc4805275b88c2d55645?editors=1100
为了使比例容器能够根据视口大小进行响应缩放,引入了padding hack。 现在,我们可以通过组合CSS中的视口单位和最大宽度/高度来模仿相同的行为。
我们有一个尺寸为644 * 1000像素的图像。 为了使其流畅,我们需要以下内容:
人才们的 【三连】 就是小智不断分享的最大动力,如果本篇博客有任何错误和建议,欢迎人才们留言,最后,谢谢大家的观看。
作者:Ahmad shaded 译者:前端小智 来源:sitepoint 原文:https://www.impressivewebs.com/min-max-width-height-css
*请认真填写需求信息,我们会在24小时内与您取得联系。