编程崽

登录

一叶在编程苦海沉沦的扁舟之上,我是那只激情自射的崽

css常用功能

css常用功能

js 读写 css

获取实时位置信息:getBoundingClientRect() 方法

官方文档

getBoundingClientRect 方法返回元素的大小及其相对于视口的位置,返回的是 DOMRect 对象,此方式获取的元素尺寸和位置信息更方便。

语法:Element.getBoundingClientRect()

js 复制代码
let htmlPositionInfo = document.querySelector('.p').getBoundingClientRect()
console.log(JSON.stringify(htmlPositionInfo))

打印以下对象,能清楚的看到某个元素的尺寸和位置信息:

json 复制代码
{
  "x": 8,
  "y": 92,
  "width": 1973,
  "height": 44,
  "top": 92,
  "right": 1981,
  "bottom": 136,
  "left": 8
}

获取Dom设置的值:CSSStyleDeclaration 对象

官方文档

CSSStyleDeclaration 对象是一个 CSS 声明块,CSS 属性键值对的集合,它暴露了样式信息和各种与样式相关的方法和属性。

CSSStyleDeclaration 对象中的 css 规则的键名是驼峰命名的写法。

以下三种方式,拿去到的都是 CSSStyleDeclaration 对象:

  • Element.style:只能读取到该 dom 节点的的行内样式声明的属性,可读可写,但写完后,也是写在了行内的样式中。
  • getComputedStyle(Element):获取该 dom 节点的所有 css 样式属性计算后生成的 CSSStyleDeclaration,但是一个只读的对象。
  • CSSStyleSheet API:不常用,比如,document.styleSheets[0].cssRules[0].style 会返回文档中第一个样式表中的第一条 CSS 规则

所以一般情况:

  • 需要写时,使用第一种方法(HTMLElement.style),只有这个才有写的功能。

  • 需要读时:使用上面第二种中方法(getComputedStyle(Element))获取,可以读取到该 Dom 的全部的 css 样式值。

使用css变量功能

css的变量功能,主流浏览器均已经支持。

直接使用

下面这段代码的功能,能够实现和scss变量类似的功能。

而且,使用js是可以读取和设置css变量的。

css 复制代码

/* 页面默认引入的css文件中设置 */
:root {
  --boxWidth: 1200px;
}
div {
  --backgroundRed: red;
}

@media screen and (max-width: 1400px) {
  :root {
    --boxWidth: 1000px;
  }
}

/* 任意某个css文件中使用 */
div.box {
  width: var(--boxWidth, 20px); /* 第二个参数选填,为缺省值 */
  background: var(--backgroundRed);
}

使用 CSSStyleDeclaration 交互

css 中:

css 复制代码
:root {
  --color: red;
}

js 中:

js 复制代码
// 【读】
// 首先获取 html 这个 dom 的可读完整 css 属性的 CSSStyleDeclaration
let htmlComputedStyleRead = getComputedStyle(document.querySelector('html'))
// 获取变量值
let varColor = htmlComputedStyleRead.getPropertyValue('--color').trim() // 获取后会有空格(写css时冒号后的空格)
console.log(varColor) // red

// 【写】
// 首先获取 html 这个 dom 的可写完整 css 属性的 CSSStyleDeclaration
let htmlComputedStyleWrite = document.querySelector('html').style
htmlComputedStyleWrite.setProperty('--color', 'rgb(0, 255, 255)') // 设置
let newColor = htmlComputedStyleWrite.getPropertyValue('--color') // 由于本来就是设置在了行内,所以可以直接用它来获取即可
console.log(newColor) // rgb(0, 255, 255)

css\less\scss的样式穿透写法

使用vue或react时,大多都会使用 scope来限制样式的生效范围,保证不影响全局或子组件的样式,但有时偏偏就需要样式穿透,修改子组件的样式。

而使用 css\less\scss 时,样式穿透的写法是不同的:

  • 使用css:没有使用css预处理器,可以使用 >>>,/deep/,::v-deep 来样式穿透。
  • 使用less或者node-sass:使用/deep/,::v-deep都可以。
  • 使用dart-sass:使用::v-deep来样式穿透。

贝塞尔曲线生成

贝斯尔曲线是使用 js 或 css 制作动画时,很有用的一个工具,但它的使用还是有一定门槛的,看不懂公式和配置。

下面这个网站,可以所见即所得的,拖拽小球配置曲线,然后自动生成贝斯而曲线的配置,复制使用,很有用的工具:https://cubic-bezier.com/

Snipaste_2021-02-24_10-08-53.png

以下是贝塞尔曲线的js实现,把上面网站的参数传入此函数,即可得到一个方法,一个传入进程值就能得到位置的方法

js 复制代码
// 贝塞尔曲线实现
export function cubicBezier(p1x, p1y, p2x, p2y) {
  const ZERO_LIMIT = 1e-6;

  const ax = 3 * p1x - 3 * p2x + 1;
  const bx = 3 * p2x - 6 * p1x;
  const cx = 3 * p1x;

  const ay = 3 * p1y - 3 * p2y + 1;
  const by = 3 * p2y - 6 * p1y;
  const cy = 3 * p1y;

  function sampleCurverDerivativeX(t) {
    return (3 * ax * t + 2 * bx) * t + cx;
  }

  function sampleCurveX(t) {
    return ((ax * t + bx) * t + cx) * t;
  }

  function sampleCurveY(t) {
    return ((ay * t + by) * t + cy) * t;
  }

  function solveCurveX(x) {
    var t2 = x;
    var derivative;
    var x2;

    //https://trac.webkit.org/browser/trunk/Source/WebCore/platform/animation
    //First try a few iterations of Newton's method -- normally very fast
    // http://en.wikipedia.org/wiki/Newton's_method
    for (let i = 0; i < 8; i++) {
      // f(t) - x = 0
      x2 = sampleCurveX(t2) - x;
      if (Math.abs(x2) < ZERO_LIMIT) {
        return t2;
      }
      derivative = sampleCurverDerivativeX(t2);
      // == 0, failure
      if (Math.abs(derivative) < ZERO_LIMIT) {
        break;
      }
      t2 -= x2 / derivative;
    }
    //Fall back to the bisection method for reliability
    //bisection
    //http://en.wikipedia.org/wiki/Wifi/bisection_method
    var t1 = 1;
    var t0 = 0;
    t2 = x;
    while (t1 > t0) {
      x2 = sampleCurveX(t2) - x;
      if (Math.abs(x2) < ZERO_LIMIT) {
        return t2;
      }
      if (x2 > 0) {
        t1 = t2;
      } else {
        t0 = t2;
      }
      t2 = (t1 + t0) / 2;
    }

    // Failure
    return t2;
  }

  function solve(x) {
    return sampleCurveY(solveCurveX(x));
  }

  return solve;
}

使用实例

js 复制代码
// 几种常见动画的方程
export const ease = cubicBezier(0.25, 0.1, 0.25, 1);
export const easeIn = cubicBezier(0.42, 0, 1, 1);
export const easeOut = cubicBezier(0, 0, 0.58, 1);
export const easeInOut = cubicBezier(0.42, 0, 0.58, 1);

设置滚动条样式

scss 复制代码
/* 滚动条整体部分,其中的属性有width,height,background,border等(就和一个块级元素一样 */
div {
  &::-webkit-scrollbar {
    width: 4px;
    height: 4px;
    background: transparent;
    /* background: #202535; */
    /* box-shadow: inset 0 1px 3px 0 rgba(0,0,0,0.50); */
  }
  /*定义滚动条*/
  &::-webkit-scrollbar-thumb {
    height: 4px;
    border-radius: 4px;
    background: rgba(255,255,255,0.3);
    /* box-shadow: inset 0 1px 3px 0 rgba(6,9,16,0.20); */
  }
  /* 两头的按钮 */
  &::-webkit-scrollbar-button {
    display: none;
    background: transparent;
    background-color: transparent;
  }
}

reset.css 去除浏览器默认样式

css 复制代码
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var,
b, i,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
  margin:0;
  padding:0;
  border:0;
  outline:0;
  font-size:100%;
  vertical-align:baseline;
  background:transparent;
}

html, body, * {
  line-height: 1.2em;
  margin: 0;
  padding: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  outline: none;
}

article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary {
  display:block;
}

ul, li {
  list-style:none;
}

blockquote, q {
  quotes:none;
}

blockquote:before, blockquote:after,q:before, q:after {
  content:'';
  content:none;
}

a {
  margin:0;
  padding:0;
  border:0;
  font-size:100%;
  vertical-align:baseline;
  background:transparent;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}
a:hover {
  color: inherit;
}

ins {
  background-color:#ff9;
  color:#000;
  text-decoration:none;
}

mark {
  background-color:#ff9;
  color:#000;
  font-style:italic;
  font-weight:bold;
}

del {
  text-decoration: line-through;
}

abbr[title], dfn[title] {
  border-bottom:1px dotted #000;
  cursor:help;
}

table {
  border-collapse:collapse;
  border-spacing:0;
}

hr {
  display:block;
  height:1px;
  border:0;
  border-top:1px solid #cccccc;
  margin:0;
  padding:0;
}

input, select {
  vertical-align:middle;
}
button {
  outline: none;
  border: 0;
  background-color: none;
  background: none;
  cursor: pointer;
}