CSS3学习随笔
CSS3
css3是css2的升级,相比新增主要内容css选择器,和css属性
新增内容:语言模块,背景,列表,边框,文本,盒子特效,多列
渐进增强和优雅降级(面试题)
渐进增强
- 针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验
优雅降级
- 最初从高版本开始考虑,向低版本做向下兼容。与渐进增强相反
选择器
属性选择器
- elemt[attr]{}匹配有该属性的元素
- div[class]
- div[id]
- elemt[attr=“value”]{}匹配===属性和属性值的元素(属性值引号可省略)
- div[id="box"]
- elemt[attr~=“value”]{}匹配有该属性和属性值的元素(属性值引号可省略)(完整值)
- 补充:
- elemt[attr^=“value”]{} 匹配属性,且值以value开始(包含值的部分)
- elemt[attr$=“value”]{} 匹配属性,且值以value结尾(包含值的部分)
- elemt[attr*=“value”]{} 匹配属性,且值包含value。(包含值的部分)
- elemt[attr|=“value”]{}匹配属性,包含value的元素(完整值)
伪类选择器
结构伪类选择器(只能为单冒号)
- elemt:nth-child(n){} 匹配所有元素的第n个元素
- 需要匹配偶数时 括号n值为2n/odd 奇数2n+1/even
- 注意:匹配的时候,兄弟姐妹都会参与排序计算(如果两个div,中间一个p,用div:nth-child(2){color:red;}不会生效,因为此时选中的2为p,所以不生效)
- elemt:nth-of-type(n){}只匹配同类型元素亲兄弟
- elemt:first-child{} 匹配元素的第一个(其他元素参与计算)
- elemt:last-child{} 匹配元素的最一个(其他元素参与计算)
- elemt:only-child{} 匹配只有一个子元素的元素
- html:root{} 匹配文档的根元素
- 也可以这样书写 :root
- elemt:empty{} 匹配空(没有子元素或文字)的元素
否定伪类选择器
- elemt:not(选择器){} 选中 除选择器外 的其他元素
- 原来选择器有冒号,书写时仍然不能丢弃
- div:not([class="box"]){}
- div:not(:nth-child(1)){}
- 原来选择器有冒号,书写时仍然不能丢弃
动态伪类选择器
- a:link{} 点击前状态 默认为蓝色(a标签特有)
- a:visited{}点击后
- a:hover{} 鼠标移入
- a:active{} 激活状态(鼠标按下到弹起之间的状态)
- input:focus{} 获取焦点后的状态
ui状态伪类选择器
-
elemt:enabled{} 可用的状态下
-
elemt:disabled{} 禁用状态下
-
elemt:checked{} 选中状态下
-
自定义单选复选框
<style> * { margin: 0; padding: 0; } form{ margin: 100px 0 0 300px; } input{ -webkit-appearance:none; width: 24px; height: 24px; border: 1px solid gray; border-radius: 50%; vertical-align: middle; } /* 自定义单选框 */ input:checked{ border: none; background:url(../img/gou.png) no-repeat center/24px 24px; } /* 自定义内部圆圈 */ /* input:checked:after{ content: ""; display: block; width: 15px; height: 15px; background-color: orange; border-radius: 50%; margin-top: 4px; margin-left: 4px; } */ </style> <body> <form action=""> <input type="radio" id="a"> <label for="a">篮球</label> </form> </body>
目标伪类选择器
- elemt:target{} 搭配锚点使用
补充:
- elemt::selection{} 文本选中时状态时设置改变背景颜色和文本颜色(!双冒号)
文字阴影text-shadow
- text-shadow: 水平偏移 垂直偏移 模糊距离 阴影的颜色;
- text-shadow:5px 5px 5px red;
- 水平和垂直,值越大,越往右移,可给负值
- 模糊距离,不可给负值
- 多个阴影用逗号隔开
- text-shadow: 5px 5px 5px red,-5px -5px 5px green;
文本换行
- word-wrap:;
- normal 只在允许的断字点换行(浏览器保持默认处理)
- break-word 属性允许长单词或 URL 地址换行到下一行
- word-break
- break-all 它断句的方式非常粗暴,它不会尝试把长单词挪到下一行,而是直接进行单词内的断句
- keep-all 文本不会换行,只能在半角空格或连字符处换行
盒子
盒子阴影 box-shadow
- box-shadow: 水平偏移 垂直偏移 模糊距离 阴影外增加大小 阴影的颜色 inset;
- inset 内阴影
- 多个阴影用逗号隔开
- 部分参数可以省略
边框圆角 boder-radius
- 以盒子最短的边为准,超过50%后将不会变化(盒子为正方形会变成整圆,长方形会变成操场形状)
- 取值
- 没有/
- 一个值 四个角的水平垂直偏移相同
- 10px 20px 左上和右下水平垂直均为10px;右上和左下水平垂直均为20px
- 10px 20px 30px 10左上 20右上,左下 30右下
- 四个值 左上 右上 右下 左下
- 有/ x/y
- 10px/20px 四个方向 水平偏移10px 垂直20px 连接形参圆滑的线
- 10px 20px/20px 10px左上水平 20px右上和左下水平
- 10px 20px 30px/20px
- 10px 20px 30px 40px/40px 30px 20px 10px
- 没有/
字体模块
字体样式(.ttf .TTF):
- css样式中 @font-face
- 使用:p
渐变
(渐变会被解析为图片,所以属性要写成background-image:😉
线形渐变linear-gradient:; (一个方向往另一个方向平稳渐变)linear线性的 gradient渐变
- 从上往下(默认)background:linear-gradient(颜色1,颜色2,颜色3...);
- 从左往右background:linear-gradient(to right,颜色1,颜色2,颜色3...);
- 从左下到右上background:linear-gradient(to right top,颜色1,颜色2,颜色3...);
- 角度background:linear-gradient(30deg,颜色1,颜色2,颜色3...);
径向渐变radial-gradient:;(由中间以水波状往四周扩散) radial放射状的
- background:radial-gradient:(center ,shape,size,颜色1,颜色2...);
- center渐变中心的位置
- 有兼容性问题,需要写前缀-webkit-
- background:-webkit-radial-gradient:(40px 60px,tomato,yellow);
- shape渐变形状
- circle正圆
- ellipse 椭圆(默认)
- background: radial-gradient(circle, tomato, yellow, black);
- size 渐变大小
- closest-side/corner 紧挨着的边/角
- farthest-side/corner最远的边/角
- 渐变中心和渐变大小同时使用时,位置需调整
- background:radial-gradient:(closest-side at 40px 60px,red,block);
- center,shape,size都可以按需省略,默认渐变形状为椭圆
- center渐变中心的位置
重复渐变repeating:;
- 重复线性渐变background:repeating-linear-gradient(tomato 50%,black 60%);
- 从50%的位置tomato向black渐变到60%
- 重复径向渐变background:repeating-radial-gradient(tomato 50%,black 60%);
过渡效果transiton:;
复合写法:transition:all linear 1s; 一般放在需要改变的元素身上,不放在hover上
不支持display:block/none;
- transition-property:;参与过渡的属性
- all
- width
- height
- transition-timing-function:;过渡效果
- linear 线性的 平稳的
- ease(默认)逐渐慢下来
- ease-in 加速
- ease-out 减速
- ease-in-out 先加速 再减速
- steps(5) 每次增加对应长度
- 贝塞尔曲线 cubic-bezier(.17,.67,.83,-0.15)
- transition-duration:2s; 过渡时间
- transition-delay:.5s;延迟
变换(2D)transform:;
transform:;
- translateX(50px);水平平移
- translateY(50px);垂直平移
- transform:translate(50px,-50px); /transform:translateX(50px) traslateY(-50px); 水平平移50 垂直-50
- 取一个值只生效水平平移,两个值x,y
- rotateX (30deg);水平旋转
- rotateY(30deg); 垂直旋转
- rotate(30deg) 沿z轴
- scaleX(1.2)垂直缩放(从中间往上下缩放 原大小的1.2倍大小)
- scaleY()水平缩放
- scale(1.2 2)上面放大1.2倍,下面放大2倍
- 取负数会使元素颠倒和再按照绝对值进行放大或缩小
- 取小于1,大于0的会缩小
- 1默认值,不进行缩放
- 0隐藏
- 取一个值表示横向纵向同时缩放
- skewX(30deg);扭曲(正数:水平拉扯元素左上和右下角变形。负数:水平拉扯元素右上和左下角变形)
- skewY();
- skew(30deg,30deg);
变换的补充
多个属性同时使用时,需要用空格隔开,且优先写平移,再写其他属性(因为旋转后xy轴会随着旋转而改变)。transform:translateX(50px) rotateX(30deg);
- transform-origin:; 变化原点 origin起源
- 0 0
- right center
- right
- top
- bottom
- center
2D动画animation:;
-
使用动画animation:donghua linear 0.5s;
-
定义动画:
-
animation-name:动画名称;
-
animation-duration:2s;执行时间
-
animation-timing-function:linear;执行效果
- linear 线性的 平稳的
- ease(默认)逐渐慢下来
- ease-in 加速
- ease-out 减速
- ease-in-out 先加速 再减速
- steps(5) 每次增加对应长度
- 贝塞尔曲线 cubic-bezier(.17,.67,.83,-0.15)
-
animation-delay:2s;延迟 (动画执行之前生效)
-
animation-iteration-count:5;执行次数
- infinite 无限次数
-
animation-direction:;执行方向
- normal 按顺序执行(默认)
- reverse 逆转
- alternate往返
-
alternate-reverse 反方向往返
-
animation-play-state:;动画播放状态
- paused暂停
- running继续
-
复合写法:animation:动画名称 执行效果 执行时间 延迟 次数 方向;
- animation:donghua linear 2s 0.5s infinite alternate;
-
animation.css插件
-
下载地址:https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css
@keyframes donghua{ from{ transform:translateX(0); } to{transform:translateX(450px)} } @keyframes donghua{ 0%{transform:translateX(0);} 50%{tansform:translateX(450px);} 75%{tansform:translateY(450px);} 100%{tansform:translateY(0);} }
3D动画
-
景深(视觉角度问题 近大远小)
-
perspective:900px;景深 (一般给父元素)
-
取值900px-1200px 值越大距离越远效果越不明显
-
给子元素时:
-
transform:perspective(900px) rotateX(30deg)
-
注意:1.同时出现perspective和其他元素,景深写前面
2.父元素和子元素同时写perspective会有冲突
-
-
-
transform-style:preserve-3d;3d旋转舞台
- 默认值flat 平面的
- preseve-3d 3d旋转舞台
-
perspective-origin:关键词组合;控制视角
- right top
- left bottom
-
transform:translateZ(30px);沿z轴平移 (一般先平移再旋转或其他)
- transform:translateX(20px)translateY(20px)translateZ(30px) / 简写:transform:translate3d(20px,20px,30px);
-
transform:roteta();
-
transform:scaleZ();沿着z缩放 效果不明显
- 配合景深
flex弹性盒布局
基本概念:是css3引入的一种新的布局方式,只对子元素生效,不会影响孙子辈元素
容器:触发弹性盒子的父元素
项目:弹性盒子里面的子元素
弹性盒特征:
1.触发弹性盒子后,里面亲儿子会变成块元素并横向排列
2.只有一个项目时设置给它margin:auto;会水平垂直居中(父盒子需要设置高度)
主轴:触发弹性盒子后,子元素的排列方向就是主轴(主轴可以改变)
侧轴:与主轴对立的方向就是侧轴
横轴:横向的轴
纵轴:竖着的轴
触发弹性盒子:display:;
- display:;(给父元素)
- flex
- inline-flex 行级元素可以用这个触发弹性布局
项目在主轴对齐方式:justify-content
- justify-content:;(给父元素)
- start 主轴开始的位置,项目之间没有间隙
- flex-start 主轴开始的位置,项目之间没有间隙(默认)
- center 主轴开始的位置,项目之间没有间隙
- end 主轴结束的位置,项目之间没有间隙
- flex-end 主轴结束的位置,项目之间没有间隙
- space-around 中间的间隙是两边间隙的2倍
- space-between 两端对齐(左右贴紧,中间间隙平均分配)
- space-evenly 平均分配(项目之间的间隙=靠边项目到容器的距离)
改变主轴的方向:flex-direction:;
- flex-direction:;(给父元素)
- row 横轴 (从左往右)
- row-reverse 横轴反向(从右向左)
- column 纵轴(从上往下)
- column-reverse 从上往下
侧轴对齐方式:align-items:;
- align-items:;(给父元素)
- flex-start 侧轴开始的位置,项目之间没有间隙
- flex-end 侧轴结束的位置,项目之间没有间隙
- center 侧轴开始的位置,项目之间没有间隙
- stretch 不设置高度时 拉伸
- baseline 基线对齐
折行flex-wrap:
- flex-wrap:;(给父元素)
- nowrap不折行(默认)空间不够时会压缩
- wrap 折行
- wrap-reverse 折行且反向
主轴方向和折行(direction/wrap)的简写:flex-flow:;
- flex-flow:方向 折行;(给父元素)
- row nowrap(默认值)
- colum wrap-reverse
项目在侧轴上的对齐方式align-content:;(必须搭配折行使用)
(行与行之间的距离)
- align-content:;(给父元素)
- flex-start 侧轴开始的位置,项目之间没有间隙
- flex-end 侧轴结束的位置,项目之间没有间隙
- center 侧轴开始的位置,项目之间没有间隙
- space-around 中间的间隙是两边间隙的2倍
- space-between 两端对齐(两端贴紧,项目之间的间隙平均分配)
- space-evenly 平均分配(项目之间的间隙=靠边项目到容器的距离)
- stretch 不设置高度时 拉伸
- flex-start 侧轴开始的位置,项目之间没有间隙
项目单独在侧轴上的对齐方式align-self:;
- align-self:;(给子元素)
- flex-start 侧轴开始的位置,项目之间没有间隙
- flex-end 侧轴结束的位置,项目之间没有间隙
- center 侧轴开始的位置,项目之间没有间隙
- stretch 不设置高度时 拉伸
- baseline 基线对齐
项目排列
- order:5;(给子元素)
- 默认为auto/0
- 数字越小,越靠前
项目分配大小flex:;
-
flex:1;(剩余大小按值分配 )
- 实现左边固定宽度,右边自适应: 左边写宽高,右边给flex:1;
- flex:1;是: flex-grow flex-shrink flex-basis的简写
- flex:1;====flex:1 1;
- flex:auto;====flex 1 1 auto;
-
flex-grow:1; 伸缩
- 0 默认不扩大
- 1 扩大
-
flex-shrink:0;压缩
- 0不压缩
- 1压缩
- 2压缩的更多
-
flex-basis:260px; 宽度
- flex-basis与宽度同时出现时以flex-basis为准
- auto
小青蛙游戏
多列 column
瀑布流,京东...
- 使用flex布局多列问题:
- overflow:auto;会使多列失效,不用overflow:auto;
- 使用多列时,头部和尾部消失,给其设置宽度
- 头部和尾部跟随文档流,设置定位
- 第二列的开始以文字开头 break-inside:avoid;
- (一般采用,上下固定高度且fixed定位,中间calc减去上下高度且margin上下高度布局方法)
给父元素:
- column-count:2;设置列数
- column-gap:50px;多列之间间隙
- column-rule:1px solid red;设置边框
- column-rule-color:;默认黑色
- column-rule-width:;默认有宽度
- column-rule-style:;边框线样式
- column-width:100px;设置宽度
- 宽度过宽会减少列数
- column-fill:;
- auto 自动填充满父元素高度再换列
- balance 平衡的 (默认值)
给子元素:
- column-span:;
- all 合并所有列
- none(默认)
- break-inside:;
- auto 元素可以中断
- avoid 不可以中断
响应式布局
内容随浏览器窗口变化发生相应改变,且不会出现滚动条。
一套代码适配不同的终端,开发成本高(代码内部结构比较杂,需要嵌套多层,后端数据处理相对麻烦)
一阶段媒体查询
二阶段bootstrap 建议自学 (相对于字体图标)https://www.bootcss.com/
https://element.eleme.io/#/zh-CN
原生媒体查询格式:
-
@media 设备类型 and(条件) and (条件){选择器{}} 监听屏幕尺寸
(注意:and左右有空格,条件后面没有分号。)
- @media screen and(max-width:700px) and (min-width:500px) {div{color:red;}}
- 扩展:
- @media only screen and(max-width:1200px) {div{color:red;}}仅在某个范围
- @media not screen and(max-width:1200px) {div{color:red;}}不在某个范围
-
@media screen (orientation:portrait){div{}} 监听竖屏横屏
- orientation:
- portrait 竖屏
- landscape 横屏
- orientation:
-
断点:
- 主断点:320px 720px 1024px
- 次断点: 480px(iphone/android手机横屏) 640px 768px(ipad/android平板电脑横屏)
移动端布局
captur screenshot短截屏
captur pullsize 长截屏
f5是普通刷新,ctrl+f5强制刷新
视口:
视觉视口===看到的窗口(屏幕的大小)
布局视口 ===编写的css和html页面就是你的布局视口
理想化视口===通过理想化视口可以将布局视口完整的放进视觉视口里面
dpr:
设备像素比=物理像素/css像素
移动端开发步骤:
-
不使用flexble.js
1.根据设计稿推断出设备像素比
2.根据设备像素比推出css像素
3.引入理想化视口
4.引入字体图标,公共样式,开始布局
正常布局(大小除以设备像素比)
-
使用flexble.js
- 引入js
- 删除理想化视口
- 正常布局(大小量多少除以100)
单位
px
- 固定像素值
em 相对单位
- 自身有大小就参照自身大小,没有就往上级查找,都没有就参照根元素字体大小
rem 相对于根目录的字体大小 (root em)
-
根据根元素大小 1rem=16px
html的字体大小16px 比如ps量取370px===》370/2=185px 185/16==11.5625 具体rem值=370/2/根目录字体大小(16px) 具体rem值=370/2/设置根目录字体大小50px
vw 相对于视口的宽度(viewport-width)
- 一个完整的视口=100vw(包含滚动条)
vh 相对于视口的高度(viewport-hight)
- 一个完整的视口=100vh
% 相对于父元素的宽高度
deg 角度单位
100%:
实际宽度:100%+盒子模型 =100%+padding+border
auto:
实际宽度:父元素或浏览器窗口的100%
网格布局(grid布局)
网格和弹性盒布局的区别:
相同点:概念类似:都有容器和项目的概念
不同点:
弹性盒布局是一维布局(确定了主轴方向,设置其他属性)
网络布局是二维布局(由行和列构成)
触发grid布局display:grid;
- grid 块级网格
- inline-grid 行级网格
设置行和列:
grid-template-rows:;设置行
grid-template-columns:;设置列
- grid-template-rows:150px 150px 150px;
- grid-template-rows:repeat(重复次数,宽/高度);
- 重复次数:可以写数值,也可写auto-fill 自动填充
- grid-template-rows:1fr 2fr 3fr;一个片段(占总数的多少分之一)fragment
- grid-template-rows:100px minmax(100px,500px) 100px;
- grid-template-rows:100px auto 100px; 自动填充
- grid-template-rows:100px 1fr 100px; 自动填充
- grid-template-rows:10% 50% 10%;
单元格之间的间隙
grid-row-gap:10px;行间距(新版本可省略grid,为row-gap:10px;)
grid-column-gap:10px;列间距
- 简写 gap:10px 20px;行/列
网格命名
- 给线取名
- grid-template-columns:[c1] 100px [c2] 100px [c3]...;
- 给每个单元格取名(取名尽量用小写字母,不用可以用英文句号占位)
- grid-template-areas:'a b c'回车'. . g'回车'h i j'.....;
- 子元素使用:grid-area:e;(让此子元素移动到e位置)
整体网格的对齐方式:
-
justify-content:; 水平的
- end
- start
- center
- space-between
- space-evenly
- space-around
- stretch 延申 (不写高度)
-
align-content:; 垂直
-
end
-
start
-
center
-
space-between
-
space-evenly
-
space-around
-
stretch 延申 (不写高度)
-
-
简写:place-content:垂直 水平 ;
内容在单元格内居中
- justify-items:center;水平居中
- left
- right
- center
- stretch 延申(不写宽高,会自动填充满)
- align-items:center;垂直居中
- start
- end
- center
- stretch
- 简写:place-items:垂直 水平;
- 子元素单独设置在单元格内的对齐方式:
- align-self:; 垂直
- justify-self:;水平
单元格的排序
- grid-auto-flow:;排序方式
-
row(默认)从左往右
-
column 从上往下
-
dense 搭配限定区域使用(使用限定区域时,使用dense排序 )
-
子元素:调整网格线实现单元格合并
-
grid-column-start:; 限定区域
-
grid-column-end:;
-
简写:grid-column:1/4;grid-row:1/4;
- 再简写:grid-area:1/2/4/3;横开始/竖开始/横结尾/竖结尾(grid-row-start grid- column-start grid-row-end grid-column-end)
-
-
-
-
合并单元格
- 给想要合并的单元格取相同的名字
- grid-template-areas:'a b c'
'e e g'; - 子元素使用:grid-area:e;
- grid-template-areas:'a b c'
边框图片
-
border-image:linear-gradient(red,green);线性渐变边框
-
border-image:url() 20 20 round; 简写
- border-image-source:url();
- border-image-slice:20;边框多大就写多大,不写单位
- border-image-repeat:;
- strech 拉伸
- repeat 平铺
- round 平铺且根据情况缩放
- space 平铺不缩放,间隙用空白填充
-
border-image-outset:1.2;倍数
背景:
背景图原点的位置
- background-origin:;图片显示位置
- border-box
- padding-box (默认值)
- content-box
背景图的裁剪
-
background-clip:;
-
text 文字裁剪(文字部分显示背景图)(有兼容问题)
1.引入背景图片
2.使用-webkit-background-clip:text;
3.文字调节为color:transparent;
-
border-box (默认值)
-
padding-box
-
content-box
-
精灵图.png(css sprites雪碧图)
优点:将网页中的一些小背景图像整合到一张大图中,这样服务器只需要一次请求即可
- 通过background-position:;调整背景图片位置
浏览器兼容:
浏览器前缀
-
-webkit- 谷歌chrome 苹果
-
-ms- IE
-
-o- 欧鹏
-
-moz- 火狐
- -webkit-border-radius:;
- /linear-gradient/box-shadow/backgrund-clip等属性有兼容问题
- -webkit-border-radius:;
-
针对IE浏览器不同版本的解决方案
-
兼容ie6的hack符号:-或_
- _border-radius:10px;
-
-
-border-radius:;
-
兼容ie6,7的hack符号:~+&
- ~border-radius:;
-
+order-radius:;
- &border-radius:;
-
-
兼容ie8的hack符号:.
- .border-radius:;
- hack符号在后 兼容ie89 10
- border-radius:10px\0;
浏览器内核
兼容问题产生的元素:不同浏览器的内核不同。
- Trident IE浏览器(2016年1月12日停用)
- Blink(以前)-webkit(现在) 谷歌(Chrome)
- Gecko 火狐(Mozilla Firefox)
- webkit 苹果safari
- Presto-webkit-Blink 欧鹏(Opera)
常见兼容性问题:
- IE低版本常见css解析Bug以及hack
- bug图片会出现边框
- hack 给图片加border:0/none;
- 在div中插入图片,图片周围会有3px间距
- hack
- 转换图片类型display:block;
- 对齐方式 vertical-align:center;
- 给盒子font-size:0;
- hack
- 鼠标指针bug(鼠标移入显示小手)
- cursor:hand;只在ie9下浏览器识别,其他浏览器不识别。
- cursor:pointer;在ie6上识别
- 其他效果
- auto 默认
- text 文本
- wait 等待
- help 帮助
- progress 过程
- progress 圈圈加箭头
- move 移动
- opacity在IE中的写法
- fillter:alpha(opacity=1-100的整数);
- 表单元素不能对齐的解决方案
- 产生原因是盒子模型不一样
- 通过浮动清除他们之间的间隙
- 通过改变盒子模型来调整大小
- 产生原因是盒子模型不一样
posted on 2022-10-29 15:04 Elementinner 阅读(44) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通