本文是对 resume.jade
& resume.scss
源码中 『经历』部分
的补充说明,请在 FirstWeb.app 中对照源码、并尝试修改。
HTML+CSS 有点像 油画,可以一层、一层的画上去,以至完善。
在浏览器中浏览 resume.jade 的时候,同时修改 resume.scss
139 行附近,将 .timelines
随意改成 .timelines_tmp
类似的,令其样式不生效,看效果如何;然后再重新修改回 .timelines
以备后用。大抵就能明白 一层一层
的意思了。
HTML+CSS 是实用主义偏向的,能达到效果,在代码结构、层次并不糟糕的前提下,怎么来都可以。
div.timelines
div.timeline.left_timeline.current_timeline
p.title Z.R.E.Y Co., LTD.
span.summary Dec 2012 to Now Product Leader
div.timeline.right_timeline
p.title Funny Co., LTD.
span.summary Nov 2011 to Dec 2012 Chief Architecture
div.timeline.left_timeline
p.title BAE
span.summary Jul 2007 to Nov 2011 UED Leader
div.timeline.right_timeline
p.title No.1 School of the Earth
span.summary Dec 2003 to Jun 2007 MBA
.clear
如上,是 timeline 相关原始的 HTML (Jade) 源码,它代表了页面的骨架。
我们要先将下面这种原始的状态,分成左右两栏:
这里的左右两栏,仅仅是视觉上的,内容都还在同一个父 DOM 元素里,或者说,HTML 并未改变过。
实现这个布局,CSS 的逻辑代码很简单:
.timeline { width: 47%; }
.left_timeline { float: left; clear: left; }
.right_timeline { float: right; clear: right; }
下面 SCSS 代码中地 &:before
,也就相当于 CSS 的 .timelines:before
,术语叫 伪元素
。同理还有 :after
,也就是在当前元素的 before
或者 after
再插入一个 (『伪造的』) DOM 元素。
绘制中线的 SCSS 代码如下所示:
.timelines {
position: relative;
display: block;
&:before {
display: block;
position: absolute;
width: 2px;
height: 100%;
left: 50%;
content: "";
background: #dddddd;
}
}
一个 伪元素,一般需要设定 content
,即使 content 是空字符,不然这个 伪元素
可能并不会被创建出来。之后,就将其作为一个普通的元素,设定尺寸(宽高)、位置以及其它属性即可。
你可以尝试将 :before
改成 :after
,但是需要增加额外的属性: top: 0; z-index: -1;
。这个尝试后,会对 before
与 after
的逻辑有更好的理解,当然对于绝对位置的坐标
也会有更好的理解。
如果后面在查看『继续理解』之『理解布局』时候,反过来再看本段的内容,也可以加深理解。
于是,我们未在修改 HTML 元素的前提下,实现了一条中间的分割线:
线条上的圆点,也使用 伪元素 的方式实现,一个元素,在其 width == height == border-radius
三者等同的情况下,实质上就是一个 圆 了。
再结合元素的 background
、border
的属性,就能对这个 圆
进行修饰了:
.timeline:before{
content: "";
position: absolute;
width: 6px;
height: 6px;
border-radius: 6px;
background: #bbbbbb;
border: 2px solid #ffffff;
left: 50%;
margin-left: -4px;
margin-top: 6px;
}
我们最终要实现如下图的参差感:
实现的逻辑很简单,就是每个 .timeline
块,给一个 margin-top
,而唯独第一个的 margin-top
是 0,就可以了。
.timeline{
margin-top: 45px;
&:first-child {
margin-top: 0;
}
}
其最终编译为 CSS 的源码为:
.timeline {margin-top: 45px;}
.timeline:first-child {margin-top: 0;}
其中 .timeline:first-child
是 CSS 选择器
的一种,在这里表示 第一个 .timeline。具体可以使用关键词 CSS 选择器
从搜索引擎中获得知识。
另一方面,如果认为 CSS 选择器 用起来也不是很好理解,或者容易用错,那么也没有关系,我们完全可以换一个思路:
.timeline
给一个 margin-top
.timeline_without_margin_top
,并设定 margin-top:0
.timeline
元素,新增一个 .timeline_without_margin_top
的 class。
简而言之,就是手工实现对第一个元素的属性设定,那么就用不到 first-child
这个选择器了。
这里一笔带过,因为后面一文《边框构建的箭头》中有详细的说明。
后续在『继续理解』中有一篇是『理解布局』,里面介绍了一种应对绝大数场景的布局方法,到时候再回过头来看,你可能会感觉到就本文内容而言,有一点不适用性 (这其实是错觉)。
为什么呢?因为这次 timeline 的布局是 Z 字型的。
假设我们面对的是如下的内容:
1-1 | 2-1
1-2 | 2-2
1-3 | 2-3
那么很容易左右分栏,然后左边管左边的布局,右边管右边的,各自为政,互不干扰。
而我们此次实际面对的虽然是视觉左右分布,但内容仍然上下关联:
1 | 2
3 | 4
5 | 6
说起来,也是非常常见的 float
布局,看起来左右分栏了,也只是视觉上的,而实际的内容、代码上都没有因为分栏而产生分裂。