css mixin
在过去的几年中,CSS网格系统已经成为在网页设计中快速生成布局脚手架的一种非常流行的方式。
它们可以节省大量时间,而才华横溢的编码人员则拥有精心打造的智能系统,可以满足设计师可能需要创建的各种布局。 但是,这并不是处理基于网格的Web布局的唯一方法,今天我们将研究一种替代方法。
CSS网格系统如何工作
网格系统通常由特定数量的列(通常为十二或十六列)组成,并且能够将元素(通常为应用了类的div)设置为这些列的X宽度。
例如,内容区域可能设置为十二列中的九列,而其旁边的侧边栏则设置为三列或十二列。 布局通常还包括固定宽度的外部容器,在其中包裹行的行容器以及在列之间设置宽度的装订线。
让我们快速看一下如何使用CSS网格通用的技术来构建经典的“页眉,内容,侧边栏,页脚”网站布局:
使用CSS网格系统创建这样的布局可以非常快速和轻松。 但是,尽管提供了很多价值,但使用这样的系统也有许多弊端。 这些缺点并不意味着CSS网格系统是“坏的”,只是意味着您应该像使用任何工具一样熟悉其优缺点,以正确确定它是否适合您的特定项目。
CSS网格的缺点
尽管所有CSS网格系统都不同,但是它们之间最常见的缺点包括:
- 大量未使用的代码
完整的网格类库通常包含200到700行代码(未精简),但是在相对简单的设计中,绝大部分代码都不会使用。 - 布局限制
由于网格是预先计算的,因此它们倾向于具有难以更改的设置宽度,例如对于容器,列宽,装订线宽度。 这样,设计便被限制为只能使用这些宽度。 - 固定像素,而不是基于em / rem或基于百分比的布局
网格宽度和/或媒体查询通常基于像素值,从而无法在设计中使用更灵活和可扩展的em / rem或百分比值。
注意:有关em / rem与基于px的设计的优势的信息,请阅读从Ems中取出“ Erm ..”。 - 设置总列数
预先计算的网格倾向于使用12列或16列,这意味着如果您希望使用不同数量的整体列,则很不走运。 - 非语义标记
使用预先计算的网格类别需要在整个文档中放置大量非语义类别名称,例如“行”,“ col”等。 - 嵌套限制
通常,网格系统只能将一列彼此嵌套一两次,这限制了布局生成的复杂性和灵活性。
归根结底,设计师使用CSS网格系统的真正原因是使布局生成更快,更容易。 所以问题是:
能否同时克服上述限制,同时又轻松快捷地生成布局?
由于CSS预处理器的出现,例如LESS和SASS / SCSS ,它们可以处理变量,执行计算并根据需要通过mixins输出CSS,在很多用例中,答案是:
是的,绝对可以!
另类的预处理解决方案
我们将介绍的替代解决方案的关键是LESS和SASS / SCSS中都提供的“ mixins”。 简而言之,mixin是可重用的规则包,根据传递给它们的信息进行处理,它们可以输出不同CSS。
从这里开始,我们将假定您对什么是预处理器以及它们如何与mixin和变量一起使用具有基本的了解,因此,如果您对这些概念不熟悉,我建议您先阅读http://lesscss.org上提供的信息。 /
在开始之前,我还要指出,已经有一些LESS和SASS mixin现有库正在努力解决预先计算CSS网格的局限性,例如:
但是,我们将采用与这些库不同的方法。 同样,没有严格的对错方法,这是在决定对项目使用哪种方法时要了解利弊的问题。
注意:我将用LESS编写这些mixins,因为要使LESS比SASS进行复杂的操作要困难一些,因此SASS用户比采用其他方法更容易适应LESS mixins。
您可以使用自己喜欢的方法来编译预处理器文件,但是我将包括一个可以在Node.js / NPM和Grunt上运行的基本“ LESScompiler”软件包。 说明包含在readme.md文件中。
解决经典布局
我们在上面研究了如何使用一组典型CSS网格类创建无处不在的“页眉,内容,侧边栏,页脚”布局,利用大约200到700行代码。 现在让我们看一下如何通过LESS mixins创建相同的布局,将所需CSS数量保持在绝对最小值,不使用像素值,并维护语义标记。
首先,让我们看一下HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Classic Layout</title>
<script type='text/javascript' src='js/modernizr.js'></script>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/classiclayout.css">
</head>
<body>
<header>
</header>
<main>
<article>
</article>
<aside>
</aside>
</main>
<footer>
</footer>
</body>
</html>
请注意,在此阶段没有使用单个类,只有纯语义HTML5标签。 对于此HTML,我们将使用以下混合代码和变量来应用以下LESS代码,稍后将对此进行说明:
header, main, footer {
.Row;
background-color: #ccc;
min-height: 200 * @toRems;
}
article {
.Cols( 3 );
min-height: 500 * @toRems;
background-color: #ddd;
}
aside {
.Cols( 1 );
min-height: 500 * @toRems;
background-color: #eee;
}
...这将生成以下35行CSS:
header,
main,
footer {
max-width: 75rem;
width: 100%;
margin: 0 auto;
background-color: #ccc;
min-height: 12.5rem;
}
header:before,
main:before,
footer:before,
header:after,
main:after,
footer:after {
content: "";
display: table;
}
header:after,
main:after,
footer:after {
clear: both;
}
article {
width: 75%;
float: left;
min-height: 31.25rem;
background-color: #ddd;
}
aside {
width: 25%;
float: left;
min-height: 31.25rem;
background-color: #eee;
}
...而我们将在浏览器中以1920 x 1080的屏幕分辨率看到的结果是:
请注意,由于我们不使用固定的像素宽度设置,因此该布局已经具有单词go带来的基本响应能力。 相同的布局看起来像是1024px宽:
像这样在768像素宽:
稍后我们将讨论较小尺寸的响应性,但首先让我们检查一下用于创建上述布局的LESS混合和变量。
//
// Variables for em / rem use
//
@base_px: 16; //set to the most common base px size used in browsers, should generally be left at default
@toRems: (1 / @base_px) + 0rem; //allows you to set values as the default px size to target, which is then converted into scalable rem values.
@toEms: (1 / @base_px) + 0em; //same as above, but with em values
//
// Grid mixins
//
@default-width: 1200 * @toRems;
@default-colspan: 1;
@default-total_cols: 4;
.Row ( @width : @default-width ) {
max-width: @width;
width: 100%;
margin: 0 auto;
// clear at the end of container
&:before,
&:after {
content:"";
display:table;
}
&:after {
clear:both;
}
}
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols ) {
width: ( @colspan * (100 / @total_cols) ) + 0%;
float: left;
}
让我们逐步介绍以上内容。
容易的px到em / rem转换
//
// Variables for em / rem use
//
@base_px: 16; //set to the most common base px size used in browsers, should generally be left at default
@toRems: (1 / @base_px) + 0rem; //allows you to set values as the default px size to target, which is then converted into scalable rem values.
@toEms: (1 / @base_px) + 0em; //same as above, but with em values
代码顶部的变量使我们进行设置,可以轻松在整个样式表中输出可伸缩的em或rem值,而不是px值。 但是,使用这些变量还可以使我们以像素为单位来概念化我们的设计,因为比起31.25rem来想象500px的空间看起来更容易。
例如,在我们的基础设计中,我们不希望页眉,主元素或页脚元素始终大于1200像素。 但是,我们没有将1200px
指定为max-width
,而是通过将其乘以@toRems
变量将该值转换为rems,如下@toRems
:
1200 * @toRems;
这将输出75rem
的值,这意味着,如果浏览器或用户将默认字体大小设置为除最常见的默认像素16px之外的其他值,则整个网站布局将按比例缩放。
也可以通过使用@toEms
变量来完成同一操作以生成em
值。
.Row()混合
@default-width: 1200 * @toRems;
.Row ( @width : @default-width ) {
max-width: @width;
width: 100%;
margin: 0 auto;
// clear at the end of container
&:before,
&:after {
content:"";
display:table;
}
&:after {
clear:both;
}
}
使用的第一个mixin是.Row()
mixin。
无需使用“ .container”类,而是在我们希望元素以最大宽度为中心的任何地方调用此混合。 在我们经典布局的情况下,我们在header
, main
和footer
元素上将此混合称为。
mixin设置max-width
以及100%的width
。 每当视口小于max-width
值时,它都会使元素自动调整以填充可用空间,从而为我们提供了基本的响应能力。
还将margin
设置为0 auto
因此元素将自动居中。
最后,它添加伪元素:before
和:after
并使用它们在元素末尾自动清除。 这是必需的,以便当我们开始在元素内添加列时,其浮动设置将被清除。
mixin接受一个参数@width
值:
.Row (@width : @default-width ) {
然后将此值传递给max-width
属性:
max-width: @width;
当mixin传递了宽度参数,例如.Row( 40rem )
,该值将应用于max-width
属性。
但是,如果在未传递参数的情况下调用mixin,即.Row
,则将使用默认值。 该默认值存储在@default-width
变量中,该变量在您看到的位置进行设置:
@default-width: 1200 * @toRems;
从上面介绍的@toRems
变量您将了解到,这意味着使用此mixin的任何元素的默认最大宽度为1200像素,转换为rem值。
通过使用此mixin,您现在可以将任何元素设置为以默认的max-width
为中心,或者以要应用的任何其他max-width
为中心。 这意味着您只需更改@default-width
变量的值即可更改整个站点@default-width
。 例如:
@default-width: 800 * @toRems;
...将基本布局更改为:
或者,您可以通过在mixin中传递width参数来一次更改单个元素的宽度。
例如,像这样应用mixin:
header, footer {
.Row;
background-color: #ccc;
min-height: 200 * @toRems;
}
main {
.Row( 800 * @toRems );
background-color: #ccc;
}
...将给您:
.cols()混合
@default-colspan: 1;
@default-total_cols: 4;
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols ) {
width: ( @colspan * (100 / @total_cols) ) + 0%;
float: left;
}
因为我们没有使用固定的像素宽度,并且希望布局保持完全灵活,所以所有列宽都将基于百分比。 我们使用.Cols()
mixin计算这些百分比。
根据您输入到mixin中的值,使用一个简单的公式来确定应应用于元素的宽度百分比值。 元素的float
值也设置为left
因此列将并排放置(您会记得我们会通过.Row()
mixin自动清除应用于列的.Row()
)。
使用.Cols()
mixin,您可以指定元素要宽多少栏,就像使用常规CSS网格系统一样。 这可以通过在mixin中传递@colspan
参数来实现,也可以通过@default-colspan
变量为mixin设置默认值来完成。
但是,与大多数CSS网格系统不同,您还可以完全控制该值相对于多少总列,而不会卡在12或16的总列中。总列可以通过将@total_cols
参数传递给mixin,或通过@default-total_cols
变量设置mixin的默认值。
在我们前面的示例中,我们将如何使用典型CSS网格构建“经典”布局,内容区域设置为12列中的9列(即四分之三),而侧边栏设置为12列中的3列(即四分之一)。 但是,出于此布局的简单目的,我们实际上不需要全部十二列。
我们要做的就是将内容区域设置为3/4宽度,并将侧边栏设置为宽度的1/4。 因此,当我们需要的只是宿舍时,将布局分解为十二分之一就太过分了。
因为我们知道只需要将此布局分成四分之一,就可以将@default-total_cols
变量的值设置为4:
@default-total_cols: 4;
然后,当我们像在“经典”布局示例中一样使用mixin时,mixin假定您希望您的列不超过可能的四列。 因此,将我们的文章元素设置为四分之三宽度,我们需要做的是:
article {
.Cols( 3 );
}
然后将我们的side / sidebar设置为四分之一宽度,我们只需使用:
aside {
.Cols( 1 );
}
但是,如果我们决定使用总数完全不同的总数列,则可以通过.Cols()
mixin传递不同的值来轻松实现。
这使我们可以轻松地将文章和元素的宽度更改为我们喜欢的任何内容,例如:
article {
.Cols( 7, 11 ); // sets this element to span 7 of a total 11 columns
min-height: 500 * @toRems;
background-color: #ddd;
}
aside {
.Cols( 4, 11 ); // sets this element to span 4 of a total 11 columns
min-height: 500 * @toRems;
background-color: #eee;
}
这给了我们:
反过来,这使得添加额外的列变得非常容易,例如,如果我们在HTML中的article
元素之前添加第二个aside
元素,然后将LESS更改为以下内容:
article {
.Cols( 5, 9 );
min-height: 500 * @toRems;
background-color: #ddd;
}
aside {
.Cols( 2, 9 );
min-height: 500 * @toRems;
background-color: #eee;
}
...我们将获得:
添加填充和边距
一旦开始在容器中添加内容,您当然希望能够控制其周围的间距。 现在,当我们添加内容时,它将与边缘齐平放置:
您可以通过两种方法来控制间距,哪种方法最适合使用,取决于您要使用所创建的特定设计所要实现的目标。
添加填充
控制间距的最简单方法是在.Row()
和.Cols()
混合文件中简单添加填充参数。
我们的mixin代码将调整为以下内容:
@default-padding: 0;
.Row ( @width : @default-width; @padding: @default-padding; ) {
max-width: @width;
width: 100%;
margin: 0 auto;
padding: @padding;
// clear at the end of container
&:before,
&:after {
content:"";
display:table;
}
&:after {
clear:both;
}
}
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols; @padding: @default-padding; ) {
width: ( @colspan * (100 / @total_cols) ) + 0%;
float: left;
padding: @padding;
}
现在,我们可以在页眉,文章,aside和页脚元素中添加填充。
请注意,我们还将在整个设计中将默认的box-sizing
属性设置为border-box
以便在任何浏览器对元素宽度的计算中均不包括填充:
* {
box-sizing:border-box;
-moz-box-sizing:border-box;
}
header, footer {
.Row (
@padding: 20 * @toRems;
);
background-color: #ccc;
min-height: 200 * @toRems;
}
main {
.Row;
background-color: #ccc;
}
article {
.Cols (
@colspan: 3;
@padding: 10 * @toRems 20 * @toRems;
);
min-height: 500 * @toRems;
background-color: #ddd;
}
aside {
.Cols (
@colspan: 1;
@padding: 10 * @toRems 20 * @toRems;
);
min-height: 500 * @toRems;
background-color: #eee;
}
现在,我们可以在每个内容上进行填充:
添加包装纸边距
有时,要添加到设计中的间距是在元素的外部,而不是内部,例如,当您希望网站的背景在元素之间显示时。 为此,我们将对.Row()
和.Cols()
混合添加更多内容。
首先,让我们在应用.Row()
mixin的元素上方和下方添加间距。 只需将现有的margin
属性值替换为可以通过mixin作为参数发送的变量,即可轻松实现。
@default-row_margin: 0 auto;
.Row ( @width : @default-width; @padding: @default-padding; @margin: @default-row_margin; ) {
max-width: @width;
width: 100%;
margin: @margin;
padding: @padding;
// clear at the end of container
&:before,
&:after {
content:"";
display:table;
}
&:after {
clear:both;
}
}
请注意,行边距的默认值仍设置为0 auto
,因此,如果未传递任何参数,则mixin仍将自动使元素居中。
但是,如果确实通过mixin传递了@margin
值:
header, footer {
.Row (
@padding: 20 * @toRems;
@margin: 10 * @toRems auto;
);
background-color: #ccc;
min-height: 200 * @toRems;
}
...我们可以像这样添加垂直间距:
另外,如果您决定不希望元素居中,则还可以执行以下操作,例如将@margin
值0 auto 0 0
左对齐元素,或将0 0 0 auto
右对齐。
添加列装订线
CSS网格系统的另一个共同特征是能够在列之间添加装订线,即在每个列之间应用边距,但不能应用到最外面的列的外部。
同样,我们可以在Cols()
mixin中添加一些功能:
@default-gutter: 0;
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols; @padding: @default-padding; @gutter: @default-gutter; @edge: false; ){
@total_gutter: (@total_cols - 1) * @gutter;
@spanned_gutters: (@colspan - 1) * @gutter;
width: ( @colspan * ( (100 - @total_gutter) / @total_cols) ) + @spanned_gutters + 0%;
float: left;
padding: @padding;
.IfEdge (@edge; @gutter);
}
.IfEdge ( @edge; @gutter; ) when (@edge = false) {
margin-right: @gutter + 0%;
}
.IfEdge ( @edge; @gutter; ) when (@edge = true) {
margin-right: 0;
}
现在,mixin还有两件事。 首先,它通过新的@gutter
参数检查值,并将其计入列的宽度计算中。
注意: @gutter
值应该是旨在用作百分比值的数字,例如2%装订线为2。
其次,它检查新的@edge
变量以查看是否将其设置为true
或false
。 如果@edge
设置为false
,则@gutter
参数的值@gutter
形式添加到右边距。 如果@edge
设置为true
,则右边距设置为0
。 这允许您指定列在布局边缘的位置,因此不应应用装订线。
为了更清楚地显示此更改对mixin的影响,我在HTML中添加了两个额外的article
元素。 该article
和aside
元素的LESS已调整为以下内容:
article {
.Cols (
@colspan: 1;
@padding: 10 * @toRems 20 * @toRems;
@gutter: 1; //include a gutter of 1%
);
min-height: 500 * @toRems;
background-color: #ddd;
}
aside {
.Cols (
@colspan: 1;
@padding: 10 * @toRems 20 * @toRems;
@gutter: 1; //include a gutter of 1%
@edge: true; //this is the column on the edge so don't set a right margin
);
min-height: 500 * @toRems;
background-color: #eee;
}
现在,这给了我们:
同样,允许控制列的垂直边距只是在mixin中包括一些其他参数,并将其调整为:
@default-margin_top: 0;
@default-margin_bottom: 0;
.Cols ( @colspan : @default-colspan; @total_cols : @default-total_cols; @padding: @default-padding; @gutter: @default-gutter; @edge: false; @margin_top : @default-margin_top; @margin_bottom : @default-margin_bottom; ){
@total_gutter: (@total_cols - 1) * @gutter;
@spanned_gutters: (@colspan - 1) * @gutter;
width: ( @colspan * ( (100 - @total_gutter) / @total_cols) ) + @spanned_gutters + 0%;
float: left;
padding: @padding;
.IfEdge (@edge; @gutter; @margin_top; @margin_bottom; );
}
.IfEdge ( @edge; @gutter; @margin_top; @margin_bottom; ) when (@edge = false) {
margin: @margin_top @gutter + 0% @margin_bottom 0;
}
.IfEdge ( @edge; @gutter; @margin_top; @margin_bottom; ) when (@edge = true) {
margin: @margin_top 0 @margin_bottom 0;
}
现在,使用.Cols()
mixin时,也可以包括顶部和底部边距设置,例如:
article {
.Cols (
@colspan: 1;
@padding: 10 * @toRems 20 * @toRems;
@gutter: 1;
@margin_top: 20 * @toRems;
@margin_bottom: 30 * @toRems;
);
min-height: 500 * @toRems;
background-color: #ddd;
}
aside {
.Cols (
@colspan: 1;
@padding: 10 * @toRems 20 * @toRems;
@gutter: 1;
@edge: true;
@margin_top: 20 * @toRems;
@margin_bottom: 30 * @toRems;
);
min-height: 500 * @toRems;
background-color: #eee;
}
这将为列增加垂直边距,如下所示:
嵌套和增加布局复杂度
现在,我们将通过不断的增多增加了复杂性的另一个层面,以我们的例子布局article
元素六将它们置于内section
元素的包装,然后将我们的混入创建以下布局:
为了实现此布局,HTML现在更改为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Classic Layout</title>
<script type='text/javascript' src='js/modernizr.js'></script>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/classiclayout.css">
</head>
<body>
<header>
<h1>Site Title</h1>
</header>
<main>
<section>
<h1>Latest Articles</h1>
<article>
<h1>Article Title</h1>
<p>...</p>
</article>
<article>
<h1>Article Title</h1>
<p>...</p>
</article>
<article>
<h1>Article Title</h1>
<p>...</p>
</article>
<article>
<h1>Article Title</h1>
<p>...</p>
</article>
<article>
<h1>Article Title</h1>
<p>...</p>
</article>
<article>
<h1>Article Title</h1>
<p>...</p>
</article>
</section>
<aside>
<p>...</p>
</aside>
</main>
<footer>
<p>Example Footer</p>
</footer>
</body>
</html>
我们现在用于控制布局的LESS代码已更改为:
header, footer {
.Row ( @padding: 20 * @toRems; @margin: 10 * @toRems auto; );
background-color: #ccc;
min-height: 100 * @toRems;
}
main {
.Row;
}
section {
.Cols ( @colspan: 3; @padding: 10 * @toRems 20 * @toRems; @gutter: 1; );
background-color: #ddd;
}
aside {
.Cols ( @colspan: 1; @padding: 10 * @toRems 20 * @toRems; @gutter: 1; @edge: true; );
min-height: 500 * @toRems;
background-color: #eee;
}
article {
.Cols ( @colspan: 1; @total_cols: 3; @padding: 0 20 * @toRems 20 * @toRems 20 * @toRems; @margin_bottom: 20 * @toRems; @gutter: 2; );
background-color: #eee;
&:nth-of-type(3n) {
margin-right: 0;
}
}
总结一下上面的LESS代码中包含的内容:
section
元素设置为占据默认总四列中的三列。 在它aside
是aside
元素,仍然设置为四列中的一列。
section
元素充当article
元素的包装。 因为article
元素现在是嵌套的,所以可以将所有新的列宽都应用于它们,并且它们每个都将占据其父元素内部的一定百分比。 因此,每列设置为三列中的一列,装订线为2%。
通过使用:nth-of-type(3n)
选择器标识每个第三article
元素,并将其设置为没有右边距/装订线。
调整为较小的显示
在本文的前面,我们展示了如何使用此方法从go一词中添加基本的响应能力。 我们将与许多其他人不同的另一件事是我们添加断点并确定这些点的行为的方法。
与其尝试识别和确定各种设备的确切屏幕尺寸,不如让我们的布局以每个单独的分辨率工作。 通过这种方式,我们变得独立于设备。
为此,我们将在布局变得过于紧凑以至于无法舒适阅读时,简单地在任意宽度处引入断点,并修改列以使内容再次可显示。
对于这种布局,我们将添加以下媒体查询:
article {
.Cols ( @colspan: 1; @total_cols: 3; @padding: 0 20 * @toRems 20 * @toRems 20 * @toRems; @margin_bottom: 20 * @toRems; @gutter: 2; );
background-color: #eee;
@media (min-width: 68rem) {
&:nth-of-type(3n) {
margin-right: 0;
}
}
}
@media (max-width: 68rem) {
article {
.Cols ( @colspan: 1; @total_cols: 2; @padding: 0 20 * @toRems 20 * @toRems 20 * @toRems; @margin_bottom: 20 * @toRems; @gutter: 2; );
@media (min-width: 53rem) {
&:nth-of-type(2n) {
margin-right: 0;
}
}
}
}
@media (max-width: 53rem) {
article {
.Cols ( @colspan: 1; @total_cols: 1; @padding: 0 20 * @toRems 20 * @toRems 20 * @toRems; @margin_bottom: 20 * @toRems; @gutter: 0; );
}
section {
.Cols ( @colspan: 2; @total_cols: 3; @padding: 10 * @toRems 20 * @toRems; @gutter: 1; );
}
aside {
.Cols ( @colspan: 1; @total_cols: 3; @padding: 10 * @toRems 20 * @toRems; @gutter: 1; @edge: true; );
}
}
@media (max-width: 36rem) {
section {
.Cols ( @colspan: 1; @total_cols: 1; @padding: 10 * @toRems 20 * @toRems; @edge: true; );
}
aside {
.Cols ( @colspan: 1; @total_cols: 1; @padding: 10 * @toRems 20 * @toRems; @edge: true; );
}
}
如上所述,断点是针对每个设计逐案确定的。
为此,我使用Firefox插件Firesizer来显示浏览器窗口的像素宽度。 我逐渐缩小浏览器的宽度,当我发现一个狭窄的地方时,我记下了显示宽度。
不幸的是,LESS不允许对用于媒体查询的值进行任何操作,因此我们无法执行@media (max-width: 1000 * @toRems)
。
因为这里不能使用@toRems
变量转换像素值,所以我改用http://pxtoem.com/将宽度转换为ems
将标识的宽度转换为rem
我们在该宽度处添加一个断点,并将新的.Cols()
mixin应用于该元素。 这可以更改colspan
值和/或totalcols
值,具体取决于在该宽度下看起来最totalcols
值。
在需要的地方,我们还将每个nth-of-type()
选择器包装在基于min-width
的媒体查询中。 这样可以确保当布局变小且列数减少时,正确地将边缘列标识为第二个而不是第三个。
例如,在68rem
的第一个断点处,我将文章从每列三列更改为两列之一。
我还在:nth-of-type(3n)
选择器周围添加了一个min-width: 68rem
媒体查询,因此它仅适用于大于68rem
大小。
然后,我向媒体查询中添加了一个新的:nth-of-type(2n)
选择器,用于小于68rem的大小,它将每隔一秒就标识为无需装订线。
当视口的宽度小于68rem
时,这些更改将创建以下布局:
在53rem
的下一个断点处,我将文章列的数量再次减少到单个列,即@colspan
1的@total_cols
1,每篇文章都堆叠在另一个之上。
再次在上面添加的nth-of-type(2n)
选择器周围添加一个min-width: 53rem
媒体查询,因此当我们的文章缩小为一列时,该查询不再适用。
我还将section
宽度从3/4列更改为2/3,并将aside
宽度从1/4宽度更改为1 /3。这为侧边栏aside
了更多的空间,因此在此宽度下不会过分挤压。
现在,当设计减小到小于53rem
的宽度时,它看起来像这样:
最后,在36rem
当布局变得太窄而无法容纳多列时,我将section
和aside
元素都更改为1/1列,这将aside
向下推到section
元素下方。
现在,布局在小于36rem的任何宽度下都是这样的:
结语
上面我们已经详细讨论了.Row()
和.Cols()
mixins的工作方式,以便使您有一个完整的了解,因此,如果您愿意,可以对其进行进一步的添加或修改。 但是,我们涵盖的所有内容的最终结果实际上是一个超级简单且易于使用的布局系统。
通过仅使用两个mixin ,您现在可以创建几乎没有限制的高度复杂,灵活且可扩展的布局,仅输出所需CSS并使用高度语义标记。
您可以为网格使用任意数量的总计列,任意宽度的单个列以及任意宽度的装订线。 另外,您的网格是无限可嵌套的。
下载您自己为本教程编写的mixins 副本 ,并尝试将其用于下一个项目布局!
css mixin