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

作者: 许骁Charles | 来源:发表于2019-03-12 19:35 被阅读13次

目录

  1. 布局相关属性
    • display
    • position
    • float
  2. 各种布局
    • 两栏布局
    • 三栏布局
    • 水平居中
    • 垂直居中
  3. 总结

概述

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

布局相关属性

1. display

display 是 CSS 布局中很重要的一个属性,它定义了元素生成的显示框类型,常见的几个属性值有:blockinlineinline-blockinheritnoneflex。inherit 表示这个元素从父元素继承 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: '';
    clear: both;
    display: block;
    visibility: hidden;
}

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

  1. overflow法

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

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

各种布局

两栏布局

基础代码如下:

<div class="container">
    <div class="left">left</div>
    <div class="right">right</div>
</div>
.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);   /* 计算宽度,运算符号左右一定要有空格 */
}

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 从上至下的加载原则,中间的自适应部分要放在前面。
基础代码:

<div class="container">
    <!-- 保证优先渲染 -->
    <div class="center">center</div>       
    <div class="left">left</div>
    <div class="right">right</div>
</div>
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部分更加简洁。

<div class="container">
    <div class="center-container">
        <div class="center">center</div>
    </div>
    <div class="left">left</div>
    <div class="right">left</div>
<div>
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. 块级元素居中:

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

总的来说,居中的方法非常多,这里贴出博客拓展阅读:

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

总结

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

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

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

相关文章

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

    目录 布局相关属性displaypositionfloat 各种布局两栏布局三栏布局水平居中垂直居中 总结 概述 ...

  • CSS边用边学(三):Flex 布局

    基本概念 Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒模型提供最大的灵活性。 任何一...

  • 边学边用,边用边学

    我一直想学很多东西,却一直没学好,甚至还没开始真正学习。 大学的时候,我就想学很多东西。想学习谈判,学习演讲,写一...

  • 边学边用

    7月14日《人生效率手册》5 书里说到,如果我们不能将所学的理论与实践相结合,换句话说,在实践场景中,无法调用知识...

  • 边学边用

    2020.08.16 星期天 阴雨天 早上去辅导的时候,马老师给学生买了高中语法书,给我...

  • 边学边用

    分享424 有这么一句话:有人不让你成功,但是没有办法不让你成长。成长是自己的事情,成长应该成为每一个人的状态。 ...

  • 边学边用

    我阅读的书目是《致青年老师》 读书笔记分享:在读《致青年老师》第三辑《心里装着学生》,想学生之所想,急学生之所急,...

  • CSS布局奇淫巧计之-强大的负边距

    CSS布局奇淫巧计之-强大的负边距css中的负边距(negative margin)是布局中的一个常用技巧,只要运...

  • markdown边学边用

    ```代码块``` ~~删除线~~ 有序列表 数字+英文句号 后面还有空格 反斜杠转义特殊字符\``` *** 分...

  • 边学边用 - 草稿

    刘斌焦点网络四期驻马店坚持分享第260天 看到刘老师分享的边学边用,用中才会有更好的进步,很有感触。这一次遇到实际...

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/alhbpqtx.html