使用纯css制作有炫酷交互的按钮

前端入门简单,真正精通却不那么容易

就css来说,会使用css做页面布局也只是第一步,css远比想象中的要强大。

js很多效果都可以利用css各种属性和伪元素,制作出来,而且比起js还要方便快速

这是一个菜单按钮的效果,成为焦点后会变成一把叉,在焦点移除后会还原会菜单形状
这时就可以配合js做状态管理写出一个完整的下拉菜单或者侧拉菜单了
之后也会使用在我的vue2.0项目中,如果爷您有兴趣可以移步到项目地址处视察视察,如果爷开心了就加个星

具体的效果是这样的
rotate menu button by css


这里是menu按钮的演示地址

写代码要信奉“能偷懒就偷懒”原则,在保证实现效果的基础上,绝不多写一个标签,多写一段代码
所以上面的效果咋一看需要至少4个标签才能写完,其实只用了一个标签
用button标签做父元素,用两个伪元素做两个横杆
问:“那还有一个横杆呢?”
是这样,通过观察效果图,发现其实由菜单图标变换到X图标只需要其中的两个横杆。
所以第三个横杆我使用了box-shadow属性来模拟,说到底,其实第三个横杆只是第二个横杆的投影而已

核心使用
属性:transform-origin, transform, box-shadow, transition 伪元素::before, :after

代码标签是用pug语法写的,css是stylus语法写的,这两种语法都比较简单,如果会使用css选择器就可以看懂
下面也会简单的说明下

话不多说,上代码
1
2
3
4
5
6
7
8
button#btn.b-menu
// pug语法里的'#'和'.'同css里一样'#'为id,'.'为class
label(for="btn") click
// 除了id与class以外的属性要如上面的形式写在括号里

// 这里扩展出来就是
// <button id="btn" class="b-menu"></button>
// <label for="btn">click</label>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// stylus是css的预编译器的一种,简化了css的写法,结构更加清晰
// 这里就不过多的陈述了,有疑问可以下方留言询问

// 先去除button的默认样式
button
border none
outline none
box-shadow none
background none
color currentColor
padding 0
cursor pointer

// 关键的部分开始了
.b-menu
width 25px
height 25px
position relative
&:before, // before是第一横杆,after是第二个横杆
&:after // stylus里的&表示承接上文的意思,这里也就等同于.b-menu:after
content ' '
position absolute // 使用绝对定位到目标位置
background-color #fff
display block
width 100%
height 3px
left 0
top 11px
border-radius 3px
transition all .5s
transform-origin 50% 50% // 设置变换中心点,这个很重要,直接影响到后面的效果
&:before
transform translateY(-6px) // 第一个横杆向上偏移,这里使用transform而不使用top属性是为了方便后面的使用
&:after
box-shadow 0 6px 0 0 #fff
&:focus:before // 通过focus获取焦点,来触发起伪元素的变化
transform rotateZ(45deg) translateY(0)
&:focus:after
box-shadow 0 0 0 0 #fff
transform rotateZ(135deg) translateY(0)


### 这个是开关的效果
效果是这样的(duang!duang!daung!)
switch button

这里是switch button演示地址

开关效果又比之前那个复杂,switch的原理其实就是checkbox,
因为input是单标签,所以无法使用伪元素,这里就用到了label

核心使用

  • 属性:transform, background-size, border-radius, border-width, transition, cubic-bezier
  • 标签:label
  • 伪元素::before, :after

代码如下:
html

1
2
3
input(id="switch",type="checkbox").b-switchBtn
label(for="switch").b-switchLabel
// label标签利用for属性与相应id的input标签绑定,从而达到点击label就是点击input的效果

css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
button,
input
border none
outline none
box-shadow none
background none
color currentColor
padding 0
cursor pointer

.b-switchLabel
position relative
display inline-block
width 60px
height 25px
input
display none
&:before, // before 作为白条
&:after // after 作为水滴状开关
content ' '
display block
position absolute
&:before
width 100%
height 4px
background-color #fff
left 0
top 50%
border-radius 5px
transform translateY(-50%)
&:after
background-image url('http://upload-images.jianshu.io/upload_images/2005796-fcc62a13bd69f679.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240')
// 因为css不好写出漂亮的水滴效果,所以这里取巧用了图片
background-size cover // 利用这个属性缩放原来太大的图片
height 25px
width 25px
left 23%
top 51%
border-radius 25px
transform-origin center center // 老套路,定下变换中心点
transform translate(-50%, -50%) // 矫正left和top的偏移
background-clip border-box // 利用border-box属性值来使背景图片在border上也能显示
background-position 50% 50%
border-style solid
border-color transparent // 设置透明border有助于背景的显示
border-width 0 3px 0 0
transition all .5s cubic-bezier(0.4, -0.95, 0.4, 1.8) // 设置贝塞尔曲线以达到Duang的效果
.b-switchBtn
display none
&:checked~.b-switchLabel // 设置开关在被选中时改变状态,配合transition就动了起来
&:after
left 78%
border-width 0 0 0 3px

有疑问的或者有建议的可以在下方留言

使用BEM+emmet的css书写与命名技巧[未完]

于日常的项目中,小型项目还好,css即使没怎么规划也不至于特别的乱,但一旦项目里css有一定的基数时,css就会显得混乱起来。
于是。。。(以下是案例,可以直接跳至[正文]有关css命名的部分

可能就遇到了这种情况:

情况1.

哎呀!这个地方布局有点问题,我改一下,于是看到了一堆css选择器,当你想要修改某个class时又害怕会影响到其他在使用这个class的组件,于是就很尴尬的又写了一个class加在上面。

情况2.

css命名冲突,你将要命名的class命已经被使用,更惨的是其他意思相近的命名单词也被使用了,这下就词穷了🤕

情况3.

毫无意义的命名:(写的时候class的意思只有自己和上帝知道,现在只有上帝知道了🙆🏻)

1
2
3
.abc {
width: 200px;
}

其他前端:一脸懵逼

针对上面的问题,于是就在命名上开始做出改变,然而却😟

情况4.

过于语义化的命名(这里举个略微夸张且有些不恰当的栗子🌰)

1
2
3
4
5
6
7
8
9
10
11
12
.navigation-width-full-line{
width: 100%;
height: 50px;
}
```
这样是把意义描述清楚了,但是命名却是过长了
#### 情况5.
有语义却不够直接简洁的命名
```css
.navigation-responsive{
flex: 1 1 10%;
}

这样无形中增加了记忆成本

命名规范 BEM

BEM是我很喜欢的一个命名规范
命名规则简单直接又不至于混乱
BEM的意思就是块(block)、元素(element)、修饰符(modifier)

1
2
3
.block {} // 顶级命名,代表了一类元素块或者一个模块
.block__element {} // 次级命名(使用两个英文下划线连接,后跟随次级名称,表示次级元素或属性)
.block--modifier {} // 状态命名(使用两个英文中划线连接,后跟随修饰符或状态名)

这样的写法可以的好处是可以避免css的嵌套,可以加快css渲染时的速度
栗子🌰

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!-- 旧版命名 -->
<div class="person">
<div class="head"></div>
<div class="body"></div>
<div class="foot"></div>
</div>
<div class="pug">
<div class="head"></div>
<div class="body"></div>
<div class="foot"></div>
</div>
<style>
// css选择时需要两个class
.person .head {
width: 100px;
}
</styles>

<!-- BEM命名 -->
<div class="person">
<div class="person__head"></div>
<div class="person__body"></div>
<div class="person__foot"></div>
</div>
<div class="pug">
<div class="pug__head"></div>
<div class="pug__body"></div>
<div class="pug__foot"></div>
</div>
<style>
// css选择时只要一个class
.person__head {
width: 100px;
}
</styles>

BEM+emmet

相信很多同学有用过emmet,其前身就是大名鼎鼎的Zen coding
想了解的同学可以google一下emmet
而emmet对于BEM命名规范其实是有一套快速生成标签的规则的
发个栗子🌰
在emmet下这段代码

1
form.search-form>input.-username+input.-password[type=password]+button.-submit--active|bem

按下Tab后会生成

1
2
3
4
<form class="search-form">
<input type="text" class="search-form__username">
<input type="password" class="search-form__password">
<button id="J_Submit" class="search-form__submit--active"></button> <form>

如果仔细看第一段代码与第二段之间的区别就可以看出其中的奥义:

  • 首个元素的class选择器会被作为BEM规则的头,后面的每一个以.-开头子元素编译后的class属性都将以这个头为开头
  • 子元素可以以.-开头来代替父元素的class名,省去了重复书写的麻烦(即:.-username被编译成了.search-form__username)
  • 子元素可以跟上--加修饰符来编译(即:.-submit--active被编译成了.search-form__submit--active)

这是一种快速生成标签的形式,方便的没话说
而有一部分同学已经不再直接写html标签了,而是使用了模板引擎了
我用的是pug(也就是之前的jade,现在已经更名为pug了)
模板引擎的好处是使整个结构看起来更加清晰有条理,也加快了编写页面的速度,
在使用模板引擎后就不在需要emmet了
but!
虽然不需要了,但是emmet的那种化繁为简的精神是可以继续存在滴,我特别喜欢这样的语法,
于是就开始了尝试在css命名上做研究

以下是我vue2.0Demo项目内有关css命名的部分

一开始看可能会有点懵逼,但是当看完以下6个小点再回头看之前的案例就会明白了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* css命名使用 BEM+emmet 风格作为命名规范
*
* 约定[分类名称][属性|组件名称]与[属性名]使用小写
* 约定[描述]与[状态]使用首字母大写
* [eg]:
* .[分类名称]-[属性|组件名称][描述]--[属性值|状态]
* => .l-flexV--c
* => .b-base--Active
*
* 1.约定 [分类名称] 缩写:
* • .layout => .l- (布局部分)
* • .utils => .u- (工具部分)
* • .button => .b- (按钮部分)
*
* 2.约定通用 [属性] 缩写:(以emmet联想风格为缩写)
* • width => w
* • height => h
* • color => c
* • background => bg
* • margin => m
* • padding => p
* • border => bd
*
* 3.约定通用 [组件名称]:(这里不使用缩写,
* 因为组件名可以自定义,缩写易混淆,会增加记忆成本)
* • flex => flex (这里所指的是弹性盒子)
*
* 4.约定通用 [描述] 缩写:(以大写)
* • horizontal => H
* • vertical => V
* • normal => N
*
* 5.约定通用 [属性值] 缩写:(以属性前缀 '--' + emmet联想风格为缩写)
* • center => --c
* • middle => --m
* • space-around => --sa
*
* 6.约定通用 [状态] 缩写:(以属性前缀 '--' + 状态首字母大写,
* 这里不使用缩写,因为状态名可以自定义,缩写易混淆,会增加记忆成本)
* • active => --Active
*/

因为是一边写vue2.0-demo项目一边写文字,所以以上是暂定的部分,后续有更新会及时在这里更新

vue2.0一起在懵逼的海洋里越陷越深(一)

本文章系列:vue2.0一起在懵逼的海洋里越陷越深 (http://leenty.com/tags/vuejs/)

就在今年的10月份,Vue2.0发布啦,来懵逼的海洋里一起下沉吧!

前段阵子都没有发随笔,一方面要准备一场考试,另一方面是在研究vue2.0,又一方面一时也不知道写点什么好。
(而其实最大的方面是自己找到了偷懒不写随笔的理由了。。。)


vue2.0

@周星星和江南另外三大才子有佳句流传:
山下一群鹅,嘘声赶落河.
下河捉鹅医肚饿,吃完回家玩…
呃…玩vue2.0 咳咳咳咳

先看看vue2.0多了哪些好玩的

  • virtual-DOM(据说不是普通的Virtual-DOM)
  • Templates || JSX || Hyperscript(现在,你可以选择你喜欢的编写模式进行开发了)
  • 流式服务端渲染(这个听起来很厉害,后面一起研究)
  • 其他(各种性能优化,更多想象发挥空间,更多可能)

伴随着vue2.0的更新,vue生态链的其他组件也跟着进行了更新

  • vue-router
  • vue-resource
  • vue-cli

好,进入正题

先贴个地址,我的vue2.0的demo
这个demo使用vue-cli快速生成还发环境
加入vue-router做前端路由
加入vue-resource做ajax
加入vuex做状态管理
demo里目前使用hash模式
具体的会在接下来一一介绍

具体细节

好的,现在打开你的终端,开始开车啦!🚌

  • 安装vue-cli

    1
    npm install -g vue-cli
  • 创建vue项目
    语法:

    1
    vue init <template-name> <project-name>

这里我选择使用webpack来创建(可以参考git入门级-在github创建项目

1
vue init webpack app

之后vue-cli就会询问Project name,你可以输入你的工程名,或者直接回车就会默认使用之前的名称
之后还会有一系列询问,你可以一路回车下来,这样就创建好了一个
大概会是这样子
vue-cli

  • 安装依赖
    1
    npm i

当完成这一步步骤后就可以使用命令启动vue应用了

1
npm run dev

  • 接下来就安装其他需要的组件,vue-router,vue-resource,vuex
    1
    npm install vue-router vue-resource vuex --save

到这一步,vue项目的骨架已经好了。

vim!告别鼠标和触摸板,让你的双手专心的留在键盘上[未完]

vim从懵懂入坑到生无可恋

mengbiboyi

曾经,作为一名前端,也许不用太多在意去刻意的玩bash/shell什么的,毕竟之前的前端不会涉及这方面的需求。

随着node的流行,随着git的流行,各种模块管理器、任务管理器、打包工具的盛行,前端渐渐的也开始接触命令行一类的东西。
在使用git处理文件冲突的时候,如果不是用GUI的话,那么就需要使用vim打开冲突的文件进行解决了。


vim有3种模式,但常见的也只有两种,即Insert模式和Normal模式
其中

  • Insert模式是我们正常的可以输入文本的状态
  • Normal模式是输入命令的状态

    模式切换

    进入Insert模式:
  • 按下I键,即:在当前字符前插入文本
  • 按下shift+I,即:在当前行前插入文本
  • 按下A键,即:在当前字符后追加文本
  • 按下shift+A,即:在当前行后追加文本
    进入Normal模式(退出Insert模式):
  • 按下esc

    快捷键

    vim的快捷键基本是在Normal模式下才起作用(废话!Insert模式输快捷键就是输入文本)

光标操作

键位 效果 shift+当前键位时的效果 数字键+当前键位时的效果
H 光标左移 光标移到到当前屏幕第一行 光标移到到当前屏幕第n行
J 光标下移 合并当前行及下一行
K 光标上移
L 光标右移 光标移动到当前屏幕最后一行
w 光标向后移动到单词头部 光标移动到下一句文本头部
B 光标向前移动到单词头部 光标移动到上一句文本头部
E 光标向后移动到单词尾部 光标移动到当前句或者下一句文本尾部
^ 移动光标到行首
$ 移动光标到行尾
ctrl+F 下一页
ctrl+B 上一页
G 移动到末行 移动到第n行
G+G 移动到首行
) 移动到下一句
( 移动到上一句

利用host域名解析解决github访问慢问题

起因

最近家里访问github速度越来越慢,今天已经是异常的慢了,于是开始寻找解决的办法
遇到打不开的网站,本能的搬起‘梯子‘去翻墙,问题就这么解决了。。。
不对啊!我去!
github什么时候需要翻墙访问啦?

so

我开始寻找不翻墙的方法。
先看这张图
github-network
发现其实github.com的响应速度并不慢,而真正拖慢速度的是assets-cdn.github.com(其中pending的部分)
这基本是由dns污染所导致,所以只要通过host映射到一个畅通的IP上就会变的好起来。
进入一个dns域名检测的网站,在其中查询assets-cdn.github.com
会搜出一个dns列表,选择其中TTL值最小的一个IP,复制出来
命令行工具打开你的hosts文件(这里以macOS为例,如果你使用windows的git命令行工具,操作就是差不多的)

1
sudo vim /etc/hosts

在hosts文件最下方添加刚刚复制出来的IP

1
151.101.xxx.xxx assets-cdn.github.com

具体vim操作步骤:

  1. 按下shift + g跳至页尾
  2. 按下o创建新的一行
  3. 按下ctrl/command + v 粘贴刚刚复制的IP
  4. 而后打个空格
  5. 接着输入assets-cdn.github.com
  6. 按下esc退出编辑模式
  7. 输入:wq保存退出
    如此就大功告成了。
    如果还不会用vim,也可以用其他编辑器打开做修改。
    保存之后,就可以尝试再次访问github了,多刷几遍就能进去。
    如果还是进不去可以输入命令sudo dscacheutil -flushcache更新dns缓存,这样就可以进入了。