HTML+CSS宝典 CSS进阶 布局
一、多栏布局
两栏布局
container 外层清除浮动
aside 侧栏宽度固定,设置浮动,并且要在该元素上设置 margin
main 主区域宽度自动适应,设置 overflow: hidden 触发 bfc 避开浮动
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>两栏布局</title> <style> .clearfix::after{ content: ""; display: block; clear: both; } .container{ background: #F0f0f0; width: 90%; } .aside{ float: left; background-color: #FF8c8c; color: #fff; width: 200px; /* 1.侧边栏固定宽度 */ margin-right: 10px; /* 3.注意,设置两栏之间的空隙,要在.aside这里设置 */ } .main{ background-color: #63A35C; color: #fff; overflow:hidden; /* 2.左边自适应,不设置宽度并触发BFC */ } </style> </head> <body> <div class="container clearfix"> <aside class="aside"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Unde aliquid earum autem blanditiis pariatur neque sapiente quod maxime commodi corporis quaerat praesentium totam rerum recusandae dignissimos explicabo iure ut fugiat voluptate et. </aside> <div class="main"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia mollitia possimus nam fuga quisquam ab est reprehenderit in quas ullam vero animi officiis minus libero aperiam architecto veritatis rem velit consequatur deserunt assumenda maiores optio excepturi sunt harum tenetur qui modi quam repellendus adipisci quae nisi culpa magnam sit laudantium aliquam quod inventore. Quos dolore distinctio esse explicabo incidunt ea et cum fugiat molestias voluptatum. Repellat architecto esse dolor magni iusto cum suscipit explicabo. Officia odit earum rem facilis blanditiis alias nobis unde quo hic tenetur soluta veniam numquam dolorem nisi repudiandae magni ex eaque nostrum modi impedit quae. Corporis. </div> </div> </body> </html>
三栏布局
两边左右浮动
中剪触发 bfc 避开浮动,成为自动适应的效果
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>三栏布局</title> <style> .clearfix::after{ content: ""; display: block; clear: both; } .container{ padding: 20px; border: 1px solid #ccc; background-color: #f8f8f8; min-width:640px; /* 给外层容器设置一个最小宽度 */ } .left{ float: left; width: 200px; background-color: lightblue; margin-right: 20px; } .right{ float: right; width: 200px; background-color: #63A35C; color: #fff; margin-left: 20px; } .main{ overflow:hidden; /* 主区域设置Bfc,避开浮动盒子 */ border:1px solid #ff8c8c; } </style> </head> <body> <div class="container clearfix"> <aside class="left"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi possimus cum mollitia voluptate nostrum unde aspernatur voluptas ipsa atque similique praesentium totam iure! Quas a excepturi cupiditate delectus reprehenderit blanditiis. </aside> <aside class="right"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi possimus cum mollitia voluptate nostrum unde aspernatur voluptas ipsa atque similique praesentium totam iure! Quas a excepturi cupiditate delectus reprehenderit blanditiis. </aside> <div class="main"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi possimus cum mollitia voluptate nostrum unde aspernatur voluptas ipsa atque similique praesentium totam iure! Quas a excepturi cupiditate delectus reprehenderit blanditiis. </div> </div> </body> </html>
二、伪等高
通常主区域内容比较多,侧边栏没什么内容,处理侧边栏高度不够有几种方式
1. css3 的弹性盒
2. js 控制
3. 伪等高
不用 css3 和 js,实现等高没有那么容易,
我们不知道 main 有多高,侧边栏 aside 设置不了高度,因为这里我们用一种巧妙的方案“伪等高”
<!DOCTYPE html> <html > <head> <meta charset="utf-8"> <title>等高</title> <style> .clearfix::after{ content: ""; display: block; clear: both; } .container{ width: 50%; margin: 0 auto; overflow: hidden;/* 第3步 */ } .aside{ float: left; background-color: #FF8c8c; color: #fff; width: 200px; margin-right: 10px; height: 10000px; /* 第1步 */ margin-bottom:-9990px; /* 第2步 */ } .main{ overflow: hidden; background-color: #63A35C; color: #fff; } </style> </head> <body> <div class="container clearfix"> <aside> Lorem ipsum dolor </aside> <div> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eveniet repellat voluptatem harum itaque quidem rerum at nobis amet natus doloribus eius beatae possimus in corporis dignissimos ut quo cumque iusto ducimus aliquid earum maxime ipsum rem ad ratione. Placeat tempora impedit soluta ad facere molestias explicabo excepturi nihil esse mollitia dignissimos natus iure architecto laudantium et illo ut culpa corporis consectetur inventore adipisci eum officiis delectus tenetur nostrum deserunt voluptatum cum quae voluptate earum quisquam maiores deleniti aliquid eius neque pariatur quia. Inventore odit sapiente facere asperiores fugiat molestias amet sint pariatur est iste voluptatem quas maxime earum ipsa eius. Quaerat expedita similique voluptatibus hic officia necessitatibus possimus nesciunt eum voluptate sit laudantium dolorum atque magnam reprehenderit asperiores et dolor dolore minima. Maiores eveniet hic et numquam adipisci nisi doloribus voluptate aliquam ut ipsum sit quam vero dolor ducimus laudantium at blanditiis tenetur veniam beatae earum distinctio officia sunt velit. Sit magni mollitia optio expedita suscipit eos quis molestiae repellat ipsa excepturi maiores cumque voluptatum recusandae officia saepe dolorum perferendis doloribus veniam assumenda quas nihil necessitatibus alias quae animi tempora. Sed quis distinctio quibusdam impedit architecto reiciendis suscipit sit neque natus? Odit corporis veniam cum minima quis enim quos asperiores. </div> </div> </body> </html>
第一步
aside 元素设置一个非常夸张的高度,比如高度值一万 height: 10000px(4个 0),
这个时候侧边栏 saide 变得很高了,太高了怎么办呢?
第二步
在给侧边栏 aside 设置 margin-bottom:-9990px
值为负数 -9999 或 -9990
请问现在 saide 的高度是多少?
盒子的高由是四个部分组成的(内容、padding、border、margin)
现在只有 height 和 margin-bottom,
10000 + -9990 = 10 实际上盒子的总高度只 10 像素,只是看起来很高
为什么要设置 margin-bottom:-9990px 呢?
1. 因为 saide 太高,把外层 container 撑开了
2. 为了避免 container 被撑的很高,只要设置了 margin-bottom:-9990px,实际上 aside 的总高度只有 10 像素,我们看到的全是背景,
内容部分很高会有背景,背景会覆盖内容部分,但是实际上盒子总高度只有 10 个像素,
这里注意 saide 高度不能是 0 个像素,如果是 0 个像素,主要内容区域 main 就跑到左边了
现在容器 container 的高度是被主区域 main 撑开的,
外层的 container 的高度跟主区域 main 是一样的,接下来要解决 aside 超出外层容器的这一部分,解决看上去很高的问题
第三步
给 container 元素设置 overflow:hidden,超出外层容器的 aside 隐藏就完事了
当然这不是真实的等高,
如果主区域 main 的东西太多了,超过 10000 个像素就又不行了,所以这好像是等高的,实际上是伪等高
注意
如果主区域 main 的内容不够,也是不行的,
如果主区域 main 的内容比 aside 的内容少,aside 的内容会显示不完全
所以这不是一个完美的解决办法,但是可以解决这个问题,
因为通常情况下都是侧边栏高度不够,而主区域高度高于侧边栏,所以可以用这种方式,
css3 有更加舒服的方式处理等高
三、元素书写顺序
上面的两栏布局或者三栏布局,它们都有一个特点,
就是浮动元素要先写,
如果把浮动元素写后面,就不能做出两栏或三栏布局了
因为先写常规流块盒,常规流块盒把第一行撑满了,
然后下面浮动盒子避开常规流
但是这样对搜索引擎不太友好,
因为搜索引擎有一个特点,是从上到下读代码,它认为网站前面的内容是最重要的
如果公司要求 main 放在前面,怎么写呢?
前提条件的 right、left 左右两侧边栏是固定宽度
main 主区域用 margin 居中,左右两边预留 300 像素
然后 right、left 左右两侧边栏设置绝对定位,相对于外层容器 container 元素定位在两边
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>三栏布局</title> <style> .container{ padding: 20px; border: 1px solid #ccc; background-color: #f8f8f8; position: relative; /* 相对定位 */ } .left{ width: 300px; background-color: lightblue; position: absolute; /* 绝对定位 */ left:20px; top:20px; } .right{ width: 300px; background-color: #63A35C; color: #fff; position: absolute; /* 绝对定位 */ right:20px; top:20px; } .main{ border:1px solid #ff8c8c; margin:0 300px; /* 设置左右两边margin预留出空间 */ } </style> </head> <body> <div class="container"> <div class="main"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi possimus cum mollitia voluptate nostrum unde aspernatur voluptas ipsa atque similique praesentium totam iure! Quas a excepturi cupiditate delectus reprehenderit blanditiis. </div> <aside class="left"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. </aside> <aside class="right"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. </aside> </div> </body> </html>
这种写法有一个缺陷,
会导致外部容器 container,根本不知道 left 和 right 这两个绝对定位元素的高度,
因为绝对定位元素已经彻底脱离了常规流,所以外层容器无法知道绝对定位的高度是多少
好处在于,
一般来说侧边栏的高度没有主区域高,一般侧边栏是这样,高度不会太高
可以用上面的等高方法,如果给侧边栏做等高
.container{ padding: 20px; border: 1px solid #ccc; background-color: #f8f8f8; position: relative; overflow:hidden; /* 3.等高 */ } .left{ width: 300px; background-color: lightblue; position: absolute; left:20px; top:20px; height: 10000px;/* 1.等高 */ margin-bottom:-9990px;/* 2.等高 */ } .right{ width: 300px; background-color: #63A35C; color: #fff; position: absolute; right:20px; top:20px; height: 10000px;/* 等高 */ margin-bottom:-9990px;/* 等高 */ } .main{ border:1px solid #ff8c8c; margin:0 300px; }
四、后台页面的布局
app 是 application 的缩写,表示应用程序,app 元素要铺面整个窗口,怎么铺满整个窗口呢?
1. 设置 app元素固定定位 position: fixed,固定定位的包含块是整个视口,就像蒙层一样把整个网页盖住
2. 然后宽高都设置为 100%
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>后台页面的布局</title> <style> body{margin:0;} .app{ position: fixed; width: 100%; height: 100%; background-color: #FF8C8C; } </style> </head> <body> <div class="app"></div> </body> </html>
为什么 app 元素的高度可以设置百分比?
因为可视窗口就是浏览器的窗口,浏览器的窗口是能确定高度的,所以 app 这里能设置高度百分比,
这样 app 一定刚好撑满整个可视窗口,不会出现滚动条,浏览器窗口尺寸变化,app 元素也跟着变化
设置 app 里面的子元素
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>后台页面的布局</title> <style> body,h1{ margin: 0; } .app{ position: fixed; width: 100%; height: 100%; background-color: #FF8C8C; } .header{ height: 60px; background-color: #008c8c; color: #fff; } .container{ width: 100%; height: 100%; background-color: #ff8c8c; } </style> </head> <body> <div class="app"> <header class="header"> <h1>后台布局学习</h1> </header> <div class="container"> container </div> </div> </body> </html>
header 元素设置高 60 像素
container 设置高度 100%,与 app 的高度是一致的,
这样出现的问题是,container 的高度加上 header 的高度,就超过了 app 容器的高度
contianer 和 header 都是常规流,两个的高度加起来太高了,
css3 里可以运算减去 60 像素,这里目前不用 css3,是没法减的
我们这样解决问题,
1. 设置 header 元素为absolute 绝对定位元素 ,它相对于容器 app 的固定定位 fixed 进行移动,
container 元素是常规流,会忽略定位元素
2. 设置 container 元素 margin-top:60px,预留出被 header占据的 60 像素
3. 由于设置了padding-top 高度有变多了,所以设置 border-box
现在不管浏览器的窗口怎么变化,都是适应视口变化的,不会出现滚动条
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>后台页面的布局</title> <style> body,h1{ margin: 0; } .app{ position: fixed; width: 100%; height: 100%; background-color: #FF8C8C; } .header{ height: 60px; background-color: #008c8c; color: #fff; position:absolute; /* 1.设置绝对定位 */ top:0; left:0; width: 100%; /* 定位元素要设置宽度 */ } .container{ width: 100%; height: 100%; background-color: #ff8c8c; margin-top:60px; /* 2.预留出被header占的60像素 */ box-sizing: border-box; /* 3. */ } </style> </head> <body> <div class="app"> <header class="header"> <h1>后台布局学习</h1> </header> <div class="container"> container </div> </div> </body> </html>
然后设置 container 区域里面的左右侧边栏,就是一个两栏布局
left 区域固定宽度,然后左浮动,
main 区域触发 BFC 避开浮动盒子
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>后台页面的布局</title> <style> body,h1{ margin: 0; } .app{ position: fixed; width: 100%; height: 100%; background-color: #FF8C8C; } .header{ height: 60px; background-color: #008c8c; color: #fff; position:absolute; top:0; left:0; width: 100%; } .container{ width: 100%; height: 100%; background-color: #ff8c8c; margin-top:60px; box-sizing: border-box; } .container .left{ float: left; width: 200px; background-color: lightblue; height: 100%; /* 外面的容器container高度是可以算出来的,这里设置百分比就刚好撑满 */ } .container .main{ overflow: hidden; /* 触发BFC避开浮动元素 */ height: 100%; /* 同样设置高度百分百 */ background-color: #fff; } </style> </head> <body> <div class="app"> <header class="header"> <h1>后台布局学习</h1> </header> <div class="container"> <aside class="left">left</aside> <div class="main">main</div> </div> </div> </body> </html>
内容太多出现滚动条怎么办?
很简单给 left 和 main 加上 overflow:auto 当内容溢出的时候出现滚动条
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>后台页面的布局</title> <style> body,h1{ margin: 0; } .app{ position: fixed; width: 100%; height: 100%; background-color: #FF8C8C; } .header{ height: 60px; background-color: #008c8c; color: #fff; position:absolute; top:0; left:0; width: 100%; } .container{ width: 100%; height: 100%; background-color: #ff8c8c; margin-top:60px; box-sizing: border-box; } .container .left{ float: left; width: 200px; background-color: lightblue; height: 100%; overflow: auto; /* 内容超出,出现滚动条 */ } .container .main{ overflow: hidden; height: 100%; background-color: lightgoldenrodyellow; padding: 20px; /* 设置padding */ box-sizing: border-box; /* 设置padding后会导致盒子高度增加,所以要设置一个css3的属性 */ overflow: auto; /* 内容超出,出现滚动条 */ } </style> </head> <body> <div class="app"> <header class="header"> <h1>后台布局学习</h1> </header> <div class="container"> <aside class="left">left</aside> <div class="main">main</div> </div> </body> </html>
主要的关键点
app 元素的高度是取决窗口,浏览器窗口的高度是可以算出来的,
所以 app 可以设置高度为百分比 height:100%
而 container 元素也可以设置高度为 height:100%,
是因为 container 取决于 app 的高度,container 的包含块是 app
container 的高度可以定下来,
里面的 left 和 mian 的高度都可以设置百分百比 height:100%