css mixin_标准CSS网格的简单Mixin替代方案

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 副本 ,并尝试将其用于下一个项目布局!

翻译自: https://webdesign.tutsplus.com/tutorials/a-simple-mixin-alternative-to-standard-css-grids--webdesign-16958

css mixin

PSF(点扩散函数)与去卷积算法消除图像模糊 本文旨在总结图像处理中使用去卷积的传统方法来进行图像去模糊的相关知识。 阅读详情

相关推荐

避坑指南:英飞凌TC3XX的MCMCAN初始化常见错误及解决方法

本文针对英飞凌TC3XX系列MCU的MCMCAN模块初始化难题,深入剖析了寄存器配置时序、总线监控模式误用、中断映射错误及Message RAM地址冲突四大常见陷阱。通过实战代码示例和诊断流程,提供了清晰的避坑指南和解决方案,帮助嵌入式开发者高效解决CAN FD通信故障,确保汽车电子与工业控制项目的稳定运行。

weixin_29193259的博客 246

Sass Mixin 是 CSS 工程化的函数式内核

CSS 作为声明式语言,天然缺乏函数、作用域和编译期逻辑能力;Sass Mixin 正是在这一能力缺口上构建的可编程接口——它支持参数校验、条件分支、内容注入与递归生成,在编译阶段完成样式逻辑的类型契约与错误拦截。相比运行时 JS 控制或 utility-first 的原子类组合,Mixin 提供更早的反馈机制(如 `@error` 编译中断)和更强的封装性,广泛应用于响应式栅格、主题系统、无障碍适配等企业级场景。尤其在 Dart Sass 模块化演进中,Mixin 已成为 `@use` 体系下替代 `@i

weixin_30635053的博客 578

SD--根据订单创建出库单(相关的函数列表的介绍系列篇(2))

创建订单样例代码参见:http://blog.youkuaiyun.com/CompassButton/archive/2007/05/09/1601712.aspx 可以根据一个订单或者部分订单项来创建出库单,代码如下:* Populating the item data lx_sales_item-ref_doc = l_vbeln. lx_sales_item-ref_item = c_000010

SAP BLOG--Jack Wu 6226

浅析css——mixin及其用法

@mixin: @mixin指令允许您定义可以在整个样式表中重复使用的样式,而避免了使用无语意的类(class),混入(@mixin)还可以包含所有的 CSS 规则,以及任何其他在 Sass 文档中被允许使用的东西,甚至可以携带 arguments,引入变量等,这就意味着只需少量的混入(@mixin)代码就能输出多样化且不重复的样式。 下面一Sass为例讲解一下mixin的使用: @mixin 指令允许我们定义一个可以在整个样式表中重复使用的样式。 @include 指令可以将混入(mixin).

全栈-菜鸟 2652

【OWL部署】Manus又一开源平替OWL真的很好用吗?手把手带你部署并运行你的AI助手OWL(对接Qwen、硅基流动接口)

本文介绍了通用人工智能OWL的部署及国内接口对接,全篇干货满满,手把手教学。

MosuoLc的博客 4043

Unity中URP实现水体效果(泡沫)

在上篇文章中,我们实现了水体的深度。在这篇文章中,我们来使用上篇文章采样后的深度图来实现水中的泡沫效果。

楠溪泽岸的博客 3489

css中的mixin及其用法

转载自@liya_nan,css中的mixin及其用法 一、mixin是什么? @mixin是一种简化代码的方法,能够提高代码的重复使用率。 二、mixin的用法 mixin定义(使用@mixin定义): @mixin hexagon-generator($hexagon-width, $factor, $border-radius){ display: inline-block; border-radius: 50%; width: ($hexagon-width + $border-rad

Andrew_SJ的博客 644

【实战指南】利用CAN适配器高效调试CAN总线通信

本文提供了一份利用CAN适配器高效调试CAN总线通信的实战指南。文章从硬件连接、终端电阻配置、软件参数设置等基础环节入手,详细解析了CAN适配器作为关键调试工具的工作原理与使用方法,并针对常见的通信故障提供了系统化的问题排查思路,帮助工程师快速打通通信链路,提升调试效率。

weixin_28285943的博客 412

mixin使用(css)

mixin是一种简化代码的方法,能够提高代码的重复使用率, Less 和 SCSS(Sass)中都可以使用此功能。虽然这两者在语法和实现细节上有所不同,但它们都提供了类似的功能,使得代码可以重用样式块。

m0_57442975的博客 561

开源鸿蒙具身机器人(ROS2框架):从内核驱动到智能算法的完整实践

本指导文档旨在为开发者提供完整的开源鸿蒙(OpenHarmony)具身机器人开发解决方案,涵盖从底层驱动到上层ROS2应用的全栈开发流程。文档结合OpenHarmony内核驱动移植技术和ROS2机器人操作系统,为具身机器人开发提供详细的技术指导。具身机器人(Embodied Robot)是指具有物理实体、能够感知环境并与之交互的智能机器人系统。感知-决策-执行闭环多模态传感器融合(视觉、听觉、触觉、力觉)实时环境感知与理解智能决策与规划精确运动控制执行具身智能特性物理世界交互能力。

m0_67505153的博客 1268

VIIRS-NPP夜间灯光遥感数据下载和预处理

右侧搜索框搜索“按掩膜提取”,提取出夜光影像中国区域。将其转换为Albers积投影和重采样到400m。点击右上角Export,选择shp格式。最后点export导出就行。点击复制按钮,来到这个。,ctrl + v粘贴。将小于0.3的值置为0。下载好月合成产品后,

热爱分享,热爱记录 1万+

CSS3 专家级编程(四)

正如你所看到的,有很多可重复使用的结构,每次创建新项目时都可以装饰。最好是写一次东西,然后添加一些新功能,而不是每次都写一些东西并描述可重复的元素。在下一章中,我们将尝试创建一个简单的 CSS 框架,其中包含准备好使用的组件!准备防弹电子邮件模板是一个复杂的过程。为什么?正如您所见,HTML 和 CSS 在您熟悉的标准网络浏览器中表现得非常奇怪,不太符合逻辑。当然,所有这些过程都可以被描述,并且有一个工作流程可以帮助您在不紧张的情况下构建邮件发送程序。

龙哥盟 957

ATECC508A芯片开发笔记(三):获取508A串号、随机数源码及I2C抓包分析

ATECC508A芯片开发笔记(三):读取508A串号、获取随机数源码及I2C抓包分析 APP层函数编写及源码分析 At508_GetSernum() GetSernum抓包记录 At508_GetRandom( ) GetRandom抓包记录 经过前两章节,CryptoAuthlib库已经成功适配在代码中了,下面简单测试一下API函数,并分析下I2C通讯流程: APP层函数编写及源码分析利用li

HowieXue 薛永浩的博客 2万+

css 布局框架 工具,Semantic:来自未来的CSS布局框架

解读问题问题1:它们不是语义架构这是我从“纯化论者”口中听到过的最大的抱怨,自我在两年前创建1KBCSSGrid框架开始,CSS网格系统就规定标记和描述必须在一起。从grid_x的CSS类到HTML元素,表象信息与其他语义标记都是混合在一起,这些,都需要网页设计师自行添加。浮动元素也必须同时清除,因为它常常会把不必要的元素添加到网页上。下图中的“clearing”DIV标签就是引用960.gs...

weixin_34966284的博客 624

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

hack.css高级定制教程:如何扩展框架功能并创建自定义主题

hack.css是一个极简的CSS框架,以其简洁的设计和灵活的定制性在前端开发社区中广受欢迎。本终极教程将指导你如何深度定制hack.css框架,创建个性化的主题,并扩展其功能以满足特定项目需求。无论你是CSS新手还是经验丰富的开发者,这篇完整指南都将帮助你掌握hack.css高级定制技巧。 ## 理解hack.css的架构设计 hack.css采用模块化的CSS架构,通过PostCSS构建系

gitblog_00880的博客 810

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

推荐开源项目:Node-Bourbon - Sass Mixin Library

推荐开源项目:Node-Bourbon - Sass Mixin Library 项目介绍 Node-Bourbon 是一个基于 Bourbon 的 Sass Mixin 库的 Node.js 版本,由 Michael LaCroix 维护。如果你熟悉 Ruby 和 Rails 平台,那你应该对原始的 Bourbon 不陌生,而这个 Node 版本则是为前端开发者在 Node.js 环境中提供便利...

gitblog_00039的博客 398

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

CSS: SASS用法指南 (附视频)

  观看视频:  CSS: SASS用法指南     学过CSS的人都知道,它不是一种编程语言。 你可以用它开发网页样式,但是没法用它编程。也就是说,CSS基本上是设计师的工具,不是程序员的工具。在程序员眼里,CSS是一件很麻烦的东西。它没有变量,也没有条件语句,只是一行行单纯的描述,写起来相当费事。 很自然地,有人就开始为CSS加入编程元素,这被叫做"CSS预处理器"(css p...

Just Code 183

dgrid技术深度解析:现代Web数据网格的架构设计与性能优化

在当今数据驱动的Web应用中,高效的数据展示与交互成为前端开发的核心挑战。dgrid作为基于Dojo Toolkit的轻量级数据网格组件库,专注于解决大规模数据集的可视化问题。其技术定位在于提供模块化、高性能的数据网格解决方案,特别针对现代Web应用的实时数据更新、虚拟滚动和移动端适配等关键需求。dgrid的核心价值体现在其与dstore数据层的深度集成,实现了数据操作与UI渲染的彻底解耦,为复杂

gitblog_00584的博客 350

Grid网格布局笔记

Grid网格布局笔记 常用的三种布局方式对比 1.传统布局方式 利用position属性 + display属性 + float属性布局,兼容性最好,但是效率低,麻烦! 2.flex布局 有自己的一套属性,效率高,学习成本低,兼容性强! 3.grid布局 网格布局(Grid)是最强大的 CSS 布局方案。但是知识点较多,学习成本相对困难些,目前的兼容性不如flex好! 容器属性 1.grid-template-columns 2.grid-template-rows a. 想要多少行或者列,就填写相应属性值

kun_96的博客 471

css 列 数量_使用数量查询使您CSS数量感知

数量查询是专门设置CSS选择器 ,可让开发人员使他们的代码感知数量 。 在响应式设计中,我们通常使用媒体查询来使我们的设计适应不同的视口。 但是,在某些情况下,在屏幕上出现一定数量的相同内容类型后 ,我们可能希望切换到不同的布局或使用其他尺寸或外观。 另请参阅: 查看CSS样式优先级 动态网站经常出现问题,我们并不总是事先知道屏幕上将显示多少个项目 。 考虑博客文章末尾的标签,电子商务...

cune1359的博客 636

SASS入门指南

SASS 变量以#326dee161.5"hello"sans-seriftruefalse// 空 Map// 带值的 Map符号代表父选择器的引用在嵌套规则中表示外层的选择器编译时会替换为父选择器的内容使用@mixin// CSS 属性或规则/*** 定义一个按钮样式的 Mixin* 这个 Mixin 提供了基础的按钮样式,包括:* - 文本修饰、光标样式、显示方式* - 边框、内边距、圆角* - 可自定义的背景颜色。

2301_80740728的博客 996

常见的 CSS 知识点整理

本文总结了CSS核心概念和常见问题,涵盖盒模型、选择器优先级、元素居中、布局方式(Flex/Grid)、BFC、响应式设计、动画、清除浮动、伪类与伪元素、多列等高布局等。重点包括标准与IE盒模型区别、Flex与Grid布局的适用场景、BFC的触发条件与作用,以及响应式设计的实现方法。文中提供了代码示例和实用技巧,适合开发者快速复习或解决实际问题。

黄同学的博客 1224

React Speed Coding 样式体系解析:PostCSS + BEM + FlexBox,构建可维护的 React 组件样式

React Speed Coding 是一个从零搭建 React 单页应用的开源教学项目,它没有使用 CSS-in-JS,而是用 **PostCSS + BEM 命名 + FlexBox 布局** 的组合,构建出一套简单却高度可维护的 React 组件样式体系。这篇文章带你拆解它的样式目录结构、变量与混入机制、布局方案,以及用 StyleLint 保证规范的工程化流程。 [![React Spe

gitblog_01183的博客 770

CSS Grid中span的本质:不是尺寸而是轨道跨度

CSS Grid中的span是一个常被误读的基础概念,它并非像素或固定宽度单位,而是描述元素在网格中跨越多少个轨道(track)的空间关系指令。其计算依赖于grid-template-columns/rows定义的显式轨道、grid-auto-rows/columns设定的隐式轨道,以及minmax()、fit-content()等动态约束机制。理解span的轨道语义,是避免布局错位、隐式轨道爆炸、跨浏览器渲染不一致等高频问题的关键。它支撑着响应式网格、动态列合并、卡片弹性占位等典型工程场景,尤其在结合Co

cixu3288的博客 438

JB2-8-CSS

CSS基础,CSS选择器,CSS样式表(文本,服务端字体,列表,表格),CSS盒模型(尺寸,颜色,背景图片,颜色渐变,隐藏,形态,边框,圆角,轮廓,边距,平移,缩放,旋转,倾斜,过渡),CSS定位(浮动,相对定位,绝对定位,固定定位,弹性布局,网格布局),SCSS预处理器(嵌套,继承,自定义变量,复用样式块)等。

周航宇的博客 1628

移动端CSS 1px边框问题:原理、解决方案与工程化实践

在移动端开发中,CSS像素与设备物理像素的差异是理解屏幕渲染的基础概念。设备像素比(DPR)决定了CSS像素与物理像素的映射关系,这直接影响了视觉还原的精度。为了解决高分辨率屏幕上1px边框渲染过粗的问题,开发者需要掌握多种技术方案以实现物理像素级的精细控制。这些方案在移动端H5页面、响应式Web应用等场景中具有重要价值,能够显著提升UI的视觉品质。本文深入剖析了transform: scale、box-shadow和linear-gradient等主流方案的实现原理与技术细节,并提供了工程化集成的实用建议

weixin_30696427的博客 387
上一篇: dribbble扩展程序_使用Flexboxgrid和Jribbble构建Dribbble投资组合网格
下一篇: html5动画模板_使基本HTML模板更上一层楼的动画
daique1908
博客等级 码龄10年 29粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值