CSS基础小结

147 阅读10分钟

CSS是前端开发中的重要技能,CSS的学习往往需要不断积累,下面对近段时间的CSS学习简要做个小结

CSS盒子模型

css盒子模型是一个文档进行布局的时候,浏览器的渲染引擎会根据标准之一的基础框盒模型,将所有元素表示为一个个矩形的盒子,一个盒子由四个部分组成:

  • content实际内容,显示文本或图像
  • padding内边距,清除内容周围的区域,内边距是透明的,取值不能为负,受盒子的background属性影响
  • border边框,围绕元素内容的内边距的一条或多条线,由粗细、样式、颜色三部分组成
  • margin外边距,在元素外创建额外的空白,空白通常指不能放其他元素的区域

下面来看一段代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <style>
    .content {
      width: 300px;
      padding: 20px;
      margin: 40px;
      height: 20px;
      background-color: yellow;
    }
  </style>

  <body>
    <div class="content">test</div>
  </body>
</html>

这段代码运行之后,我们来看看效果:

image.png

我们发现,盒子的大小变成了宽340px,高60px,这是因为在CSS中,盒子模型是可以分为W3C标准盒子模型IE怪异盒子模型,默认情况下,盒子模型为W3C标准盒子模型,设置box-sizing属性可以切换盒子模型

W3C标准盒子模型

在标准盒子模型中,box-sizing属性需要设置为content-box

image.png

width属性指的只是content的宽度,不包含border、padding等,因此上面的例子中,盒子的大小加上了padding

IE怪异盒子模型

在怪异盒子模型中,box-sizing属性需要设置为border-box

image.png

width属性指的是content加上border、padding的宽度,即content的实际大小是width、height减去border、padding,因此设置为border-box之后,content的宽度变成了260px。

image.png

那么问题来了,效果中盒子的高度表现的不太对,因为我们设置的高度如果减去padding的话,高度不 够减,在模型图中显示出来的content是0,但是表现出来的好像是40px,这是为什么呢?

在怪异盒子模型中,如果高度不够,会自动向外扩展,表现出来就会和预期不太一致

PS box-sizing还有个属性值是inherit,表示box-sizing的值需要从父元素继承

块级格式化上下文

我们在平时开发过程中,经常碰到元素的表现和预期不一样的情况,比如元素的高度没了、间距好像有点奇怪等等,这些问题大都是因为元素之间相互的影响,导致了意料之外的情况出现。这里引入一个新的概念,即BFC(块级格式化上下文),BFC是页面中的一块渲染区域,并且有一套自己的渲染规则

  • 内部的盒子会在垂直方向上一个接一个排列
  • 对于一个BFC的两个相邻的盒子,他们的margin会发生重叠,与方向无关
  • 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此
  • BFC的区域不会和float的元素的元素区域重叠
  • 计算BFC的高度的时候,浮动元素的高度也会被计算
  • BFC是页面上一个隔离的独立容器,容器里面的元素不会影响到外面的元素,反之亦然

测试代码如下所示:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <style>
    .content {
      width: 300px;
      /* padding: 20px;
      margin: 40px;
      height: 20px; */
      background-color: yellow;
    }

    .test1 {
      margin: 20px;
    }

    .test2 {
      margin: 20px;
    }

    .float {
      height: 50px;
      background-color: red;
      float: left;
    }
  </style>

  <body>
    <div class="content">
      <div class="test1">1</div>
      <div class="test2">2</div>
      <div class="float">111</div>
    </div>
  </body>
</html>

验证效果如下所示:

image.png

可以看到左边界相接触,在BFC中浮动元素的高度也计算了,并且margin发生了重叠,验证了上面的原则

BFC的触发条件

触发BFC的条件包含但不限于:

  • 根元素,即HTML元素
  • 浮动元素,float值为left或right,
  • overflow的值不为visible
  • display的值为inline-block、table-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
  • position的值为absolute或fixed

BFC的应用场景

防止margin重叠、塌陷

先前可以知道,在一个BFC中的两个元素,其margin会发生重叠,那么我们就可以将其中一个元素用div包裹,并生成一个新的BFC,BFC外部的元素不会影响内部的元素,具体实现代码如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <style>
    .content {
      width: 300px;
      background-color: yellow;
    }

    .test1 {
      margin: 20px;
    }

    .test2 {
      margin: 20px;
    }

    .float {
      height: 50px;
      background-color: red;
      float: left;
    }
  </style>

  <body>
    <div class="content">
      <div class="test1">1</div>
      <div style="overflow: hidden">
        <div class="test2">2</div>
      </div>
      <div class="float">111</div>
    </div>
  </body>
</html>

这样实现的效果为

image.png

发现元素的margin没有重叠了

清除内部浮动

内部元素都浮动后,父容器的高度会塌陷

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <style>
    .content {
      width: 300px;
      background-color: yellow;
    }

    .test1 {
      margin: 20px;
    }

    .test2 {
      margin: 20px;
    }

    .float {
      height: 50px;
      width: 20px;
      background-color: red;
      float: left;
    }
  </style>

  <body>
    <div class="content">
      <div class="float">1</div>
      <div class="float">2</div>
      <div class="float">111</div>
    </div>
  </body>
</html>

效果如下:

image.png

给容器加上overflow:hidden后,清除内部浮动

image.png

验证了BFC可以清除内部浮动

自适应多栏布局

浮动元素会被其他元素遮挡,以下面的代码为例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <style>
    .content {
      width: 300px;
      background-color: yellow;
      height: 50px;
    }

    .aside {
      width: 20px;
      height: 100px;
      background-color: red;
      float: left;
    }
  </style>

  <body>
    <div class="aside">1</div>
    <div class="content">2</div>
  </body>
</html>

效果如下: image.png

可以看到黄色部分是被红色部分挡住了的,这个时候想到可以让黄色部分生成一个新的BFC,就不会和浮动元素重叠,给content类名的div加上overflow:hidden即可

image.png

响应式设计

响应式网络设计是一种网络页面设计布局,页面设计与开发应该和用户行为以及设备环境进行相应的响应和调整。响应式的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端页面头部必须要有meta声明viewport,例如

<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0,maximum-scale=1,user-scalable=no"
/>

其中width=device-width是自适应手机屏幕的尺寸宽度,maximum-scale是缩放比例的最大值,maximum-scale是缩放的初始化,user-scalable是用户的可以缩放的操作,这段是必要的操作,接下来就是我们实现响应式布局的各种操作方式了

实现方式

媒体查询

使用@Media查询,可以针对不同的媒体类型定义不同的样式,比如我们如果要让视窗大小在375px-600px之间,字体颜色是红色,字体大小16px,我们可以这么设置:

@media screen (min-width: 375px) and (max-width: 600px){
    body {
        color: red;
        font-size: 16px;
    }
}

百分比

使用百分比单位来实现响应式的效果,比如当浏览器的宽高发生变化的时候,通过百分比单位,可以使得浏览器中的组件的宽高随着浏览器的变化而变化,但是这里需要注意:heightwidth属性的百分比依托于父标签的宽高,但其他属性不同:

  • topleftbottomright如果设置为百分比,则相对于直接非static定位的父元素的宽高
  • padding如果设置百分比,则只和直接父元素的宽度有关,与高度无关
  • marigin如果设置百分比,则相对于直接父元素的宽度,与高度无关
  • border-radius设置成百分比,则相对于自身的宽度

如果每个属性都使用百分比,会导致布局过于复杂,不建议使用百分比实现响应式

vw/vh

vw表示相对于视图窗口的宽度,vh表示相对于视图窗口的高度。任意层级元素,在使用vw的情况下,1vw都是表示视图宽度的百分之一

rem

rem是相对于根元素html的font-size属性,例如浏览器默认字体大小是16px,这个时候1rem就是16px

布局技巧

元素水平垂直居中

实现元素水平垂直居中的方式有:

  • 定位+margin: auto
  • 定位+margin: 负值
  • 定位+transform
  • table布局
  • flex布局
  • grid布局

定位+margin: auto

首先看下面的代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
      maximum-scale="1"
      user-scalable="no"
    />
    <title>Document</title>
  </head>

  <style>
    .father {
      width: 200px;
      height: 50px;
      background-color: red;
      position: relative;
    }

    .son {
      width: 50px;
      height: 20px;
      background-color: yellow;
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      margin: auto;
    }
  </style>

  <body>
    <div class="father">
      <div class="son">son</div>
    </div>
  </body>
</html>

这段代码具体的实现效果如下:

image.png 这里的top:0等属性让子元素虚拟大小和父元素一样,但是由于设置了宽高,显示出来的大小就是我们设置的大小,这个时候我们设置margin: auto就可以让子元素居中

定位+margin: 负值

设置父元素为相对定位,子元素移动自身50%实现水平垂直居中

定位+transform

和上面的方法一样,不过在不知道自身宽高的情况下,可以使用transform: translate(-50%,-50%)来实现

table布局

父元素设置为display: table-cell,子元素设置为display: inline-block,然后父元素设置vertical-align: middletext-align: center即可

flex布局

常使用的布局方式,父元素设置为display: flexjustify-content: centeralign-items: center即可

grid布局

父元素设置为display: gridjustify-content: centeralign-items: center

文本溢出省略

单行文本

设置属性overflow: hiddenwhite-space: nowraptext-overflow: ellipsis

多行文本

基于高度截断

设置高度即可

伪元素+定位

代码如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
      maximum-scale="1"
      user-scalable="no"
    />
    <title>Document</title>
  </head>

  <style>
    .demo {
      position: relative;
      line-height: 20px;
      height: 40px;
      overflow: hidden;
      width: 200px;
    }

    .demo::after {
      content: "...";
      position: absolute;
      bottom: 0;
      right: 0;
      /* padding: 0 20px 0 10px; */
    }
  </style>

  <body>
    <div class="demo">
      文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本
      文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本
    </div>
  </body>
</html>

效果如下

image.png

基于行数截断

使用webkit的CSS属性扩展,兼容范围是webkit内核的浏览器 代码如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
      maximum-scale="1"
      user-scalable="no"
    />
    <title>Document</title>
  </head>

  <style>
    .demo {
      width: 400px;
      -webkit-line-clamp: 3;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  </style>

  <body>
    <div class="demo">
      文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本
      文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本
    </div>
  </body>
</html>

效果如下:

image.png

CSS选择器

常用的CSS选择器有:

  • id选择器(#box)
  • 类选择器(.bix)
  • 标签选择器(div)
  • 后代选择器(#box div)
  • 子选择器(.one>one_1)
  • 相邻同胞选择器(.one+.two)
  • 群组选择器(div,p)
  • 伪类选择器(:link,:visited,:active,:hover,:focus,:first-child)
  • 伪元素选择器(:first-letter,:first-line,:before,:after)
  • 属性选择器([attribute],[attribute=value],[attribute~=value],[attribute|=value])

CSS3中新增了一些选择器

  • 层次选择器(p~div)
  • 伪类选择器(:nth-child(n),:last-child,:root,:enabled等)
  • 属性选择器([attribute*=value]等)

优先级

内联元素 > ID选择器 > 类选择器 > 标签选择器

继承属性

继承属性可以分为

  • 字体系列属性
  • 文本系列属性
  • 元素可见性
  • 表格布局属性
  • 列表属性
  • 引用
  • 光标属性

无继承属性

  • display
  • 文本属性: vertical-align,text-decoration
  • 盒子模型的属性:宽度、高度、内外边距、边框
  • 背景属性:背景图片、颜色、位置等
  • 定位属性:浮动、清除浮动、定位position
  • 生成内容属性:content、counter-reset、counter-increment
  • 轮廓样式属性:outline-style、outline-width、outline-color、outline
  • 页面样式属性:size、page-break-before、page-break-after