伪类:
条件伪类
:lang():基于元素语言来匹配页面元素;:dir():匹配特定文字书写方向的元素;:has():匹配包含指定元素的元素;:is():匹配指定选择器列表里的元素;:not():用来匹配不符合一组选择器的元素;
行为伪类
:active:鼠标激活的元素;:hover: 鼠标悬浮的元素;::selection:鼠标选中的元素
状态伪类
:target:当前锚点的元素;:link:未访问的链接元素;:visited:已访问的链接元素;:focus:输入聚焦的表单元素;:required:输入必填的表单元素;:valid:输入合法的表单元素;:invalid:输入非法的表单元素;:in-range:输入范围以内的表单元素;:out-of-range:输入范围以外的表单元素;:checked:选项选中的表单元素;:optional:选项可选的表单元素;:enabled:事件启用的表单元素;:disabled:事件禁用的表单元素;:read-only:只读的表单元素;:read-write:可读可写的表单元素;:blank:输入为空的表单元素;:current():浏览中的元素;:past():已浏览的元素;:future():未浏览的元素;
结构伪类
:root:文档的根元素;:empty:无子元素的元素;:first-letter:元素的首字母;:first-line:元素的首行;:nth-child(n):元素中指定顺序索引的元素;:nth-last-child(n):元素中指定逆序索引的元素;;:first-child:元素中为首的元素;:last-child:元素中为尾的元素;:only-child:父元素仅有该元素的元素;:nth-of-type(n):标签中指定顺序索引的标签;:nth-last-of-type(n):标签中指定逆序索引的标签;:first-of-type:标签中为首的标签;:last-of-type:标签中为尾标签;:only-of-type:父元素仅有该标签的标签;
伪元素
::before:在元素前插入内容;::after:在元素后插入内容
格式化上下文
-
BFC (Block Formatting Context) 块级格式化上下文;
-
IFC (Inline Formatting Context) 行内格式化上下文;
-
FFC (Flex Formatting Context) 弹性格式化上下文;
-
GFC (Grid Formatting Context) 格栅格式化上下文
注:其中 BFC 和 IFC 在 CSS 中扮演着非常重要的角色,因为它们直接影响了网页布局,所以需要深入理解其原理。
BFC 渲染规则
- 内部的盒子会在垂直方向,一个接一个地放置;
- 盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠;
- 每个元素的 margin 的左边,与包含块 border 的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此;
- BFC 的区域不会与 float 盒子重叠;
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算 BFC 的高度时,浮动元素也参与计算。
如何创建 BFC?
- 根元素:html
- 非溢出的可见元素:overflow 不为 visible
- 设置浮动:float 属性不为 none
- 设置定位:position 为 absolute 或 fixed
- 定义成块级的非块级元素:display: inline-block/table-cell/table-caption/flex/inline-flex/grid/inline-grid
BFC 应用场景
1、 自适应两栏布局 :BFC 的区域不会和浮动区域重叠,所以就可以把侧边栏固定宽度且左浮动,而对右侧内容触发 BFC,使得它的宽度自适应该行剩余宽度。
2、清除内部浮动 浮动造成的问题就是父元素高度坍塌,所以清除浮动需要解决的问题就是让父元素的高度恢复正常。而用 BFC 清除浮动的原理就是:计算 BFC 的高度时,浮动元素也参与计算。只要触发父元素的 BFC 即可。
3、 防止垂直 margin 合并 BFC 渲染原理之一:同一个 BFC 下的垂直 margin 会发生合并。所以如果让 2 个元素不在同一个 BFC 中即可阻止垂直 margin 合并。那如何让 2 个相邻的兄弟元素不在同一个 BFC 中呢?可以给其中一个元素外面包裹一层,然后触发其包裹层的 BFC,这样一来 2 个元素就不会在同一个 BFC 中了。
IFC
IFC 的形成条件非常简单,块级元素中仅包含内联级别元素,需要注意的是当IFC中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个 IFC。
IFC 渲染规则 行内元素默认就是IFC
- 子元素在水平方向上一个接一个排列,在垂直方向上将以容器顶部开始向下排列;
- 节点无法声明宽高,其中 margin 和 padding 在水平方向有效在垂直方向无效;
- 节点在垂直方向上以不同形式对齐;
- 能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的线盒(line box)。线盒的宽度是由包含块(containing box)和与其中的浮动来决定;
- IFC 中的 line box 一般左右边贴紧其包含块,但 float 元素会优先排列。
- IFC 中的 line box 高度由 line-height 计算规则来确定,同个 IFC 下的多个 line box 高度可能会不同;
- 当内联级盒子的总宽度少于包含它们的 line box 时,其水平渲染规则由 text-align 属性值来决定;
- 当一个内联盒子超过父元素的宽度时,它会被分割成多盒子,这些盒子分布在多个 line box 中。如果子元素未设置强制换行的情况下,inline box 将不可被分割,将会溢出父元素
IFC 应用场景
- 水平居中:当一个块要在环境中水平居中时,设置其为 inline-block 则会在外层产生 IFC,通过 text-align 则可以使其水平居中。
- 垂直居中:创建一个 IFC,用其中一个元素撑开父元素的高度,然后设置其 vertical-align: middle,其他行内元素则可以在此父元素下垂直居中。
层叠上下文
层叠顺序
在同一个层叠上下文中如果有多个元素,那么他们之间的层叠顺序是怎么样的呢?
值和单位
px
设备像素(Device pixels)
设备屏幕的物理像素,表示的是屏幕的横纵有多少像素点;和屏幕分辨率是差不多的意思。
设备像素比(DPR)!!!
设备像素比表示 1 个 CSS 像素等于几个物理像素。
计算公式:DPR = 物理像素数 / 逻辑像素数;
在浏览器中可以通过 window.devicePixelRatio 来获取当前屏幕的 DPR。
像素密度(DPI/PPI)
像素密度也叫显示密度或者屏幕密度,缩写为 DPI(Dots Per Inch) 或者 PPI(Pixel Per Inch)。从技术角度说,PPI 只存在于计算机显示领域,而 DPI 只出现于打印或印刷领域。
计算公式:像素密度 = 屏幕对角线的像素尺寸 / 物理尺寸
比如,对于分辨率为 750 * 1334 的 iPhone 6 来说,它的像素密度为:
Math.sqrt(750 * 750 + 1334 * 1334) / 4.7 = 326ppi
复制代码
设备独立像素(DIP)
DIP 是特别针对 Android设备而衍生出来的,原因是安卓屏幕的尺寸繁多,因此为了显示能尽量和设备无关,而提出的这个概念。它是基于屏幕密度而计算的,认为当屏幕密度是 160 的时候,px = DIP。
计算公式:dip = px * 160 / dpi
rem 计算
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
psdWidth = 750, // 设计图宽度
recalc = function () {
var clientWidth = docEl.clientWidth;
if ( !clientWidth ) return;
if ( clientWidth >= 640 ) {
docEl.style.fontSize = 200 * ( 640 / psdWidth ) + 'px';
} else {
docEl.style.fontSize = 200 * ( clientWidth / psdWidth ) + 'px';
}
};
if ( !doc.addEventListener ) return;
// 绑定事件的时候最好配合防抖函数
win.addEventListener( resizeEvt, debounce(recalc, 1000), false );
doc.addEventListener( 'DOMContentLoaded', recalc, false );
function debounce(func, wait) {
var timeout;
return function () {
var context = this;
var args = arguments;
clearTimeout(timeout)
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
})(document, window);
颜色关键字
transparent 关键字
transparent 关键字表示一个完全透明的颜色,即该颜色看上去将是背景色。从技术上说,它是带有 alpha 通道为最小值的黑色,是 rgba(0,0,0,0) 的简写。 轻松实现三角形
用 transparent 实现三角形的原理:
- 首先宽高必须是 0px,通过边框的粗细来填充内容;
- 那条边需要就要加上颜色,而不需要的边则用 transparent;
- 想要什么样姿势的三角形,完全由上下左右 4 条边的中有颜色的边和透明的边的位置决定;
- 等腰三角形:设置一条边有颜色,然后紧挨着的 2 边是透明,且宽度是有颜色边的一半;直角三角形:设置一条边有颜色,然后紧挨着的任何一边透明即可。
增大点击区域
常常在移动端的时候点击的按钮的区域特别小,但是由于现实效果又不太好把它做大,所以常用的一个手段就是通过透明的边框来增大按钮的点击区域:
.btn {
border: 5px solid transparent;
}
媒体查询
媒体查询是指针对不同的设备、特定的设备特征或者参数进行定制化的修改网站的样式。
你可以通过给 <link> 加上 media 属性来指定该样式文件只能对什么设备生效,不指定的话默认是 all,即对所有设备都生效:
<link rel="stylesheet" src="styles.css" media="screen" />
<link rel="stylesheet" src="styles.css" media="print" />
复制代码
都支持哪些设备类型?
- all:适用于所有设备;
- print:适用于在打印预览模式下在屏幕上查看的分页材料和文档;
- screen:主要用于屏幕;
- speech:主要用于语音合成器。
媒体查询支持逻辑操作符:
- and:查询条件都满足的时候才生效;
- not:查询条件取反;
- only:整个查询匹配的时候才生效,常用语兼容旧浏览器,使用时候必须指定媒体类型;
- 逗号或者 or:查询条件满足一项即可匹配;
/* 用户设备的最小高度为680px或为纵向模式的屏幕设备 */
@media (min-height: 680px), screen and (orientation: portrait) {}
复制代码
1px 边框解决方案
Retina 显示屏比普通的屏幕有着更高的分辨率,所以在移动端的 1px 边框就会看起来比较粗,为了美观通常需要把这个线条细化处理。这里有篇文章列举了 7 中方案可以参考一下:7种方法解决移动端Retina屏幕1px边框问题
而这里附上最后一种通过伪类和 transform 实现的相对完美的解决方案:
只设置单条底部边框:
.scale-1px-bottom {
position: relative;
border:none;
}
.scale-1px-bottom::after {
content: '';
position: absolute;
left: 0;
bottom: 0;
background: #000;
width: 100%;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
同时设置 4 条边框:
.scale-1px {
position: relative;
margin-bottom: 20px;
border:none;
}
.scale-1px::after {
content: '';
position: absolute;
top: 0;
left: 0;
border: 1px solid #000;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: left top;
transform-origin: left top;
}
消除浏览器默认样式
reset.css
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
水平垂直剧中
不固定宽高的块级盒子
方法一:absolute + transform
方法二:line-height + vertical-align
方法三:writing-mode
方法四:table-cell
方法五:flex
方法六:grid
DPR
在 iphone 没有搞事之前,物理像素和逻辑像素是相等的,但如今高清屏已经快成标配,可显示的像素点越多越清晰,导致设备上每英寸可显示的像素点(PPI)越来越多,这样一来,屏幕的大小没变,css的逻辑像素没变,可物理像素却变多了,一个逻辑像素要对于多个物理像素,这两者的比例就是 DPR
DPR = 物理像素/css逻辑像素
可通过 window.devicePixelRatio 获取设备的 DPR
link 和 @import 的区别
-
从属关系区别
link:是 html 提供的标签,不仅可以加载css样式表,还可以定义 RSS、rel 连接属性等。
@import:是 css 提供的语法规则,用于导入样式表。
-
加载顺序区别
link:文件是同时加载。
@import 引入的 CSS 将在页面加载完毕后被加载。
-
兼容性问题
link 不存在兼容性问题;@import 可能会有兼容性问题
Sass、Less、Stylus区别
CSS预处理器是一种语言用来为CSS增加一些编程的特性,无需考虑浏览器兼容问题,例如你可以在CSS中使用变量,简单的程序逻辑、函数等在编程语言中的一些基本技巧,可以让CSS更加简洁,适应性更强,代码更直观等诸多好处
区别:
1.扩展名,- - Sass是以.sass为扩展名,Less是以.less为扩展名,Stylus是以.styl为扩展名
2.变量,
-
Sass 变量必须是以$开头的,然后变量和值之间使用冒号(:)隔开,和css属性是一样的。
-
Less 变量是以@开头的,其余sass都是一样的。
-
Stylus 对变量是没有任何设定的,可以是以$开头或者任意字符,而且变量之间可以冒号,空格隔开,但是在stylus中不能用@开头
注: 三种预处理器都有:嵌套、运算符、颜色函数、导入、继承、混入。Stylus还有一些高级特性。例如循环、判断等。
flex
1.flex-direction
属性决定主轴的方向 (即项目的排列方式)
- row 主轴水平方向,起点在左端
- row-reverse 主轴水平方向,起点在末端
- column 主轴垂直方向,起点在上沿
- colunm-reverse 主轴垂直方向,起点在下沿
2.flex-wrap
- nowrap 默认,不换行
- wrap 换行,第一行在上面
- wrap-reverse 换行,第一行在下面
3.flex-flow
是flex-direction 属性和flex-wrap属性的简写,默认值row、nowrap
4.justify-content
属性定义了项目在主轴上的对齐方式
- flex-start 默认值,左对齐
- flex-end 右对齐
- center 居中
- space-between 两端对齐,项目之间间隔相等
- space-around 两端间隔是中间项目的一半
- space-evenly 项目之间间隔均分(包括与两端的间隔)
-
5.align-items
定义项目交叉轴上如何对齐(单行)
- flex-start 交叉轴起点对齐
- flex-end 交叉轴终点对齐
- center 垂直方向,居中对齐
- baseline 项目第一行文字基线对齐
- stretch 默认值,如果项目未设置高度或设为auto,将占满整个容器的高度
6.align-content
多行轴线对齐,用法同align-items
1.order
定义项目排列顺序,数值越小越靠前,默认为0
2.flex-grow
定义项目放大比例,默认为0
3.flex-shrink
定义项目缩小比例,默认为1,如果空间不足则会缩小,值为0不能缩小
4.flex-basis
定义项目自身大小,默认auto
5.flex
属性是flex-grow,flex-shrink ,flex-basis的简写,默认值为0、1、auto
6.align-self
项目自身对齐
CSS优化、提高性能的方法
- 避免过度约束
- 避免后代选择符
- 避免链式选择符
- 使用紧凑的语法
- 避免不必要的命名空间
- 避免不必要的重复
- 最好使用表示语义的名字。一个好的类名应该是描述他是什么而不是像什么
- 避免!important,可以选择其他选择器
- 尽可能的精简规则,你可以合并不同类里的重复规则
- 修复解析错误
- 避免使用多类选择符
- 移除空的css规则
- 正确使用display的属性:由于display的作用,某些样式组合会无效,徒增样式体积的同时也影响解析性能。
- display:inline后不应该再使用width、height、margin、padding以及float。
- display:inline-block后不应该再使用float。
- display:block后不应该再使用vertical-align。
- display:table-*后不应该再使用margin或者float。
- 不滥用浮动:虽然浮动不可避免,但不可否认很多css bug是由于浮动而引起。
- 不滥用web字体
- 对于中文网站来说Web Fonts可能很陌生,国外却很流行。web fonts通常体积庞大,而且一些浏览器在下载web fonts时会阻塞页面渲染损伤性能。
- 不声明过多的font-size:这是设计层面的问题,设计精良的页面不会有过多的font-size声明。
- 不在选择符中使用ID标识符,主要考虑到样式重用性以及与页面的耦合性。
- 不给h1~h6元素定义过多的样式
- 全站统一定义一遍heading元素即可,若需额外定制样式,可使用其他选择符作为代替。
- 不重复定义h1~h6元素
- 值为0时不需要任何单位
- 标准化各种浏览器前缀:通常将浏览器前缀置于前面,将标准样式属性置于最后
- 使用CSS渐变等高级特性,需指定所有浏览器的前缀
- 避免让选择符看起来像正则表达式
- CSS3添加了一些类似~=等复杂属性,也不是所有浏览器都支持,需谨慎使用。
- 遵守盒模型规则(Beware of broken box models)
响应式和自适应的区别
自适应布局主要是通过检测视口分辨率,来判断当前访问的设备从而进一步请求服务层,返回不同的目标页面;
响应式布局通过检测视口分辨率,针对不同客户端在客户端做代码处理。
-
自适应布局需要做多套页面,响应式布局只需要做一个页面就可以。
-
自适应布局如果屏幕太小就会导致内容拥挤不美观,响应式布局没有这个问题。
自适应布局是指通过JS及CSS的控制,借助rem、百分比等相对度量单位,在不同大小的设备上呈现相同的网页。
响应式布局是指据屏幕的大小自动的调整页面的展现方式,可以实现用一个网页自动适应不同大小的屏幕。
content属性的特点
我们使用 content生成的文本是无法选中、无法复制的,好像设置了user-select:none声明一般,而普通元素的文本可以被轻松选中。content生成的文本无法被屏幕阅读设备读取,也无法被搜索引擎抓取,因此,千万不要自以为是地把重要的文本信息使用 content属性生成, 因为这对可访问性和SEO都不友好,content属性只能用来生成一些无关紧要的内容,如装饰性图形或者序号之类;同样,也不要担心原本重要的文字信息会被 content替换,替换的仅仅是视觉层。
content 动态生成值无法获取。content是一个非常强大的CSS属性