CSS是一个很独特的语言。看起来非常简单,但是某种特殊效果看似简单,实现起来就颇有难度。这篇文章主要是给在学习前端的童鞋分享一些新的CSS技巧,一些在前端教程和培训课堂中不会讲到的知识。第二就是让还在前端开发这条道路上的童鞋们,重新燃起对前端排版和特效的热爱和热情!
1. 固定底部内容
这种是一个非常常见的布局方式,但是对于新手来说是比较常见的难题。
这种布局方式在后台管理系统中比较常见,当我们内容不足浏览器窗口高度时,底部内容需要固定在底部。当内容超出了浏览器窗口高度,就会随着内容往后推。
在有CSS3之前,实现这个效果是颇有难度的。浏览器窗口高度是会根据不同用户打开浏览器的情况,屏幕大小的差异和浏览器的缩放比例而变。我们需要借助JavaScript来实时获取浏览器高度进行运算才能实现。虽然说标题是说“固定”底部,但是我们想要的效果不是position: fixed
。使用固定定位,在内容高于窗口高度时,就会挡住我们的内容。
随着CSS3的来临,最完美的实现方式是使用Flexbox
。实现的关键就是使用不太被关注的flex-grow
属性,可以在我们的内容标签元素(比如div
)中使用。在我们下面的例子里使用了main
标签。
我来讲解一下实现原理吧。
flew-grow
是用来控制一个flex元素相对它同等级flex元素的自身可扩充的空间。如果我们使用flex-grow: 0
,那这个flex元素就完全不会扩展了。所以我们需要把头部和底部之间的内容标签元素设置为flex-grow: 1
或者flex-grow: auto
,这样内容部分就会自动填充满头部和底部之外的所有空间。
为了避免底部内容受内容部分扩充空间的影响,我们给footer
底部元素flex-shrink: 0
属性。flex-shrink
的作用与flex-grow
是恰恰相反,用来控制flex元素收缩的空间,这里我们给了flex-shrink: 0
就是为了底部footer
的大小不受影响。
我们直接上HTML和CSS代码看看是怎么实现的。
- HTML
可以添加更多内容看看底部的变化哦!
- CSS
#document {
height: 100vh;
display: flex;
flex-direction: column;
background: #202020;
font-family: microsoft yahei,wenquanyi micro hei,sans-serif !important;
}
nav, footer {
background: #494949;
display: flex;
justify-content: center;
}
main {
color: #bdbdbd;
flex: auto;
}
footer {
flex-shrink: 0;
}
* {
margin: 0;
}
h1,
p {
padding: 15px;
}
nav > h1 {
color: #82FCFD;
text-shadow: 1px 1px 4px #00000080;
}
footer > h1 {
color: #82FCFD;
text-shadow: 1px 1px 4px #00000080;
}
知识点总结:
- flex-grow --- 是用来控制一个flex元素相对它同等级flex元素的自身可扩充的空间
- flex-shrink --- 作用与
flex-grow
是恰恰相反,用来控制flex元素收缩的空间
预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
2. 悬停放大图片特效
悬停放大图片是一个特别吸引眼球的特效,比较常用于可点击的图片。当用户悬停鼠标在图片上,图片会稍微的放大。
其实实现这个特效是非常简单的。首先我们需要一个div
包裹这img
标签,这个包裹层是用来遮挡住图片,当图片放大时不会出现图片超出我们规定的宽高以外。
首先我们来讲讲div
包裹的属性,我们需要给它一个固定的width
宽和height
高。然后我们必须给予这个元素overflow: hidden
属性。让图片放大的时候不会超出这个div
元素的宽高。有了这个包裹层,我们就可以编写img
的各种效果了。
我的例子里面用了transform: scale(1,1)
作为悬停时的图片特效,这个transform
是用于改变任何元素的属性的,然后scale
是用于放大(整数就会放大)或者缩小(负数就会缩小)元素的。
上代码让大家看看:
- html body中放入
- CSS
.img-wrapper {
width: 400px;
height: 400px;
overflow: hidden;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}
.img-wrapper img {
height: 400px;
-webkit-transition: 0.3s linear;
transition: 0.3s linear;
}
.img-wrapper img:hover {
transform: scale(1.1);
}
.img-wrapper {
display: inline-block;
box-sizing: border-box;
border: 3px solid #000;
}
如果你们想让图片更加炫酷可以加上图片过滤属性filter
,让图片变灰或者变深褐色,然后悬停时候出现更加炫酷的颜色变幻。灰化的属性是filter: grayscale(100%);
,然后深褐色化的属性是filter: sepia(100%)
。其实图片还有很多过滤属性的,大家有兴趣也可以去尝试一下哦!
加入特殊效果的代码如下:
- HTML
- CSS
/* ==============
* 灰度过滤
* ==============*/
.grayscale-img {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
.grayscale-img:hover {
-webkit-filter: grayscale(0);
filter: grayscale(0);
}
/* ==============
* 深褐色过滤
* ==============*/
.sepia-img {
-webkit-filter: sepia(100%);
filter: sepia(100%);
}
.sepia-img:hover {
-webkit-filter: sepia(0);
filter: sepia(0);
}
知识总结
- transform --- 用于改变元素
- scale --- 对元素进行放大和缩小
- filter --- 图片过滤器
- grayscale --- 灰度过滤
- sepia --- 深褐色过滤
预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
3. 瞬间黑暗模式
最近微信也逃脱不了黑暗时代的到来,网页也很多都做了黑暗模式的兼容和主题。如果我们在做的一个网站想瞬间实现黑暗模式可以怎么实现呢?
其实有一个很快的方式,我们可以使用invert
和hue-rotate
两个CSS3过滤器来实现。
filter: invert()
— 是从0
到1
的刻度,1
是从白变黑。
filter: hue-rotate()
— 用于改变你元素的颜色,同时或多或少保持原本相同的色系。这个属性的值可以从0deg
到360deg
。
在我们页面的body
标签上添加这两个属性,我们就可以快速尝试把我们的网站变成"黑暗模式"。这里需要注意的是,如果body
和html
上没有设置background
背景颜色,这个过滤就会不起效了哦。
CSS的代码如下:
html {
background: #fff;
}
body {
background: #fff;
filter: invert(1) hue-rotate(270deg);
}
实现效果
这里我们会发现图片的颜色会受影响,并不是很美观,使用css过滤器是无法完美切换黑暗模式的。不过使用JavaScript辅助就可以完美的切换黑暗模式。
最近出了一个JavaScript辅助插件叫Darkmode.js
。
Darkmode.js
其实Darkmode.js
运用的也是css里面的一个特性叫mix-blend-mode
— “CSS 属性描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合“。加上Javascript的辅助判断哪些页面上的元素需要黑化的,哪些是不需要黑化的。就会想我们之前那种做法,导致其他不需要黑化的元素,比如图片,受到影响导致颜色出现问题。
使用Darkmode.js
非常简单,只要在脚本里面添加以下代码就可以马上加入一个插件,
如果你不希望用这个插件的默认按钮,你可以在你的JavaScript代码中自主控制。我们可以通过.toggle()
方法来切换模式,同时可以使用.isActivated()
来检测是否已经进入黑暗模式。
const darkmode = new Darkmode();
darkmode.toggle();
console.log(darkmode.isActivated()) // 如果已经进入黑暗模式会返回 true
知识总结
- filter: invert() — 可以把页面从白变黑,也可以从黑变白。
- filter: hue-rotate() — 用于改变你元素的颜色,同时或多或少保持原本相同的色系。
- Darkmode.js — 瞬间实现黑暗模式。
Invert方式黑暗模式:预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
Darkmode.js黑暗模式:预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
4. 自定义列表符号
ul
,li
的无序列表有默认的符号·
,但是在很多情况下我们希望可以给这个符号加入自己的样式和颜色,甚至是换成自定义的符号。默认的符号我们是无法做任何的样式处理,而且默认的符号在CSS属性里面只有几个选择可以使用,很多情况下都是无法满足我们的设计。
其实自定义无序列表符号不难,我们只需要使用伪类::before
加content
属性就可以实现。
在我这个例子里面我做了两个任务列表,一个是待处理任务,一个是已完成任务,各自给了不一样的列表符号和颜色。
实现原理
一、首先我们禁用了ul
的默认符号样式list-style: none
二、在li
的:before
伪类上给予content
内容值,待处理任务使用,已完成任务
li.completed:before
使用✔
三、为了展示效果更加好看我分别给了li
和li .completed
两个不同的颜色
上代码看看是怎么实现的吧:
HTML
待处理
- 待办任务1
- 待办任务2
- 待办任务3
- 待办任务4
- 待办任务5
已完成
- 完成任务1
- 完成任务2
- 完成任务3
CSS
ul {
list-style: none;
color: #fff;
font-size: 20px;
border: 3px solid #000;
padding: 1rem 2rem;
min-height: 200px;
margin: 15px 2rem 0 0;
background: #323232;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
border-radius: 8px;
}
li {
padding: 0.3rem 0;
}
li::before {
content: " ";
color: aqua;
}
li.completed::before {
content: "✔ ";
text-decoration: none;
color: greenyellow;
}
li.completed {
text-decoration: line-through;
color: #bdbdbd;
}
::before
和::after
伪类加content
属性可以用来做很多特殊的效果,也是当代前端排版比较常用的“魔法”。说到伪类的使用,我再给大家说一个比较常用的使用场景。
在管理后台或者是文章展示中,我们经常可以见到的“面包屑导航”也是用伪类来插入每个目录中间的符号的。
实现逻辑
一、这个导航含有3个a
标签,首先给每个a
标签加入一个伪类::after
,然后在content
属性插入/
符号。
二、然后使用a:first-child
,这个伪类会选择到第一个a
标签,然后使用content
属性加入»
符号。
三、因为我们第一步在每个a
标签的后面插入了/
符号, 所以我们需要在最后一个a
标签清除掉。这里我们使用:last-child
选择到最后一个a
标签,然后用content: " "
属性把伪类的内容清楚掉。
HTML
CSS
.breadcrumb {
font-size: 1.6rem;
color: #fff;
}
.breadcrumb a:first-child {
color: #82fcfd;
}
.breadcrumb a:first-child::before {
content: " » ";
}
.breadcrumb a::after {
content: " /";
color: #ef6eae;
}
.breadcrumb a:last-child::after {
content: "";
}
知识总结
- ::before | ::after — 伪类用于向某些选择器添加特殊的效果。
- content — CSS 属性用于在元素的 ::before 和 ::after 伪元素中插入内容。使用content 属性插入的内容都是匿名的可替换元素。
- :first-child — CSS伪类表示在一组兄弟元素中的第一个元素。
- :last-child — CSS伪类代表父元素的最后一个子元素。
自定义无序列表:预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
面包屑导航:预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
5. 图片视差效果
这个超级炫酷的效果在官网中非常的受欢迎,这种效果可以给用户带来视觉冲击,也给我们的网站带来了活力。普通的网页图片会跟随着网页一起滑动,但是视觉差效果图就会固定在底部,只有图片所在的窗口上的元素会移动。
仅使用CSS
对你没有看错,这个效果只需要用到CSS就能轻易的实现!我们只要使用一个CSS背景图的属性background-attachment: fixed
,这个特性会把背景相对于视口固定。即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。
实现理论:
一、在含有图片的元素中加入background: url()
和background-size: cover
(第二个属性适用于定义图片为封面,可以让图片大小自动适应,在很大的屏幕也会显示完整的图片)
二、然后附加固定背景图的属性background-attachment: fixed
三、最后给这个元素加入一个高度height: 100%
或者任意的高度height: 400px
就那么简单哦!不用怀疑,马上上代码,大家都可以自己去试试哦!
HTML
这里填写一堆文字就可以了,尽量多一点哦
CSS
.wrapper {
height: 100wh;
}
.parallax-img {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
background-image: url("http://ppe.oss-cn-shenzhen.aliyuncs.com/collections/182/7/thumb.jpg");
}
p {
font-size: 20px;
padding: 1.5rem 3rem;
min-height: 1000px; // 当你的文字内容不够,也能撑出足够的高度来看到效果,当然如果你文字足够多,就不需要了
}
如果想做到我动图里面一样的效果,或者想看是怎么实现的,可以查看下面总结里面的“预览实际效果”或者看“GitHub源码”。
知识总结
- background-attachment: fixed — 把背景相对于视口固定。即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。
- background-size: cover — 可以让图片大小自动适应,在很大的屏幕也会显示完整的图片。
预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
使用CSS + JavaScript
有些童鞋可能没有被这个震撼到或者还是觉得不够刺激。那我们再来一个高级例子,上面的例子在滑动的时候图片是固定死的。如果我们加上JavaScript的助力,我们可以让窗口的图片缓慢的跟随这个页面滑动,使得效果更有动力和更有冲击感。
实现理论
首先讲一下排版,因为我们需要在我们滑动页面的时候使用JavaScript偏移图片,所以我们需要给图片一个CSS属性让我们可以让图片可以根据一个速度来往上或者往下移动。这个例子里面我们让所有图片包裹在一个div
里面,class
名为block
。这个div
给予相对定位属性position: relative
,这个时候我们就可以在里面加入图片,然后让图片绝对定位position: absolute
在这个div
盒子里面。
但是图片是可能很大的,我们需要把图片不超出我们定义个盒子,所以我们的div
同时也给予了overflow: hidden
和一个高度height: 100%
。这样图片超出div
盒子就会被隐藏。
布局代码如下:
视差速度 -1
视差速度 1
html, body{
margin: 0;
padding: 0;
height: 100%;
width: 100%;
font-family: 'Amatic SC', cursive;
}
.block{
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
font-size: 16px;
}
.block h2{
position: relative;
display: block;
text-align: center;
margin: 0;
top: 50%;
transform: translateY(-50%);
font-size: 10vw;
color: white;
font-weight: 400;
}
.img-parallax {
width: 100vmax;
z-index: -1;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%,0);
pointer-events: none
}
实现这个布局,在你滑动的时候,图片是不会移动的。因为最后一步就是加入JavaScript的辅助,让图片活起来。
知识总结
- position: relative — 相对定位。
- position: absolute — 绝对定位。
- overflow: hidden — 如果需要,内容将被剪裁以适合填充框。 不提供滚动条。
预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
6. 裁剪图像的动画
在有CSS3之前裁剪图片实现也是颇有难度的。现在我们有了两个非常方便简单的CSS3属性可以实现裁剪,那就是object-fit
和object-position
, 这两个属性可以让我们改变图片的大小,但是不影响图片的长宽比。
当然我们可以使用图片处理工具或者使用JavaScript等插件来实现图片裁剪功能。但是因为有了CSS3的属性,我们不只可以裁剪,我们还可以用裁剪的属性来做图片的动态效果。
为了让我们的例子更加简单,我们这里使用了
复选框元素,这样我们就可以使用:checked
的伪类来触发启动效果。所以在例子里面我们完全不需要JavaScript的协助。
实现原理:
一、首先给予图片一个宽高height: 1080px
,width: 1920px
。
二、然后用CSS选择器,锁定当input
被选中后img
标签的样式变化。当被选中时,给图片设定一个新的宽高,这里我们给宽高各自500像素:width: 500px
,height: 500px
。
三、然后我们加上了过渡效果和时间让图片改变宽高时有动画过渡效果:transition: width 2s, height 4s;
。
四、最后加上object-fit: cover
和object-position: left-top
这两个属性来保持图片的宽高比例,这样就大功告成了!
我们来看看完成的代码:
勾选裁剪图片
input {
transform: scale(1.5); /* 只是用来放大复选框大小 */
margin: 10px 5px;
color: #fff;
}
img {
width: 1920px;
height: 1080px;
transition: 0s;
}
/* css选择器锁定复选框被选中时的状态 */
input:checked + br + img {
width: 500px;
height: 500px;
object-fit: cover;
object-position: left-top;
transition: width 2s, height 4s;
}
知识总结
- object-fit — CSS 属性指定可替换元素的内容应该如何适应到其使用的高度和宽度确定的框。
- object-position — 用来切换被替换元素的内容对象在元素框内的对齐方式。
- transition — 过渡可以为一个元素在不同状态之间切换的时候定义不同的过渡效果。
预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
7. 混合模式(Blend)
如果有使用过Photoshop的同学对blend
混合模式应该是非常熟悉了,我们都知道混合模式是非常强大,也是p图时非常常用的一个功能。但是你们有没有想象过可以在浏览器的CSS中直接使用呢?对我们不需要设计师给我们做图,我们前端也可以实现混合模式了。
在CSS中我们不只可以对background
背景加入混合模式,我们可以对任何一个元素的自带背景加入混合模式,让你可以做出很多之前没有想过的效果和排版。
往一个元素加入混合模式,我们只需要使用到一个CSS属性mix-blend-mode
即可。
简单实现原理:
首先我们只需要加一个h1标题标签
混合模式:颜色减淡
然后我们给h1
标签加入mix-blend-mode
中的颜色减弱模式color-dodge
,但是要注意的是我们需要给body
和html
加入背景颜色background: white
,要不你会发现这个效果会无效。因为h1
我们没有给颜色,会自动往上级继承,并且混合模式是针对背景颜色的过滤,所以body和html需要有背景颜色才行。
h1 {
mix-blend-mode: color-dodge;
font-family: yahei;
font-size: 5rem;
text-align: center;
margin: 0;
padding: 20vh 200px;
color: #D1956C;
}
html,
body {
margin: 0;
background-color: white;
}
body {
background-image: url(https://images.unsplash.com/photo-1505567745926-ba89000d255a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3302&q=80);
background-repeat: no-repeat;
background-size: cover;
min-height: 100vh;
overflow: hidden;
}
换换背景图和h1
标签的字体颜色就可以弄出各种不同的特效了。
知识总结
- mix-blend-mode — CSS 属性描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。
预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
8. 瀑布流布局
CSS Grid
和Flexbox
让我们可以更简便,更容易和更快的实现各式各样的响应布局,并且让我们快捷方便的在布局中实现横向剧中和竖向剧中。但是回想一下以前是颇为困难的。
虽然这些新出的布局方式可以让我们解决很多以前的布局难题,但是像瀑布流布局这种,就无法用它们简单来实现了。因为瀑布流一般来说都是宽度一致,但是高度是根据图片自适应的。并且图片的位置也是根据在上方图片的位置而定的。
其实最好实现瀑布流布局的办法就是用CSS的列属性套件,这套属性大多数都是用于排版杂志中的文本列。但是用于布局瀑布流也是特别实用哦。因为以前需要实现瀑布流,就必须有JavaScript的辅助来计算图片高度然后决定每张图片的定位和位置,所以现在有了列属性就可以使用纯CSS实现了。
实现原理:
实现这个布局,首选我们需要把所有的内容先包裹在一个div
元素里面,然后给这个元素column-width
和column-gap
属性。
然后,为了防止任何元素被分割到两个列之间,将column-break-inside: avoid
添加到各个元素中。
神奇的效果就完美实现了,零JavaScript。
我们来看看代码:
.columns {
column-width: 320px;
column-gap: 15px;
width: 90%;
max-width: 1100px;
margin: 50px auto;
}
.columns figure {
display: inline-block;
box-shadow: 0 1px 2px rgba(34, 25, 25, 0.4);
column-break-inside: avoid;
border-radius: 8px;
}
.columns figure img {
width: 100%;
height: auto;
margin-bottom: 15px;
border-radius: 8px;
}
知识总结
- column-width — CSS属性建议一个最佳列宽。 列宽是在添加另一列之前列将成为最大宽度。
- column-width — 该 CSS 属性用来设置元素列之间的间隔 (gutter) 大小。
- column-break-inside — 设置或检索对象内部是否断。
预览实际效果 | GitHub源码 | 喜欢的童鞋 star 一下谢谢
总结
我希望这8个前端小技巧和特效对大家有帮助,或多或少有吸收一点新的前端知识。这篇文章提到的内容,其实很多都是值得深挖和学习的。有一些例子我做的比较简单,但是其实是有无限的可能性。喜欢前端的童鞋们,让我们继续在前端领域中一起深挖,让我们的热爱无限的燃烧起来吧!
在最后我想给大家讲一下我对前端的热爱和态度。
回想前端这几年,发展真的是突飞猛进,从前端排版,HTML5+CSS3做H5页面,到前端组件化,各种UI框架满天飞。
一开始我随着热潮用起了UI框架,起初觉得特别方便,来一个新的项目就直接上一个UI框架,研发速度也非常快。但是久而久之就觉得前端开发变成了处理数据,对接接口,实现交互。
某天在阅览国外的一些前端设计和框架的时候,我突然发现国内多数的前端开发者都不再怎么使用CSS3做出一些很好玩的布局和特效了。现在市面上的系统和页面都是千篇一律,普遍都是用一些知名的UI框架搭建系统和APP,基本自己动手去排版已经少之又少。前端已不再是以前的前端,缺少了灵魂。
但是我们回想一下,我们刚刚开始学习前端的时候,让我们最有成就感,觉得前端特别有意思的那种感觉。就是那种让我们觉得神乎奇迹,不可思议的布局,特效和交互。那种感觉自己成功实现了很优美,很炫酷的页面和特效的感觉,让我们越做越来劲,越做越是兴奋。
但是在某些公司,研发部都是要求快速开发,UI设计部门也是受到时间的控制和限制,所以逐步走进了UI框架的限制之中。都是围绕这一些UI框架来设计和开发系统和应用。
作为一名热爱前端的开发者,我还是坚持在绝大多数的项目中,自己排版和实现页面交互特效。然后使用UI框架作为辅助,主要是用来减轻一些小组件和常用组建的快速实现。(可以说我是比较追求完美和外貌协会的程序员 )