爆肝!!一文带你全面学习Css所有布局方式

前言

初入前端行业不久的朋友,对于Css 的各种布局可能会有一些疑问,什么情况下用什么布局?在某种场景下,使用哪种布局是最佳选择?

小朋友,你是否有很多问号?那么恭喜你,认真看完本文,你绝对能对所有布局方式侃侃而谈,简单做个横向对比更是不在话下,那么废话不多说,上干货!!

常用的布局方式有以下几种,每种技术都有它们的用途,各有优缺点,相互辅助。通过理解各个布局方法的设计理念,你能够找到构建你想要的网页需要的布局方案。

重点:本文将从大方向上带你了解各种布局的基本使用和主要概念,对不同的布局方式做出横向对比,而不是从细节上 教会每种布局的使用方式,具体每种布局使用方式还需要再单独去学。

但我相信,读完本文,您绝对能对所有布局方式有个很好很全面的认识,真心希望能帮到您!!

正常布局流

HTML 元素完全按照源码中出现的先后次序显示——第一个段落、无序列表、第二个段落。

出现在另一个元素下面的元素被描述为元素,出现在另一个元素旁边的是行内元素

如果两个垂直相邻的元素都设置了外边距并且两个外边距相接触,那么更大的外边距会被保留,小的则会消失——这被称为外边距折叠。外边距折叠仅与垂直方向有关。

flex布局

布局介绍

Flexbox 是 CSS 弹性盒子布局模块(Flexible Box Layout Module)的缩写,它被专门设计出来用于创建横向或是纵向的一维页面布局。要使用 flexbox,你只需要在想要进行 flex 布局的父元素上应用display: flex ,所有直接子元素都将会变成 flex项(flex容器的子项),按照 flex 进行布局

弹性盒子是一种用于按行或按列布局元素的一维布局方法。元素可以膨胀以填充额外的空间,收缩以适应更小的空间。弹性盒子的真正价值可以体现在它的灵活性/响应性,如果你调整浏览器窗口的大小,或者增加一个 元素,这时的布局仍旧是好的。

为什么要用flex 布局?

长久以来,CSS 布局中唯一可靠且跨浏览器兼容的创建工具只有 floatspositioning。这两个工具大部分情况下都很好使,但是在某些方面它们具有一定的局限性,让人难以完成任务。

以下简单的布局需求是难以或不可能用这样的工具(floatspositioning)方便且灵活的实现的:

  • 在父内容里面垂直居中一个块内容。

  • 使容器的所有子项占用等量的可用宽度/高度,而不管有多少宽度/高度可用。

  • 使多列布局中的所有列采用相同的高度,即使它们包含的内容量不同。

正如你将在后面的章节中看到的一样,弹性盒子使得很多布局任务变得更加容易

flex布局基本用法

常用属性: flex-direction 和 flex-wrap的缩写是flex-flow ,flex 项排序,flex 嵌套

grid布局

布局介绍

也叫网格布局,Flexbox 用于设计横向或纵向的布局,而 Grid 布局则被设计用于同时在两个维度上把元素按行和列排列整齐。

CSS 网格是一个用于 web 的二维布局系统。利用网格,你可以把内容按照行与列的格式进行排版。另外,网格还能非常轻松地实现一些复杂的布局。

网格是由一系列水平及垂直的线构成的一种布局模式。根据网格,我们能够将设计元素进行排列,帮助我们设计一系列具有固定位置以及宽度的元素的页面,使我们的网站页面更加统一。

我们通过把容器的 display 属性设置为 grid ,来定义一个网格。与弹性盒子一样,将父容器改为网格布局后,他的直接子项会变为网格项。与弹性盒子不同的是,在定义网格后,网页并不会马上发生变化。因为 display: grid 的声明只创建了一个只有一列的网格,所以子项还是会像正常布局流那样,自上而下、一个接一个的排布。

一个网格通常具有许多的列(column)与行(row),以及行与行、列与列之间的间隙,这个间隙一般被称为沟槽(gutter)

为什么要用grid 布局?

CSS 网格布局擅长于将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系(前提是 HTML 生成了这些区域)。

像表格一样,网格布局让我们能够按行或列来对齐元素。然而在布局上,网格比表格更可能做到或更简单。例如,网格容器的子元素可以自己定位,以便它们像 CSS 定位的元素一样,真正的有重叠和层次。

比如如下效果,使用网格布局会更方便做到:

代码如下:

 
// html
<div class="wrapper">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
  <div class="four">Four</div>
  <div class="five">Five</div>
  <div class="six">Six</div>
</div>
​
​
// css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 10px;
  grid-auto-rows: minmax(100px, auto);
}
.one {
  grid-column: 1 / 3;
  grid-row: 1;
}
.two {
  grid-column: 2 / 4;
  grid-row: 1 / 3;
}
.three {
  grid-row: 2 / 5;
  grid-column: 1;
}
.four {
  grid-column: 3;
  grid-row: 3;
}
.five {
  grid-column: 2;
  grid-row: 4;
}
.six {
  grid-column: 3;
  grid-row: 4;
}

flex布局 VS 网格布局

1、Flex 布局相对于 Grid 布局更加灵活,适用于比较简单的布局场景,如导航菜单、列表排列等,特别是在移动端布局中表现更加优秀。它的特点是可以随意控制子元素排列的方向、对齐方式、间距等属性,并且具有很高的自适应性,能够适应不同终端大小的屏幕。

2、Grid 布局相对于 Flex 布局更加强大,适用于比较复杂的布局场景,如网格布局、多栏排版等,它可以划分出不同区块,进行更加精细的布局,具有高度自适应性和可读性,且在处理大量信息和多种布局的时候表现比较优秀。

因此,选择 Flex 布局还是 Grid 布局,应该根据具体的页面需求和场景来进行选择。如果只是简单的列表、导航菜单之类的布局,选择 Flex 布局足够了。如果需要更加复杂的布局,比如网格式布局、多栏排版等,则建议选择 Grid 布局。

需要注意的是,使用 Grid 布局的话,兼容性方面需要更加考虑。而 Flex 布局的兼容性比 Grid 布局更加良好。因此,在使用 Grid 布局的时候,建议进行兼容性测试,并适当添加兼容性处理。

浮动

介绍

把一个元素“浮动”(float) 起来,会改变该元素本身和在正常布局流(normal flow)中跟随它的其他元素的行为。这一元素会浮动到左侧或右侧,并且从正常布局流 (normal flow) 中移除,这时候其他的周围内容就会在这个被设置浮动 (float) 的元素周围环绕。

最初,引入 float 属性是为了能让 Web 开发人员实现简单的布局,包括在一列文本中浮动的图像,文字环绕在它的左边或右边。你可能在报纸版面上看到过。

但 Web 开发人员很快意识到,任何东西都可以浮动,而不仅仅是图像,所以浮动的使用范围扩大了。之前的 fancy paragraph example 的课程展示了如何使用浮动创建一个有趣的 drop-cap(首字下沉)效果。

浮动曾被用来实现整个网站页面的布局,它使信息列得以横向排列(默认的设定则是按照这些列在源代码中出现的顺序纵向排列)。目前出现了更新更好的页面布局技术,所以使用浮动来进行页面布局应被看作传统的布局方法

怎么使用float ?

例子:效果如下

注意

我们可以在浮动元素上应用 margin,将文字推开,但不能在文字上应用 margin 将浮动元素推走。这是因为浮动的元素脱离了正常文档流,紧随其后的元素排布在它的“后方”。

目标元素的行内盒子已被缩短,故文字会排布在浮动元素周围,但是浮动元素从正常文档流移出,故段落的盒子仍然保持全部宽度。

代码如下:

// html 删掉了一些英语文字,想用的时候,把p标签里的内容随便扩充一下
<h1>Simple float example</h1>
<div class="box">Float</div>
<p class="special">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam
  dolor
</p>
​
<p>
  Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet
  orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare
  ex malesuada et.
</p>
​
<p>
  Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada
  ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed
  est. Nam id risus quis ante semper consectetur
</p>
​
// css
body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  font:
    0.9em/1.2 Arial,
    Helvetica,
    sans-serif;
}
​
.box {
  float: left;
  margin-right: 15px;
  width: 150px;
  height: 100px;
  border-radius: 5px;
  background-color: rgb(207, 232, 220);
  padding: 1em;
}
​
.special {
  background-color: rgb(79, 185, 227);
  padding: 10px;
  color: #fff;
}

清除浮动

我们看到,一个浮动元素会被移出正常文档流,且其他元素会显示在它的下方。如果我们不想让剩余元素也受到浮动元素的影响,我们需要 停止 它;这是通过添加 clear 属性实现的。

在前例的 HTML 代码中,向浮动元素下方的第二个段落添加 cleared 类,然后向 CSS 文件中添加以下样式:

.cleared {
  clear: left;
}

应该看到,第二个段落已经停止了浮动,不会再跟随浮动元素排布了。clear 属性接受下列值:

  • left:停止任何活动的左浮动

  • right:停止任何活动的右浮动

  • both:停止任何活动的左右浮动

清除浮动元素周围的盒子

现在你知道了如何停止浮动元素其后元素的浮动行为。我们来看个例子,如果存在一个盒子 同时 包含了很高的浮动元素和一个很短的段落,会发生什么。

问题所在

改变你的文档结构,使得第一个段落与浮动的盒子共同处于类名为 wrapper 的 <div> 元素之下。

<div class="wrapper">
  <div class="box">Float</div>
​
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
    aliquam dolor, eu lacinia lorem placerat vulputate.
  </p>
</div>

在你的 CSS 代码中,为 .wrapper 类添加如下规则并重载页面:

.wrapper {
  background-color: rgb(79, 185, 227);
  padding: 10px;
  color: #fff;
}

此外,将原先的 .cleared 类移除:

.cleared {
  clear: left;
}

你会看到,就像示例代码一样,如果将背景色属性置于段落上,那么这个背景色将处于浮动元素之下。

再一次强调,这是因为浮动元素处于正常文档流之外,停止紧随其后元素的浮动并不像之前那样奏效。如果你想让盒子联合包住浮动的项目以及第一段文字,同时让紧随其后的内容从盒子中清除浮动,这就是一个问题。

有三种方法可以处理这个问题,其中的两种在所有浏览器中均可以奏效(虽然看上去有点“小技巧”),剩下的一种是可以处理问题的较新的解决方案。

clearfix 小技巧

传统上,这个问题通常由所谓的 "clearfix 小技巧" 解决,其过程为:先向包含浮动内容及其本身的盒子后方插入一些生成的内容,并将生成的内容清除浮动。

向示例中添加以下 CSS 代码:

.wrapper::after {
  content: "";
  clear: both;
  display: block;
}

现在重载页面,盒子的浮动就应该清除了。这与在浮动盒子后手动添加诸如 div 的 HTML 元素,并设置其样式为 clear:both 是等效的。

使用 overflow

一个替代的方案是将包裹元素的 overflow 属性设置为除 visible 外的其他值。

移除上一节添加的 clearfix CSS 代码;在包裹元素上添加 overflow: auto 规则。现在,盒子应该再一次停止浮动。

.wrapper {
  background-color: rgb(79, 185, 227);
  padding: 10px;
  color: #fff;
  overflow: auto;
}

这个例子之所以能够生效,是因为创建了所谓的 块格式化上下文(BFC)。可以把它看作页面内部包含所需元素的一小块布局区域。如此设置可以让浮动元素包含在 BFC 及其背景之内。大部分情况下这种小技巧都可以奏效,但是可能会出现莫名其妙的滚动条或裁剪阴影,这是使用 overflow 带来的一些副作用。

display: flow-root

一个较为现代的方案是使用 display 属性的 flow-root 值。它可以无需小技巧来创建块格式化上下文(BFC),在使用上没有副作用。

.wrapper 中移除 overflow: auto 规则并添加 display: flow-root。如果你的浏览器支持该属性(支持的浏览器列表),盒子就会停止浮动。

.wrapper {
  background-color: rgb(79, 185, 227);
  padding: 10px;
  color: #fff;
  display: flow-root;
}

定位

介绍

定位 (positioning) 能够让我们把一个元素从它原本在正常布局流 (normal flow) 中应该在的位置移动到另一个位置。定位 (positioning) 并不是一种用来给你做主要页面布局的方式,它更像是让你去管理和微调页面中的一个特殊项的位置。

定位允许你从正常的文档流布局中取出元素,并使它们具有不同的行为,例如放在另一个元素的上面,或者始终保持在浏览器视窗内的同一位置。

有五种主要的定位类型需要我们了解:

1,静态定位(Static positioning)

是每个元素默认的属性——它表示“将元素放在文档布局流的默认位置——没有什么特殊的地方”。

2,相对定位(Relative positioning)

允许我们相对于元素在正常的文档流中的位置移动它——包括将两个元素叠放在页面上。这对于微调和精准设计非常有用。

相对定位,让你能够把一个正常布局流中的元素从它的默认位置(正常布局流下的位置),即相对它原来的默认位置按坐标进行相对移动(通过 top,left等属性控制)。比如将一个图标往下调一点,以便放置文字

3,绝对定位(Absolute positioning)

将元素完全从页面的正常布局流中移出,类似将它单独放在一个图层中。我们可以将元素相对于页面的 <html> 元素边缘固定(默认如此),或者相对于该元素的 最近被定位祖先元素。绝对定位在创建复杂布局效果时非常有用,例如通过标签显示和隐藏的内容面板或者通过按钮控制滑动到屏幕中的信息面板。

绝对定位用于将元素移出正常布局流,以坐标的形式相对于它的容器定位到 web 页面的任何位置,以创建复杂的布局。有趣的是,它经常被用于与相对定位和浮动的协同工作。

注意:脱离文档流,类似于将它单独放在了一个图层,而之前和它一块的 正常布局流 中的元素,会当做不存在这个元素一样,按照 正常布局流 的正常默认规则,进行排列(即绝对定位之后,该元素不会在它原来的位置,依旧占着空间)

不开启定位的效果:

绝对定位开启的效果:(不再站着原来位置2)

这和相对定位截然不同!绝对定位元素现在已经与页面布局的其余部分完全分离,并位于页面的顶部。其他两段现在靠在一起,好像之前那个中间段落不存在一样

相对定位开启效果:(依然占着位置2)

4,固定定位(Fixed positioning)

与绝对定位非常类似,但是它是将一个元素相对浏览器视口固定,而不是相对另外一个元素。这在创建类似在整个页面滚动过程中总是处于屏幕的某个位置的导航菜单时非常有用。

固定定位 同 绝对定位一样,将元素从文档流 (document flow) 当中移出了。但是,定位的坐标不会应用于"容器"边框来计算元素的位置,而是会应用于视口 边框。利用这一特性,我们可以轻松搞出一个固定位置的菜单,而不受底下的页面滚动的影响。

5,粘性定位(Sticky positioning)

是一种新的定位方式,它会让元素先保持和 position: static 一样的定位,当它的相对视口位置(offset from the viewport)达到某一个预设值时,它就会像 position: fixed 一样定位。

粘性定位 (sticky positioning) 是最后一种我们能够使用的定位方式。它将默认的静态定位 (static positioning) 和固定定位 (fixed positioning) 相混合。当一个元素被指定了position: sticky时,它会在正常布局流中滚动,直到它出现在了我们给它设定的相对于容器的位置,这时候它就会停止随滚动移动,就像它被应用了position: fixed一样。

文档流

定位是一个相当复杂的话题,所以我们深入了解代码之前,让我们审视一下布局理论,并让我们了解它的工作原理。

首先,围绕元素内容添加任何内边距、边界和外边距来布置单个元素盒子——这就是盒模型 ,我们前面看过。

默认情况下,块级元素的内容宽度是其父元素的宽度的 100%,并且与其内容一样高。内联元素高宽与他们的内容高宽一样。你不能对内联元素设置宽度或高度——它们只是位于块级元素的内容中。如果要以这种方式控制内联元素的大小,则需要将其设置为类似块级元素 display: block;

这只是解释了单个元素,但是元素相互之间如何交互呢?正常的布局流(在布局介绍文章中提到)是将元素放置在浏览器视口内的系统。默认情况下,块级元素在视口中垂直布局——每个都将显示在上一个元素下面的新行上,并且它们的外边距将分隔开它们。

内联元素表现不一样——它们不会出现在新行上;相反,它们互相之间以及任何相邻(或被包裹)的文本内容位于同一行上,只要在父块级元素的宽度内有空间可以这样做。如果没有空间,那么溢流的文本或元素将向下移动到新行。

如果两个相邻元素都在其上设置外边距,并且两个外边距接触,则两个外边距中的较大者保留,较小的一个消失——这叫外边距折叠, 我们之前也遇到过。

z-index

两个开启绝对定位的元素,谁会把谁压在下层? 默认源顺序中后定位的元素将赢得先定位的元素。

但是可以通过 z-index 来改变这个堆叠顺序

多列布局

介绍

多列布局(Multicol )模组给了我们 一种把内容按列排序的方式,就像文本在报纸上排列那样。由于在 web 内容里让你的用户在一个列上通过上下滚动来阅读两篇相关的文本是一种非常低效的方式,那么把内容排列成多列可能是一种有用的技术。

要把一个块转变成多列容器 (multicol container),我们可以使用 column-count属性来告诉浏览器我们需要多少列,也可以使用column-width来告诉浏览器以至少某个宽度的尽可能多的列来填充容器。

怎么使用多列布局 ?

Multicol 创建的列无法单独的设定样式。不存在让单独某一列比其他列更大的方法,同样无法为某一特定的列设置独特的背景色、文本颜色。你有两个机会改变列的样式:

效果如下:

代码如下:

.container {
  column-count: 3;
  column-gap: 20px;
  column-rule: 4px dotted rgb(79, 185, 227);
}

值得一提的是这条分割线本身并不占用宽度。它置于用 column-gap 创建的间隙内。如果需要更多空间,你需要增加 column-gap 的值

表格布局

HTML 表格对于显示表格数据是很好的,但是很多年前——在浏览器中支持基本的 CSS 之前——web 开发人员过去也常常使用表格来完成整个网页布局——将它们的页眉、页脚、不同的列等等放在不同的表行和列中。这在当时是有效的,但它有很多问题——表布局是不灵活的,繁重的标记,难以调试和语义上的错误(比如,屏幕阅读器用户在导航表布局方面有问题)。

一个 <table> 标签之所以能够像表格那样展示,是由于 css 默认给 <table> 标签设置了一组 table 布局属性,当这些属性被应用于排列非 <table> 属性时,这种用法被称为 "表格布局"

使用表格布局,在现在这个时间点应该被认为是一种传统方法,它通常会被用于兼容一些不支持 Flexbox 和 Grid 的浏览器。

学习flex布局的资源链接

30 分钟学会 Flex 布局 - 知乎 (zhihu.com)

flex网页布局首选方案 灵活应用css flex弹性布局快速构建web结构 - By DeathGhost

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值