css

217 阅读13分钟

实现固定宽高比(width: height = 4: 3)的div,怎么设置

  • 将div元素的高度设为了0,通过padding-bottom来撑开盒子的高度,实现了4/3的固定宽高比。
  • padding设置为百分比,是以元素的宽度乘以100%从而得到的padding值的。
  • 只是一个徒有其表的空盒子,里面没有内容。如果想在里面放入内容,我们还需要将div内部的内容使用绝对定位来充满固定尺寸的容器元素。
.body {
  width: 100%;
}
.div {
  width: 100%;
  height: 0;
  padding: 0;
  padding-bottom: 75%;
}

flex容器布局

blog.alanwu.site/2020/03/18/…

主轴属性

  • flex-direction: row | row-reverse | column | column-reverse;起点在左端|右|上|下
  • flex-wrap:nowrap | wrap | wrap-reverse;不换行|第一行在上|第一行在下
  • flex-flow:flex-direction> || flex-wrap>;row nowrap
  • justify-content: flex-start | flex-end | center | space-between | space-around;左对齐|右|居中|两端对齐|间隔相等
  • align-items:flex-start | flex-end | center | baseline | stretch;起点对齐|终点|中点|第一行文字|未设高度占满容器
  • align-content: flex-start | flex-end | center | space-between | space-around | stretch;多根轴线的对齐方式

交叉轴属性

  • order:0 项目的排列顺序。数值越小,排列越靠前,
  • flex-grow:0 项目的放大比例,默认为0
  • flex-shrink:1 项目的缩小比例,默认为1,
  • flex-basis:auto 分配多余空间之前,项目占据的主轴空间
  • flex:flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto
  • align-self:auto|flex-start|flex-end|center|baseline|stretch;单个项目与其他项目不一样对齐方式,覆盖align-items属性

flex:1 flex属性是flex-grow, flex-shrink 和 flex-basis, 默认值为0 1 auto。后两个属性可选, 根据元素自身的 width 或 height 属性来调节元素大小。当还剩余一些空闲空间时,它使 flex 元素呈现的是固定大小的样式;当没有足够的空间时,它允许它收缩到最小。

伪类和伪元素

css引入伪类和伪元素概念是为了格式化文档树以外的信息。伪类和伪元素是用来修饰不在文档树中的部分。

伪类 用于当元素处于某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。比如说,用户悬停在指定的元素时,我们可以通:hover来描述这个元素的状态

伪元素 用于创建不在文档树中的元素,并为其添加样式,比如说,我们可以通过:before来在一个元素前添加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。

display: none和 visibility:hidden的区别

是否占据空间

  • display: none 不占据空间
  • visibility:hidden 占据空间

是否渲染

  • display:none,会触发reflow(回流),进行渲染。
  • visibility:hidden,只会触发repaint(重绘),因为没有发现位置变化,不进行渲染。

是否是继承属性(株连性)

  • display:none,display不是继承属性,元素及其子元素都会消失。
  • visibility:hidden,visibility是继承属性,若子元素使用了visibility:visible,则不继承,这个子孙元素又会显现出来。

em rem vh vw calc(), line-height 百分比

  • px 相对长度单位。像素px是相对于显示器屏幕分辨率而言的
  • em em: 相对单位,参考物是父元素的font-size,具有继承的特点。如果字体大小是16px(浏览器的默认值),那么 1em = 16px
  • rem rem:相对单位,可理解为”root em”, 相对根节点html的字体大小来计算,不会像em那样,依赖于父元素的字体大小,而造成混乱
  • vw 和vh vw:viewpoint width,视窗宽度,1vw等于视窗宽度的1%。 vh:viewpoint height,视窗高度,1vh等于视窗高度的1%。 vmin:取当前vw和Vh中较小的那一个值, vmax:取当前Vw和Vh中较大的那一个值

vw、vh 与 % 百分比的区别: % 是相对于父元素的大小设定的比率,vw、vh 是视窗大小决定的。 vw、vh 优势在于能够直接获取高度,而用 % 在没有设置 body 高度的情况下,是无法正确获得可视区域的高度的,所以这是挺不错的优势。

  • calc() calc(): CSS3中新增的一个函数, 用于动态计算宽/高, 语法非常简单,就像我们小时候学加 (+)、减(-)、乘(*)、除(/)一样,使用数学表达式来表示
  • dpr, dpr是设备像素比,是css里面1px所能显示的像素点的个数,dpr的值越大,显示的越精细;window.devicePixelRatio获取到当前设备的dpr。

清除浮动方法及原理

为什么要清除浮动:父元素因为子级元素浮动引起的内部高度为0的问题。 清除浮动常用的四种方式:

  • 父级div定义height
  • 额外标签法: 在有浮动的父级元素的末尾插入了一个没有内容的块级元素div 并添加样式clear:both。
  • 利用伪元素:父级div定义 伪类:after,我们可以写一个.clearfix 工具样式,当需要清除浮动时,就为其加上这个类 .clearfix:after { display: block; clear :both; content: '';}。
  • 父级添加overflow属性: 包含浮动元素的父标签添加样式overflow为hidden或auto,通过触发BFC方式,实现清除浮动

BFC/IFC

BFC(Block Formatting Context)叫做“块级格式化上下文"

  • (1) 内部的盒子会在垂直方向,一个个地放置;
  • (2) 盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠;
  • (3)每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此;
  • (4)BFC的区域不会与float重叠;
  • (5)BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此;
  • (6)计算BFC的高度时,浮动元素也参与计算。 触发条件
  • 根元素()
  • 浮动元素(元素的 float 不是 none)
  • 绝对定位元素(元素的 position 为 absolute 或 fixed)
  • 行内块元素(元素的 display 为 inline-block)
  • 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
  • 匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table)
  • overflow 值不为 visible 的块元素
  • -弹性元素(display为 flex 或 inline-flex元素的直接子元素)
  • 网格元素(display为 grid 或 inline-grid 元素的直接子元素)

IFC(inline Formatting Context)叫做“行级格式化上下”

  • (1)内部的盒子会在水平方向,一个个地放置;
  • (2)IFC的高度,由里面最高盒子的高度决定;
  • (3)当一行不够放置的时候会自动切换到下一行;

CSS盒模型

W3C 标准盒模型: 属性width,height只包含内容content,不包含border和padding

IE 盒模型: 属性width,height包含border和padding,指的是content+padding+border

content-box(标准盒模型) border-box(IE盒模型)

position CSS的四种定位

Static 这个是元素的默认定位方式,元素出现在正常的文档流中,会占用页面空间。

Relative 相对定位方式,相对于其父级元素(无论父级元素此时为何种定位方式)进行定位,准确地说是相对于其父级元素所剩余的未被占用的空间进行定位(在父元素由多个相对定位的子元素时可以看出),且会占用该元素在文档中初始的页面空间,即在使用top,bottom,left,right进行移动位置之后依旧不会改变其所占用空间的位置。可以使用z-index进行在z轴方向上的移动。

Absolute 绝对定位方式,脱离文档流,不会占用页面空间。以最近的不是static定位的父级元素作为参考进行定位,如果其所有的父级元素都是static定位,那么此元素最终则是以当前窗口作为参考进行定位。可以使用top,bottom,left,right进行位置移动,亦可使用z-index在z轴上面进行移动。当元素为此定位时,如果该元素为内联元素,则会变为块级元素,即可以直接设置其宽和高的值;如果该元素为块级元素,则其宽度会由初始的100%变为auto。 注意:当元素设置为绝对定位时,在没有指定top,bottom,left,right的值时,他们的值并不是0,这几个值是有默认值的,默认值就是该元素设置为绝对定位前所处的正常文档流中的位置。

Fixed 绝对定位方式,直接以浏览器窗口作为参考进行定位。其它特性同absolute定位。当父元素使用了transform的时候,会以父元素定位

sticky 粘性定位元素(stickily positioned element)是计算后位置 粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。 #one { position: sticky; top: 10px; }在 viewport 视口滚动到元素 top 距离小于 10px 之前,元素为相对定位。之后,元素将固定在与顶部距离 10px 的位置,直到 viewport 视口回滚到阈值以下。

子元素的垂直水平居中

  • 行内元素:text-align + line-height
  • 定宽定高:absolute + margin:auto
  • 不定高: transform: translate(-50%,-50%);
  • 不定高:flex+ justify-content: center;align-items: center;
  • display: table;

三栏布局

  • position + margin:父元素相对定位,通过绝对定位将左右两栏固定,通过 margin 设置左右边距,留出内容块
  • 浮动: 左右两栏使用 float 浮动到相应位置, 中间栏通过 margin 属性进行撑开
  • flex布局:display:flex;+ flex:1;
  • gird布局: display: grid; + grid-template-columns: 100px 100px 100px; + grid-template-rows: 100px 100px 100px;

css 三角形

triangle-up { width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid red; }

CSS全局污染

  • scoped 属性
  • css in js
  • CSS Modules CSS Modules 提供各种插件,支持不同的构建工具。本文使用的是 Webpack 的css-loader插件

css modules 的原理生成唯一的类名

左边定宽,右边自适应

  1. 左边设置左浮动,右边宽度设置100%
.left{float:left}
.right{width: 100%}
  1. 父容器设置 display:flex;Right部分设置 flex:1
body{display: flex}
right{flex: 1}
  1. 设置浮动 + 在 css 中使用 calc() 函数
.left{float:left}
.right{float:left;width:cacl(100vw-200px)}
  1. 使用负margin
<div class='container'>
	<div class='right'></div>
</div>
<div class='left'></div>

.container {float:left;width:100%}
.right{margin-left:200px}
.left{float:left; margin-left:-100%}
  1. left absolute
<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>
  
.container {
  position: relative;
}
.left {
  position: absolute;
}
.right {
  width: 100%;
  padding-left: 200px;
  box-sizing: border-box;
}
  1. all absolute
<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>

.container {
  position: relative;
}
.left-item {
  position: absolute;
}
.right-item {
  position: absolute;
  left: 200px;
  right: 0;
}

  1. grid
<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>

.container {
  display: grid;
  grid-template-columns: 10em auto;
}
.left-item {
}
.right-item {
}

# 是否在可视区判断

  • el.offsetTop - document.documentElement.scrollTop < window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight 相对于其 offsetParent(最近的定位元素) 元素的顶部内边距的距离 - 滚动条内的顶部隐藏部分的高度 < 元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距
  • element.getBoundingClientRect().top < window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight 元素的大小及其相对于视口的位置 < 元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距。
  • IntersectionObserver 异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。

在 V8 event-loop 的更新渲染阶段之前,在动画帧回调函数执行之后,被称为Update the rendering,UP 的理解是这个阶段处理 window 中各个容器的渲染更新,因此更适合在此阶段计算相交矩形,同时该阶段触发在异步阶段,执行频率并不高(这也是为什么滚动快的话有些中间的 threshold 触发不到),从而实现不阻塞主线程的同时实现监控目标元素出现的事件。根据 SOF 上一篇优质回答上提到,Intersection Observer 触发频率已经很高了(60fps for most devices, or once every 16.66 miliseconds),这样的频率虽然不如主线程轮询,但对用户来说大部分时候是感知不到的,适合绝大部分的场景需求,但是如果这样的频率还不能满足一些高速 (high-velocity) 的应用场景,那么可以考虑采用以下思路:

  1. 利用 setTimeout 修改 intersection Observer 的 callback
  2. 利用节流和 CSS 中 scrollTop 处理 wheel 事件
  3. 实现自定义的 intersection 检测
var intersectionObserver = new IntersectionObserver(function(entries) {
  // If intersectionRatio is 0, the target is out of view
  // and we do not need to do anything.
  if (entries[0].intersectionRatio <= 0) return;
  console.log('Loaded new items');
});
// start observing
intersectionObserver.observe(document.querySelector('#构造器'));

解决在移动端1px的问题?

在高清屏下,移动端的1px 会很粗。

  • 使用伪元素 缺点:暂用了after 伪元素,可能影响清除浮动。
.setOnePx{
  position: relative;
  &::after{
    position: absolute;
    content: '';
    background-color: #e5e5e5;
    display: block;
    width: 100%;
    height: 1px; /*no*/
    transform: scale(1, 0.5);
    top: 0;
    left: 0;
  }
}
  • 设置viewport的scale值 根据设备像素设置viewport

前端换肤换主题

  1. 利用class 命名空间 最简单的换肤方案
  2. 准备多套CSS主题 传统前端最常用
  3. 利用CSS预处理生成多套主题样式 现代前端最常用
  • 利用Less,stylus 或 sass 的变量代替颜色值
  • 配置多个主题颜色配置
  • 利用webpack等工具输出多套主题样式
  • 页面加载后,根据用户需求加载不同的样式列表(同方案2)
  1. 动态换肤 支持浏览器热换肤,最酷炫
  2. CSS变量换肤 不考虑IE,最佳换肤方式 利用CSS 变量设置颜色
<style>
      :root {
        --theme-color: red /* css 变量赋值位置 */
      }
      .title {
        color: var(--theme-color) /* 用css变量标记颜色 */
      }
    </style>
  1. HTML rel属性的alternate属性值实现。
<link href="reset.css" rel="stylesheet" type="text/css"> // 无论如何都会加载并渲染
                
<link href="default.css" rel="stylesheet" type="text/css" title="默认"> // 默认样式CSS文件加载并渲染
<link href="red.css" rel="alternate stylesheet" type="text/css" title="红色"> // 备选样式CSS文件加载,默认不渲染
<link href="green.css" rel="alternate stylesheet" type="text/css" title="绿色"> // 备选样式CSS文件加载,默认不渲染


document.querySelector('link[href="red.css"]').disabled = false;

判断webp是否可用

  1. 使用 canvas 的 toDataURL 进行判断 在不支持 webp 的浏览器进行toDataURL,得到的图片类型并不是 webp,因此我们可以通过这个进行判断。
var isSupportWebp = function () {
  try {
    return document.createElement('canvas').toDataURL('image/webp', 0.5).indexOf('data:image/webp') === 0;
  } catch(err) {
    return false;
  }
}
  1. 通过加载一张 webp 图片进行判断 加载一张 1x1 的白色的正方形背景图,用来测试浏览器是否支持 webp。

Google官方文档是这样处理的(先加载一个WebP图片,如果能获取到图片的宽度和高度,就说明是支持WebP的,反之则不支持)

function check_webp_feature(feature, callback) {
    var kTestImages = {
        lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
        lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
        alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
        animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
    };
    var img = new Image();
    img.onload = function () {
        var result = (img.width > 0) && (img.height > 0);
        callback(feature, result);
    };
    img.onerror = function () {
        callback(feature, false);
    };
    img.src = "data:image/webp;base64," + kTestImages[feature];
}

z-index 失效

  • 问题标签无position属性(除了static)

  • 问题标签设置了浮动(float)属性(在IE6下,子元素如果设置浮动会影响父元素的相对定位设置,最终造成父元素的z-index属性无效。)

  • 问题标签的父元素的层叠优先级比其他元素低(简单来讲,对于层叠元素的优先级对比都是在兄弟元素之间进行的,子元素的优先级并不会影响到父元素与其他兄弟元素之间的优先级关系。这里所指的层叠元素,是指有进行定位并    且有设置z-index属性的元素。如果没有进行定位和设置z-index的元素,其最终层叠优先级反而由当前元素的层叠子元素决定) 

【解决方法】

  • 给问题标签设置position属性(relative、absolute、fixed)

  • 解决方法有三个,第一种就是去除元素的浮动属性,第二种方法是为浮动元素添加相对定位或者绝对定位,第三种方法就是将父元素的position:relative改为position:absolute。

  • 提高父标签的z-index值

animation、transition、transform的区别

1.transform用于元素旋转、缩放、移动、倾斜等效果

2.transition用于较为单一的动画

3.animation一般用于较为复杂、有中间态的动画

transition是过度属性:强调过度,他的实现需要触发一个事件(比如鼠标移动上去,焦点,点击等)才执行动画。它类似于flash的补间动画,设置一个开始关键帧,一个结束关键帧。

transition语法 transition: property duration timing-function delay; transition默认值:all 0 ease 0 transition 属性是一个简写属性,用于设置四个过渡属性:

animation是动画属性:他的实现不需要触发事件,设定好时间之后可以自己执行,且可以循环一个动画。他也类似于flash的补间动画,但是他可以设置多个关键帧(用@keyframe定义)完成动画。

animation语法 animation: name duration timing-function delay iteration-count direction;

transition需要触发,并且只有开始和结束的关键两祯,animation不需要触发,可以设置好时间自动开始,并可以定义多帧动画

单行文本以省略号结尾

text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;

多行文本以省略号结尾

-webkit-line-clamp用来限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他的WebKit属性。常见结合属性: display: -webkit-box; 必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 。 -webkit-box-orient 必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 。

display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;