HTML用于定义内容的结构和语义,CSS用于设计风格和布局。
CSS规则由选择器和声明块组成;声明由属性(properties)和属性值组成。
CSS介绍:
盒=框=box,边界=border,内边距=填充=padding
DOM (文档对象模型)是一种树形结构. 标记语言中的每个元素、属性(?)、文本片段都变为一个 DOM 节点。由于 DOM 是 CSS 与文档内容的相遇之处,理解 DOM 有助于设计、调试和维护你的 CSS 文件。
用外部样式表将 CSS 应用到 HTML 上可以说是最好的方法,因为你可以使用一个样式表来设置多个文档的样式,并且需要更新 CSS 的时候只要在一个地方更新。除此之外还有内部样式表(某些情况下很有用,比如你正在使用一个CMS(内容管理系统),不能直接修改 CSS 文件)和内联样式(除非有必要,否则不要这么做!您唯一可能需要使用内联样式是当您的工作环境真的非常受限,比如您的CMS只允许您编辑 HTML 的 body)。
保持不同类型代码(比如HTML和CSS)的分离和纯净使处理该代码的人的工作更为容易。
CSS 是一种声明式语言,这令其语法相当简单直观且易于理解。此外,CSS还有着相当不错的错误修复系统,这一特性允许你犯一些错误(包含语法错误,或者浏览器不支持该特性)但并不会造成什么异常影响 —— 比如,有可能你的某些声明浏览器并不理解,这时浏览器会直接忽略掉这些内容并继续执行渲染。当然这一特性也可能导致一些问题,比如一些异常情况出现的时候,可能会对定位问题的原因造成一些障碍。
CSS 的属性和属性值都是区分大小写的。
CSS 有超过300 个不同的属性以及几乎无穷无尽的属性值。属性和属性值不能任意组合:每个属性都有一个已经定义好的可用属性值范围。
重要: 如果使用了未知属性,或者给属性赋予了无效值,该声明会被视为无效,浏览器的 CSS 引擎会完全忽略它。
声明块里的每一个声明必须用半角分号(;)分隔,否则代码会不生效(至少不会按预期的生效)。声明块里的最后一个声明结束的地方,不需要加分号,但是最后加分号是个好习惯,因为可以防止在后续增加声明时忘记加分号。
一个元素可以被多个选择器所匹配,因此,一个给定的属性可能被多个规则设置多次。 CSS 定义了哪个规则比其它规则更具优先级:这被称为层叠算法(cascade algorithm)。
CSS 规则是样式表的主要组成块 —— 是你在 CSS 中最常见的块。除此之外还有@-规则 ,@-规则在CSS中被用来传递元数据、条件信息或其它描述性信息—— CSS 规则只是被称为 CSS 语句中的一种。
一些属性比如 font,background,padding,border,和 margin被称为简写属性。注:似乎大多数简写属性的属性值的顺序都无关紧要。
选择器分为简单选择器、属性选择器、伪类和伪元素选择器、组合器和多选选择器。
简单选择器(Simple selectors):通过元素类型、class 或 id 匹配一个或多个元素。其中,类选择器由一个点“.”以及类后面的类名组成;类名是在HTML 中的class属性中没有空格的任何值;文档中的多个元素可以具有相同的类名,单个元素也可以有多个类名(以空格分开多个类名)。而ID选择器由#以及后面的ID组成;ID唯一,这是选择单个元素的最有效的方式。通用选择(*)是最终的王牌。它允许选择在一个页面中的所有元素。重要提示:使用通用选择时要小心。因为它适用于所有的元素,在大型网页利用它可能对性能有明显的影响:网页的显示可能比预期要慢。大多数情况下,你都不会使用这个选择器。
属性选择器(Attribute selectors):通过元素的属性和(或)属性值匹配一个或多个元素。由方括号([]) 组成,其中包含属性名称,后跟可选条件以匹配属性的值。比如[lang|="fr"]。
存在和值属性选择器:[attr]、[attr=val]和[attr~=val]。
子串值(Substring value)属性选择器:
[attr|=val] : 选择attr属性的值是 val 或值以 val- 开头的元素(注意有个-)。
[attr^=val] : 选择attr属性的值以val开头(包括 val)的元素(与上面那个不同)。
[attr$=val] : 选择attr属性的值以val结尾(包括 val)的元素。
[attr*=val] : 选择attr属性的值中包含字符串 val 的元素。
伪类(Pseudo-classes):匹配处于确定状态的一个或多个元素,比如被鼠标指针悬停的元素,或当前被选中或未选中的复选框,或元素是DOM树中一父节点的第一个子节点。以冒号(:)作为前缀,冒号前面是其它的选择器。
伪元素(Pseudo-elements):匹配处于相关的确定位置的一个或多个元素,例如每个段落的第一个字,或者某个元素之前生成的内容。前缀是两个冒号 (::),冒号前面是其它的选择器。
组合器(Combinators):组合两个或更多的选择器用于非常特定的选择的方法。例如,你可以只选择divs的直接子节点的段落,或者直接跟在headings后面的段落:
A B(B是A的后代结点);
A>B(B是A的(直接)子节点,注意(直接)子节点的意思,不能理解就看上面那一行);
A+B(B是A的下一个兄弟节点);
A~B(B是A之后的兄弟节点中的任意一个)。
多选选择器(Multiple selectors):不是单独的选择器,是将以逗号分隔开的多个选择器放在一个CSS规则下面, 以将一组声明应用于由这些选择器选择的所有元素。
data-* 属性被称为数据属性。它们提供了一种在HTML属性中存储自定义数据的方法,由此,这些数据可以轻松地被提取和使用。
两个选择器紧挨着则表示选择的元素要同时满足这两个条件。
使用相对单位是非常有用的——你可以调整你的HTML元素大小相对于你的全局字体大小或视口大小,这意味着布局将保持看起来正确。
颜色系统:
关键词(如red)
16进制值(如#ff0000)、RGB(如rgb(255,0,0)):RGB值可以说比十六进制值更直观,更容易理解;
HSL:hsl()函数接受色相、饱和度以及明度值,如hsl(0,100%,50%);
RGBA和HSLA:比RGB和HSL多一个透明度的参数(0到1的值);
不透明度:通过CSS——opacity 属性设置。可以同时改变背景和文本的透明度。
层叠和继承:
元素的最终样式可以在多个地方定义,它们以复杂的形式相互影响。这些复杂的相互作用使CSS变得非常强大,但也使其非常难于调试和理解。这是CSS 理论中最复杂的地方。
什么选择器在层叠中胜出取决于三个因素(以下是按重量级顺序排列的——前面的的一种会否决后一种):重要性(Importance,似乎就只有!improtant这一个东西能影响重要性)、专用性(Specificity)、源代码次序(Source order)。
在CSS中,有一个特别的语法可以让一条规则总是优先于其他规则:!important。把它加在属性值的后面可以使这条声明有无比强大的力量。重载这个 !important 声明的唯一方法是在后面的源码或者是一个拥有更高专用性的源码中包含相同的 !important 特性的声明。知道 !important存在是很有用的,这样当你在别人的代码中遇到它时,你就知道它是什么了。但是!我们建议你千万不要使用它,除非你绝对必须使用它。您可能不得不使用它的一种情况是,当您在CMS(内容管理系统)中工作时,您不能编辑核心的CSS模块,并且您确实想要重写一种不能以其他方式覆盖的样式。 但是,如果你能避免的话,不要使用它。由于 !important 改变了层叠正常工作的方式,因此调试CSS问题,尤其是在大型样式表中,会变得非常困难。
专用性(基本上是衡量选择器的具体程度的一种方法——它能匹配多少元素(越少越专用)):ID选择器>class选择器>元素选择器。战胜ID选择器的唯一方法是使用 !important(其实足够多的class选择器也可以战胜)。
一个选择器具有的专用性的量是用四种不同的值(或组件)来衡量的,它们可以被认为是千位,百位,十位和个位——在四个列中的四个简单数字(权重并不准确,因为11个class选择器不能战胜1个id选择器):
千位:如果声明是在style 属性中该列加1分(没有选择器, 规则在HTLM文件中的一个元素的style属性里,所以它们的专用性总是1000);
百位:在整个选择器中每包含一个ID选择器就在该列中加1分;
十位:在整个选择器中每包含一个类选择器、属性选择器、伪类就在该列中加1分;
个位:在整个选择器中每包含一个元素选择器或伪元素就在该列中加1分;
注意: 通用选择器 (*), 复合选择器 (+, >, ~, ' ') 和否定伪类 (:not) 在专用性中无影响。
在考虑所有这些层叠理论和什么样式优先于其他样式被应用时,你应该记住的一件事是,所有这些都发生在属性级别上——属性覆盖其他属性,但你不会让整个规则凌驾于其他规则之上。
哪些属性默认被继承哪些不被继承大部分符合常识。
控制继承:
inherit:该值将应用到选定元素的属性值设置为与其父元素一样;
initial :该值将应用到选定元素的属性值设置为与浏览器默认样式表中该元素设置的值一样。如果浏览器默认样式表中没有设置值,并且该属性是自然继承的,那么该属性值就被设置为 inherit;
unset :该值将属性重置为其自然值,即如果属性是自然继承的,那么它就表现得像 inherit,否则就是表现得像 initial(与initial不同之处在于判决顺序)。
重新设置所有的属性值:属性 all 能够被应用到每一个继承属性。这里的值可以是继承属性里的任何一个 (inherit, initial, unset, or revert)。对于撤销对样式的修改,这是非常方便的一种方式。
如果您开始遇到样式应用不如你意的问题,它可能是专用性问题。
CSS框模型(译者注:也被称为“盒模型”)是网页布局的基础 ——每个元素被表示为一个矩形的方框,框的内容、内边距、边界和外边距,分别对应width 和 height、padding、border、和margin。
注意: 外边距有一个特别的行为被称作外边距塌陷(margin collapsing):当两个框彼此接触时,它们的间距将取两个相邻外边距的最大值,而非两者的总和。
默认情况下,块级元素的content的width 被设置为可用空间的100%(在margin, border, padding占据了它们的空间后剩下的空间的宽度);块级元素的content的height默认设置为内容的高度(没内容就为0)。
外边距可以接受负数,这可以用来引起元素框的重叠。
默认情况下background-color/background-image 延伸到了border的外边缘(对于<body>元素例外)。该行为可以使用background-clip 属性来改变。比如background-clip: padding-box;能使任何背景色只填充内容和内边距的区域,而不填充到边界的区域。
一般情况下,height和border-width都忽略百分比(相对于父元素的height)设置。当元素的父元素有确定的height时(父元素的确定的height不一定非得是直接在自身设置的绝对高度,也可以是从它的父元素继承而来的,只要它的父元素有确定的height就行)或元素是绝对定位元素时(父元素有确定的height的特殊情况),元素的height设置百分比才有效。
盒的总宽度是width, padding-right, padding-left, border-right, 以及 border-left 属性之和(注意没有margin)。在一些情况下比较恼人(例如,假使你想要一个盒占窗口宽度的50%,但边界和内边距是用像素来表示时该怎么办?),为了避免这种问题,可以使用属性box-sizing来调整框模型(或者用calc())。使用值border-box,它将盒模型更改成这个新的模型:
如果选择器是无效的,则整个规则也不会再做任何事情,浏览器只会继续执行下一个规则。
开发者工具中的CSS编辑器:每个CSS属性旁边还有一个复选框,可以选择checked/unchecked来启用/禁用您的CSS属性。这对于找出可能导致错误的原因也非常有用。
我们认为对于一个大型的样式表,首先要通过validator.w3.org来消除任何基本的语法错误,然后再依赖浏览器开发人员工具来确定其他问题。
width和max-width的配合使用:举个栗子,一看就懂:
body {
width: 80%;
max-width: 800px;
}
注:百分比是相对于其父元素,在这里是<html>。
最佳实践:你应该在所有规则的选择器中都用,比如, .card 作为开头,这样的好处是:如果将名片放在带有其他内容的页面的情况下,这些规则不会干扰其他元素的样式。
.card header, footer不等于.card header, .card footer
line-height(行高,它的单位非常神奇):该属性的值通常用无单位的数字,表示这个数字乘当前元素的字体大小(即使当前元素的字体大小是2em,也是乘2em);该属性的值以em为单位的效果和没单位一样。
属性(properties,不同于HTML的属性Attribute):
background:包括background –color、background-image、background-position、background-repeat和background-scroll
border:包括border-top, border-right, border-bottom, border-left和border-width, border-style, border-color, 以及它们的两两组合,如border-top-width
text-shadow
padding(内边距):包括padding-top、padding-right、padding-bottom和padding-left
font:包括font-style, font-variant(变体), font-weight, font-size, line-height, and font-family。
margin(外边距):举个栗子,margin:0 auto,第一个值代表上和下,第二个值代表右和左。如果是3个值,则分表代表上、右和左、下。
单位:
px:像素
em(相对单位):比如,1em表示与当前元素的字体大小相同。Web开发中最常用的相对单位(我觉得rem更好用)。默认值是16px,但是要小心——em单位受会继承父元素的字体大小。
rem(root em):以和em同样的方式工作,但它总是等于默认基础字体大小的尺寸,即继承的字体大小将不起作用。
%:例如,其宽度为其父容器宽度的一定百分比,如果父元素是<body>,那么宽度会随着视口(viewport,即浏览器的窗口大小)的变化而变化。
注:0值不要需要单位。
其它:
nth:n代表数字,th代表第几个,比如4th、5th。
样式化文本:
你可以有一个单位全部都使用 em 的网站,这样维护起来会很简单。
当调整你的文本大小时,将文档(document)的基础font-size 设置为10px往往是个不错的主意,这样之后的计算会变得简单,所需要的 (r)em 值就是想得到的像素的值除以 10,而不是 16。
在样式表的指定区域列出所有font-size的规则集是一个好主意,这样它们就可以很容易被找到。
链接的每一个状态都可以用对应的伪类来应用样式:
Link (没有访问过的): 这是链接的默认状态,可以使用:link 伪类来应用样式。
Visited: 这个链接已经被访问过了(存在于浏览器的历史纪录), 可以使用 :visited 伪类来应用样式。注:只能直接改变color和column-rule-color,不能直接改变background-color和boder等,要想通过:visited改变后两者等,要先在:visited以外的地方先设定后两者的值(比如白色)。如果用focus,则鼠标点到别的地方去,样式就没了。
Focus: 一个链接当它被选中的时候 (比如鼠标左键点它(因为点了就锁定了),或者通过键盘的 Tab 移动到这个链接的时候(用Tab时还会有个虚线框),或者使用编程的方法来选中这个链接(HTMLElement.focus())它可以使用 :focus 伪类来应用样式。
Hover: 当用户的鼠标光标刚好停留在这个链接,可以使用 :hover 伪类来应用样式。
Active: 一个链接当它被激活的时候 (当你点击链接时,按住鼠标按钮,链接会变红色),它可以使用 :active 伪类来应用样式。
链接的规则集的顺序固定,为LoVe F Hate
使用 background-size 来指定要显示的背景图像的大小,这样对有一个大的图标,然后重新调整它的大小是很有帮助的,也是响应式网站设计的需要。但是,这仅适用于IE 9及更高版本。所以你如果需要支持那些老的浏览器,你只能先调整图像大小,再插入它。
链接相关的伪类,比如,悬停 (hover) 的状态,可以为不同的元素应用样式,不只是链接。
例子:Now onto the sizing! We want to fill up the whole width of the <ul>
, leave a little margin between each button (but not a gap at the right hand edge), and we have 5 buttons to accommodate that should all be the same size. To do this, we set the width
to 19.5%, and the margin-right
to 0.625%. You'll notice that all this width adds up to 100.625%, which would make the last button overflow the <ul>
and fall down to the next line. However, we take it back down to 100% using the next rule, which selects only the last <a>
in the list, and removes the margin from it. Done!
您可以使用字体栈来指定可选择的字体,但是为了确保您的设计在每种字体中都可以使用,这增加了测试的开销。
@font-face块:在CSS的开始处,允许您指定在访问随您的网站时随你的网站一起下载的字体文件,这意味着任何支持Web字体的浏览器都可以使用您指定的字体。这个块中需要包括的属性有font- family和src。举个栗子:
@font-face {
font-family: "myFont"; /* 注意有引号,即使没有空格 */
src: url("myFont.ttf"); /* 注意要用url函数 */
}
在这段代码之后代码,你可以使用@font-face中指定的字体名字来将它应用到你喜欢的任何东西上。
注:font-family的名字随你喜欢设置;可在font-family后加个空格再加format函数以声明每种字体文件的格式,这不是必要的,但是声明它是很有用的,因为它让浏览器能更快地找到它能用字的体。可以列出多个声明,用逗号分隔——浏览器会搜索并使用它能找到的第一个——因此,最好是把新的、更好的格式比如WOFF2放在前面,把偏老的,不是那么好的格式像TTF这样的放在后面。
在线字体服务(如Google Fonts)通常会为你存储和提供字体,这样你就不用写@font-face代码了,通常只需要在你的网站上插入一两行代码(用link)就可以让一切都运行。
属性:
color: The color
property sets the color of the foreground content of the selected elements (which is usually the text, but can also include a couple of other things, such as an underline or overline placed on text).
font-famliy:字体。能不能生效看的是正在用来看网页的电脑上有没有相应的字体。字体栈:浏览器从字体栈列表的第一个字体开始,查看在当前机器中,这个字体是否可用。如果可用,就把这个字体应用到选中的元素中;如果不可用,它就移到列表中的下一个字体,然后再检查。注意: 有一些字体名称不止一个单词,比如Trebuchet MS ,那么就需要用引号包裹。
font-style: 用来打开和关闭文本 italic (斜体)。(你很少会用到这个属性,除非你因为一些理由想关闭斜体文字的斜体状态),可能的值有normal、italic和oblique(斜的)。
font-size:在调整字体大小时,最常用的单位是px、em和rem。
font-weight:设置文本的粗体。常用的值有normal和bold。
text-transform:能实现的功能有将所有文本转为大写(uppercase)、将所有文本转为小写(lowercase)、让所有单词的首字母大写(capitalize)、将所有字形转换成固定宽度的正方形(full-width)
text-decoration:能实现的功能有取消已经存在的任何文本装饰(none)、下划线(underline)、穿过文本的线(line-through)。text-decoration是一个缩写形式,它由 text-decoration-line, text-decoration-style 和 text-decoration-color 构成。
text-shadow:至少有前2个值,最多4个值,空格隔开,依次是阴影水平偏移、阴影垂直偏移、模糊半径(默认为0)、颜色(默认为black)。注:偏移的数值可正可负。
text-align:align意思是排列。可用的值有left(左对齐)、right、center和justify(改变单词之间的距离,使所有文本行的宽度相同且达到最大。你需要仔细使用,它可以看起来很可怕如果你要使用这个,你也应该考虑一起使用别的东西,比如 hyphens(连字符)属性)。
line-height:推荐的行高是1.5到2。
letter-spacing 和 word-spacing:字母和字间距。你不会经常使用它们。
text-indent:首行缩进。
以下三个属性可以在CSS(因为是样式,所以不是在HTML里用)的<ul> 或 <ol> 元素上设置:
list-style-type:设置列表的项目符号的类型。值为none则不显示自带的项目符号,然后就可以用background 属性来代替项目符号。
list-style-position :设置在每个项目开始之前,项目符号是出现在列表项内,还是出现在其外。简单的说,就是一个列表项内换行后是否和项目符号左对齐。
list-style-image :为项目符号使用自定义图片,其语法相当简单。然而,这个属性在控制项目符号的位置,大小等方面是有限的。 您最好使用background 系列属性。background-position设置为0 0则意味着项目符号将出现在每个列表项的最左上侧。background-repeat:默认条件下,背景图片不断复制直到填满整个背景空间,设为no-repeat就不会复制了。
以下两个属性可在HTML(因为不是样式,所以不是在CSS里用)的<ol>上用:
start:从1 以外的数字开始计数。示例:<ol start="4">。
reverse:倒计数(辣鸡Edge不支持——2018年6月3日)。
value:可用于HTML的<li>,用于指定数值。即使你使用非阿拉伯数字的 list-style-type, 你仍需要使用与其同等意义的数值作为 value 的属性。
outline:轮廓。有点像边框,唯一的区别是边框占用了盒模型的空间,而轮廓没有。举个栗子,选中链接时链接周围的框框。
border-bottom:也能用作下划线,但比起text-decoration,有一些人喜欢前者,因为前者比后者有更好的样式选项, 并且绘制的位置会稍微低一点,所以不会穿过字母 (比如 字母 g 和 y 底部)——似乎不关我事,因为,我主要是写中文网页——另外,如果border-bottom不设置颜色,就可以使下划线采用和元素文本一样的颜色,这对链接是很有用的,因为链接的每种状态下,文本的颜色是不同的(text-decoration不也是这样吗- -?)。
样式化盒子(box):
叫盒子更好听,但叫框更贴切。
对于块级元素:如果盒子的height被设置为百分比,那么盒子的height不会遵循这个设置了的百分比长度(除非盒子的父元素的height是确定的),而是总会采用盒子内容的高度(除非给它设置了一个非百分比高度(例如,px或者em))。总结:除非绝对定位或者父元素有确定的height,否则height设置百分比跟没设置一样。
对于内联元素:除非绝对定位,否则width、height、上下内边距、上下外边距无效,上下边界也不会推开别的元素或移动自己。
边界(border)的width也会忽略百分比设置。
当用绝对的值设置盒子的大小时(比如,固定px的 width 和 height),内容可能会超出设置的大小,此时内容就会溢出盒子。要控制这时候发生的事情,我们可以使用 overflow 属性。该属性有好几个可能的取值,不过最常用的是:
auto:超出盒子大小的内容被隐藏,而滚动条显示出来,从而可以让用户滚动滚动条来看到所有内容;
hidden:超出盒子大小的内容被隐藏;
visible:超出盒子大小的内容显示在盒子之外(这通常是默认的行为)。
元素的背景由颜色和图像组成(即background-color和background-image)。背景并不在外边距的下层——外边距不是元素区域的一部分,而是元素外面的区域。
outline位于外边距的区域。如果您要使用 outline 属性,请确保不要让它看起来像是被focus的链接,因为这会让用户混淆。
有一些属性可以灵活地控制盒的内容的大小 — 是通过设置大小约束,而不是设置一个绝对大小。这是通过属性 min-width、max-width、min-height 和 max-height 实现的。
margin: 0 auto;可以将应用这段代码的容器在它的父容器内居中。auto(在这种情况下)让左右外边距共享父容器左右外边距之间的可用空间使它居中。
display 可以有很多种不同的值, 其中三种常见的值为 block, inline, 和 inline-block(另外还有flex和grid):
块盒(block box):独自占一行;可以给它设置宽度和高度(设置百分比高度是有条件的)。
行内盒(inline box):与块盒相反,它会与周围的文本和其它行内元素出现在同一行,除非位置不够了。width、height、上下内边距、上下外边距设置对行内盒无效;上下边界也不会推开别的元素或移动自己。
行内块盒(inline-block box):介于前两者之间,它会像行内盒一样,跟随周围的文本流堆放,不会在其前后创建换行;不过,它可以像块盒一样,使用width和height设置大小,并且维护其块完整性。
background-attachment: 当内容滚动时,指定元素背景的行为,例如,它是固定还是滚动。fixed(固定)和local(滚动:将背景设置为它所设置的元素的背景,因此当您滚动元素时,背景会随之滚动)这两个属性值比较好用。
大多数元素的默认背景颜色不是white (白色)而是transparent(透明)。
设置背景颜色作为后备是很重要的。背景颜色在各处都得到了支持,而背景梯度等奇异的特性只在较新的浏览器中得到支持,加上背景图像可能由于某种原因无法加载,因此,设置基本的背景颜色是一个好主意,这样的话,无论如何,元素的内容都是可读的(没有背景也可读就无所谓设不设置背景颜色作为后备了)。
需要记住的一件重要的事情是,由于背景图像是使用CSS设置的,并且出现在内容的背景中,它们将会在屏幕阅读器之类的辅助技术中不可见。它们不是内容图片,只是为了装饰,如果你想在你的页面上包含一个图片,而这又是内容的一部分,那么你应该在HTML中用<img>元素来做。
background-repeat 允许您指定背景图像是如何重复的。默认值是repeat,其他常见的和广泛支持的值是:no-repeat,repeat-x和repeat-y。
属性值什么时候用空格分隔、什么时候用逗号分隔见下(函数的参数当然还是用逗号分隔,和C++一样filter属性的函数比如drop-shadow的参数竟然是用空格分隔的!):
background: url(image.png) no-repeat 99% center,
url(background-tile.png),
linear-gradient(to bottom, yellow, #dddd00 50%, orange);
background-position:最常用的单位有px、rem、百分比和关键词(left、center等)。我看百分比的值挺好用的。如果您只指定一个值,那么该值将被假定为水平值,而垂直值将默认为center。
background-image还有另一组可用的值——颜色渐变,其中,线性渐变是通过linear-gradient()函数传入的,它是一个background-image属性的值。函数至少需要用逗号分隔的三个参数——背景中渐变的方向,开始的颜色和结束的颜色。可选的参数是颜色站点。注意,您还可以使用repeating-linear-gradient()函数来设置一个重复的线性渐变(栗子:repeating-linear-gradient(to right, yellow, orange 25px, yellow 50px);)。“去左上角”是to top left。
默认情况下,边界是不可见的。当只设置border-style属性(如设为solid)时,边界会默认使用文本的颜色,且宽度为3px。
border-radius:圆角。甚至可以创建椭圆形角,比如border-radius: 10px 20px 30px 40px / 40px 30px 20px 10px;。可以指定1到4个值来指定4个圆角的半径,还可以使用普通写法属性,单独设置边界的一个角的边界半径,如border-top-left-radius。圆角以百分比为单位很有意思。
border-image使实现复杂的图像边界变得容易得多,但是必须在现代浏览器中才能实现(Internet Explorer 11+支持它,以及其他现代浏览器)。注意:只要你用了border-image,您就应该也包括border定义——因为如果浏览器不支持border-image,则该操作可以作为一个回退。使用 border-image-source指定要使用的源图像作为边界图像,它的工作原理和background-image一样
样式化表格:
在你的表上,给table-layout属性设置一个为fixed的值通常是一个好主意,因为它使表的行为在默认情况下更可预测。通常情况下,表列的大小会根据所包含的内容大小而变化(即使设置了width),这会产生一些奇怪的结果。通过 table-layout: fixed,您可以通过控制<th>的宽度来控制列的宽度。Table and column widths are set by the widths of table and col elements or by the width of the first row of cells. Cells in subsequent rows do not affect column widths.
th:nth-child(2):选择<th>的父元素的第2个子元素且该子元素必须是<th>,否则无效。而th:nth-of-type(2):在<th>的父元素中的所有兄弟<th>里选第2个。()里不止可以填数字还可以填odd或2n+1、even或2n。另外,还有first-child这更简明的方式(但没有second-child之类的)。
border-collapse属性的collapse值对于任何表样式来说都是一个标准的最佳实践,能把 变成。
有多个嵌套的元素是很有用的,这样您就可以将样式层叠在一起。是的,我们确实可以在同一个元素上,比如<thead>,同时使用背景图像和背景线性渐变,但是我们还是决定分开到两个有嵌套关系的元素中使用,因为考虑到不支持多个背景图像和线性梯度的老浏览器”。
表格样式小贴士:
l 使您的表格标记尽可能简单,并且保持灵活性,例如使用百分比,这样设计就更有响应性。
l 使用 table-layout: fixed 创建更可预测的表布局,可以通过在<th>中设置width来轻松设置列的宽度。
l 使用 border-collapse: collapse 使表元素边框合并,生成一个更整洁、更易于控制的外观。
l 使用<thead>, <tbody>和<tfoot> 将表格分割成逻辑块,并提供额外的应用CSS的地方,因此如果需要,可以更容易地将样式层叠在一起。
l 使用“斑马线”表格来提高可读性。
l 使用 text-align直线对齐您的<th>和<td>文本,使内容更整洁、更易于跟随。
在我们的样式化文本模块,我们学习了text-shadow属性,它允许您将一个或多个阴影应用到元素的文本上。对于盒子来说,存在一个等价的属性——box-shadow允许您将一个或多个阴影应用到一个元素的盒子上。和文本阴影一样,盒子阴影在各种浏览器中也得到了很好的支持,但只有在IE9+(IE9及更新版本)中可用。你的旧IE版本的用户可能只需要应付没有阴影的情况,所以只要测试一下你的设计,确保你的内容在没有阴影的情况下是清晰可见的。box-shadow还可创建一个带有多个颜色图层的凸起的盒子,而且你可以用任何你想要的方式来使用它,例如,用基于多个光源的阴影来创建一个更加真实的外观。与text-shadow不同的地方是,box-shadow有一个inset关键字可用——把它放在一个影子的属性值的开始,使它变成一个内部阴影,而不是一个外部阴影,比如,通过:active将盒阴影换成一个非常暗的inset盒阴影,给人一种按钮被按下的样子。
-webkit-:不建议使用。
多个背景:最近(自从Internet Explorer 9),我们已经具备了将多个背景连接到单个元素的能力。这是一件好事,因为多重背景非常有用。用逗号分隔不同的背景定义,这些背景都是堆叠在一起的,第一个出现在顶部,第二个在第一个的下面,第三个……所以要注意堆叠顺序。
background:和background-color/img……:效果不一样!前者会把之前的所有background覆盖掉,但是后者不会,后者是层叠。
基本上,filters可以应用在任何元素上,块元素(block)或者行内元素(inline)——你只需要使用filter属性,并且给它一个特定的过滤函数以及函数的参数。有些filter选项和其他CSS特性做的事情十分相似,例如drop-shadow()的工作方式以及产生的效果和 box-shadow 或text-shadow十分相似。然而filter:drop-shadow()真正出色的地方在于,它作用于盒(box)内内容(content)的确切形状,而不仅仅将盒子本身作为一个大的块,这看起来会更棒,就像下面这图:
记住,你可以这样为较旧的浏览器创建一个后备方案:先写一个较旧的浏览器支持的后备声明,然后再接着写只有较新的浏览器才支持的声明。这样比较旧的浏览器会应用第一个声明而忽略掉第二个不支持的声明,与此同时比较新的浏览器会先应用第一个声明,然后用第二个声明把它覆盖掉。
被box-shadow用于生成阴影的东西是border(border的宽是0px都行)。
有些时候,CSS代码不生效是因为该用空格分隔的属性值或参数用了逗号分隔,或者反过来。
例子:多个盒阴影:一个标准的盒阴影,使它看起来稍微从页面上浮起来;另外两个是内嵌(inset)的盒阴影,一个是左上角(不加inset的两个正值表示外部的往下和往右,加了inset的两个正值就表示内部的往下和往右,即左上角的内部阴影)附近的白色半透明阴影(inset 5px 5px 3px rgba(255, 255, 255, 0.5))和另一个是右下角附近的黑色半透明阴影(inset -5px -5px 3px rgba(0, 0, 0, 0.5)),让盒子有一个漂亮的3D外观。
CSS排版概述:
HTML元素完全按照源码中出现的先后次序显示,但布局技术会覆盖默认的布局行为。
浮动——应用 float属性的值,诸如 left 能够让块级元素互相并排成一行,而不是一个“堆叠”在另一个上面。
float 属性有四个可能的值:
left — 将元素浮动到左侧;
right — 将元素浮动到右侧;
none — 默认值, 不浮动;
inherit — 继承父元素的浮动属性。
有四种主要的定位类型需要我们了解:
静态定位(Static positioning)是每个元素默认的属性——它表示“将元素放在文档布局流的默认位置——没有什么特殊的地方”。
相对定位(Relative positioning)允许我们相对元素在正常的文档流中的位置移动它——包括将两个元素叠放在页面上。这对于微调和精准设计(design pinpointing)非常有用。relative值——这属性本身不做任何事情,所以我们还要添加top和left属性。这些可以将受影响的元素向下或向右移。
绝对定位(Absolute positioning)将元素完全从页面的正常布局流中移出(所以绝对定位会使其它元素的位置发生变化),类似将它单独放在一个图层中. 我们可以将元素相对于页面的 <html> 元素边缘固定,或者相对于离元素最近的被定位的父元素(ancestor element)(相对定位或绝对定位的父元素都行)。绝对定位在创建复杂布局效果时非常有用,例如通过标签(tabbed boxes)显示和隐藏的内容面板(选项卡消息框)或者通过按钮控制滑动到屏幕中的信息面板(通过按图标使面板滑动出现或者消失)。top和left属性对绝对位置元素的影响不同于相对位置元素。在这种情况下,他们没有指定元素相对于原始位置的移动程度。相反,它们指定元素应该离页面边界的顶部和左边的距离(确切地说,是离 <html>元素的距离)。
固定定位(Fixed positioning)与绝对定位非常类似,除了它是将一个元素相对浏览器视口(viewport)固定,而不是相对另外一个元素。 在创建类似页面滚动总是处于页面上方的导航菜单时非常有用。
HTML表格对于显示表格数据是很好的,但是很多年前——在浏览器中支持基本的CSS之前——web开发人员过去也常常使用HTML表格来完成整个网页布局——将它们的页眉、页脚、不同的列等等放在不同的表行和列中。这在当时是有效的,但它有很多问题——表布局是不灵活的,非常重的标记,难以调试和语义上的错误(比如,屏幕阅读器用户在导航表布局方面有问题)。CSS表格的存在是为了让您能够像表格一样布局元素,而没有上面描述的任何问题。
CSS是一种功能强大的语言,它可以做很多事情,但它却在布局上有所下降。传统的布局方法,如float和positioning,有时会希望有更复杂、更灵活、更有弹性的方法。flexbox应运而生。
display: flex; 告诉,比如<section>元素,的子元素作为flexible boxes——默认情况下,它们都将展开以填充父类的可用高度,它们至少会留有足以包裹它们的内容的宽度(有余就平分剩余宽度使填充父类的可用宽度。
floats:
虽然有更新的更好的布局技术可用——但浮动仍然是人们的旧爱,因为它可以支持到 Internet Explorer 4。
最初,引入 float 属性是为了能让 web 开发人员实现简单的布局,包括在一列文本中浮动的图像,文字环绕在它的左边或右边。
让我们考虑一下浮动是如何工作的——浮动元素 (这个例子中是<img> 元素)会脱离正常的文档布局流,并吸附到其父容器的,比如,左边 (这个例子中是<body>元素)。在正常布局中位于该浮动元素之下的内容,此时会围绕着浮动元素,填满其右侧的空间。
浮动通常用于创建多个列布局,尽管事实上,它不是真的打算做这个工作,并有一些奇怪的副作用必须处理。
两列布局:需要注意的一件事是,当浏览器宽度变得非常窄时,列就会变得很糟糕。窄屏幕的情况下(如手机),切换回单列布局通常是有意义的,使用媒体查询(media queries)可以实现这一功能。你们将在未来的响应式网页设计模块中学习这些知识。
所有在浮动下面的自身不浮动的内容都将围绕浮动元素进行wrap(与浮动不同),如果没有处理这些元素,就会变得很糟糕。幸运的是,有一种简单的方法可以解决这个问题—— clear 属性。当你把这个属性应用到一个元素上时,它主要意味着"此处停止浮动"——这个元素和源码中后面的元素将不浮动,除非您稍后将一个新的float声明应用到此后的另一个元素。clear 可以取三个值:left:停止左浮动;right:停止右浮动;both:停止左右浮动。
浮动元素在父元素中所占的区域的有效高度为0 ——如果你在浏览器中加载 1_three-column-layout.html 并用开发工具查看 <body> 的高度,你将会看到我们的意思是什么——所报告的<body>的高度只有 <h1> 的高度,而没有包括浮动元素的高度。这个可以通过很多方式解决,其中一种是clearing the float at the bottom of the parent container。
非浮动元素的外边距不能用于它们和浮动元素之间创建空间(好好理解),但浮动元素的外边距可以用于它们和非浮动元素之间创建控件;在正常布局中位于浮动元素之下的元素可以用外边距“穿过”浮动元素来创建空间,但如果清除了浮动,就不行了。如果您需要一个元素来间接清除您的浮动,在您想要清除的浮动之前添加一个看不见的“clearfix div”是非常有用的。
有一个问题是列高度是不同的—— 如果列都是相同的高度,它看起来会更好。我们可以通过给所有的列固定height 来解决这个问题,然而在许多情况下这并不理想——它使设计呆板。如果你能保证列中总是有相同数量的内容,这是可以的,但这并不总是如此——在很多类型的网站上,内容也会定期更改,而且浏览器窗口的变小也可能会使内容溢出。这正是像flexbox这样的新布局技术所解决的问题。Flexbox可以自动地延长列,这样他们就会像最长的一列一样。你也可以考虑:
l 将这些列的背景颜色设置为父元素的背景颜色,这样您就看不到高度是不同的。这是目前最好的选择。
l 将它们设置为固定的高度,并用overflow使内容滚动。
l 使用一种叫做伪列(faux columns)的技术——这包括将背景(和边界)从实际的列中提取出来,并在列的父元素上画一个伪造的背景,看起来像列的背景一样。不幸的是,这将无法处理列边界。
positioning:
默认情况下,块级元素的内容的width+padding+border是其父元素的内容的width的100%,并且总高与自己的的内容的height一样。Inline elements are all tall as their content, and as wide as their content(their是指内联元素自己).You can't set width or height on inline elements — they just sit inside the content of block level elements.
默认情况下,块级元素在视口中垂直布局——每个都将显示在上一个元素下面的新行上,并且它们的外边距将分隔开它们。
相对定位与静态定位非常相似,占据在正常的文档流中,除了你仍然可以修改它的最终位置。
绝对定位的元素不再存在于正常文档布局流中。相反,它坐在它自己的层独立于一切。这是非常有用的——这意味着我们可以创建不干扰页面上其他元素的位置的隔离的UI功能 ——例如弹出信息框和控制菜单,翻转面板,可以在页面上的任何地方拖放的UI功能等。
哪个元素是绝对定位元素的“包含元素”? 默认情况下,它是<html>元素。“包含元素”准确的名字是定位上下文。
我们可以改变定位上下文, 这是通过在元素的其他祖先之一上设置定位(即设置position: relative;或position: absolute;或position: fixed;)来实现的——它是嵌套在其中的元素之一。
默认情况下,被定位的元素都具有z-index,为auto,实际上为0。z-index只接受无单位索引值。静态定位的元素的z-index改不了,想改就先把该元素设置为别的定位。
可靠的居中老技巧 margin: 0 auto;。注:第一个值也可以不是0。
实际的定位例子:
我们研究的第一个例子是一个经典的选项卡消息框,你想用一块小区域包括大量信息时,一个非常常用的特征。这包括含有大信息量的应用,比如策略战争游戏,比如移动版的网页(屏幕狭小、空间有限),比如你可能想要放置许多信息的紧凑消息框,不用就会充满整个UI。
在早先的课程中我们建议尽可能不固定内容容器的高度。这个情况下是可以的,因为我们是在选项卡中固定的内容,如果每个标签都有不同的高度,看起来也有些不和谐。
We are using descendant selectors with .info-box at the start of the chain throughout this example — this is so that we can insert this feature into a page with other content already on it, without fear of interfering with the styles applied to other parts of the page.
.info-box ul li a.active:意思是类名为info-box的元素中的<ul>元素中的<li>元素中的<a>元素,且<a>元素的类名为active。
在我们的第二个例子中,我们将会采用我们的第一个例子——我们的信息盒子——把它加到一个满的网页之中去。但是不仅仅是这样——我们将固定它的位置,以便于它能待在浏览器窗口的同一个位置。当主要内容滚动时,这个信息盒子将会待在屏幕的同一个位置。
最后一个我们在这里介绍的例子是通过按图标使面板滑动出现或者消失——就像前面提到的,这种场景在移动端的布局中很流行,因为移动端的屏幕很小,所以你不希望使用大部分屏幕显示信息面板或者菜单。
有名的checkbox hack 技术,可以通过切换按钮来提供一个无JS的方法来控制一个元素。记住,点击<label>标签也会选择相对应的checkbox!我们已经告诉你这是一种hack了。
cursor: pointer;能把移到label上的鼠标光标变成“手”,可,作为一个额外的可视化线索告诉用户这个label可以做一些有趣的事情。
以下代码通过把复选框移到屏幕外来隐藏复选框。
input[type="checkbox"] {
position: absolute;
top: -100px;
}
:checked伪类:表示被选中。
transition(过渡)属性,允许你在状态改变的时候平滑地过渡,而不是粗暴地“变”或“还原”。
这个例子是一个相当巧妙地避免使用JavaScript来创建一个切换按钮效果的方式。但这种效果确实有一些问题 ——有点滥用表单元素(它们不是为了这个目的),并且在可访问性方面效果不是很好 —— 标签在默认情况下不可被focus,并且表单元素的非语义使用可能会导致屏幕朗读器出现问题。 JavaScript和链接或按钮可能更合适,但这样的实验仍然很有趣。
flexbox:
我们需要把要设置为flexible boxes的元素(即(flex item))的父元素(即flex container)的display 设置为flex。注意:假如你想设置行内元素为 flexible box,也可以置 display 属性的值为 inline-flex。
section {
display: flex;
}
单单上面这个规则就可以生成具有相同宽度和高度的列(这些列本来是成行布局的)。
弹性盒子提供了 flex-direction 这样一个属性,它可以指定主轴的方向(flex item放置的方向)— 它默认值是 row(即多个列)。还可以使用 row-reverse 和 column-reverse 值反向排列 flex 项目。
当flex item超出了flex container, 解决此问题的一种方法是将以下声明添加到 flex container的规则中:flex-wrap: wrap;。
flex-direction 和 flex-wrap的缩写是flex-flow。
flex(决定如何分配剩余空间): 1; 在每个flex item的标签上设置,表示每个flex item占用空间都是相等的。因为它是一个比例,这意味着将每个 flex 项的设置为 400000 的效果和 1 的时候是完全一样的。设置为0则意味着不参与分配剩余的可用空间。
flex: 1 200px; 表示这个flex item将首先给出200px的可用空间,然后,剩余的可用空间再根据分配的比例共享。
弹性盒子的真正价值可以体现在它的灵活性/响应性,如果你调整浏览器窗口的大小,或者增加一个flex item,这时的布局仍旧是好的。
flex 是一个可以指定最多三个不同值的缩写属性。我们建议不要使用flex的全写属性,除非你真的需要(比如要去覆盖之前写的缩写属性中的一个属性)。使用全写会多写很多的代码,它们也可能有点让人困惑。
justify-content(写在flex container里)控制 flex 项在主轴上的位置。默认值是 flex-start,这会使所有 flex 项都位于主轴的开始处。你也可以用 flex-end 来让 flex 项到结尾处。center也是可用的,可以让 flex 项在主轴居中。而space-around 是很有用的——它会使所有 flex 项沿着主轴均匀地分布,而且在两端都会留有一点空间。还有一个值是 space-between,它和 space-around 非常相似,只是它不会在两端留下任何空间。
align-items(写在flex container里)控制 flex 项在交叉轴上的位置。默认的值是 stretch,其会使所有 flex 项沿着交叉轴的方向拉伸以填充父容器。如果父容器在交叉轴方向上没有固定的高度,则所有 flex 项将变得与最长的 flex 项一样长(即高度保持一致)。使用center 值会使flex 项保持其原有的高度,而且会在交叉轴居中。你也可以设置诸如 flex-start 或 flex-end 这样使 flex 项在交叉轴的开始或结束处对齐所有的值。
你可以用 align-self (flex item元素中用)覆盖 align-items(flex container元素中用)的行为。
弹性盒子有可以改变 flex 项的布局位置的功能,order,而不会影响到源顺序(即 dom 树里元素的顺序)。这也是传统布局方式很难做到的一点。
所有 flex 项默认的 order 值是 0。order 值大的 flex 项比 order 值小的在显示顺序中更靠后。相同 order 值的 flex 项按源顺序显示(设置负值也是可以的)。
flex 嵌套:弹性盒子也能创建一些颇为复杂的布局。设置 flex 项为 flex 容器也是没有什么问题的,它的孩子也就表现为 flexible box 了。
Grids:
任何有设计背景的人似乎都感到惊讶,CSS没有内置的网格系统,而我们似乎使用各种次优方法来创建网格状的设计。正如你将在本文的最后一部分中发现的那样,这将被改变,但是你可能需要知道在未来一段时间内创建网格的现有方法。
目前大多数网格类型布局是使用浮动创建的。使用浮动来创建一个多列布局——这是任何使用网格系统的本质方法。
12列网格 —— 一种很常见的选择,因为12可以被6、4、3和2整除,被认为非常适应不同的情况。
你可以使用calc()函数在你的CSS里面做数学 — 这允许你插入简单的数学方程到你的CSS值。
偏移容器(offset containers):比如下面这个,有点巧妙(这样,想偏移的时候加个class名就好了)。
.offset-by-one {
margin-left: 10.41666666%;
}
用浮动创建的网格的最大限制是它基本上是一维的。我们处理的是列元素,只能跨越多个列,而不能跨越行。这些旧的布局方法非常难以控制元素的高度。而没有明确设置高度,这是一个非常不灵活的方法 - 它只有当你能保证你的内容将是一定的高度才有效。
Flexbox是一维设计。它处理单个维度,即行或列。不能为列和行创建严格的网格,这意味着如果我们要为网格使用flexbox,我们仍然需要为浮动布局计算百分比。
在您的项目中,您可能仍然选择使用flexbox'grid',因为flexbox提供的额外对齐和空间分布能力超过浮动。但是,您应该知道,您这样使用flexbox的方式不是它的设计目的。
第三方网格系统:所有的Skeleton(或任何其他网格框架)在CSS中设置了预定义的类,您可以通过将它们添加到您的标记来使用。这和你自己计算这些百分比的工作完全一样。当使用Skeleton时,我们需要写很少的CSS。它为我们处理所有的浮动,当我们添加类到我们的标记。正是这种将布局的责任转移给其他东西的能力使网格系统的框架成为一个引人注目的选择!Skeleton是比你可能遇到的一些比框架更简单的网格系统框架。大型框架(如Bootstrap和Foundation)中的网格为各种屏幕宽度提供了更多的功能和额外的断点。但是,它们都以类似的方式工作 - 通过向您的标记添加特定类,您可以使用预定义的网格控制元素的布局。
Native CSS Grids with Grid Layout:即CSS内置的网格系统,正在逐渐被浏览器支持。使用CSS网格布局,您可以完全在CSS中指定网格,而不需要像第三方网格和手工构建的网格一样,在HTML中添加<div>来形成行和确定在这些行中的列数。
CSS网格属性:用display: grid;声明为网格,然后用grid-template-columns: repeat(12, 1fr);(也可以不用repeat而直接写12个1fr)创建12列的网格,每列的单位是1fr(它描述在网格容器的一小部分可用控件),然后grid-gap: 20px;(顾名思义)。要对跨越网格上的多个列轨道的容器进行样式化,我们可以使用该grid-column属性,如grid-column: auto / span 6;,正斜杠之前的值是开始列——在这种情况下,我们没有明确设置,则让浏览器放在下一个可用的列;正斜杠之后的span 6意思是跨越6列,也可以只用数字,那么意思就是跨越到数字代表的那一列。另外,还有grid-row。grid-column:和grid-row:后都可只跟1个数字表示那一列或那一行。
CSS网格是二维的,因此随着布局的增长和缩小,元素保持水平和垂直排列。
另外:
CSS transform 属性允许你修改CSS视觉格式模型的坐标空间。使用它,元素可以被移动(translate)、旋转(rotate)、缩放(scale)、倾斜(skew)。
vertical-align(可用于垂直居中;用在子元素上,这点与text-align不同):specifies the vertical alignment of an inline or table-cell box.
垂直居中还可以用绝对定位和calc()实现(即使缩放窗口仍居中)。