(5)《Head First HTML与CSS》学习笔记---布局与定位

层叠与CSS的权重判断

1.要理解层叠,除了前面的内容外还差最后一个知识点。你已经知道如何使用多个样式表来更好地组织你的样式,或者支持不同类型的设备。不过实际上用户访问你的页面时还有另外一些样式表。

 

2.我们来复习一下。

浏览器确定要对一个元素应用哪个样式时,优先级是

作者样式   >    读者样式(个别浏览器允许读者自己设置样式;如果读者在一个属性声明最后加上!important就能覆盖作者样式)   >   浏览器默认样式

实际上,这就是在问“层叠”的作用,只是问法不同。

给定一组样式表中的一组样式,浏览器就是以层叠方式来确定具体使用哪一个样式。

后面会让你弄清楚为什么没有像你预期的那样应用某些样式,不仅如此,你会比99%的web页面开发人员都更懂层叠(不是开玩笑)。--本书出版于2013年。

 

3.要想确定层叠的结果是什么,有两步:

第一步:

    收集所有样式表:包括页面作者样式表、读者增加的样式表、浏览器的默认样式表

     ------>

    找到所有匹配的声明:比如我们向判断的是h1元素的font-size,就要查看所有可能选择h1元素的选择器的font-size声明    

     ------>

     对所有匹配的规则排序:按作者>读者>浏览器默认进行排序

第二步:

     按特定性对所有声明排序,方法是:

 

还有一些例子,忘了可以看书的P461

 

最后总结:

先按作者、读者、浏览器对所有规则排序(包括指向多个样式表的情况)——————在各个类别中再按特定性排序——————对于特定性一样的元素,根据样式表中的顺序再次进行排序,最后出现的就是最终的胜利者————如果还是没有最终胜利者(比如没有设定过),那么就要使用继承了,看是否继承了父辈元素的属性————如果这个属性不能继承或者父辈元素里也没有,那么就看浏览器设置的默认值了(所有浏览器都应该对每个元素设置了默认值,所以可以认为是不可能进行到这一步的)

 

 

布局与定位

1.一个小小的属性float可以给页面带来巨大的变化!我们能用这个属性对页面做更有意思的处理!

不过,我们首先要了解浏览器在页面上如何摆放元素,了解这些后才能开始讨论可以用什么方法改变页面的布局以及如何在页面上定位元素。

 

2.首先要了解什么是“流(Flow)”

块元素从上往下流;

内联元素,从左往右流,直到没有更多空间为止。在这里注意,内联元素中有一种特殊情况,即文本,text并不是一个元素,而是一个文本!这一部分的内容,必须看书,书里说的已经很详细了,没有任何我认为可以省略不记的部分,所以就不在这记录了,主要看P475~477。

 

3.看P478的问题;看P574.

 

4.浮动元素,看P479~480

在这我要强调一个现象——浏览器窗口大小变化,会影响围绕在浮动元周围的显示效果!如下图:

 上图由于图片的问题,看起来可能是浮动的饮料栏宽度随着浏览器的大小而变化了,实际上并不是这样的!宽度并没有变!比如我们可能会这样想:

 

问:将来我们是不是可以把主内容浮动到左边,而不是把边栏浮动到右边,这样不行么?因为主内容已经在最上面,这样我们就不用到处移动HTML,也能得到同样的效果。

答:表面看来不错,但不推荐这样做。

按照你的想法,我们只需要对主内容的div设置一个宽度,然后浮动到左边,也可以得到两栏的效果——但是两种方式的效果是不一样的!你要注意,width设置的宽度定死了,不会随着浏览器的大小而改变了!而设置width是浮动的基础,如果你对主内容设置宽度,当页面的其余部分随着浏览器宽度变化而调整大小时,主内容区的宽度却是一直保持固定的(当然,如果你本来就要照成这样的效果,那么这样做也是可以的!换句话说,你希望哪个内容区会随着浏览器大小改变,那么就不要让它浮动!)。

 

5.

注意,P492页的主内容区外边距为什么要设置为330?或者说为什么要与边栏宽度相同?

我们来仔细观察一下这两张布局信息图

你会发现一个之前提过但是很容易忘记的知识点:边栏是真的浮在其它元素上的!你可以明显看到,id为main(后面简称min)的内容区把边栏整个包括进去了!虽然因为文本围绕的原因让你以为两者是分开的,但是实际上边栏这时候整个都处于min的内容区里!(说“整个”不对,这里是为了强调....实际上你注意看颜色,你会发现边栏的右外边距和右内边距与主内容区的右外边距、内边距是重合的,上内外边距也有一部分重合!仔细想一想,这里面究竟为什么是这样?反正我是看懂了,这玩意就像是两张纸叠着放一样,一张纸是主内容,另一张纸是边栏,这些纸都有各自的内外边距,只不过现在是两张角对角地对齐放在body这个纸上!)

这意味着,我们可以通过min的右外边距等于边栏的总宽度,然后再靠min早就有的右内边距让两个栏实现真正的分离!注意,正常来说要分离就直接让右外边距大于边栏总宽度一点,就能让两栏之间有空隙。但是我们这里只需要一样,因为我们的主内容已经设了一点右内边距,靠这个右内边距也可以使空隙出现了。

我们来看看,给min的右外边距加上和边栏同宽的宽度后是什么样子:

 

从这里我还发现一个细节:实际上页面大小是一定的,你加了外边距,就意味着内边距或者内容区要变小!形象地说就是无论你怎么在一张固定大小的纸上划分内容、外边距、内边距、边框大小,这张纸就那么大,必然是“顾此失彼”的!

还有就是,千万千万不要把这种浮动和“两个图像并排所以之间的间隔等于两个图的外边距之和”联系起来!

搞清楚了!这是浮动,是不同维度上的“流”了!形象地比喻就是,浮动就像另一个维度上的东西,不会影响内容区大小、外边距内边距边框大小,真正影响的只有“效果”,比如内联元素(em、p之类)、文本。文本会围绕浮动元素,虽然实际上文本可以写在浮动元素的里面(那样就被浮动的元素挡住了!)。就好像一张纸叠在另一张纸上,你总不能把字写到被纸挡住的那部分上吧。

可以简单的说:只要你设定了某个具体的外边距、内边距、内容区大小等的值,就意味着浏览器大小改变时这些值不再是auto,不再是自动随着浏览器而改变了!能随着浏览器大小变化的只能是你没设值的那些东西。所以能不设值就尽量别设值,想一想,一旦你把一大堆非必要的值都设了,或者说固定死了,当浏览器开始改变大小时就完蛋咯!基于这一段的讨论,你就能体会“为什么要那么麻烦地非得设外边距,为什么不是设主内容宽度?”这种做法的缺点!明白为什么不这样做。

让我来解释“为什么要那么麻烦地非得设外边距,为什么不是设主内容宽度?”

当我只设置了外边距、内边距,没设置内容区宽度时,浏览器变小时,就相当于把整个布局的最大宽度变小了,这时候我设置的值就相当于强制规定不管这个最大宽度有多少,都必须让外边距、内边距保持这个值的大小——这也就意味着边栏与主内容区之间始终存在那个距离,代价就是内容区宽度变小(之前解释过,详见前几段的划线句子:从这里我还发现一个细节...)。而这正是我们希望的;如果你是设定内容区宽度,没设定外边距内边距,那么页面缩小的代价就只能是缩小内外边距的宽度直到这两都为0,这时候就无法区分边栏与主内容区了。

以上分析的一部分可以用书里的一个问答高度概况:

问:能不能把浮动元素想成是被块元素忽略的元素,但是内联元素知道它们在哪里,这样考虑对么?

答:可以,这样考虑很好。嵌套在块元素中的内联内容总会围绕着浮动元素,内联元素会留意浮动元素的边界,而块元素会正常流向页面。又一个例外,对一个块元素设置clear属性时,会导致块元素下移,直到它右边、左边或两边没有浮动元素挨着它(具体取决于clear的值)

 到目前为止,我们都在说为什么不把主内容float到左边,接下来我们来说说什么情况可以这样做,详见第6点。

 

6.clear解决重叠问题:详见P495.另外,在这里我发现了新的一种布局模式:Flex布局。这个必须学。

 

7.对主内容用float left。

在4中我们说了边栏浮动主内容不浮动的好处,但其实那样做也是有坏处的:由于我们需要把边栏放到主内容前,所以当有人用功能受限的浏览器(比如PDA、小的移动设备等),屏幕宽度小的时候,她们看到的页面就是边栏在最前面,主页面在边栏后面了。

这种时候,我们就要用另一种设计方法了,也就是让主内容浮动到左侧而不是边栏浮动到右侧。

浮动的元素上下文是什么,影响特别大!后面会专门写一篇文章。(这个问题起源于P525。我想弄明白float的浮动位置究竟是怎么确定的。在我试图写一个探究浮动的位置的网页时,突然醒悟——书里在讨论浮动时,只探讨了两种情况:1.全部都是块元素时,浮动的元素会怎么动2.两个img在一个div里时浮动一个img会发生什么。书里避免了其他复杂的情况:比如浮动文本img元素会如何围绕之类的。我猜那些情况靠这本书不足以让我们理解,所以只看了这本书的我瞎试是徒劳的,只能先放下,后面再说。我已经为此设立了一个网页项目:float浮动位置探究,后面我将完成这个项目并放到个人网站里)

究竟是什么在围绕浮动的元素?只有清楚这一点,才能知道怎么实现围绕的效果!

首先,块元素从上向下流,那么只考虑块元素的浮动就如同上图一样,会有对齐的效果;内联元素从左上角向右下角流,这种元素的围绕就大有文章了。

首先要强调,文本是内联元素的一种特殊情况!我们来看这段代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="绕图文本.css">
    <title>绕图文本</title>
</head>
<body>
  <img src="images/header.gif" alt="Starbuzz Coffee header image">
<div>
  物理学习中,一本静止的书必须加一个力才能开始运动,从而我们得出结论,给了力物体才能处于运动状态——这并不对,没有力,物体也可以处于匀速运动状态,那么为什么我们会得出这么一个错误,但是符合现实的结论呢?因为我们并不知道他的真实机制——存在摩擦力所以现实中必须有力才能持续得动,虽然事实是一个物体会因为惯性保持运动状态。
  而在计算机语言的学习中也会发生这种错误的理解,比如C中的内存机制。但值得庆幸的是,语言是人建立的,其真实机制我们是可以知道的——通过汇编追踪、理解底层物理机制等方式。
  aaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaa aaaaaaaaaaa aaaaaaaaaaaa aaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa  
</div>

</body>
</html>
img{
    width: 200px;
    height: 200px;
    float: right;
    background-color: blueviolet;
}

你可以试试,当你把众多a之间的空格删去后,这个页面会出现英文字母无法围绕图片显示的情况——这是因为,浏览器把没有空格隔开的a看成了一个单词!所以只能换行显示,导致无法在图片右侧显示出来。当你用空格适当隔开这些a,就正常了。

书的P475曾说:“内联元素在水平方向上相互挨着摆放(只要右边还有空间能方向)......内容(内联文本)会从左向右流,直到没有更多空间为止,剩下的内容全放在下一行。注意浏览器必须用不同方式分解文本,使他能刚好适合内容区大小”,这句话中的“分解文本”,现在应该有了更深刻的理解了。

解决这两个概念,就没啥好记录的了。

 

 

8.流体与冻结设计:流体布局、冻结布局、凝胶布局

前面我们的设计都称流体布局,顾名思义;现在我们来看看冻结布局——锁定元素,让元素不能移动,我就能避免由于窗口扩展带来的一些问题(比如之前提到的边栏float时在小屏幕上看页面会主内容在边栏下面的情况)。

看到这里是我第一想法就是把主内容和边栏的div宽度都设固定值即可实现——但书里更干脆,直接用一个div包围所有body下的元素,给这个div设宽即可(注意,这个div的宽度可不会被继承哦,这个宽度是盒子的属性!从这看,我估计大部分的盒子属性都不能继承——百度了一下,这是对的)。

有时间,针对学过的属性进行分析,为什么能继承,为什么不能继承;不能继承的如果能继承了会发生什么?能继承的不能继承了又会如何?

所谓凝胶布局,就是使用一个之前提过的属性值:auto。              

凝胶布局会锁定页面中内容区的宽度,不过会将它在浏览器中居中——注意,其实凝胶布局是建立在冻结布局之上的,如下图代码:

 

#allcontent{
  width: 800px;
  padding-top: 5px;
  padding-bottom: 5px;
  background-color: #675c47;
}
/*冻结布局*/

#allcontent{
  width: 800px;
  padding-top: 5px;
  padding-bottom: 5px;
  background-color: #675c47;
  margin-left: auto;
  margin-right: auto;
}
/*凝胶布局*/

 

为了方便对比,我就把两端代码写在一起了。

可以看到,所谓冻结布局的实际实现是靠固定div中所有元素和内容的大小(或者换句话说是锁定内容区宽度)来实现的,其核心是划线部分的代码;

而所谓凝胶布局,则是在冻结布局的基础上,把左右外边距设为auto(即划线部分)——其实在上面所说的冻结布局中我们并没有规定内外边距(其实规定了上下内边距),其默认值是0(注意,这里针对的是div盒),在这里我们设定了左右外边距为auto,其目地是让div的左右外边距根据浏览器窗口的变化而自动改变左右外边距,这种“自动”的真正作用是让左右外边距相等,其效果表示为内容居中(注意区分效果和作用)。为什么会表示为居中呢?auto使左右外边距相等,这就导致了div元素离浏览器的左右有一定的距离,这个距离会根据浏览器窗口的大小改变而自动变化,这在效果上就表现为div始终在左右两边与窗口边界保持一个距离(当然,内容区的大小还是800px!)

不知道你有没有想过,为什么不让上下外边距或者左右内边距为auto?

现在来分析以下。

代码和效果图我就不贴了,自己就可以试试,我直接文字分析了。

当你把所有外边距设为自动时,也是一样的效果——但是上下外边距的auto是多此一举的行为(查看开发人员选项中的页面布局可以看到,改变窗口大小时div只有左右外边距变了,上下外边距始终是0没变过!)。想一想,div这个盒子是在body盒子中的,外边距保证的是元素与元素之间有距离以此来区分两者。在这个页面里,这个div是body下唯一的一个子元素(但是有很多子孙元素),只有一个的话,上下外边距还有就是多此一举!会让页面看起来上下有空白,很奇怪。那么,如果body下有多个子元素而不是一个子元素,这个上下外边距的auto会不会就有用了?

我试了一下,还是0没有任何区别。这样看来,auto这个属性究竟有什么作用(而不是有什么效果)?我也无从猜测了,留着以后看吧。

最后是讨论为什么不让左右内边距为auto。

注意,我们已经用width设定了内容区的宽度,即内容区是不会变的了,能变的只有边框、内外边距。我们来回忆一下边框、内外边距的作用:

内边距用来在内容区周围创建可见的空间;

边框提供了从视觉上分离内容的一种手段;

外边距允许在元素和其他元素之间增加空间;

在这里我们使用凝胶布局的原因是,想让整个页面的内容居中要想居中,就要让内容左右两边适应浏览器的变化而变化,让两边始终距离边界有相同的距离,这样才能“居中”。我们看看这三种属性的作用——边框不行,因为就算有一个框告诉你内容区在哪,但是左右两边不等大,看上去还是很别扭;内边距也不行!你要知道,我们已经把div的内容区确定大小了!而在div里的每个元素其实都是属于div的内容区里的!这里所谓的内边距自动其实是无效的

以上划线部分的分析是错的——错误的分析方向!错在:

1.不能乱穷举情况来逐一分析,这样会陷入“暴力穷举”的怪圈

2.不能忽视属性值的真正作用来分析——或者换句话说,auto值在不同的属性中的作用是不一样的!具体见css中写auto和不写的auto,区别在哪里?中顾秩灵的回答。

考虑到这,发现这应该是个以后再考虑的问题——这在CSS权威指南中有一章专门介绍。参考资料:为什么「margin:auto」可以让块级元素水平居中?

 

 

9.流体布局、冻结布局、凝胶布局是float的三种应用效果。

实现一种布局通常有很多方法,分别有自己的长处和短处。实际上我们正打算介绍另一种创建两栏布局的常用技术,它能让内容保持正确的顺序,同时避免流体布局存在的一些问题。不过,你会看到,这种方法同样要做一些折衷。                                                                                                     利用这种新技术,我们不会浮动元素。实际上,我们要使用CSS的一个特性,可以在页面上精确地定位元素。这称绝对定位(absolute positioning)——不仅能建立多栏布局,后面还会看到一些漂亮的效果。

 

                                                                                                                                                                                                                 

position——绝对定位  

部分讨论写在了《Head First HTML与CSS》的CSS属性的11里。

 

 

表格化

1.P513页的题目,自己写的与答案不同,思考了一下是自己滥用“结构化”了。

这一页的题目我是这样写的:

 

<div class=one_form>
  <div class=one_Row>
    <div class=one_line>
      <div id=main>
    <div class=two_line>
      <div id=sidebar>

 

答案是:

 

<div id=tableContainer>
  <div id=tableRow>
    <div id=main>
    <div id=sidebar>

 

注意观察两者区别,可以修正我的一些错误认知:

1.变量名问题。

我英语不行,表格的单词应该是table而不是form(所以table标签是表格标签,form标签是表单标签。表格和表单是不同的东西!)。

答案最外层用于定义表的div的id名是“表容器”,这和我想的“第一个表”不同的——暂时想不出来这两种想法区别在哪里。        

明明只有一个行,我却非要在名字里加上数字,好像后面有很多行一样.......这是不易读的代码!如果后面要求有更多行,我只需要在加的时候把名字重新定义一遍即可(不仅要改HTML,还要改CSS甚至Javascript.....),虽然这样好像自己麻烦了点,但是增加了易读性,我认为这是可以接受的取舍。

另一个,用数字来标记行也是不对的!应该用描述性的语言,比如这是一个“猫行”,说明了这是个与猫有关的行,用数字标记除非是特殊情况,否则也是不易读的代码。

2.div问题

很明显的看到,我的div用的比答案的多——我觉得答案写得好,因为没必要为了说明这是第几列就又加一个div!直接在相应div上说明即可;至于行要单独用一个div当容器放进去,我也不知道为什么,会不会是必须列在行里之类的硬性原因?能不能反过来之类?

行和列的顺序和HTML中元素的顺序是有关的。当你在CSS中定义某两个元素是行/列的时候,最先出现的元素就是第一行/列,以此推类。

 

2.“表格的边框间距(boder-spacing)看做是常规元素的外边距”的意思是里面元素的外边距失去了效果,改由这个属性控制了?那么内边距和边框也是这样?P516              

最后,总结一下上面四种布局的优劣(其实,不应该这样总结——应该如实陈述某个布局能做到什么就可以了,这样当我们需要某个布局的时候自然就知道该用哪个,这并不需要我们知道它们具体不能做到什么。

1.浮动布局

优:可以让其他内容围绕浮动元素,很适合在一个文本段落里浮动图像。

劣:为了浮动某个元素,要牺牲HTML的结构性;浮动是无法创建两个高度相同的列的。

2.凝胶布局                  

优:借助auto的特性可以让内容居中固定;是第一种布局的变种,可以实现围绕的效果。

劣:不再能根据浏览器窗口的变化而变化;不能始终填充整个浏览器窗口。

3.绝对布局

优:保证结构                          

劣:不能实现围绕效果;浏览器窗口变化时存在覆盖元素的可能。

4.表格布局

参考:网页的 Table 布局和 DIV+CSS 布局从哪里可以看出来?Table 布局已经过时了吗?     用 CSS 布局的时候,什么情况下用表格最为适合?

书里P522

注意,要分清楚里面说的是“CSS表格布局”还是“HTML表格布局”。后续要专门写一篇来总结这个问题。    

 

P525要求对页眉的图片进行修改,目标是两张图片横向排列,并能适应浏览器窗口大小。我自己的想法是用表格布局——即第一行第一列放一个图,第二列又一个图,让其能适应浏览器大小,但是我无法实现。由此引出了一系列的问题:1.表格里的单元格的元素如果是img,img外必须套div?img的CSS设置不能用display:table-cell?2.line-block是为img准备的display值?3.width属性有什么用?

参考资料: 布局神器(一)display:table-cell

inline-block和inline,block,table,table-cell的区别是什么,就是之间有什么特性

 

posted on 2017-12-08 08:39 wuduojia 阅读(...) 评论(...) 编辑 收藏

导航

统计