css网格
在本教程中,我们将使用CSS Grid,SVG和一些节日的欢呼声来构建季节性出现日历! 让我们先看一下我们将要朝着什么方向前进-单击日期以查看其背后的内容:
您需要什么
本教程实际上并不需要太多,只需要一个代码编辑器(依靠CodePen使事情变得更容易)以及一些基本HTML和CSS知识即可。 但是,您将需要一些节日的视觉效果-我已经从Envato Elements(它们是向量,绝对是完美的)上由非常有才华的masastarus进行了插画:
1.网格诞生
对于我们的降临日历,我们将使用25个网格项目; 一次在圣诞节前的每一天,另一次举行标题图。 在小屏幕上看起来像这样:
在更大的屏幕上:
绿松石色网格项将保留我们的标题图形。
标记
首先,我们需要在一个容器中放置25个项目,因此让我们将一些HTML放在一起:
<section class='grid-1'>
<div class='title'></div>
<div class='day-1'></div>
<div class='day-2'></div>
<div class='day-3'></div>
<div class='day-4'></div>
<div class='day-5'></div>
<div class='day-6'></div>
<div class='day-7'></div>
<div class='day-8'></div>
<div class='day-9'></div>
<div class='day-10'></div>
<div class='day-11'></div>
<div class='day-12'></div>
<div class='day-13'></div>
<div class='day-14'></div>
<div class='day-15'></div>
<div class='day-16'></div>
<div class='day-17'></div>
<div class='day-18'></div>
<div class='day-19'></div>
<div class='day-20'></div>
<div class='day-21'></div>
<div class='day-22'></div>
<div class='day-23'></div>
<div class='day-24'></div>
</section>
提示 :考虑到此标记的重复性质,您可能更喜欢使用诸如HAML之类的模板语言。 HAML可以让您遍历24个项目,以免您将每个项目写出来。 以下小片段将完全编译为您在上面看到的内容:
%section.grid-1
%div.title
- (1..24).each do |i|
%div{:class => "day-#{i}"}
当我们在这些div中嵌套更多元素时,您会感激HAML为您节省的时间!
基本网格样式
现在让我们添加一些基本样式来建立网格。 我们首先分配display: grid;
到我们的容器元素。 然后,在一些尺寸之后,我们定义网格项。
/* mobile first grid layout */
.grid-1 {
display: grid;
width: 96%;
max-width: 900px;
margin: 2% auto;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
grid-gap: 25px;
}
我们已经“移动优先”,所以您会看到我们只定义了三列; 我们稍后将使用媒体查询来显示更大的屏幕。
-
grid-template-columns: repeat(3, 1fr);
给我们三列,每列相等的宽度(以1fr为单位) -
grid-template-rows: auto;
是实际上的默认值,但它指出行将没有特定的高度归因于它们-我们可以添加任意数量的行,并且行会随着内容的增长而增加。 -
grid-gap: 25px;
定义我们的装订线。
这实际上就是我们所需要的,只要离开网格,网格就可以从这里处理事情,但是我们想更具体地说明放置每个网格项的位置。 因此,我们将使用网格区域。
网格区域
我们可以为定义的网格的每个区域分配一个名称,也可以用一种直观的方式来写它:
grid-template-areas: "t t t"
"d23 d20 d12"
"d2 d14 d4"
"d5 d22 d16"
"d1 d7 d9"
"d10 d11 d18"
"d13 d3 d15"
"d6 d17 d8"
"d19 d24 d21";
在这里,我们为第一个区域命名,该区域跨越第一行t
上的三列(我们将在其中放置标题)。 这可能不是最有用的名称,但目前可以完成。 每个其他区域都会根据日期编号来命名,如您所见,我们可以将它们放置在所需的任何位置。 像这样“随机”布置事物的能力非常适合出现日历。
响应Swift
通过添加媒体查询,我们可以(真的很容易)更改大屏幕的布局。
/* media query */
@media only screen and (min-width: 500px) {
.grid-1 {
grid-template-columns: repeat(6, 1fr);
grid-template-areas: "t t t d2 d7 d8"
"t t t d4 d11 d12"
"t t t d19 d9 d13"
"d6 d1 d24 d24 d21 d20"
"d17 d18 d24 d24 d5 d22"
"d3 d23 d16 d14 d10 d15";
}
}
通过此媒体查询,我们声明对于大于500px(任意图)的视口,我们将更改网格,使其具有六列: grid-template-columns: repeat(6, 1fr);
。
我们可以完全重新定义项目的安排,将日期放到我们希望的任何位置。 您会注意到,标题栏现在占据了左上角的三列三行,并且d24占据了2×2的面积,以赋予它更大的意义。 在下一步将网格项目分配给网格区域时,这一点将变得很清楚。
目前,我们实际上看不到已完成的任何操作,因此让我们向网格项添加一些临时样式以使内容可见。
section div {
background: #2e313d;
padding: 40px;
}
看一看:
分配网格区域
现在,我们需要将网格项分配给我们设定的区域。 我们这样做如下:
/* individual items */
.title {
grid-area: t;
}
.day-1 {
grid-area: d1;
}
.day-2 {
grid-area: d2;
}
.day-3 {
grid-area: d3;
}
...
您可以看到我们的div.title
已分配给网格区域t
,并且每天都已分配给相应的区域。 没什么好说的,您不能将.day-3
分配给grid-area: d16;
当然,我们只是选择以这种方式组织事物。 看起来怎么样
2.开门
这是所有基本结构,现在我们需要制造CSS门。 我们将在每个网格项中放置两个div,一个用于门的前面,另一个用于后部,两个都包裹在另一个div中,并且我们将使用复选框hack来将整个内容翻转点击。
首先,向每个网格项添加标签,复选框和div:
<div class='day-1'>
<label>
<input type='checkbox'>
<div class='door'>
<div class='front'>1</div>
<div class='back'></div>
</div>
</input>
</label>
</div>
同样,您需要对所有24个网格项目执行此操作,这是一个庞大的块,重复标记长达245行,因此您可能会发现HAML很有帮助。 外观如下:
%div{:class => "day-#{i}"}
%label
%input{ :type=>"checkbox" }
.door
.front #{i}
.back
通过略微调整填充,这就是所有这些复选框现在的样子:
门
做好准备; 可以说,这将是整个构建过程中最复杂的部分。 如果没有全部内容,这是一个很大的部分,几乎没有什么工作,所以请多多包涵。 我们将对3D变换进行一些调整。
首先,我们隐藏复选框,然后声明要对标签应用一定级别的透视图(perspective: 1000px;
处理)。transform-style: preserve-3d;
指出标签的子项将显示在3D空间中,而不是沿平面显示。 然后,我们使用一些Flexbox样式来确保标签填充可用的整个区域。
然后, .door
元素上的某些样式(包含正面和背面)将设置过渡时间并进一步整理:
/* door styles */
.grid-1 input {
display: none;
}
label {
perspective: 1000px;
transform-style: preserve-3d;
cursor: pointer;
display: flex;
min-height: 100%;
width: 100%;
height: 120px;
}
.door {
width: 100%;
transform-style: preserve-3d;
transition: all 300ms;
border: 2px dashed transparent;
}
正面和背面
好吧,现在集中精力在门的正面和背面。
.door div {
position: absolute;
height: 100%;
width: 100%;
backface-visibility: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.door .back {
background-color: #2e313d;
transform: rotateY(180deg);
}
.front
.door div
选择器指向.front
和.back
div。 我们使用它使.door
容器的宽度和高度各占100%,并且绝对位于左上方。 Flexbox规则确保其中的内容(数字)在中心对齐,并且backface-visibility: hidden;
规则可确保当背面朝向我们时,看不到任何面Kong。 这很重要,因为我们随后将重点放在.back
并将其设置为通过transform: rotateY(180deg);
翻转transform: rotateY(180deg);
。
现在为有趣的东西
所有这些都导致了实际上很酷的效果。 我们将使用复选框的选中状态来转换面Kong。 当我们单击标签(填充整个网格区域)时,即使未显示复选框,它也会选中并取消选中该复选框。 根据该状态,我们更改.door
面向的方式。
label:hover .door {
border-color: #385052;
}
:checked + .door {
transform: rotateY(180deg);
}
第一条规则使我们处于悬停状态。 第二条规则使用相邻的选择器,因此当.door
元素紧跟在:checked
元素之后时,我们将其在Y轴上旋转180度(将其翻转)。 所有这些都为我们提供了基本的门功能!
3.装修时间
让我们看起来更漂亮。 我们要插入的第一个图像是标题图形。 我使用快乐的孩子们庆祝圣诞节的插图作为标题,更改了细节并保存了SVG文件 。
提示 :有关像这样的详细矢量,请在Illustrator中转到“ 对象”>“路径”>“简化...” ,您可以降低复杂性。 通过修整曲线和点的数量,可以显着减小文件大小,而不会损失太多的整体效果。
我们可以通过几种方法将该图像添加到页面中,但是我只是在标记中放置了一个img
标签:
<div class='title'>
<img src='merry-gridmas.svg'>
</div>
某些样式使我们的图像更加流畅,并使其在网格区域内居中对齐:
.title {
display: flex;
align-items: center;
justify-content: center;
}
.title img {
width: 90%;
height: auto;
}
为了增强空白背景,我们通过CSS向身体添加了另一个SVG(降雪和云):
body {
background: url(snow-bg.svg) no-repeat top center #82d8cb;
background-size: cover;
}
在门上添加图像
我们的24扇门中的每扇门也都需要隐藏在它们后面。 同样,我们可以通过几种不同的方式来执行此操作,但是在这种情况下,我们将保存一堆SVG文件并通过CSS将其添加为背景。 对于每扇门,在定义其网格区域之后,我们将为.back
面设置一条规则:
.day-6 {
grid-area: d6;
}
.day-6 .back {
background: url(snowflake.svg);
}
这就是给我们的:
非常好! 现在,我们只需要整理一些常规规则即可整理这些图像。
整理
首先,这些背景图片只需显示一次,因此我们将添加一个no-repeat
。 它们还需要处于中心位置并适当缩放。
.door .back {
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
background-color: #2e313d;
transform: rotateY(180deg);
}
在.door
和.door div
添加一些border-radius
可以使我们更友好。 最后,我们链接到Google字体上的Kalam字体,以完善最后的印刷细节:
<link href="https://fonts.googleapis.com/css?family=Kalam" rel="stylesheet">
样式:
/* added to .door div */
font-family: 'Kalam', cursive;
color: #385052;
font-size: 2em;
font-weight: bold;
text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.2);
结论
那把东西结语了! 当然,这实际上只是为了获得新颖性和实践CSS Grid(在下次浏览器会话或任何其他操作中都不会保存每扇门的状态),但是我们已经走了很长一段路,只提供了一些标记和某些样式。
支持是最后要提到的一点。 本教程的某些方面尚未获得完整的浏览器支持-有关如何处理此问题的一些技巧,请参见下面链接的资源。
希望您喜欢本教程,并喜欢倒数计时!
css网格