CSS边用边学(一):一站式各种布局实践

目录

  • 概述
  • 布局相关属性
    • display
    • position
    • float
  • 各种布局
    • 两栏布局
      1. 设置 display 为 inline-block
      2. 使用 float
      3. 用 absolute
    • 三栏布局
      1. 圣杯布局
      2. 双飞翼布局
    • 水平居中
      1. 行内元素居中
      2. 块级元素居中
    • 垂直居中
      1. 文字垂直居中
      2. 块级元素居中
  • 总结

概述

本文开始,我想写一个零基础小白的CSS边用边学的系列。因为CSS语法非常简单,所以更多地是自己去踩一个一个的坑,并记录下来时常回顾。而这些坑在书本里并不会告诉你。为了了解如何布局,需要先学习CSS布局的相关知识。这里推荐一个小白快速入门网站:CSS布局说

布局相关属性

1. display

display 是 CSS 布局中很重要的一个属性,它定义了元素生成的显示框类型,常见的几个属性值有:blockinlineinline-blockinheritnoneflexinherit 表示这个元素从父元素继承 display 属性值;none 表示这个元素不显示,也不占用空间位置;flex 是 flex 布局重要的属性设置,本篇只讲传统的布局方式,这边先介绍前面三个属性值。

每个元素都有默认的 display 属性,比如 div 标签的默认 display 属性是 block,我们通常称这类元素为块级元素;span 标签的默认 display 属性是 inline,我们通常称这类元素为行内元素。

块级元素没有设置宽度时,它的宽度是其容器的 100%。可以设置宽高、内边距、外边距等盒模型属性。可以包含块级元素和行内元素。
行内元素行内元素不会独占一行,只会占领自身宽高所需要的空间。给行内元素设置宽高不会起作用,margin 值只对左右起作用,padding 值也只对左右起作用。行内元素一般不可以包含块级元素,只能包含行内元素和文本。

一个块级元素的高度有什么决定?结论是:块级元素的高度由其内部文档流元素的高度总和决定
文档流(normal flow),直译为普通流,是指文档内元素的流动方向,block元素因为默认宽度是其容器的100%,所以它的文档流是从上至下;inline元素无法设置宽高,它的边框是紧贴内容的(注意可替代元素,如img,给 img 标签设置宽高是可以影响图片大小的),所以它的文档流是从左至右的,如果超过浏览器宽度,则另起一行继续流。

Tips:如果span元素中只有一个单词,中间没有空格,那么其内容会一直超出屏幕不换行(或者形成横向滑动条),除非添加属性:word-break: break all;(中文网站使用较多)或者word-break: break word;

那么一个行内元素的高度由什么决定?结论是:由字体设计师决定,但一般默认为line-height
每种字体有自己的基线,和不同的建议行高,所以包含不同字体的span的高度是不一样的,一个div中如果有多个span,那么div的默认高度就等于最高那个span的高度,这是在行高足够高的情况下成立。具体的细节涉及到IFC等内容,推荐:深入理解 CSS:字体度量、line-height 和 vertical-align。

inline-block 的元素,既具有块级元素可以设置宽高的特性,又具有行内元素不换行的特性。如果在写多个inline-block元素的时候习惯性回车隔开,那么最后呈现的时候两两之间会有空隙,因为浏览器会将 HTML 中的换行符、制表符、空白符合并成空白符,需要设置vertical-align: top;
更多内容推荐:CSS深入理解vertical-align和line-height的基友关系 以及 去除inline-block元素间间距的N种方法。

2. position

在布局中很重要的因素就是定位,position属性就是用来定义元素的定位机制。position 的常用属性值有:

  • static:默认值,没有定位属性,元素正常出现在文档流中;top/right/down/left无效,可以设置margin来移动
  • relative:相对定位,相对于元素的正常位置进行定位;不脱离文档流,top/right/down/left可能会遮挡附近元素,一般使用margin来移动
  • absolute:绝对定位,相对于除 static 定位以外的元素进行定位,会一直往爸爸爷爷祖宗上面找,直到找到非static定位的元素或者浏览器窗口进行定位;脱离文档流,一般用top/right/down/left来移动,也可以设置margin
  • fixed:固定定位,相对于浏览器窗口进行定位,网站中的固定 header 和 footer 就是用固定定位来实现的
  • inherit:继承父元素的 position 属性值

3. float

float 属性定义元素在哪个方向浮动,常用属性值有 left、right,即向左浮动和向右浮动。设置了 float 的元素,会脱离文档流,然后向左或向右移动,直到碰到父容器的边界或者碰到另一个浮动元素。块级元素会忽略 float 元素,文本和行内元素却会环绕它,所以 float 最开始是用来实现文字环绕效果的。

当不给父元素设置宽高时,父元素的宽高会被子元素的内容撑开。但是当子元素设置浮动属性后,子元素会溢出到父元素外,父元素的宽高也不会被撑开了,称之为“高度塌陷”。
解决这个问题便是要清除浮动

这里介绍两种常用的:

  1. after伪元素法
.clearfix::after {
    content: '';
    display: block;  /* 或者 table */
    clear: both;
}
.clearfix {
    zoom: 1;  /* 兼容 IE6 */
}

将clearfix类添加到需要浮动的元素的父元素class里即可。

  1. overflow法

给父元素加上一条style overflow: auto即可。如果子元素内容太多,被修剪,则会出现滚动条,另一种overflow: hidden;则是当子元素内容超过父元素高度,则被隐藏。

更多清除浮动详情请见clearfix。
Tips:内联元素浮动之后默认display: block。


各种布局

两栏布局

基础代码:

left
right

建议:在HTML的书写上,“窄一点”的模块写在前面,方便布局。

.left {
    width: 100px;
    height: 150px;
    background-color: #FFB5BF;
}
.right {
    height: 150px;
    background-color: #94E8FF;
}

预计效果:

下面介绍几种两栏布局方法:

1. 设置 display 为 inline-block

.container {
    font-size: 0;    /* 消除间距 */
}
.left, .right {
    display: inline-block;
}
.right {
    width: calc(100% - 100px);   /* 计算宽度,运算符号左右一定要有空格 */
}

注意:计算宽度函数 calc,运算符号左右一定要有空格!

2. 使用 float

处于文档流中的块级元素无法感知到浮动元素的存在,如果设置 .left 为 左浮动,.right 会当 .left 不存在,由于块级元素的默认宽度是父级元素的 100%,此时 .right 的宽度就已经是 100% 了,但是文字仍会环绕。别忘了设置 .right 的 margin 值来给 .left 预留空间。

.left {
    float: left;
}
.right {
    margin-left: 100px;   /* 为 .left 留出空间 */
}
.container {
    overflow: hidden;    /* 别忘了清除浮动 */
}

我们可以还设置 .left、.right 均左浮动,这时,它们便会紧贴着排列在一行。因为 .right 是浮动的,所以需要计算宽度。

.left {
    float: left;
}
.right {
    float: left;
    width: calc(100% - 100px);
}
.container {
    overflow: hidden;
}

.left 浮动的时候,.right 会无视 .left,有没有不无视,留出位置的可能?有的,让 .right 形成 BFC,.right 就不会和 .left 重合了。BFC 不会忽视浮动元素,这也是它的特点之一。

.left {
    float: left;
}
.right {
    overflow: auto;    /* 形成 BFC */
}
.container {
    overflow: hidden;
}

关于BFC,这里不做详述,请见BFC。

3. 用 absolute

.container {
    position: relative;
}
.left {
    postion: absolute;
}
.right {
    margin-left: 100px;
}

三栏布局

三栏布局中耳熟能详的便是圣杯布局和双飞翼布局了。圣杯布局来源于2006年的一篇文章:In Search of the Holy Grail。双飞翼布局始于淘宝 UED。两者都是在解决两边固定宽度,中间自适应的三栏布局,并且主要内容要优先渲染,按照 DOM 从上至下的加载原则,中间的自适应部分要放在前面。

基础代码:

center
left
right
body {
    min-width: 630px;
}
.center {
    width: 100%;
    height: 150px;
    background-color: #94E8FF;
}
.left {
    width: 100px;
    height: 150px;
    background-color: #FFB5BF;
}
.right {
    width: 200px;
    height: 150px;
    background-color: #8990D5;
}

预计效果:

1. 圣杯布局

思路:

  1. 三个div都设置浮动float: left;,.container 清除浮动。
  2. 因为 .center 的宽度是 100%,所以 .left 和 .right 排在了第二行,可以理解为排在了 .center 的后面。这个时候,.left 要回到 .center 的最左边,便是要向左移动 .center 的宽度,即 100%,.left 移动了之后,.right 会自动补上 .left 的空位,此时,.right 想要达到 .center 的最右边,只需要向左移动它自己本身的宽度就可以了,即 200px
  3. 此时 .center 的文字被遮挡了,.left、.right 都覆盖在 .center 的上面,这里先设置父元素 .container 的 padding 属性,给 .left、.right 留出空间,即padding-left: 100px;padding-right: 200px;
  4. 由于父元素设置了 padding,所有子元素都往中间挤了,此时只需将 .left、.right 分别向左向右拉到准备的空位就好了。首先将定位属性设置为 relative,即相对自己定位,.left 要向左移动 100px,.right 要向右移动 200px,所以 .left 只要设置 left: -100px; 、.right 设置 right: -200px; 便能达到效果。
body {
    min-width: 630px;
}

.container {
    overflow: hidden;
    padding-left: 100px;
    padding-right: 200px;
}

.center {
    width: 100%;
    height: 150px;
    background-color: #94E8FF;
    float: left;
}

.left {
    width: 100px;
    height: 150px;
    background-color: #FFB5BF;
    float: left;
    margin-left: -100%;
    position: relative;
    left: -100px;
}

.right {
    width: 200px;
    height: 150px;
    background-color: #8990D5;
    float: left;
    margin-left: -200px;
    position: relative;
    right: -200px;
}

圣杯布局的核心思想是使用浮动布局,用 padding 为左右元素留空间,灵活使用 margin 的负值和相对定位让元素移动到相应的位置。

2. 双飞翼布局

双飞翼布局与圣杯布局的前部分一样,给左右两边元素留出位置的思路是:多加了一个 div,将中间自适应部分包裹起来,利用子 div 的 margin 来给左右元素留空间。CSS部分更加简洁。

center
left
left
body {
    min-width: 630px;
}
.container {
    overflow: hidden;
}
.center-container {
    width: 100%;
    float: left;
}
.center-container .center {
    height: 150px;
    background-color: #94E8FF;

    margin-left: 100px;        /* 新添加的属性 */
    margin-right: 200px;       /* 新添加的属性 */
}
.left {
    width: 100px;
    height: 150px;
    background-color: #FFB5BF;
    float: left;
    margin-left: -100%;
}
.right {
    width: 200px;
    height: 150px;
    background-color: #8990D5;
    float: left;
    margin-left: -200px;
}

参考:CSS布局实践
还有一些比较粗暴的方法,因为有各种尺寸限制的bug,就不列举了。

水平居中

水平居中分为块级元素居中和行内元素居中。

1. 行内元素居中:

只需要给其父元素添加属性:

text-align: center;

Tips:块级元素中的文字也会随着居中,但位置不变。

2. 块级元素居中:

定宽

margin: 0 auto;

不定宽:参考不定宽居中

垂直居中

1. 文字垂直居中:

单行文字的垂直居中,只要将行高与容器高设为相等即可,即 height = line-height。
如果有n行文字,那么将行高设为容器高度的n分之一即可。

2. 块级元素居中:

建议方案:父元素不写死 height,然后用内部块级元素的上下 margin 去撑开,上下 margin 相等即可达到居中效果。这样子元素的内容可以任意增删不影响居中布局。

另外,通过 vertical-align: middle 实现CSS垂直居中是常使用的方法,但是有一点需要格外注意,vertical生效的前提是元素的 display:inline-block

这里贴出我的另一篇博客,总结了许多常用的居中方法:所有CSS居中方法,了解一下?

另外,介绍一个神奇的网站:How to Center In Css,一键式解决所有烦恼。

总结

想说一下我的初衷:为什么叫边用边学。当你刚知道选择器是啥的时候,如果一上来给你一个任务:用一个div实现一个纯CSS的会旋转的阴阳八卦,大概是这样:阴阳八卦,你一定是一脸懵逼的,但如果慢慢去把文档过一遍再动笔,大概需要3天看完,两周消化,一个月熟悉。不妨先做着,写的过程中,通过不断地模仿,查文档,读博客,和使用generator生成的效果代码,会让你成就感爆棚。

我觉得学CSS应该像学英语一样,先记些简单的句子表达,接着立马去实践,遇到不会说的地方再回去查漏补缺,而不是一开始抱着牛津字典从第一页开始背。包括之前学算法,一上来抱着算法导论开始啃,一头包,并逐渐劝退。

这篇里讲的是比较经典的布局方式,个人觉得最有价值的是学会双飞翼布局,这里没有用到的像flex,grid,column等布局方式,以后会慢慢研究。

参考:

  • CSS垂直居中的11种实现方式
  • 大小不固定的图片、多行文字的水平垂直居中
  • 七种垂直居中的方法

你可能感兴趣的:(CSS边用边学(一):一站式各种布局实践)