CSS内容布局

Wesley13
• 阅读 678

网页是由不同内容块构成的:标题、段落、链接、列表、图片、视频,等等。

1.定位

定位并不适合总体布局,因为它会把元素拉出页面的正常流。

  • 元素的初始定位方式为静态定位(static),即块级元素垂直堆叠
  • 把元素设置为相对定位(relative),然后可以相对于其原始位置控制该元素的偏移量,同时又不影响其周围的元素。
  • 绝对定位(absolute)支持精确定位元素,相对于其最近的定位上下文。
  • 固定定位(fixed)的定位上下文为浏览器视口。

1.1 绝对定位

1.1.1 绝对定位的应用场景

绝对定位非常适合创建弹出层、提示和对话框这类覆盖于其他内容之上的组件。

如果没有显式声明元素大小,那么绝对定位元素的大小由自身包含内容的多少来决定。如果相对于定位上下文的各个边声明偏移量,那么元素会被拉伸以满足设定的规则。

<header class="photo-header">
    <img src="images/big_spaceship.jpg" alt="An artist’s mockup of the ”Dragon” spaceship">
    <div class="photo-header-plate">
        <h1>SpaceX unveil the Crew Dragon</h1>
        <p>Photo from SpaceX on <a href="https://www.flickr.com/photos/spacexphotos/16787988882/">Flickr</a></p>
    </div>
</header>


.photo-header {
    position: relative;
}

.photo-header-plate {
    position: absolute;
    right: 4em;
    bottom: 4em;
    left: 4em;
    /* 省略 */
}

1.1.2 定位与z-index

z-index是堆叠元素的次序。 静态定位(static)以外的元素会根据它们在代码树中的深度依次叠放。就像打扑克发牌一样,后发的牌会压在先发的牌上面。它们的次序可以通过z-index来调整。 设置了z-index的元素,只要值是正值,就会出现在没有设置z-index的元素上方。尚未设置z-index的元素在z-index值为负的元素上方。 **堆叠上下文:**所有z-index不是auto的定位元素都会在这个上下文中排序。 堆叠上下文是由特定属性和值创建的。 在一个堆叠上下文内部,无论z-index值多大或多小,都不会影响其他堆叠上下文。 设置小于1的opacity值也可以触发新的堆叠上下文。

2.水平布局

通常,页面会随内容增加沿垂直方向扩展。后来添加的任何块容器(divarticleh1~`h6`,等等)都会垂直堆放起来,因为块级元素的宽度是自动计算的。

2.1 使用浮动

很多CSS布局会用到的一种基本技术:让浮动的元素构成一行中的列。

figure {
  float: right;
  max-width: 50%;
}

因为浏览器对浮动的支持极为普遍,所以浮动也成为了各种水平布局中的常用技术。

2.2 行内块布局

<p class="author-meta">
  <!-- image from Jeremy Keith on Flickr: https://flic.kr/p/dwFRgH -->
  <img class="author-image" src="images/author.jpg" alt="Arthur C. Lark">
  <span class="author-info">
    <span class="author-name">Written by Arthur C. Lark</span>
    <a class="author-email" href="mailto:arthur.c.lark@example.com">arthur.c.lark@example.com</a>
  </span>
</p>


.author-image,
.author-info {
  display: inline-block;
  /* 将这个行内块的垂直中心点与这行文本x高度的中心点对齐。 */
  vertical-align: middle;
}
.author-name,
.author-email {
  display: block;
}

对于每个块都占据确切宽度的水平布局而言,空白是一个突出的问题。

.navbar ul {
  /* 省略 */
  list-style: none;
  padding: 0;
  font-size:0;
}

.navbar li {
  text-transform: uppercase;
  display: inline-block;
  text-align: center;
  width: 25%;
  /* 使用box-sizing: border-box 确保每一项的边框及内边距都包含在各自25%的宽度以内。 */
  box-sizing: border-box;
  font-size:1rem;
}

.navbar li a {
  display: block;
  text-decoration: none;
  line-height: 1.75em;
  padding: 1em;
}

HTML源代码中的换行符被渲染成了空白符。 把包含元素的font-size设置为0,从而让每个空格的宽度为0。

使用表格显示属性实现布局:

.navbar ul {
  display: table;
  table-layout: fixed;
  width: 100%;
  height: 100px; /* 结合vertical-align: middle使用以实现垂直对齐 */
}
.navbar li {
  display: table-cell;
  width: 25%;
  vertical-align: middle; /* 垂直对齐 */
}

表格行中每一列的宽度有两种算法。

  • 默认情况下,浏览器会使用"自动"算法。根据自身单元格内容所需的宽度来决定整个表格的宽度。
  • "固定"表格布局(table-layout:fixed)。列宽由表格第一行的列决定。

3.Flexbox

Flexbox是CSS提供的用于布局的一套新属性。这套属性包含针对容器(弹性容器,flex container)和针对对其直接子元素(弹性项,flex item)的两类属性。 Flexbox已经得到主流浏览器新版本的广泛支持。

3.1 理解Flex方向:主轴与辅轴

Flexbox可以针对页面中某一区域,控制其中元素的顺序、大小、分布及对齐。这个区域的盒子默认沿水平方向排列(这个排列方向称为主轴)。 与主轴垂直的方向称为辅轴。 Flexbox布局中最重要的尺寸是主轴方向的尺寸(主尺寸):水平布局时的宽度或垂直布局时的高度。

.navbar ul {
    display: flex; /* 默认flex-direction: row */
}

CSS内容布局

导航条的链接项水平排列,而且根据各自的内容进行了收缩适应。 所有链接项集中在左侧,是从左到右书写的语言环境下的默认行为。我们可以使用flex-direction设置为row-reverse,那么所有链接项就会集中到右侧。 如果不指定大小,Flex容器内的项目会自动收缩。也就是说,一行中的各项会收缩到各自的最小宽度。 对Flex的子项指定值为auto外边距:

.navbar li:first-child {
    margin-right: auto;
}

CSS内容布局

3.2 对齐与空间

Flexbox对子项的排列有多种方式。沿主轴的排列叫排布(justification),沿辅轴的排列则叫对齐(alignment)。 用于指定排布方式的属性是justify-content,其默认值是flex-start,表示按照当前文本方向排布(向左对齐)。 Flexbox不允许指定个别项的排布方式。

.navbar ul {
    justify-content: flex-end; /* 向右对齐 */
}

默认情况下,Flex子项会沿辅轴方向填满Flex容器。 控制辅轴对齐的属性align-items,其默认值是stretch(拉伸)。也就是说,子项默认拉伸,以填满可用空间。

.navbar ul {
    align-items: flex-start;
    min-height: 100px;
}

CSS内容布局

我们还可以使用align-items: baseline将子项中文本的基线与容器基线对齐。

除了同时对齐所有项,还可以在辅轴上指定个别项的对齐方式。

.navbar ul {
    align-items: flex-end;
    min-height: 100px;
}
.navbar li:first-child {
    align-self: flex-start; /* 指定个别项的对齐方式 */
    margin-right: auto;
}

CSS内容布局

Flex中的垂直对齐:

<div class="flex-container">
    <div class="flex-item">
        <h2>Not so lost in space</h2>
        <p>This item sits right in the middle of its container, regardless of the dimensions of either.</p>
    </div>
</div>


.flex-container {
    height: 100%;
    display: flex; /* 将容器设置为flex。 */
    background-color: #12459e;
}
.flex-item {
    max-width: 25em;
    padding: 2em;
    margin: auto; /* 容器中的各项的自动外边距会扩展相应方向的空间。 */
    background-color: #fff;
}

CSS内容布局

Flex容器中有多个元素的垂直对齐:

<p class="author-meta">
    <img class="author-image" src="images/author.jpg" alt="Arthur C. Lark">
    <span class="author-info">
        <span class="author-name">Written by Arthur C. Lark</span>
        <a class="author-email" href="mailto:arthur.c.lark@example.com">arthur.c.lark@example.com</a>
    </span>
</p>


.author-meta {
    display: flex;
    align-items: center; /* 垂直对齐 */
    justify-content: center; /* 水平排布 */
}
.author-name,
.author-email {
    display: block;
}

CSS内容布局

3.3 可伸缩的尺寸

Flexbox支持对元素大小的灵活控制。这一点既是实现精确内容布局的关键,也是迄今为止Flexbox中最复杂的环节。 Flex的意思是“可伸缩”,体现在3个属性中:

  • flex-basis(控制主轴方向上的“首选”大小,默认值为auto。)
  • flex-grow(弹性系数 ,默认为0。)
  • flex-shrink(弹性系数,默认为1。)

使用flex简写属性一次性设置flex-growflex-shrinkflex-basis属性,值以空格分隔:

.navbar li {
    flex: 1 0 0%; /* flex: flex-grow  flex-shrink  flex-basis */
}

flex-grow: 1 中的1表示占整体的“几份”。 简写法中的flex-basis必须带单位,因此这里要么加百分号,要么就写成0px。 把flex-basis的值设置为0,那在这一步就不会给项目分配空间了。这种情况下,容器内部的全部空间都会留到第二步再分配(这里第二步使用flex-grow: 1 来确定具体项目的尺寸)。 当项目宽度总和超过容器宽度时,Flexbox会按照flex-shrink属性来决定如何收缩它们: 每个项目先用自己的flex-shrink乘以自己的flex-basis,然后再用乘积除以每一项的flex-shrinkflex-basis的乘积之和,最后再拿得到的比例系数去乘以超出的宽度,从而得到该项目要收缩的空间数量。 推荐阅读flex - CSS(层叠样式表) | MDN

3.4 Flexbox布局

Flexbox支持让内容排布到多行或多列。

<ul class="tags">
    <li><a href="https://my.oschina.net/Binary_planet">Binary planet</a></li>
    <li><a href="https://my.oschina.net/Carbon_planet">Carbon planet</a></li>
    <--! 还有更多··· -->
</ul>


.tags {
    display: flex;
    flex-wrap: wrap; /* 允许折行 */
    margin: 0;
    padding: 1em;
    list-style: none;
}
.tags li {
    display: inline-block; /* 行内块 */
    margin: .5em;
}

CSS内容布局

相关阅读:行内元素和块元素以及行内块元素的特点

折行与方向:

.tags {
    /* 省略 */
    flex-direction: row-reverse; /* 从右向左排布 */
}

CSS内容布局

.tags {
    /* 省略 */
    flex-direction: row-reverse; /* 从右向左排布 */
    flex-wrap: wrap-reverse; /* 向上折行 */
}

CSS内容布局

多行布局中可伸缩的大小:

.tags li {
    flex: 1 0 auto;
}

稍微缩小一点浏览器窗口,就会导致最后一个标签折行。 CSS内容布局

使用max-width限制可伸缩的范围。

.tags li {
    flex: 1 0 auto;
    max-width: 14em;
}

CSS内容布局

在多行布局中,我们可以相对于容器来对齐行或列。

.tags {
    display: flex;
    flex-wrap: wrap;
    align-content: stretch; /* 默认值 */
    min-height: 300px;
}

align-content: stretch 表示每一行都会拉伸以填充自己应占的容器高度。

3.5 列布局与个别排序

Flexbox的order属性:默认情况下,每个项目的order值都为0,意味着按照它们在源代码中的顺序出现。

<div class="article-teaser">
    <h2>The Dragon and other spaceships</h2>
    <div class="article-teaser-text">
        <p>There are actual spaceships, flying in space right now, probably. For example, there’s the International 
        Space Station, which is a spaceship of sorts. Well, actually it’s a space station, which is even cooler!</p>
    </div>
    <img src="images/medium_spaceship.jpg" alt="The Dragon spaceship in orbit around Earth.">
    <p class="article-teaser-more">
        <a href="https://my.oschina.net/spaceships">Read the whole Spaceship article</a>
    </p>
</div>


.article-teaser {
    display: flex;
    flex-direction: column;
}
.article-teaser img {
    order: -1; /* order的值比较小的元素先出现。 */
}

order的值不一定要连续,而且正、负值都可以。只要是可以比较大小的数值,相应的项就会调整次序。

3.6 嵌套的Flexbox布局

<div class="article-teaser-group">
    <div class="article-teaser">
        <h2>The Dragon and other spaceships</h2>
        <div class="article-teaser-text">
            <p>There are actual spaceships,
            flying in space right now, probably. For example, there’s the International Space Station, which is 
            a spaceship of sorts. Well, actually it’s a space station, which is even cooler!</p>
        </div>
        <img src="images/medium_spaceship.jpg" alt="The Dragon spaceship in orbit around Earth.">
        <p class="article-teaser-more">
            <a href="https://my.oschina.net/spaceships">Read the whole Spaceship article</a>
        </p>
    </div>
    <div class="article-teaser">
        <!-- 省略 -->
    </div>
</div>


.article-teaser-group {
  display: flex;
}

.article-teaser {
  display: flex;
  flex-direction: column;
  /* 省略 */
}
.article-teaser-more {
  margin-top: auto;
}

CSS内容布局

Flexbox的bug与提示:

  • 图片、视频,以及其他带有固定宽高比的对象,在作为可伸缩项时可能会有问题。解决方案是给这些对象加个包装元素,让包装元素作为可伸缩项。
  • Flex的可伸缩项具有所谓的“隐性最小宽度”。

参考资料:

  • 菜鸟教程
  • w3school
  • 《精通CSS》— [英] 安迪·巴德、[瑞典] 埃米尔·比约克隆德
点赞
收藏
评论区
推荐文章
Python进阶者 Python进阶者
3年前
一篇文章带你了解CSS定位知识
大家好,我是IT共享者,人称皮皮。这篇我们来讲讲CSS定位。一、Position(定位)CSS定位属性允许你为一个元素定位。它也可以将一个元素放在另一个元素后面,并指定一个元素的内容太大时,应该发生什么。元素可以使用的顶部,底部,左侧和右侧属性定位。然而,这些属性无法工作,除非是先设定position属性。他们也有不同的工作方式,这取决于定位方法。二、属
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Selenium 详解CSS定位
xpath定位是“屠龙刀”,那CSS定位就是"倚天剑了",相对xpath来说,具有语法简单,定位速度快等优点一、属性定位1、可以通过元素的id,class,tag标签这三个属性直接定位  表示id属性,如:kw.  表示class属性,如:.s\_ipt直接用标签名称,如:inpu
Stella981 Stella981
3年前
Python+Selenium自动化篇
本篇文字主要学习selenium定位页面元素的集中方法,以百度首页为例子。0.元素定位方法主要有:id定位:find\_element\_by\_id('')name定位:find\_element\_by\_name('')class定位:find\_element\_by\_class\_name(''
Wesley13 Wesley13
3年前
CSS块级元素与行内元素
CSS块级元素与行内元素行内元素与块状元素1、块级元素:可以设置width,height属性。行内元素:设置width和height无效,其宽度随其元素的内容(文字或者图片等)的宽度而变化。可以通过lineheight设置行高(行高和height是不同的东西)。2、块级元素:可以设置margin和padd
Stella981 Stella981
3年前
RobotFramework自动化测试之元素定位
前言:最近在做基于RF框架的Web自动化测试,其中涉及到元素的定位,主要用到id、name、xpath、css四中定位方法,尤其后面的两种方法特别有效,可以解决大部分的定位问题。
Wesley13 Wesley13
3年前
CSS相对定位与绝对定位
CSS相对定位设置为相对定位的元素框会偏移某个距离。“相对于”元素仍然保持其未定位前的形状,它原本所占的空间仍保留!CSS相对定位实例(http://static.oschina.net/uploads/img/201312/01164555_uxZw.gif)注意:在使用相对定位时,无论是否进行移动,元素仍然占据原来
Stella981 Stella981
3年前
CSS的相对定位和绝对定位(position)
什么是定位呢?定位(position),故名思议,就是确定元素在页面中的位置。CSS的常用定位有两种,一种是相对定位,一种是绝对定位。下面我们看例子1.<html2.<head3.<style4.div0{5./设置背景色为黄色/6.backgrou
Stella981 Stella981
3年前
CSS 分类 (Classification)
★★CSS分类属性(Classification)★★⑴CSS分类属性允许你控制如何显示元素,设置图像显示于另一元素中的何处,相对于其正常位置来定位元素,使用绝对值来定位元素,以及元素的可见度。⑵下面是常用的属性以及描述:!(https://oscimg.oschina.net/oscnet/00cb565
Stella981 Stella981
3年前
CSS 定位 (Positioning) 实例
CSS定位和浮动CSS为定位和浮动提供了一些属性,利用这些属性,可以建立列式布局,将布局的一部分与另一部分重叠,还可以完成多年来通常需要使用多个表格才能完成的任务。定位的基本思想很简单,它允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素、另一个元素甚至浏览器窗口本身的位置。显然,这个功能非常强大,也很让人吃惊。要知道,用户代理对