一文学会使用 CSS 中的 min(), max(), clamp() 以及它们的使用场景

做者:Ahmad shaded
译者:前端小智
来源:sitepoint
点赞再看,微信搜索 【大迁世界】关注这个没有大厂背景,但有着一股向上积极心态人。本文 GitHub https://github.com/qq44924588... 上已经收录,文章的已分类,也整理了不少个人文档,和教程资料。

2020年4月8日Firefox浏览器支持了 CSS 比较函数min()max()clamp()),这意味着如今全部主流浏览器都支持它们。 这些CSS函数最大的做用就是能够为咱们提供动态布局和更灵活设计组件方法。 css

简单的这些元素主要用来设置元素尺寸,如容器大小,字体大小,内距,外距等等 。在这篇文章中,我将用一些示例和你们一块儿来探讨这几个函数在实际中的使用,但愿能更好的帮助你们理解它们。前端

兼容性

minmax 的支持状况:git

clipboard.png

clamp()的支持状况:github

图片描述

CSS 比较函数

根据CSS规范,比较函数是关于比较多个值并取其一的操做,咱们来研究一下函数。浏览器

Min() 函数

min() 函数支持一个或多个表达式,每一个表达式之间使用逗号分隔,而后以最小的表达式的值做为返回值,咱们可使用min()为元素设置最大值。微信

考虑下面的例子,咱们但愿元素的最大宽度为500pxapp

.element {
    width: min(50%, 500px);
}

clipboard.png

浏览器须要在(50%,500px) 取一个最小值,由于有个百分比,因此最终结果取决于视口宽度。若是50%的计算值大于500px,那么就取 500pxide

不然,若是50%计算值小于500px,则50%将用做宽度的值,假设视口的宽度是 900px, 最终元素的宽度为 900px x 50% = 450px函数

clipboard.png

下面是一个交互的动画为了让你们更好的理解:工具

图片描述

事例源码:https://codepen.io/shadeed/debug/f5e338c8a1c7cd29e382c72a5eb37e48/auth

Max() 函数

max()函数和min()函数语法相似,区别在于max()函数返回的是最大值,min()函数返回的是最小值。一样,咱们可使用man()为元素设置最小值。

考虑下面的例子,咱们但愿元素的最小宽度为500px

.element {
    width: max(50%, 500px);
}

浏览器须要在(50%,500px) 取一个最大值,由于有个百分比,因此最终结果取决于视口宽度。若是50%的计算值小于500px,那么就取 500px

不然,若是50%计算值大于500px,则50%将用做宽度的值,假设视口的宽度是 1150px, 最终元素的宽度为 1150px x 50% = 575px

clipboard.png

事例源码:https://cdpn.io/shadeed/debug/cca927df45964fbe1a8342ad3ace6d71

Clamp() 函数

clamp()函数做用是返回一个区间范围的值。语法以下:

clamp(MIN, VAL, MAX)

其中MIN表示最小值,VAL表示首选值,MAX表示最大值。意思是,若是VALMINMAX范围之间,则使用VAL做为函数返回值;若是VAL大于MAX,则使用MAX做为返回值;若是VAL小于MIN,则使用MIN做为返回值。

clamp(MIN, VAL, MAX)实际上等同于max(MIN, min(VAL, MAX))

考虑下面的例子

.element {
    width: clamp(200px, 50%, 1000px);
}

假设咱们有一个元素,其最小宽度为200px,首选值为50%,最大值为1000px,以下所示:

clipboard.png

上面的计算过程是这样的:

  • 宽度永远不会低于200px
  • 内容中间首选值是50%,只有在视口宽度大于400px小于2000px时才有效
  • 宽度不会超过 1000px

事例源码:https://codepen.io/shadeed/pen/924419f15bfdcf0cd0103b0587524b0b?editors=0010

上下文很重要

计算值取决于上下文。 多是%emremvw/vh。 甚至百分比值也能够基于视口宽度(若是元素直接位于<body>中),也能够基于其父元素。

数学表达式

值得一提的是, clamp() 函数也能够用于数学表达式,而没必要借助于 calc(),以下代码所示:

.type {
  /* 强制字体大小保持在 12px 到 100px 之间 */
  font-size: clamp(12px, 10 * (1vw + 1vh) / 2, 100px);
}

用例

侧边栏和主界面

clipboard.png

一般,页面的侧边栏是固定的,主界面度是灵活的。 若是视口足够大,咱们能够根据视口的大小动态增长侧边栏宽度,这里咱们可使用max()函数为其设置最小宽度。

考虑下面的示例:

.wrapper {
    display: flex;
}

aside {
  flex-basis: max(30vw, 150px);
}

main {
  flex-grow: 1;
}

若是视口大于 500px,则侧边栏的最小宽度为150px(500 * 30% = 150)。

事例源码: https://codepen.io/shadeed/pen/7f9558f31fdf60bc08c827817c10bf3a?editors=1100

标题字体大小

clipboard.png

clamp()的一个很好的用例是用于标题。假设咱们但愿标题的最小大小为16px,最大大小为50pxclamp()函数将为咱们提供一个介于二者之间的值。

.title {
    font-size: clamp(16px, 5vw, 50px);
}

在这里使用clamp()是很是适合的,由于它确保了所使用的字体大小是可访问的和易于阅读的。若是换作min(),那么就不能在小的视图中控制字体了。

.title {
    font-size: min(3vw, 24px); /* Not recommended, bad for accessibility */
}

clipboard.png

在移动端,字体大小很小。所以,不要对字体大小使用min()函数。固然,咱们也能够经过媒体查询来适配,可是这样就错过了一次使用 CSS 比较函数实战。

如前所述,能够在max()函数中嵌套min()来实现clamp() 效果,该函数将模仿clamp()函数,以下所示:

.title {
    font-size: max(16px, min(10vw, 50px));
}

事例源码:https://codepen.io/shadeed/pen/db76480260c104df00c65991df90a203?editors=1100

装饰性标题

clipboard.png

注意看上图标题下面有一个大的半透明的标题,这是一个装饰性的文本,根据视窗的大小来缩放。咱们可使用max()函数和CSS viewport单元来设置它的最小值。

.section-title:before {
  content: attr(data-test);
  font-size: max(13vw, 50px);
}

源码: https://codepen.io/shadeed/pen/e0128b73de7c84cb9b98cf733a3835c4?editors=1100

平滑渐变

当在CSS中使用渐变时,你可能须要对它进行一些调整,使颜色之间的过渡更加平滑。咱们先看看下面的渐变:

.element {
    background: linear-gradient(135deg, #2c3e50, #2c3e50 60%, #3498db);
}

clipboard.png

注意移动的过渡是有一条比较明显的线分开,这是很差的。咱们能够经过使用媒体查询来解决这个问题:

@media (max-width: 700px) {
    .element {
        background: linear-gradient(135deg, #2c3e50, #2c3e50 25%, #3498db)
    }
}

有一种更加简洁的方法就是使用 min() 函数,以下 所示:

.element {
    background: linear-gradient(135deg, #2c3e50, #2c3e50 min(20vw, 60%), #3498db);
}

clipboard.png

事例源码:https://codepen.io/shadeed/pen/2c4bf2ded32f66390fdef13409be4a10?editors=1100

透明渐变

当须要在图片上放置文本时,咱们应该在图片上加层渐变让文本更加可读。与上一个示例相似,渐变大小应该在小视图和大视图之间有所不一样。见下图:

clipboard.png

.element {
    background: linear-gradient(to top, #000 0, transparent max(20%, 20vw));
}

事例源码:https://codepen.io/shadeed/pen/babf1bfd4c85eeb1b6f9f549dd0fe602?editors=1100

容器宽度

clipboard.png

若是有一个容器,它的宽度应该是它父容器的80%,但不能超过780px,你会用什么?一般,你应该会用max-width,以下所示:

.container {
    max-width: 780px;
    width: 80%;
}

这里使用 min() 函数也能够为元素设置最大值:

.container {
    max-width: min(80%, 780px);
}

事例源码:https://codepen.io/shadeed/pen/3d8b44709b04efdd7336fe91363e3d76?editors=1100

边界与阴影

图片描述

在一些设计案例中,若是元素边框的宽度和弧度比较大时,在移动时应尽可能减少。经过使用clamp(),咱们能够根据视窗宽度使其动态。

.element {
    box-shadow: 0 3px 10px 0 red;
    border: min(1vw, 10px) solid #468eef;
    border-radius: clamp(7px, 2vw, 20px);
    box-shadow: 0 3px clamp(5px, 4vw, 50px) 0 rgba(0, 0, 0, 0.2);
}

事例源码:https://codepen.io/shadeed/pen/7b5c7979e09573ca32150ebfc7f74a66?editors=1100

Grid Gap

clipboard.png

在一个使用风格布局的界面上,若是咱们想根据视口大小来调整网格之间的间距,使用 clamp() 是很容易作到的:

.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-gap: clamp(1rem, 2vw, 24px);
}

事例源码:https://codepen.io/shadeed/pen/a14c7d9fcbbae84340a4f83833294f5b?editors=1100

若是在不兼容浏览器使用这些方法

与任何新的 CSS 函数同样,提供后退方案是很重要的。 要实现这一点,咱们可使用如下方法之一:

1.手动添加回退方案

咱们能够在使用比较函数以前加一个默认的方式,以下所示:

.hero {
    padding: 4rem 1rem;
    padding: clamp(2rem, 10vmax, 10rem) 1rem;
}

支持的浏览器将忽略第一个,不支持的将使用第一个padding

使用 CSS @supports

咱们可使用@supports检测浏览器是否支持 CSS 比较函数,以下所示:

.hero {
    /* 默认值,用于不支持的浏览器 */
    padding: 4rem 1rem;
}

@supports (width: min(10px, 5vw)) {
   /* 用于支持的浏览器  */
  .hero {
    padding: clamp(2rem, 10vmax, 10rem) 1rem;
  }
}

代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug

原文:https://heydesigner.com/every...

交流

文章每周持续更新,能够微信搜索【大迁世界 】第一时间阅读,回复【福利】有多份前端视频等着你,本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,欢迎Star。

相关文章
相关标签/搜索