gzl的博客

  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

CSS编码技巧

发表于 2019-07-23 分类于 CSS

尽量减少代码重复

从一个 button 的 CSS 代码开始

固定尺寸

下面这两段代码是对一个 button 添加 CSS 样式

HTML 部分

1
2
3
<div class="wrapper">
<button class="btn">Yes!</button>
</div>

CSS 部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.wrap{
font-size: 16px;
}
.btn{
padding: 6px 16px;
border: 1px solid #446d88;
background: #58a linear-gradient(#77a0bb, #58a);
border-radius: 4px;
box-shadow: 0 1px 5px gray;
color: white;
text-shadow: 0 -1px 1px #335166;
font-size: 20px;
line-height: 30px;
}

比例变化

如果我们决定改变字号,就得同时调整行高以及一系列属性,因为这些属性都写成了绝对值。当某些值相互依赖时,应该把它们的相互关系用代码表示出来。在这个例子中,行高是字号的 1.5 倍,其他属性除了 border-radius 都按比例改过来。改成 百分比 或 em 单位更容易维护。

1
2
3
4
5
6
7
8
9
10
11
.btn{
padding: 0.3em 0.8em;
border: 1px solid #446d88;
background: #58a linear-gradient(#77a0bb, #58a);
border-radius: 0.2em;
box-shadow: 0 0.05em 0.25em gray;
color: white;
text-shadow: 0 -0.05em 0.05em #335166;
font-size: 125%; /* 假设父级的字号是 16px,125% 是 20px */
line-height: 1.5;
}

现在我们改变父级的字号,按钮的尺寸就会随之变化,并且是依赖字号进行缩放,这样我们就可以在一处控制按钮的所有尺寸了。

颜色通用

假设我们要创建一个红色的取消按钮,或者一个绿色的确定按钮,该怎么做呢?我们可能需要覆盖四条声明(border-color、background、box-shadow 和 text-shadow),而且还有另一大难题:要根据按钮的亮面和暗面相对于主色调 #58a 变亮和变暗程度来分别推导出其他颜色各自的亮色和暗色版本。此外,若我们想把按钮放在一个非白色的背景之上呢?显然使用灰色(gray)做投影只适用于纯白背景的情况。

其实只要把半透明的黑色或白色叠加在主色调上,即可产生主色调的亮色和暗色变体。这样就简单地解决问题了。

推荐使用 HSLA 而不是 RGBA 来产生半透明的白色。

所以现在只需覆盖 background-color 属性,就可以得到不同颜色版本的按钮了。

HTML 部分

1
2
3
4
5
<div class="wrap">
<button class="btn">Yes!</button>
<button class="btn cancel">Cancel</button>
<button class="btn ok">OK</button>
</div>

CSS 部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.wrap{
font-size: 20px;
}
.btn{
padding: 0.3em 0.8em;
border: 1px solid rgba(0, 0, 0, 0.1);
background: #58a linear-gradient(hsla(0, 0%, 100%, 0.2), transparent);
border-radius: 0.2em;
box-shadow: 0 0.05em 0.25em rgba(0, 0, 0, 0.5);
color: white;
text-shadow: 0 -0.05em 0.05em rgba(0, 0, 0, 0.5);
font-size: 125%;
line-height: 1.5;
}
button.cancel{
background-color: #c00;
}
button.ok{
background-color: #6b0;
}

合理使用简写

1
2
3
4
5
.btn{
background: url(tr.png) no-repeat top right / 2em 2em,
url(br.png) no-repeat bottom right / 2em 2em,
url(bl.png) no-repeat bottom left / 2em 2em;
}

下面的方式更好

1
2
3
4
5
6
7
.btn{
background: url(tr.png) top right,
url(br.png) bottom right,
url(bl.png) bottom left;
background-size: 2em 2em;
background-repeat: no-repeat;
}

LC-爬楼梯

发表于 2019-07-22 更新于 2020-03-14 分类于 LeetCode

题目描述

爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

1
2
3
4
5
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
1
2
3
4
5
6
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

代码实现

递归

自上而下的递归,n 变大以后会超出时间限制

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
if (n === 1) {
return 1;
}
if (n === 2) {
return 2;
}
return climbStairs(n - 1) + climbStairs(n - 2);
};

备忘录哈希表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
let map = [1, 2];
if (n === 1 || n === 2) {
return map[n - 1];
}
for(let i = 2; i < n; i ++) {
map[i] = map[i - 1] + map[i - 2]
}
return map[n - 1];
};

动态规划

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
let a = 1;
let b = 2;
if (n === 1 || n === 2) {
return n;
}
for (let i = 2; i < n; i++) {
[a, b] = [b, a + b];
}
return b;
};

参考

漫画:什么是动态规划?

LC-对称二叉树

发表于 2019-07-22 更新于 2020-03-21 分类于 LeetCode

题目描述

对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

1
2
3
4
5
    1
/ \
2 2
/ \ / \
3 4 4 3

但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

1
2
3
4
5
  1
/ \
2 2
\ \
3 3

代码实现

DFS(递归)

递归比迭代要简单很多

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
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
if (!root) {
return true;
}
function DFS(l, r) {
if (!l && !r) {
return true;
}
if ((!l && r) || (l && !r) || (l.val !== r.val)) {
return false;
}
return DFS(l.right, r.left) && DFS(l.left, r.right)
}
return DFS(root.left, root.right)
};

BFS(队列 + 迭代)

队列 + 迭代的实现方式

这里的 while (q1.length && q2.length) 少了 length 就会一直执行下去,因为 Boolean([]) 为 true,这里的q指代 队列,shift 方法为删除数组的第一个元素并返回第一个元素的值。

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
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
if (!root) {
return true;
}
let q1 = [root.left];
let q2 = [root.right];
while (q1.length || q2.length) {
let n1 = q1.shift();
let n2 = q2.shift();
if (!n1 && !n2) {
continue;
}
if ((n1 && !n2) || (!n1 && n2) || (n1.val !== n2.val)) {
return false;
}
q1.push(n1.left);
q1.push(n1.right);
q2.push(n2.right);
q2.push(n2.left);
}
return true;
};
1…242526…32

gzl

96 日志
14 分类
37 标签
© 2020 gzl
由 Hexo 强力驱动 v3.7.1
|
主题 – NexT.Pisces v7.2.0