制作网页可以简单分为两步:
- 快速排列盒模型来整体布局
- 布局后调整样式、丰富内容
- 另外
- 推荐一个学习网站:https://css-tricks.com/snippets/css/
布局相当于整个页面的骨架,如何做到快速且结构合理?下面就此记录一些布局要点。
float流式布局
注意:不常用
float最常用方式:
一个float的block元素,其他inline内容会围绕它的宽高浮动
就好比:我们看到inline文本会相互排斥,其实是文本的宽高撑开了其他文本,比如设置line-height撑开其他文本,inline自身没有宽高
如下:文本环绕
如下:son1设置float:left,son2的block宽高不受son1影响了,但是son2文本还是会环绕
总结:float浮动之后,跟其他float按区域排列,被文本环绕。
-
float元素的宽高坍塌,不再排斥其他block元素的宽高,但是float的宽高会排斥所有
文本inline行内元素,也即是说设置了float之后,就会无视所有block元素的空白宽高,直接贴到inline元素实体部分。 -
跟position:absolute很相似,但是position:absolute会直接脱离文档流,无视所有其他inline和block。float只是无视block,没有无视inline文本。
利用float的这个特性,可以实现:
设置前一个元素为float,让block宽高可以重合,但是内容inline被float元素宽高撑开:
因为float布局后续如果复杂起来可能不好重写,建议复杂结构不用。
flex一维布局
flex一维布局的意思是,
它是在水平或者垂直方向上成一条直线把子元素排列,
如果设定可以换行,它也是像文本那样流动到下一行,所以是一维的。
flex一维布局,优点:用法简单,设置display即可。用法广泛,下面来看广泛在哪:
第一种布局(居中,居左右,平均分布)
如上图,flexbox弹性布局可以把整个content容器内的子元素堆放在中间、在左右、或者平均分布,使用#justify-content设置即可。
这里说的是row水平方向,垂直方向一样的效果,就是设置flex-direction为column就行。这里只说row方向。
然后,垂直方向可以放上面,中间,下面。只要有高度空间。
###第二种布局(真正的居中)
如果布局要更加灵活,比如一部分居左中,一部分居居中,一部分居右中 呢?
上面是分为3部分,那么就需要把子元素分成3份(可以是N份,根据需要),如下代码
使用id=app的容器给3个ul子元素布局,
#app {
margin-top: 100px;
display: flex;
}
ul {
flex: 1;
display: flex;
justify-content: center;
border: 5px dashed red;
}
ul.center {
flex: 0;
border: 5px dashed black;
}
ul li a {
white-space: nowrap;
display: inline-block;
font-size: initial;
line-height: 80px;
border: 1px solid blue;
}
从上图可以看到,右边内容只要还没完全放不下,就不会把中间的挤出中间位置。
是因为设置了其他的放大比例为flex: 1;,而中间的放大比例为flex: 0;
也即是中间的内容只要左右还有位置,就不会被挤出居中的位置。
如果左边没有元素,那么给个看不见的同标签ul元素即可,方便统一选择器。
第三:如何把一部分子元素靠右、靠左
像上图左边的子元素,我们又可以设置为flex布局,层层套娃。
这里关键点在于,如果只是想要达到左右两个方向“浮动”布局,当然可以使用float设置,但是float之后,垂直方向的调整就不好搞了,如下图(我们要保留垂直方向这个能力):
所以,可以这样:
ul.left {
display: flex;
}
ul.left li:nth-of-type(2) {
margin-left: auto;
}
ul.left li:nth-of-type(3) {
margin-right: auto;
}
flex中弹性布局,体现在用margin:auto直接可以设置子元素的浮动位置(垂直方向忽略即可):
因为这种方式的居中是按margin空间来算的,如果右边元素很宽,那么居中就不准确,所有才有上面第二种真正的居中。
所以,巧用margin!!!
总结下,flex弹性布局在于,对于宽高不固定的元素,可以很好的设置比例来使得元素按比例缩放。
虽然上面元素都是固定宽高的。
第四:实操:用flex来实现各种网站的布局
第一个案例
原图:右边一个按钮靠右,左边图标,中间区块,在缩小宽度后会下移:
我作出来的效果(忽略文字差异):
右边使用头部导航区块容器内的绝对定位,左侧两个区块使用flex并设置换行,伪代码如下:
<div 定位锚点>
<div flex布局>
<ul></ul>
<ul 自动换行></ul>
</div>
<div 绝对定位>右侧浮动</div>
</div>
第二个案例
如下图:
可以看到,导航条被分为两边,两边内容居中。
这是我做出的效果:
直接一个ul作为flex容器,通过设置里头的li的margin来分区域:
ul.center {
display: flex;
justify-content: center;
}
ul li:nth-of-type(1) {
margin-left: auto;
}
ul li:nth-of-type(3) {
margin-right: auto;
}
ul li:last-of-type {
margin-right: auto;
}
当然,这样是按相等的margin区域来平均分布的。
第四个案例
来做一个简单的整体页面布局,我随机打开一个网站:
这个网页布局,顶上导航条是跟下面内容面板区域分开的。
而且导航条宽度固定,使用fixed即可,这个导航条明显是左右浮动布局:
关键代码如下:
<div class="container">
<div class="header">
<div class="center">
<ul class="left">
<li class="noted">Diego</li>
</ul>
<ul class="right">
<li>Jayla</li>
</ul>
</div>
</div>
<div class="main">
<div class="content">
<br>
</div>
<div class="box">
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
给container容器设置min-height高度为适应屏幕高度100vh,min-width宽度为最大元素的宽度:
.container {
min-height: 100vh;
min-width: 900px;
background-color: #e1e1e1;
}
.header {
position: fixed;
left: 0;
right: 0;
top: 0;
display: block;
height: 52px;
background-color: rgba(249, 249, 249, 0.5);
}
.center {
width: 900px;
margin: 0 auto;
}
ul.left {
float: left;
}
ul.right {
float: right;
}
.main {
display: flex;
overflow: auto;
justify-content: center;
margin-top: 52px;
}
- 这里指出
float浮动的一个特点,子元素设置float之后,- 宽高将不占用兄弟元素的宽高空间,只排斥文本内容空间
- 同时,子元素也不会撑开父元素的宽高边框,自由溢出父元素区域。
- float子元素想要撑开父元素的宽高,则在父元素加上
overflow溢出能够滚动,auto或scroll。- 另一种清除float父元素高度坍塌的办法是
parent:after { display: block; clear :both ;}- inline和inline-block无法清除左右浮动! overflow会存在滚动,所以还是用after最好。
给右边区块 加上媒体查询@media 判断,如果宽度太小,就改为隐藏:
如上图,当宽度变小后,自动收缩右边区块,使用按钮点击来展示/隐藏。
@media screen and ( max-width: 670px ) {
.main a.nav-btn {
visibility: visible;
}
}
let mediaQuery = window.matchMedia("(min-width: 671px)");
mediaQuery.addEventListener("change", e => {
mediaMatch(e);
});
function mediaMatch(mediaQuery) {
if (mediaQuery.matches) {
right.style.visibility = "visible";
} else {
right.style.visibility = "hidden";
}
}
如上图,加上隐藏头部导航和图标上移下移功能
let beforeScrollTop = htmlElem.scrollTop;
document.addEventListener("scroll", e => {
let delta = htmlElem.scrollTop - beforeScrollTop;
beforeScrollTop = htmlElem.scrollTop;
if (delta === 0) {
return false;
} else if (delta > 0) {
headerElem.style.top = "-52px";
} else {
headerElem.style.top = "0";
}
});
//transition: top 1s; 动画效果
grid二维布局(除非布局复杂且以后结构相对不变,否则不建议)
具体就是把一个区域划分为行列网格,然后通过设置一个个区块占网格里的哪些部分,来标记好这些区域后,样式就可以应用到具体区块上。
略。
一些问题和技巧记录:
tips:外边距合并问题 --跟清除浮动类似
- 1、父元素边框和子元素边框之间没有任何元素和内容,那么子元素的外边距会贴着父元素传到外面
- 还有上下兄弟元素直接没有阻挡,那么外边距会相互渗透合并
- 解决办法:
- 1、给子元素套个容器,容器设置overflow:hidden之类,容器就会把子元素外边距包进去。
- overflow不好的地方:多了一层标签
- 2、给贴合的边距设置1px的透明边框或者1px padding,也不好,多了1px
- 3、使用before、after设置content:“1”,block,fontsize设为0。同时清除浮动和边距合并问题。
/* 清除浮动 和外边距合并 */
.clear-after::after {
content: "1"; /* 不能为空 */
display: block;
font-size: 0;
clear: both;
}
.clear-before::before {
content: "1"; /* 不能为空 */
display: block;
font-size: 0;
clear: both;
}
tips:水平居中问题
- 1、凡是内盒子宽度固定,使用
margin: 0 auto;
<div class="parent">
<div class="box">sss
</div>
</div>
.box {
width: 100px;
margin: 0 auto;
}
- 2、内盒子宽度不固定,把外盒子变成flex布局(或者直接加上
外盒子{text-align: center;})
.parent {
display: flex;
justify-content: center;
}
- 3、内盒子宽度不固定,不想给外盒子加属性,使用
margin: 0 auto;加上display: table;
.box {
outline: 2px dashed blue;
margin: 0 auto;
display: table;
}