快速提高前端布局效率的小技巧

在布局中,对于每块功能的 DOM 结构,我们一般使用一个带有 wrapper 类元素把它包裹起来,让代码或者网页内容更易于阅读。为此,我们一般使用wrapper 或者 container。在CSS 中使用wrapper可能有多种方式,这些方式中,有些会带来一些问题。

在本文中,将介绍 CSS中 的 wrapper 布局,它们如何工作,如何使用它们以及何时不使用它们。 请注意,在本文中,可能会提到wrappercontainer这两个术语,它们的含义相同。

wrapper 简介

当我们说到 wrappercontainer,实际上是指一组元素被包装包含在另一个元素内。 我们可以为 <body> 元素添加一个 wrapper类,这样我们就不用额外元素,如下所示:

body {
    max-width: 1170px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 16px;
    padding-right: 16px;
}

但是,将 wrapper添加到<body>元素是不切实际。 wrapper元素可以防止子项超出其边界。 考虑下图:

1.png

我们这里有asidemain元素,它们被放在了wrapper 元素中。当然,.wrapper元素有一个宽度。

<div class="wrapper">
    <aside>...</aside>
    <main>...</main>
</div>

如果没有wrapper,子元素将粘附在屏幕的边缘。这可能会让用户非常恼火,尤其是在大屏幕上。

2.png

上图显示了当没有用wrapper进行包裹时元素是如何展开的,用户不应该体验这种行为。我们来解释一下背后的原因。

为什么页面上 wrapper 有必要的

通过多加一层 wrapper 布局,有很多好处:

  1. 使内容更具可读性。 没有多加一层 wrapper,文本和图像之类的内容就可以拉伸以占据整个屏幕宽度。 对于小屏幕,这似乎可以。 但是,对于大屏幕,这是非常烦人的。
  2. 对设计元素进行分组可以更好地增加间距。
  3. 在没有wrapper的情况下,将设计元素划分为列是不容易完成的。

在CSS中实现 wrapper

目前我们已经了解了wrapper基础知识和优点,接下来我们来具体的看看在 CSS 如何使用它。

设置宽度

3.png

实现wrapper第一件事就是要确认它的宽度。 而宽度如何这取决于 UI 的设计。 一般来说,最常用宽度是1000px-1300px。 例如,流行的框架Bootstrap使用1170px的宽度。

.wrapper {
    width: 1170px;
}

但是,不建议使用width属性,因为当屏幕尺寸小于1170像素时,会出现水平滚动。 可以max-width 来解决这个问题。

.wrapper {
    width: 1170px;
    max-width: 100%;
}

我们还可以更简单点,仅使用 max-width

.wrapper {
    max-width: 1170px;
}

现在有了宽度,我们可以将它居中 。

居中 wrapper

4.png

为了让 wrapper 居中,使用让左右外边距的值为 auto,如下所示:

.wrapper {
    max-width: 1170px;
    margin: 0 auto;
}

根据 CSS 规范,下面是margin: 0 auto;的工作原理

如果'margin-left'和'margin-right'均为'auto',则它们的使用值相等。 这会让元素相对于包含块的边缘水平居中。

这里我使用margin:0 auto,这基本上将顶部和底部的margin重置为零,并使其左侧和右侧为auto。 使用此功能会有一些后果,这将在本文后面介绍。 目前,建议使用简化版边距:

.wrapper {
    max-width: 1170px;
    margin-left: auto;
    margin-right: auto;
}

在左侧和右侧添加 padding

5.png

要考虑的重要事项是在左侧和右侧添加padding。 当视口大小小于 wrapper 的最大宽度时,这将导致 wrapper 边缘粘在视口上。

.wrapper {
    max-width: 1170px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 16px;
    padding-right: 16px;
}

通过添加padding,我们可以确保从左右两边得到一个16px的偏移量,即使视口的大小小于最大宽度。padding作为一种保护策略,避免在宽度不足时让 wrapper 粘在视口边缘。

使用百分比的 wrapper

我收到了有关使用百分比宽度(如max-width:90%)用于包装器而不是使用padding-left和padding-right的答复。

我经常可以到直接在 'wrapper' 使用百分比宽度,如max-width: 90%。而不是使用padding-leftpadding-right

6.png

在大屏幕上,宽度90%太大了,我们可以使用媒体查询来覆盖它。

.wrapper {
    max-width: 90%;
    margin-left: auto;
    margin-right: auto;
}

/* A media query for a large screen */
@media (min-width: 1170px) {
    .wrapper {
        max-width: 1170px;
    }
}

使用百分比宽度,我们多添加了一个额外的步骤。 通过使用固定的宽度值,我们可以轻松地避免此步骤。 对应于这种方案,我们可以将width: 90%max-width:1170px属性结合在一起。

.wrapper {
    width: 90%;
    max-width: 1170px;
    margin-left: auto;
    margin-right: auto;
}

这是一个有趣的方法,但我更喜欢自己添加padding,而不是依赖于百分比宽度。

Wrapper 的display类型

由于wrapper<div>,因此默认情况下它是块级元素。 问题是,当要将wrapper内的内容放置在grid中时,该怎么办? 我们直接在 wrapper 上添加 display: grid

我不建议您这样做,因为这与关注点分离的概念背道而驰。 wrapper用于包裹其内容,仅此而已。 如果需要使用grid布局,则在多添加一层 <div>专门用来 grid 布局会更容易也更清晰还容易维护。

<div class="wrapper">
    <!-- Content -->
</div>

不建议这样做,因为wrapper元素可以在另一页上使用,这可能会无意间破坏布局。

.wrapper {
    display: grid;
    grid-template-columns: 2fr 1fr;
    grid-gap: 16px;
}

更好的解决方案如下:

<div class="wrapper">
    <div class="featured-news">
        <!-- Elements that needs to be placed in a grid -->
    </div>
</div>
.featured-news {
    display: grid;
    grid-template-columns: 2fr 1fr;
    grid-gap: 16px;
}

在 wrapper 之间添加 margin

上面我们说到不建议使用简写版本来居中wrapper 元素:

.wrapper { 
    margin: 0 auto;
}

虽然它可以工作,但当页面上有多个wrapper ,并且需要在它们之间添加间距时,它可能会令人困惑。由于布局需要,我们需要在 wrapper 上多添加一个类,如 wrapper-variation,那么margin有可能无法正常工作。

.wrapper-variation {
    margin-top: 50px;
}

.wrapper { 
    max-width: 1170px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 16px;
    padding-right: 16px;
}

.wrapper-variation元素的margin无法使用,因为它已被margin: 0 auto覆盖。为避免此类混淆,建议在这种情况下使用非简写格式 。

现在让我们来添加页边距。在每个项目中,我都准备了一组用于marginpadding的实用工具类,在必要时使用它们,考虑下图。

7.png

<div class="wrapper mb-5"></div>
<section>
    <div class="wrapper"></div>
</section>
<div class="wrapper"></div>
.mb-5 {
    margin-bottom: 3rem !important;
}

这样,wrapper 的 CSS保持原样,并且使用附加的 CSS 类添加了间距。 现在,你可能会问,为什么可以在一个页面上添加多个wrapper? 在上面的HTML中,两个wrapper之间有一个<section>元素。

在这里使用!important很好,因为实用程序类的要点是强制属性,通过添加!important,我们可以确保做到这一点。

全屏中的 Wrapper

在某些情况下,如果某个部分的背景视口宽度为100%,并且其中包含wrapper`,则可能会出现这种情况。 与上一个示例中介绍的类似。

<section>
    <div class="wrapper"></div>
</section>
<section>
    <div class="wrapper"></div>
</section>

<section>的宽度是 100%。 我们可以向其添加背景颜色或图像。 在其中,wrapper可防止内容占据视口的整个宽度。

8.png

主内容需要添加 wrapper 吗?

这要看情况。 让我们探讨两种最常用内容区间的设计。

第一个以其内容为中心,并受特定宽度限制。

9.png

第二个将其内容扩展到主内容的边缘。

10.png

为了更好地理解这两种模式,我们来一起探讨如何构建其中的每种模式。

内容居中

你可能想在不使用 wrapper前提下让内容居中。

<section class="hero">
    <h2>How to make bread at home</h2>
    <p>....</p>
    <p><a href="/sign-up">Sign up</a></p>
</section>

在上面的 HTML 中,可以使用text-align将内容居中

.hero { text-align: center; }

除非你调整浏览器窗口的大小,不然你可能会忽略掉这个问题。

内容紧贴边缘

由于左侧和右侧没有padding,因此内容将粘在边缘上。 这对用户是不友好的,因为使内容浏览变得更加困难。

11.png

大屏幕的行长

在大屏幕上,由于行长太长,段落文本可能很难看清。 根据应用于 Web 的版式样式元素,行的建议字符数为4575。超出该范围的任何字符都会使阅读更加困难。

12.png

为避免上述问题,可以使用wrapper来防止文本长度变得过长并在移动设备中增加间距。

<section class="hero">
    <div class="hero__wrapper">
            <h2>How to make bread at home</h2>
            <p>...</p>
            <p><a href="/sign-up">Sign up</a></p>
    </div>
</section>

这里使用了hero__wrapper类,因为该wrapper可能仅是针对hero部分定制的,因此它可以具有一定的宽度,该宽度小于通用的wrapper元素。

.hero__wrapper {
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 16px;
    padding-right: 16px;
}

为了使内容居中,可以根据具体情况使用具体的属性。 对于此示例,使用text-align:center足以使内容居中。

wrapper使用 CSS 变量

只用一种尺寸的wrapper很少。 wrapper的宽度可以小也可以大,具体取决于内容。 通过利用 CSS 变量,我们可以创建一个更现代的wrapper,它拥有极大的灵活性。 考虑以下内容:

<div class="wrapper"></div>
.wrapper {
    max-width: var(--wrapper-width, 1170px);
    margin-left: auto;
    margin-right: auto;
    padding-left: 16px;
    padding-right: 16px;
}

var有两个值,第一个值是变量--wrapper-width,第二个值是1170px,如果未设置--wrapper-width变量,则将使用1170px

当然,我们可以直接在标签内对 --wrapper-width 进行赋值,这样就能动态设置我们想要的值。

<div class="wrapper" style="--wrapper-width: 720px"></div>

如果你不使用 CSS 变量的方式,也可以通过多加一个类来解决:

<div class="wrapper wrapper--small"></div>
.wrapper--small {
    --wrapper-width: 720px;
    /* this will override the default wrapper width. */
}

使用 display: contents

首先,简要介绍一下这个属性。CSS中的每个元素都是一个盒子,该盒子包含contentpaddingmarginborderdisplay: contents样式规则使div元素不产生任何边界框,因此元素的marginborderpadding部分都不会渲染。然而,继承的属性如颜色(color)和字体(font)却能照常影响到子元素。

<header class="site-header">
    <div class="wrapper site-header__wrapper">
            <!-- Header content -->
    </div>
</header>
.site-header__wrapper {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}

13.png

在上面的示例中,你可能需要让标题扩展到整个页面的宽度,而不是受wrapper宽度的限制。

.site-header__wrapper {
    display: contents;
}

.site-header {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}

这样,.wrapper元素将被隐藏(类似)。 现在,当将display:flex应用于.site-header元素时,.wrapper的后代项将成为.site-header的子项。

14.png

流动背景,固定内容

Lea Verou 在她的《CSS Secrets》一书中介绍了一种有趣的技巧,该技巧可用于流动背景(占据整个视口宽度)且内部带有wrapper部分。 让我们回顾一下常见的做法。

<section>
    <div class="wrapper"></div>
</section>
section {
    background-color: #ccc;
}

.wrapper {
    max-width: 1170px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 16px;
    padding-right: 16px;
}

margin-left: automargin-right: auto的工作方式是计算视口宽度的一半减去内容宽度。 使用padding也可以做到。

15.png

section {
  padding: 1rem calc(50% - 585px);
}

这样还有问题,在移动设上内容将粘贴备的边缘,一种解决方案如下:

section {
  padding: 1rem;
}

@media (min-width: 1170px) {
    section {
      padding: 1rem calc(50% - 585px);
    }
}

英文原文地址:https://ishaded.com/article/styling-css/

作者:Ahmad shaded


推荐文章
怎么关闭VPN?

关闭vpn的操作方法:1、打开IE浏览器,点击右上角的工具2、点击工具后,选择选项3、点击选项后,弹出Internet选项框,点击连接4、然后点击局域网设置5、然后把代理服务器下面的勾勾去掉6、勾勾去

C语言关系运算符详解

在上节《C语言ifelse语句》中看到,if的判断条件中使用了、!=等符号,它们专门用在判断条件中,让程序决定下一步的操作,称为关系运算符(RelationalOperators)。 关系运算符在使

Linux RPM包安装、卸载和升级(rpm命令)详解

本节讲解如何使用rpm命令对RPM二进制包进行安装、卸载和升级操作。 我们以安装apache程序为例。因为后续章节还会介绍使用源码包的方式安装apache程序,读者可以直观地感受到源码包和RPM包的

zigbee与wifi的区别是什么?

zigbee在蓝牙技术的使用过程中,人们发现蓝牙技术尽管有许多优点,但仍存在许多缺陷。对工业,家庭自动化控制和遥测遥控领域而言,蓝牙技术显得太复杂,功耗大,距离近,组网规模太小等,……而工业自动化对无

JSP setProperty动作

动作标记通常与动作标记一起使用,它以请求中的参数给创建的JavaBean中对应的属性赋值,通过调用bean中的setXxx()方法来完成。其语法格式如下: {   property="*"   |

Linux dump命令用法详解:备份分区、文件或目录

在系统学习dump命令之前,由于CentOS6.x系统默认是没有安装此命令的,因此需要我们手动安装dump命令,安装命令如下: [root@localhost~]#yum-yinstalldump

Linux自动挂载(配置/etc/fatab)详解

了解了mount命令之后,读者可能会问,系统如何在开机时自动挂载硬盘,它又是怎么知道哪些分区是需要挂载的呢? 很简单,Linux通过/etc/fstab配置文件来确定这些信息,这个配置文件对所有用户

Spring Cloud集成Spring Data Redis

Redis是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 Redis是一个高性能的key-value数据库,同时支持多

C++ deque添加和删除元素方法详解

deque和vector都有成员函数push_back()和pop_back(),它们在序列尾部添加或删除元素的方式相同。deque也有成员函数push_front()和pop_front(),可以在

HBase的安装与配置(非常详细)

本节讲述如何安装、部署HBase集群,以及如何通过命令行方式来完成HBase集群的启动和停止。 首先介绍部署HBase之前需要做的准备工作,如Java、SSH和Hadoop这些先决条件的配置;然后介

C语言中什么是运算符?

C语言运算符在C语言中,运算符是一种告诉编译器执行特定的数学或逻辑操作的符号;它是构造C语言表达式的工具。C语言内置了丰富的运算符,除了控制语句和输入输出以外的几乎所有的基本操作都为运算符处理。除了常

C++11 nullptr:初始化空指针

实际开发中,避免产生“野指针”最有效的方法,就是在定义指针的同时完成初始化操作,即便该指针的指向尚未明确,也要将其初始化为空指针。 所谓“野指针”,又称“悬挂指针”,指的是没有明确指向的指针。野指

PHP preg_quote():对正则表达式进行转义

PHPpreg_quote()函数用来对正则表达式字符串进行转义,也就是在特殊字符前边增加一个反斜杠\,其语法如下: preg_quote($str[,$delimiter=NULL]) 参数说明如

编写第一个Qt程序

学习一种编程语言或编程环境,通常会先编写一个“HelloWorld”程序。我们也用QtCreator编写一个“HelloWorld”程序,以初步了解QtCreator设计应用程序的基本过程,对使用Qt

C++ peek函数用法详解

peek成员函数与get类似,但有一个重要的区别,当get函数被调用时,它将返回输入流中可用的下一个字符,并从流中移除该字符;但是,peek函数返回下一个可用字符的副本,而不从流中移除它。 因此,g

MySQL中count(1)和count(*)的区别是什么?

count是一种最简单的聚合函数,一般也是我们第一个开始学习的聚合函数.很多人认为count(1)执行的效率会比count()高,原因是count()会存在全表扫描,而count(1)可以针对一个字段

13 个关于前端的安全提示

无论你是React.js、Angular、Vue.js程序员还是前端页面仔,你的代码都可以成为引诱黑客入侵的大门。作为前端开发人员,我们最关心的是性能、SEO和UI/UX——安全性却经常被忽略。你可能

MySQL默认值(DEFAULT)

默认值(Default)的完整称呼是“默认值约束(DefaultConstraint)”,用来指定某列的默认值。在表中插入一条新记录时,如果没有为某个字段赋值,系统就会自动为这个字段插入默认值。 例

SEO关键字密度深入探讨

关于关键字密度在《搜索引擎如何对网页进行排名》中已经提到过,指的是在一个页面中,关键字(keyword)或关键字段(keyphrase)占该页面中总的文字的比例。 关键词密度对搜索引擎的优化起到关键

前端学习Selenium的十大理由

如果你正在阅读本文,那么可能希望从手动测试升级为自动化测试。你是对的,因为你需要学习Selenium。我这样说是因为自动化测试已经风靡全球,而且业界正很缺少Selenium认证专家。你可能还想知道,怎