CSS基础以及布局适配

205 阅读18分钟

样式

min-width/max-width 和 min-height/max-height 属性间的覆盖规则?

  1. max-width 会覆盖 width,即使 width 是行内样式或者设置了 !important。
  2. min-width 会覆盖 max-width,此规则发生在 min-width 和 max-width 冲突的时候;

继承

CSS 为控制继承提供了四个特殊的通用属性值:inherit(继承父元素),initial(默认样式),unset(自然直),revert(有兼容性,Chorme已经无效了)

<div class="father">
father
  <div class="son1">son1</div>
  <div class="son2">son2</div>
  <div class="son3">son3</div>
  <div class="son4">son4</div>
</div>
.father {
  font-size: 12px;
  color: red;
}
.son1 {
  /* 继承父类 */
  color: inherit;  
}
.son2 {
  /* 默认样式 */
  color: initial;
}
.son3 {
  /* 自然属性,color具有继承性 */
  color: unset;
}
.son4 {
  color: reset;
}

CSS选择器

  • !important
  • 内联样式,style=""
  • ID选择器,#app
  • 类选择器 . box,伪类选择器:hover,属性选择器E[attr$="container"]
  • 标签选择器 div ,伪元素选择器 ::before
  • 通配符*,子选择器>,相邻元素选择器+
  • 继承的样式,没有权值

浏览器从右向左解析匹配,避免回溯消耗资源。若从右向左匹配,先找到所有的最右节点,对于每一个节点,向上寻找其父节点直到找到根元素或满足条件的匹配规则,则结束这个分支的遍历。两种匹配规则的性能差别很大,是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点),而从左向右的匹配规则的性能都浪费在了失败的查找上面。而在 CSS解析完毕后,需要将解析的结果与DOM Tree的内容-起进行分析建立-棵Render Tree,最终用来进行绘图。在建立Render Tree时(WebKit 中的「Attachment」过程), 浏览器就要为每个DOM Tree中的元素根据CSS的解析结果(Style Rules)来确定生成怎样的Render Tree。

伪类和伪元素的区别

  • 表示⽅法
    • CSS2 中伪类、伪元素都是以单冒号:表示,
    • CSS2.1 后规定伪类⽤单冒号表示,伪元素⽤双冒号::表示,
    • 浏览器同样接受 CSS2 时代已经存在的伪元素(:before, :after, :first�line, :first-letter 等)的单冒号写法。
    • CSS2 之后所有新增的伪元素(如::selection),应该采⽤双冒号的写法。
    • CSS3中,伪类与伪元素在语法上也有所区别,伪元素修改为以::开头。浏览器对以:开头的伪元素也继续⽀持,但建议规范书写为::开头
  • 定义不同
    • 伪类即假的类,可以添加类来达到效果
    • 伪元素即假元素,需要通过添加元素才能达到效果
  • 总结:
    • 伪类和伪元素都是⽤来表示⽂档树以外的"元素"。
    • 伪类和伪元素分别⽤单冒号:和双冒号::来表示。
    • 伪类和伪元素的区别,关键点在于如果没有伪元素(或伪类),
    • 是否需要添加元素才能达到效果,如果是则是伪元素,反之则是伪类
    • 伪类和伪元素都不出现在源⽂件和DOM树中。也就是说在html源⽂件中是看不到伪类和伪元素的。
    • 伪类其实就是基于普通DOM元素⽽产⽣的不同状态,他是DOM元素的某⼀特征。
    • 伪元素能够创建在DOM树中不存在的抽象对象,⽽且这些抽象对象是能够访问到的。

盒子

块级盒子block

  1. 独占一行
  2. 可设置width, height, padding, margin, border

行内元素

  1. 不独占一行
  2. 设置width, height无效,垂直padding, margin, border设置不会推开其他行内元素,水平方向会推开

行内块元素

  1. 设置width 和height 属性会生效。
  2. padding, margin, 以及border 会推开其他元素。
  3. 不会跳转到新行,如果显式添加width 和height 属性,它只会变得比其内容更大。

盒子模型

通过box-sizing切换标准盒和怪异盒

标准盒: width = 内容区,盒宽=width + padding + border

怪异盒: width = 内容区 + padding + border

背景

  • 背景颜色background-color
  • 背景图片background-image :url()
  • 背景平铺 background-repeat:repeat | no-repeat | repeat-x | repeat-y
  • 背景图片位置background-position: x y; 可以使用 方位名词 或者 精确单位
  • 背景图像固定background-attachment : scroll | fixed
  • 背景色半透明background: rgba(0, 0, 0, 0.3);
  • 复合写法background: transparent url(image.jpg) repeat-y fixed top ;

定位

position: static | relative | fixed | absolute | sticky
left/top/right/bottom

static:默认

relative:相对自己原本的位置移动

fixed:相对于视口(viewport,浏览器窗口)进行偏移,即定位基点是浏览器窗口

absolute:相对于第一个有定位的祖先元素的位置(子绝父相)

sticky:定位的元素表现得像相对定位一样,直到它滚动到某个阈值点为止,此后它就变得固定了。以浏览器的可视窗口为参照点移动元素,粘性定位占有原先的位置

fixed/absolute会脱离文档流,z-index可以设置堆叠的顺序。

浮动

  1. 浮动特性
  • 浮动元素会脱离标准流(脱标),盒子不再保留原先的位置,后面不浮动的盒子会挤上来
  • 浮动的元素会一行内显示并且元素顶部对齐,没有缝隙,父元素宽度不够会另起一行,一行的最高高度由最高的盒子决定
  • 浮动的元素会具有行内块元素的特性。不给宽度,大小由内容决定
  1. 使用方式----搭配标准流的父盒子,内部浮动排列
  2. 清除浮动 -----父元素不方便给高度,但浮动盒子不占高度,因此父元素高度为0,影响后面的标准流布局(高度塌陷) ,解决方式--闭合浮动

清除浮动后,父级就会根据浮动的子盒子自动监测设置高度

清除浮动方式:

  1. 额外标签:浮动末尾添加空标签,
<div style=”clear:both”></div>
// 缺点:添加无意义标签,结构化较差
  1. 父级添加overflow:hidden/auto/scroll不为visiable就行(缺点:无法显示溢出的部分)
  2. 伪元素法
.clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix { 
 /* IE6、7 专有 */
  *zoom: 1;
} // 需要照顾低版本浏览器
  1. 双伪元素: 给before和after都清除浮动
  2. 定位特殊特性&浮动**
  • 行内元素添加绝对或固定定位,可以直接设置高度和宽度
  • 块级元素添加绝对或固定定位,如果不给宽度或高度,默认大小是内容的大小
  • 脱标的盒子不会触发外边距塌陷,但会父级高度塌陷
  • 浮动元素只会压住它下面标准流的盒子,但是不会压住下面标准流盒子里面的文字(图片)。但绝对定位(固定定位) 会压住下面标准流所有的内容。

布局

流式布局

  • 正常布局流是一套在浏览器视口内放置、组织元素的系统。默认的,块级元素按照基于其父元素的书写顺序(默认值: horizontal-tb)的块流动方向(block flow direction) 放置 --- 每个块级元素会在上一个元素下面另起一行,它们会被设置好的margin 分隔。
  • 内联元素的表现有所不同 --- 它们不会另起一行;只要在其父级块级元素的宽度内有足够的空间,它们与其他内联元素、相邻的文本内容(或者被包裹的)被安排在同一行。如果空间不够,溢出的文本或元素将移到新的一行。
  • 如果两个相邻的元素都设置了margin 并且两个margin有重叠,那么更大的设置会被保留,小的则会消失 --- 这被称为外边距叠加

flex布局

  • flex 是 flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 flex 布局。
  • 当我们为父盒子设为 flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。
  • 给父盒子添加flex属性,来控制子盒子的位置和排列方式
  • 对PC兼容性较差

父项常见属性

  • flex-direction:设置主轴的方向,默认水平从左至右

row | column | row-reverse | column-reverse

  • justify-content:设置主轴上的子元素排列方式

flex-start | flex-end | center | space-around | space-between

  • flex-wrap:设置子元素是否换行,默认不换行

no-wrap | wrap

  • align-content:设置侧轴上的子元素的排列方式(多行)

flex-start | flex-end | center | stretch | space-around | space-between

  • align-items:设置侧轴上的子元素排列方式(单行)

flex-start | flex-end | center | stretch

  • flex-flow:复合属性,相当于同时设置了 flex-direction 和 flex-wrap

子项常见属性

  • flex:flex-grow flex-shrink flex-basis 无单位比例 溢出量 最小值
  • align-self控制子项自己在侧轴的排列方式
  • order属性定义子项的排列顺序(前后顺序)

rem布局

rem相对于根元素的字体大小,假设设计稿为750px,根元素字体大小为50px,则1rem = 50px

媒体查询

使用 @media查询,可以针对不同的媒体类型/屏幕尺寸定义不同的样式,在重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面

@media mediatype and|not|only (media feature) {
    CSS-Code;
}
  • @media
  • mediatype 媒体类型 all | print | screen
  • 关键字 and | not | only 连接逻辑语句
  • media feature 媒体特性必须有小括号包含 (width | min-width | max-width)
@number: 15;
@media screen and (min-width:320px){
    html {
        font-size: (320px / @number);
    }
}

只对需要等比缩放的元素进行 rem 换算,对于不需要缩放的元素,比如边框阴影,使用 px 等其他单位。

BFC

BFC: 块级格式化上下文
BFC基本概念:BFC是CSS布局的一个概念,是一块独立的渲染区域,是一个环境,里面的元素不会影响到外部的元素

BFC原理(渲染规则|布局规则):

(1)内部的Box会在垂直方向,从顶部开始一个接着一个地放置;
(2)Box垂直方向的距离由margin(外边距)决定,属于同一个BFC的两个相邻Box的margin会发生重叠;
(3)每个元素的margin Box的左边, 与包含块border Box的左边相接触,(对于从左到右的格式化,否则相反)。即使存在浮动也是如此;
(4)BFC 在页面上是一个隔离的独立容器,外面的元素不会影响里面的元素,反之亦然。文字环绕效果,设置float;
(5)BFC 的区域不会与float Box重叠(清浮动);
(6)计算BFC的高度时,浮动元素也参与计算。

CSS在什么情况下会创建出BFC(即脱离文档流)

0、根元素,即 HTML 元素(最大的一个BFC)
1、浮动(float 的值不为 none)
2、绝对定位元素(position 的值为 absolute 或 fixed)
3、行内块(display 为 inline-block)
4、表格单元(display 为 table、table-cell、table-caption、inline-block 等 HTML 表格相关的属性)
5、弹性盒(display 为 flex 或 inline-flex)
6、默认值。内容不会被修剪,会呈现在元素框之外(overflow 不为 visible)

BFC作用(使用场景)

1、自适应两(三)栏布局(避免多列布局由于宽度计算四舍五入而自动换行)
2、避免元素被浮动元素覆盖
3、可以让父元素的高度包含子浮动元素,清除内部浮动(原理:触发父div的BFC属性,使下面的子div都处在父div的同一个BFC区域之内)
4、去除边距重叠现象,分属于不同的BFC时,可以阻止margin重叠

盒子塌陷

当父元素没设置足够大小的时候,而子元素设置了浮动的属性,子元素就会跳出父元素的边界(脱离文档流),尤其是当父元素的高度为auto时,而父元素中又没有其它非浮动的可见元素时,父盒子的高度就会直接塌陷为零, 我们称这是CSS高度塌陷

(1)给每个盒子设定固定的width和height,简单方便,兼容性好,适合只改动少量内容不涉及盒子排布的版面。缺点是非自适应,浏览器的窗口大小直接影响用户体验。

(2)给外部的父盒子也添加浮动,让其也脱离标准文档流,这种方法方便,但是对页面的布局不是很友好,不易维护。

(3)给父盒子添加overflow属性。

overflow:auto; 有可能出现滚动条,影响美观。

overflow:hidden; 可能会带来内容不可见的问题。

(4)清除浮动

水平垂直居中

行内元素: 父元素设置text-align: center,line-height: height

块级元素:

高度不固定

  1. flex
.father{
  display:flex;
  justify-content:center;
}
.child{
  align-self:center;
}
  1. 绝对定位+transform
.wrap{
  position:relative;
}
.child{
  position: absolute;
  top:50%;
  left:50%;
  -webkit-transform:translate(-50%,-50%);
}
  1. table布局
<div class="wrap">
   <div class="child">
          <div>sadgsdgasgd</div>
   </div>
</div>
.wrap{
  display:table;
  text-align:center;
}
.child{
  background:#ccc;
  display:table-cell;
  vertical-align:middle;
}
.child div{
    width:300px;
    height:150px;
    background:red;
    margin:0 auto;
}

CSS三角

从全边框看三角

如果不给盒子width和height,且将边框宽度变大,则

需要哪个朝向的三角形,就将其他方向的边框设为透明色。

div {
  width :0;
  height: 0;
  /* 不是重点
  line-height: 0;
  font-size: 0;
  */
  border: 50px solid transparent;
  border-left-color: pink;
}

CSS扇形

<style>
  .sector{
    border-radius:80px 0 0;
    width: 80px;
    height: 80px;
    background: #666;
  }
</style>
<div class="sector"></div>

CSS动画

  1. 2D转换transform(同时有位移和其他属性的时候,记得要将位移放到最前)
  • 移动translate-------transform: translate(x,y); 或者分开写
  • 旋转rotate-----------transform:rotate(45deg) + 顺时针 -逆时针
  • 转换中心点-----------transform-origin: x y; 默认为元素中心
  • 缩放scale-------------transform: scale(x,y) 可以设置中心点缩放,不影响其他盒子
  • 过渡transition,移动、旋转、缩放等有个类似于动画的过渡
属性描述
transition简写属性,用于在一个属性中设置四个过渡属性。
transition-property规定应用过渡的 CSS 属性的名称。
transition-duration定义过渡效果花费的时间。默认是 0。
transition-timing-function规定过渡效果的时间曲线。默认是 "ease"。
transition-delay规定过渡效果何时开始。默认是 0。
  • 动画animation。定义->调用
@keyframes move {
  0% {
    transform: translate(0,0)
  }
  100% {
    transform: translate(100px, 100px)
  }
}
div {
  animation-name: move;
  animation-duration: 3s;
  // animation: move 5s linear 2s infinite alternate;
}

\

动画属性描述
@keyframes定义动画
animation动画属性的简写,不包括animation-play-state
animation-duration规定动画完成一个周期的时间(s, ms),默认0
animation-timing-function规定动画的速度曲线,默认“ease”
animation-delay动画延时器
animation-iteration-count规定动画被播放的次数,默认1,infinite无限
animation-direction动画是否子下一周期逆向播放,默认'normal',alternate逆播放
animation-play-state规定动画是否正在运行或暂停,默认“running”,"paused"
animation-fill-mode规定动画结束后的状态,保持forwards,回到起始backwards

速度曲线animation-timing-function

linear动画匀速
ease默认,以低速开始,然后加快,在结束前变慢
ease-in动画以低速开始
ease-out动画以低速结束
ease-in-out以低速开始,以低速结束
steps指定时间函数中的间隔数量

3D转换

  • 3D移动 translate3d
    transform: translateX(100px)
    transform: translateY(100px)
    transform: translateZ(100px)
    transform: translate3d(x,y,z)
  • 透视perspective
    在2D平面产生近大远小视觉立体
    有了透视才能看到translateZ引起的变化,近大远小,往外是正值,往里是负值
  • 3D旋转rotate3d

transform:rotateX(45deg):沿着x轴正方向旋转 45度
transform:rotateY(45deg) :沿着y轴正方向旋转 45deg
transform:rotateZ(45deg) :沿着Z轴正方向旋转 45deg
transform:rotate3d(x,y,z,deg): 沿着自定义轴旋转 deg为角度

  • 3D呈现 transfrom-style

控制子元素是否开启三维立体环境

transform-style: flat 子元素不开启3d立体空间 默认的

transform-style: preserve-3d; 子元素开启立体空间

浏览器私有前缀----兼容

-moz-:代表 firefox 浏览器私有属性
-ms-:代表 ie 浏览器私有属性
-webkit-:代表 safari、chrome 私有属性
-o-:代表 Opera 私有属性

动画和过渡的区别

  1. 过渡需要触发条件(eg,hover),动画则调用动画即可
  2. 过渡只有开始结束两种状态,动画基于关键帧,可以有很多状态

移动端适配

基本概念

  • 物理像素:即屏幕的实际像素点。像素是屏幕设备的最小显示单元,如 iPhone4 的屏幕分辨率是640x960像素,即 iPhone4 的屏幕由横向640个像素和纵向960个像素排列组成。
  • 设备独立像素:即逻辑像素,用于定义应用的 UI(UI即用户界面,这里指的是定义应用界面的各个元素的大小)。苹果 iPhone4 首次提出了 Retina Display(视网膜屏幕)的概念,在 iPhone4 使用的视网膜屏幕中,把 2x2 个像素当 1 个物理像素使用,即使用 2x2 个像素显示原来 1 个物理像素显示的内容,从而让 UI 显示更精致清晰,这 2x2 个像素即使逻辑像素。
  • 屏幕像素比(device pixel ratio 简称 dpr):即物理像素与逻辑像素的比值。
设备名称物理像素设备独立像素屏幕像素比
iPhone4640x960320x4802
iPhone6,6S,7750x1334375x6672
iPhone6 Plus,6S Plus,7 Plus1080x1920414x7363
Galaxy S4, S51080x1920360x6402
Galaxy Note41440x2560360x6404
  • 视口(Viewport):当前可见的计算机图形区域,在浏览器中,是指能用来显示网页的区域。
    • 可视视口: 视口当前可见的部分
    • 布局视口(layout viewport): 整个网页所占据的区域(包括可视也包括不可视的区域)
    • 当可视视口比布局视口小时,浏览器网页就会出现横向滚动条,以支持用户浏览整个网页的内容。
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

适配方案

rem方案

rem相对于根元素的字体大小,假设设计稿为750px,根元素字体大小为50px,则1rem = 50px

rem 适配通常采用如下的 viewport 设置

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">

合理设置rem

const rem = document.documentElement.clientWidth / 10

只对需要等比缩放的元素进行 rem 换算,对于不需要缩放的元素,比如边框阴影,使用 px 等其他单位。

vw 适配

vw 是一个相对于 viewport 的单位,100vw 就等于 viewport 的宽度。vw 适配同样是一个缩放处理设计思想的适配方案,得益于现代浏览器对 vw 单位的良好支持性而流行,它是比 rem 适配更优秀的适配方案。vw 适配通常采用如下的 viewport 设置:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">

弹性盒(Flexbox)适配

弹性盒(CSS Flexible Box Layout Module 简称 Flexbox)是一种用于在单个维度(行或列)中显示项目的布局模型。当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式,提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。Flexbox 布局的两个基本概念:

  • 容器:弹性布局的父元素(display=flex的元素)。
  • 项目:弹性布局容器中的每一个子元素。

弹性盒适配就是采用了 Flexbox 布局模型的适配方案,这种适配方案通常使用如下的 viewport 设置:

<meta name="viewport" content="width=device-width, initial-scale=1">

使用弹性盒适配的优点是不需要进行单位转换,因为其不需进行缩放处理,因此通常情况下都使用 px 单位。弹性盒适配的基本原则是:

  • 内容流式:即弹性项目(弹性布局容器中的每一个子元素)的填充内容使用流式布局。
  • 布局弹性:即涉及元素排列、对齐和空间分配时,使用弹性盒进行布局。

移动端 1px 问题

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

DPR(devicePixelRatio) 设备像素比,它是默认缩放为100%的情况下,设备像素和CSS像素的比值。如果设计稿750px,1px的线条缩放到375px的屏幕中是0.5px,iOS 8+系统支持,安卓系统不支持0.5px。

解决方式如下:

1. 边框图片

border: 1px solid transparent;
border-image: url('./image/96.jpg') 0.5 repeat;
  • 优点:没有副作用
  • 缺点:border颜色变了就得重新制作图片;圆角会比较模糊。

2. 使用box-shadow实现

box-shadow: 0  -1px 1px -1px #e5e5e5,   //上边线
            1px  0  1px -1px #e5e5e5,   //右边线
            0  1px  1px -1px #e5e5e5,   //下边线
            -1px 0  1px -1px #e5e5e5;   //左边线
  • 优点:使用简单,圆角也可以实现
  • 缺点:模拟的实现方法,仔细看谁看不出来这是阴影不是边框。

3. 使用伪元素

将伪元素设置绝对定位,并且和父元素的左上角对齐,将width 设置100%,height设置为1px,然后进行在Y方向缩小0.5倍。

.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;
  }
}
  • 优点:全机型兼容,实现了真正的1px,而且可以圆角。
  • 缺点:暂用了after 伪元素,可能影响清除浮动。

4. 设置viewport的scale值

<html>
  <head>
    <title>1px question</title>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">        
    <style>
      html {
        font-size: 1px;
      }            
      .top_b {
        border-bottom: 1px solid #E5E5E5;
      }

    </style>
    <script>
      var viewport = document.querySelector("meta[name=viewport]");
      //下面是根据设备像素设置viewport,浏览器可能会存在精度问题,不一定是准确的1,2,3
      if (window.devicePixelRatio == 1) {
        viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');
      }
      if (window.devicePixelRatio == 2) {
        viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
      }
      if (window.devicePixelRatio == 3) {
        viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');
      }
      var docEl = document.documentElement;
      var fontsize = 32* (docEl.clientWidth / 750) + 'px';
      docEl.style.fontSize = fontsize;
    </script>
  </head>
  <body>
    <div class="top_b">111</div>
  </body>
</html>

0.5px的线条

  1. 使用scale缩放
<style>
  .hr{
    height: 1px;
    transform: scaleY(0.5);
  }
</style>
<div class="hr scale-half"></div>
  1. 线性渐变linear-gradient
<style>
  .gradient {
    height: 1px;
    background: linear-gradient(0deg, #fff, #000);
  }
</style>
<div class="gradient"></div>
  1. box-shadow
<style>
  .boxshadow {
    height: 1px;
    background: none;
    box-shadow: 0 0.5px 0 #000;
  }
</style>
<div class="boxshadow"></div>
  1. viewport
// 根据DPR设置缩放
<meta name="viewport" content="width=device-width,initial-scale=0.5">