导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

冷门技能

⭐️ css 的单位有哪些,你常用的有哪些

px, %, em, rem, vw/vh

  1. 在视觉稿要求固定尺寸的元素上使用px。比如1px线,4px的圆角边框。
  2. 在字号、(大多数)间距上使用rem
  3. 慎用em

慎用 em 的原因

<!-- HTML -->
<span>
    abc
    <span>def</span>
    abc
</span>

// CSS
span {font-size: 1.5em;}

实际效果:

Untitled

先要搞清楚em的计算原理,它是根据当前元素的字号按比例计算的。

外层span的字号是16px(浏览器默认值),所以1.5em之后是24px。由于字号是继承的,导致内层span的字号继承过来是24px,再经过1.5em之后就成了36px

所以,就算要用em的话,尽量不要用在继承属性(font-size)上,除非你真的清楚你在做什么!

媒体查询

⭐️ 媒体查询的书写顺序

一般建议书写方式

媒体查询一般用在 PC 端,兼容移动端

那么就先考虑设计稿宽度,最后向下兼容:

.sw-conttainer {
	 padding-bottom: 120px;
	 @media (min-width: $sw-xs) {
	   padding-bottom: 40px;
	 }
	 @media (min-width: $sw-sm) {
	   padding-bottom: 60px;
	 }
	 @media (min-width: $sw-md) {
	   padding-bottom: 80px;
		 }
	 @media (min-width: $sw-lg) {
	   padding-bottom: 100px;
	 }
	 @media (min-width: $sw-xl) {
	   padding-bottom: 120px;
	 }
 }

终端识别

Untitled

⭐️ REM 适配方案

原理是什么?

rem 是一个相对单位,相对的是根元素(html)的字体大小(font-size)。这样一来我们就可以通过 html 上的字体大小来控制页面上所有以 rem 为单位的元素尺寸。

两种常见方案

把页面宽度分成 10 份

思路:

  1. 把页面宽度分成10分,算出每份 px 值(window.innerWidth / 10
  2. 写个 scss mixin 函数,参数为设计稿px值,返回对应rem值(也就是份数)
  3. 公式:rem份数 = 设计稿px / 每份有多少px值

⚪️ 示例代码

例如在 vue 项目的 index.html 页中动态计算根元素字体大小

index.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,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
    ...
  </head>
  <body>
    <noscript>
      ...
    </noscript>
    <div id="app"></div>
    <script>
    ;(function(doc, win) {
      const docEl = doc.documentElement
      const resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
      const recalc = () => {
        let clientWidth = docEl.clientWidth;
        clientWidth = clientWidth < 750 ? clientWidth : 750;
        // 把屏幕宽度划分成10份,那么每一份的宽度就等于1rem,也就是 75px
        docEl.style.fontSize = clientWidth / 10 + 'px'
      }
      if (!doc.addEventListener) return
      win.addEventListener(resizeEvt, recalc, false)
      doc.addEventListener('DOMContentLoaded', recalc, false)
      recalc()
    })(document, window)
    </script>
  </body>
</html>

然后利用 css 预处理器定义一个 mixin 函数(下方用的stylus),用来将设计稿上的 px 转为对应的 rem 值

计算公式为:

页面元素的 rem 值 = 设计稿元素值(px)/(屏幕宽度 / 划分的份数)

mixin.stylus

/* 把px转为rem */
/* 用设计稿px除以每一份rem的px,就能算出几个rem */
px2rem(designpx)
  $rem = 750 / 10;
  return (designpx / $rem)rem

最后在 css 中使用

某 vue 组件的 style 标签中

/* 375 设计稿上 100% 宽以及 50 高的导航条(iPhone6 的 dpr 为 2 ,所以 px 值得都乘以 2) */

header
  width px2rem(750)
  height px2rem(100)

html 的 font-size 设置为 100px (PC端适配)

思路:

  1. html { font-size: 100px; },把100px当做因子
  2. 如果要设置 1200px 宽,那么换算下来就是 { width: 12rem }
  3. 这样也不会受到浏览器默认字体的影响(对比设置 html 字体大小为 62.5% )

rem 布局产生小数像素怎么解决

来源:https://juejin.cn/post/6844903923539509262

⭐️ VW 适配方案

原理就是:把屏幕分成 100 份

举例:

假设设计稿尺寸是 750px,页面有一个按钮,按钮文字标注大小 28px,按钮高度标注为 48px,宽度为 120px,边框为 1px 不缩放。

<!DOCTYPE html>
<html
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    .button {
      width: 16vw;        /*  120/(750/100vw)  */
      font-size: 3.73vw;  /*  28/(750/100vw)  */
      line-height: 6.4vw; /*  48/(750/100vw)  */
      border: 1px solid #000; /* 不需要缩放的部分用px */
      text-align: center;
    }
  </style>
</head>
<body>
  <div class="button">按钮</div>
</body>
</html>

在正式的项目里,我们也可以用SCSS,把换算交给预处理器

@function px2vw($px) {
  @return $px * 100vw / 750;
	/* 或者 */
	@return $px / (750 / 100vw);
}
.button {
  width: px2vw(120);
  font-size: px2vw(28);
  line-height: px2vw(48);
  border: 1px solid #000;
  text-align: center;
}

来源:https://zhuanlan.zhihu.com/p/340299974

⭐️ 1px 物理像素解决

媒体查询 + 变换缩放

原理

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0"/>
    <title></title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      #test {
        width: 100%;
        height:1px ;
        margin-top: 50px;
        background: black;
      }
      @media only screen and (-webkit-device-pixel-ratio:2) {
        #test {
          transform: scaleY(.5);
        }
      }
      @media only screen and (-webkit-device-pixel-ratio:3) {
        #test {
          transform: scaleY(.333333333333333333);
        }
      }
    </style>
  </head>
  <body>
    <div id="test"></div>
  </body>
</html>

stylus 实现方案

/* 给 dpr 1.5 的设备设置 0.7 的缩放 */
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5)
  .border1px
    &::after
      -webkit-transform: scaleY(.7)
      transform: scaleY(.7)
/* 给 dpr 2.0 的设备设置 0.5 的缩放 */
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2)
  .border1px
    &::after
      -webkit-transform: scaleY(.5)
      transform: scaleY(.5)

/* 给需要1px下边框的元素添加一个伪元素,
使其宽100%;高为用户自定义 */
border1px($color)
  position: relative
  &:after
    display: block
    position: absolute
    left: 0
    bottom: 0
    width: 100%
    border-top: 1px solid $color
    content: ' '
<!-- 1. 给需要添加1像素边框的元素设置一个类作为标识,让媒体查询能够识别 -->
<header class="border1px"></header>

<style lang="stylus" scoped>
header
  width px2rem(750)
  height px2rem(100)
  border1px(black) /* 2. 通过border1px设置边框 */
  background-color transparentify
</style>

让 Chrome 支持小于12px 的文字方式有哪些?区别?

来源:https://vue3js.cn/interview/css/less_12px.html

一、背景

Chrome 中文版浏览器会默认设定页面的最小字号是12px,英文版没有限制

原由 Chrome 团队认为汉字小于12px就会增加识别难度

与网页语言无关,取决于用户在Chrome的设置里(chrome://settings/languages)把哪种语言设置为默认显示语言

浏览器默认设定页面的最小字号,用户可以前往 chrome://settings/fonts 根据需求更改

而我们在实际项目中,不能奢求用户更改浏览器设置

对于文本需要以更小的字号来显示,就需要用到一些小技巧

二、解决方案

常见的解决方案有:

Zoom

zoom 的字面意思是“变焦”,可以改变页面上元素的尺寸,属于真实尺寸

其支持的值类型有:

使用 zoom 来”支持“ 12px 以下的字体

代码如下:

<style type="text/css">
    .small-text1 {
        font-size: 12px;
        display: inline-block;
        zoom: 0.8;
    }
    .small-text2 {
        display: inline-block;
        font-size: 12px;
    }
</style>
<body>
    <span class="small-text1">测试10px</span>
    <span class="small-text2">测试12px</span>
</body>

效果如下:

Untitled

需要注意的是,Zoom 并不是标准属性,需要考虑其兼容性

Untitled

优点:

缺点:

webkit-transform: scale()

针对 chrome 浏览器,加 webkit 前缀,用 transform:scale() 这个属性进行放缩

注意的是,使用 scale 属性只对可以定义宽高的元素生效,所以,下面代码中将 span 元素转为行内块元素

实现代码如下:

<style type="text/css">
    .small-text1 {
        font-size: 12px;
        display: inline-block;
        -webkit-transform:scale(0.8);
    }
    .small-text2 {
        display: inline-block;
        font-size: 12px;
    }
</style>
<body>
    <span class="small-text1">测试10px</span>
    <span class="small-text2">测试12px</span>
</body>

效果如下:

Untitled

优点:

缺点: