CSS 布局(一)

到目前为止,我们已经了解了CSS基础知识,如何设置文本样式,以及如何设置和操作内容所在的框现在是时候看看如何根据视口以及彼此之间的关系正确地安排你的盒子了。我们已经介绍了必要的先决条件,所以让我们深入了解CSS布局,查看各种功能:不同的显示设置,定位,现代布局工具,如flexbox和CSS网格( CSS grid),以及一些您可能仍然想知道的遗留技术。

1、概述

1.1 指南

这些文章将提供有关CSS中可用的基本布局工具和技术的指导。在课程的最后是一个评估,以帮助你检查你的布局方法的理解,通过布局网页。

1.1.1 CSS布局简介

本文将回顾我们在以前的模块中已经接触过的一些CSS布局特性(例如不同的display值),并介绍我们将在本模块中讨论的一些概念。

1.1.2 常规流(Normal flow)

网页上的元素按照常规的流排列——除非我们做些什么来改变它。这篇文章解释了正常流的基础,作为学习如何改变它的基础。

1.1.3 弹性盒子(Flexbox)

Flexbox是一种一维布局方法,用于在行或列中布局项。项可以伸缩以填充额外的空间,也可以收缩以适应更小的空间。本文解释了所有的基本原理。在学习了本指南之后,你可以在继续之前测试你的弹性盒子技能来检查你的理解。

1.1.4 网格(Grids)

CSS网格布局(CSS Grid Layout)是一个面向web的二维布局系统。它允许您以行和列的形式布局内容,并且具有许多使构建复杂布局变得简单的功能。本文将为您提供开始页面布局所需的所有知识,然后在继续之前测试您的网格技能

1.1.5 浮动

最初用于在文本块内浮动图像,float属性成为在网页上创建多列布局最常用的工具之一。随着Flexbox和Grid的出现,它现在已经回到了它最初的目的,正如本文所解释的那样。

1.1.6 定位

定位(Positioning)允许您将元素从正常的文档布局流中取出,并使它们的行为不同,例如,通过坐在另一个的顶部,或者始终保持在浏览器视窗内的相同位置。本文解释了不同的position值以及如何使用它们。

1.1.7 多列布局

多列布局规范为您提供了一种按列布局内容的方法,就像您在报纸上看到的那样。本文将解释如何使用此功能。

1.1.8 响应式设计

随着越来越多的屏幕尺寸出现在支持网络的设备上,响应式网页设计(responsive web design, RWD)的概念出现了:一组允许网页改变其布局和外观以适应不同屏幕宽度、分辨率等的实践。这一理念改变了我们设计多设备网页的方式,在本文中,我们将帮助你了解掌握它所需的主要技术。

1.1.9 媒体查询入门指南

CSS媒体查询(CSS Media Query)为您提供了一种仅当浏览器和设备环境匹配您指定的规则时才应用CSS的方法,例如,“视口宽度大于480像素”。媒体查询是响应式网页设计的关键部分,因为它们允许你根据视窗的大小创建不同的布局。它们还可以用于检测站点运行环境的其他特性,例如,用户是否使用触摸屏而不是鼠标。在本课中,您将首先了解媒体查询中使用的语法,然后您将在交互式示例中使用它们,展示如何使简单的设计具有响应性。

1.1.10 传统的布局实现

网格系统是CSS布局中非常常见的特性。在CSS网格布局之前,它们倾向于使用浮动或其他布局特性来实现。首先,您可以将布局想象为一组列(例如,4、6或12),然后将内容列放入这些想象的列中。在本文中,我们将探讨这些旧的方法是如何工作的,以便您在处理旧的项目时了解它们是如何使用的。

1.1.11 支持旧有浏览器

在这个模块中,我们建议使用Flexbox和Grid作为您设计的主要布局方法。但是,将来一定会有使用旧浏览器的访问者访问您开发的站点,或者浏览器不支持您使用的方法。这在网络上总是如此——随着新功能的开发,不同的浏览器会优先考虑不同的功能。本文解释了如何在不排斥旧技术用户的情况下使用现代web技术。

1.2 评估

下面的评估将测试你对上面指南中涉及的CSS布局方法的理解。

基本布局理解
通过网页布局测试你对不同布局方法的了解程度。

2、CSS布局简介

本文将回顾我们在以前的模块中已经接触过的一些CSS布局特性,例如不同的display值,并介绍我们将在本模块中涉及的一些概念。

CSS页面布局技术允许我们使用网页中包含的元素,并控制它们相对于以下因素的位置:它们在正常布局流中的默认位置、它们周围的其他元素、它们的父容器和主视窗/窗口。我们将在本模块中详细介绍的页面布局技术是:

  • Normal flow
  • The display property
  • Flexbox
  • Grid
  • Floats
  • Positioning
  • Table layout
  • Multiple-column layout

每种技术都有其用途、优点和缺点。任何技术都不是为孤立使用而设计的。通过了解每种布局方法的设计目的,您将能够很好地了解哪种方法最适合每个任务。

2.1 常规流

常规流是指当您不做任何控制页面布局的操作时,浏览器在默认情况下如何布局HTML页面。让我们看一个简单的HTML示例:

<p>I love my cat.</p>

<ul>
  <li>Buy cat food</li>
  <li>Exercise</li>
  <li>Cheer up friend</li>
</ul>

<p>The end!</p>

默认情况下,浏览器将显示如下代码:
在这里插入图片描述
注意HTML是如何按照源代码中出现的确切顺序显示的,元素堆叠在一起—第一段,然后是无序列表,然后是第二段

一个在另一个下面出现的元素被描述为块元素(block elements),与内联元素(inline elements)相反,内联元素像段落中的单个单词一样出现在另一个旁边。

注意:块元素内容的布局方向称为块方向(Block Direction)。在像英语这样有水平书写模式(horizontal writing mode)的语言中,块方向是垂直运行的。它将在任何具有垂直书写模式的语言中水平运行,例如日语。相应的内联方向是内联内容(如句子)运行的方向。

对于页面上的许多元素,正常流程将创建您所需要的布局。但是,对于更复杂的布局,您需要使用CSS中提供的一些工具来更改此默认行为。从结构良好的HTML文档开始是非常重要的,因为这样您就可以使用默认的布局方式,而不是与之抗争。

可以改变CSS中元素布局的方法有:

  • display属性 诸如blockinlineinline-block之类的标准值可以改变元素在正常流中的行为,例如,通过使块级元素的行为像内联级元素一样(更多信息请参阅CSS例子的类型)。我们还通过特定的display 值启用了整个布局方法,例如,CSS GridFlexbox,它们可以改变子元素在父元素中的布局方式。
  • 浮动(Floats)-应用float 值(如left)可以导致块级元素沿元素的一侧换行,就像杂志布局中的图像有时会在其周围浮动文本一样。
  • position 属性 允许您精确地控制框在其他框中的位置。static定位是正常流中的默认值,但是您可以使用其他值来改变元素的布局,例如,固定在浏览器视窗的顶部。
  • 表格布局 为HTML表格的部分样式化设计的特性可以通过display: table和相关属性用于非表元素。
  • 多列布局 Multi-column布局属性可以使块的内容按列布局,就像您在报纸上看到的那样。

2.2 display属性

在CSS中实现页面布局的主要方法都涉及指定display属性的值这个属性允许我们改变默认的显示方式正常流程中的所有内容都有v的默认值;也就是说,元素的默认行为方式。例如,英文段落在另一个段落下面显示的事实是因为它们使用了display: block样式。如果在段落内的某些文本周围创建链接,该链接将与文本的其余部分保持内联,而不会插入新行。这是因为<a>元素默认为display: inline

您可以更改此默认显示行为。例如,<li>元素在默认情况下是display: block,这意味着在我们的英文文档中,列表项一个在另一个下面显示。如果我们将显示值更改为inline,则它们将彼此相邻显示,就像句子中的单词一样。您可以更改任何元素的display值,这意味着您可以根据语义选择HTML元素,而不必关心它们的外观。他们的样子是可以改变的

除了能够通过将项目从block 变为inline (反之亦然)来改变默认表示方式之外,还有一些更复杂的布局方法,它们以display的值开始。但是,在使用这些属性时,通常需要调用其他属性。我们讨论布局时最重要的两个值是display: flexdisplay: grid

2.3 弹性盒子(Flexbox)

Flexbox是Flexible Box Layout CSS模块的简称,它的设计目的是让我们可以很容易地在一个维度上进行布局——无论是作为行还是作为列。要使用flexbox,你需要对你想要布局的元素的父元素应用display: flex然后,它的所有直接子节点都成为flex items。我们可以在一个简单的例子中看到这一点。

设置display: flex

下面的HTML标记为我们提供了一个带有wrapper类的包含元素,其中包含三个<div>元素。默认情况下,这些元素将显示为块元素,也就是说,在我们的英语语言文档中,它们位于另一个元素的下方。

.wrapper {
    
    
  display: flex;
}
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
</div>

设置flex属性

除了可以应用于flex 容器(flex container)的属性之外,还有一些属性可以应用于flex 项(flex items)。除此之外,这些属性可以改变项flex方式,使它们能够根据可用空间扩展或收缩。

作为一个简单的例子,我们可以将flex属性添加到所有子项目中,并将其值设置为1。这将导致所有的项生长并填满容器,而不是在最后留下空间。如果有更多的空间,那么物品就会变宽;如果空间变小,它们就会变窄。此外,如果在标记中添加另一个元素,则其他项都将变小,以便为它腾出空间;这些物品加在一起继续占据所有的空间。

.wrapper {
    
    
  display: flex;
}

.wrapper > div {
    
    
  flex: 1;
}

注意:这是一个非常简短的介绍什么是可能在Flexbox。要了解更多信息,请参阅我们的Flexbox 文章。

2.4 网格布局(Grid Layout)

flexbox是为一维布局设计的,而Grid layout是为二维布局设计的——将东西排成行和列。

设置 display: grid

与flexbox类似,我们使用特定的显示值display: grid来启用Grid Layout。下面的示例使用了与flex示例类似的标记,带有一个容器和一些小元素。除了使用display: grid之外,我们还分别使用grid-template-rowsgrid-template-columns属性为父对象定义了一些行和列轨迹。我们定义了三列,每列1fr,以及两行100px。我们不需要给子元素设置任何规则;它们被自动放置在我们的网格创建的单元格中。

.wrapper {
    
    
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px 100px;
  gap: 10px;
}
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
  <div class="box5">Five</div>
  <div class="box6">Six</div>
</div>

在网格上放置项

一旦你有了一个网格,你就可以显式地把你的项目放在上面,而不是依赖于上面看到的自动放置行为。在下面的示例中,我们定义了相同的网格,但这次使用了三个子项。我们已经使用grid-columngrid-row属性设置了每个条目的开始行和结束行。这将导致项跨越多个轨道。

.wrapper {
    
    
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px 100px;
  gap: 10px;
}

.box1 {
    
    
  grid-column: 2 / 4;
  grid-row: 1;
}

.box2 {
    
    
  grid-column: 1;
  grid-row: 1 / 3;
}

.box3 {
    
    
  grid-row: 2;
  grid-column: 3;
}
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
</div>

注意:这两个例子只是网格布局的一个小例子。要了解更多信息,请参阅我们的网格布局文章。

本指南的其余部分涵盖了其他布局方法,这些方法对页面的主布局不太重要,但仍然有助于实现特定的任务。通过理解每个布局任务的本质,你很快就会发现,当你查看设计的特定组件时,最适合它的布局类型通常会很清楚。

2.5 Floats

浮动一个元素会改变该元素以及在正常流程中跟随它的块级元素的行为。被浮动元素向左或向右移动,并从正常流中移除,周围的内容围绕其浮动。

浮动属性有四个可能的值:

  • left -使元素向左浮动。
  • right -将元素向右浮动。
  • none -指定不浮动。这是默认值。
  • inherit- 指定浮动属性的值应该从元素的父元素继承。

在下面的例子中,我们将<div>浮动在左侧,并在右侧设置margin,以使周围的文本远离它这为我们提供了文本围绕框元素的效果,这是你在现代网页设计中所需要知道的关于浮动的大部分内容。

.box {
    
    
  float: left;
  width: 150px;
  height: 150px;
  margin-right: 30px;
}
<h1>Simple float example</h1>

<div class="box">Float</div>

<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam
  dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus
  ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus
  laoreet sit amet. 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. In vitae convallis lacus. Aliquam erat
  volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros
  pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec
  lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien.
</p>

注意:在我们关于float和clear属性的课程中对float进行了充分的解释。在Flexbox和Grid Layout等技术出现之前,浮动被用作创建列布局的方法。你可能仍然会在网上遇到这些方法;我们将在遗留布局方法一课中介绍这些方法。

2.6 定位技术

定位允许您将元素从常规流中放置的位置移动到另一个位置定位不是一种创建页面主要布局的方法;它更多的是关于管理和微调页面上特定项的位置。

但是,有一些有用的技术可用于获取依赖于position属性的特定布局模式。理解定位也有助于理解常规流,以及将项移出常规流的含义。

以下是你应该了解的五种定位:

  • 静态定位(Static positioning)是每个元素的默认设置。它的意思是“把元素放到文档布局流程中的正常位置——这里没有什么特别的”。
  • 相对定位(Relative positioning)允许您修改元素在页面上的位置,使其相对于其在正常流程中的位置移动,以及使其与页面上的其他元素重叠
  • 绝对定位(Absolute positioning)将元素完全移出页面的正常布局流程,就像它位于自己单独的图层上一样从那里,您可以将其固定到相对于其最近定位祖先的边缘的位置(如果没有定位其他祖先,则变为<html>)。这对于创建复杂的布局效果非常有用,例如选项卡框,其中不同的内容面板彼此重叠,并根据需要显示和隐藏,或者默认情况下位于屏幕外的信息面板,但可以使用控制按钮在屏幕上滑动。
  • 固定定位(Fixed positioning)非常类似于绝对定位,除了它固定一个元素相对于浏览器视口,而不是另一个元素。这对于创建持久的导航菜单等效果非常有用,当其余内容滚动,该菜单总是在屏幕上的同一位置。
  • 粘性定位(Sticky positioning)是一种较新的定位方法,它使元素的行为类似position: relative,直到它到达从视口中定义的偏移量,此时它的行为类似position: fixed

简单定位示例

为了使您熟悉这些页面布局技术,我们将向您展示几个快速示例。我们的示例都将采用相同的HTML结构(一个标题后面跟着三个段落),如下所示:

<h1>Positioning</h1>

<p>I am a basic block level element.</p>
<p class="positioned">I am a basic block level element.</p>
<p>I am a basic block level element.</p>

默认情况下,该HTML将使用以下CSS样式:

body {
    
    
  width: 500px;
  margin: 0 auto;
}

p {
    
    
  background-color: rgb(207, 232, 220);
  border: 2px solid rgb(79, 185, 227);
  padding: 10px;
  margin: 10px;
  border-radius: 5px;
}

相对定位

相对定位允许您将项从常规流中的默认位置偏移。这意味着你可以完成一个任务,比如把一个图标向下移动一点,使它与一个文本标签对齐。为此,我们可以添加以下规则来添加相对定位:

.positioned {
    
    
  position: relative;
  top: 30px;
  left: 30px;
}

这里我们给中间段落一个relativeposition值。它自己不做任何事情,所以我们还添加了topleft属性。它们的作用是将受影响的元素向下和向右移动这似乎与您所期望的相反,但您需要将其视为元素在其左侧和顶部被推动,从而导致其向右和向下移动。

绝对定位

绝对定位用于将元素完全从正常流中移除,而使用包含块边缘的偏移量来定位它。

回到我们最初的非定位示例,我们可以添加以下CSS规则来实现绝对定位:

.positioned {
    
    
  position: absolute;
  top: 30px;
  left: 30px;
}

这里,我们给中间段落的position值为absolute,并赋予与之前相同的topleft属性。

这是非常不同的!定位元素现在已经完全与页面布局的其余部分分离,并位于页面布局的顶部。其他两个段落现在放在一起,就好像它们的被定位的兄弟元素不存在一样。top和left属性对绝对定位元素的影响与对相对定位元素的影响不同。在这种情况下,偏移量是从页面的顶部和左侧计算的。可以改变父元素,使其成为这个容器,我们将在定位中看到这一点。

固定定位

固定定位将元素从文档流中移除,其方式与绝对定位相同。但是,不是从容器中应用偏移量,而是从视窗中应用偏移量。由于项相对于视口保持固定,因此我们可以创建这样的菜单效果,当页面在它下面滚动时,它保持固定。

对于这个例子,我们的HTML包含三个文本段落,以便我们可以滚动页面,以及一个属性为position: fixed的盒子。

<h1>Fixed positioning</h1>

<div class="positioned">Fixed</div>

<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam
  dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus
  ut, rutrum luctus orci.
</p>

<p>
  Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. 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>
  In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet
  turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas
  augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id
  ornare felis, eget fermentum sapien.
</p>
.positioned {
    
    
  position: fixed;
  top: 30px;
  left: 30px;
}

粘性定位

粘性定位是我们可以使用的最后一种定位方法。它混合了相对定位和固定定位。当一个项具有position: sticky时,它将在正常流程中滚动,直到它与我们定义的视口发生偏移。在这一点上,它变得“卡住”,好像它有位置:固定应用。

.positioned {
    
    
  position: sticky;
  top: 30px;
  left: 30px;
}

注意:要了解更多关于定位的信息,请参阅我们的定位文章。

2.7 表格布局

HTML表格可以很好地显示表格数据,但是很多年前——甚至在基本的CSS被浏览器可靠地支持之前——web开发人员也习惯使用表格来进行整个网页布局,将他们的页眉、页脚、列等放在不同的表格行和列中。这在当时是可行的,但是它有很多问题:表格布局不灵活,标记非常重,难以调试,语义错误(例如,屏幕阅读器用户在导航表格布局时遇到问题)。

当您使用表格标记时,表格在网页上的外观取决于一组定义表格布局的CSS属性。这些相同的属性也可以用于布局非表格的元素,这种用法有时被描述为“使用CSS表格(using CSS tables)”

下面的例子展示了一个这样的用法。必须指出的是,使用CSS表进行布局在这一点上应该被视为一种遗留方法,并且应该只用于支持缺乏Flexbox或Grid支持的旧浏览器。

让我们来看一个例子。首先,一些创建HTML表单的简单标记。每个输入元素都有一个标签,我们还在段落中包含了一个标题。出于布局的目的,每个标签/输入对都包装在<div>中。

<form>
  <p>First of all, tell us your name and age.</p>
  <div>
    <label for="fname">First name:</label>
    <input type="text" id="fname" />
  </div>
  <div>
    <label for="lname">Last name:</label>
    <input type="text" id="lname" />
  </div>
  <div>
    <label for="age">Age:</label>
    <input type="text" id="age" />
  </div>
</form>

至于CSS,除了使用display属性外,它的大部分内容都相当普通。<form><div>s、<label>s和<input>s分别显示为表、表行和表单元格。基本上,它们的作用类似于HTML表标记,使标签和输入在默认情况下排列得很好。然后我们所要做的就是添加一些大小,边距等,让一切看起来更好一点,我们就完成了。

你会注意到标题段落已经被赋予了display: table-caption;,这使得它的行为像一个表格<caption>,和caption-side: bottom;为了样式化的目的,告诉标题位于表的底部,即使标记位于源文件中的<input>元素之前。这就提供了很好的灵活性。

您还可以在css-tables-example.html中查看这个示例(也请参阅源代码)。

注意:表格布局与本页的其他主题不同,由于它的遗留应用程序,在本模块中不会进一步讨论。

2.8 多列布局

多列布局CSS模块为我们提供了一种按列布局内容的方式,类似于报纸上的文本流。由于用户必须上下滚动,因此在web环境中上下地阅读列不太有用,然而,将内容排列到列中可能是一种有用的技术。

要将块转换为多列容器,我们可以使用column-count属性(它告诉浏览器我们希望拥有多少列)column-width属性(它告诉浏览器用指定宽度的尽可能多的列填充容器)。

在下面的示例中,我们从包含<div>元素的HTML块开始,该元素带有container类。

<div class="container">
  <h1>Multi-column Layout</h1>

  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
    aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
    pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at
    ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta.
  </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 eget aliquam lorem.
  </p>

  <p>
    Vivamus tristique elit dolor, sed pretium metus suscipit vel. Mauris
    ultricies lectus sed lobortis finibus. Vivamus eu urna eget velit cursus
    viverra quis vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum
    sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus
    mus.
  </p>
</div>

我们在该容器上使用200像素的列宽,使浏览器创建尽可能多的200像素的列。列之间剩余的空间将被共享。

.container {
    
    
  column-width: 200px;
}

猜你喜欢

转载自blog.csdn.net/chinusyan/article/details/132761702