谈谈前端常见布局方式及概念分析

192 阅读10分钟

我正在参加「掘金·启航计划」

涅槃计划CSS篇

前言

hi大家好,我是小鱼,今天复习的是CSS的布局方式,有些人写一个页面只需10分钟,而有些人可能需要20分钟,有些人30,而我......摆烂吧,我写不出来。或者有时候明明可以用这个布局会更好更快,可是我们并没有,那说明我们对某些布局方式不是太熟悉,或者是不知道在什么时候该用什么布局,今天就展开这个,一起讨论下CSS到底有哪些布局方式。 赶紧学习,拉近差距。


静态布局

静态布局是一种最传统的布局方式,网页中所有尺寸都是由px作为单位,设置了min-width,如果宽度小于就会出现滚动条,如果大于这个宽度则内容居中外加背景,这种设计常见于pc端。

优点:这种布局方式对设计师和CSS编写者来说都是最简单的,亦没有兼容性问题。

缺点:显而易见,即不能根据用户的屏幕尺寸做出不同的表现。当前,大部分门户网站、大部分企业的PC宣传站点都采用了这种布局方式。固定像素尺寸的网页是匹配固定像素尺寸显示器的最简单办法。但这种方法不是一种完全兼容未来网页的制作方法,我们需要一些适应未知设备的方法。

简单来说我们可以把它分为三大类分别是文档流、浮动和定位,传统布局实际上对于现在的设计师来说很难达到他们的要求,需要熟练掌握并配合其他布局来实现更多的页面框架和精美布局。这些都是基础中的基础,我简单描述即可。

浮动

float可取值left、right、none。元素默认取值是none。当取值为left时元素会浮到包含块中的左上方。当取值为right时会浮到包含块的右上方。当多个盒子同时设置float:left或right时,如果宽度允许,这些盒子会按照书写顺序依次排列在父元素包含块的左上角或右上角。

定位

使用position属性也可以让元素脱离文档流,默认值是static,即浏览器默认定位方式。不加调整的话元素就默认是在常规流中。合理运用其他属性也可以实现一些布局效果。

自适应布局

自适应布局的特点是分别为不同的屏幕分辨率定义布局,即创建多个静态布局,每个静态布局对应一个屏幕分辨率范围。改变屏幕分辨率可以切换不同的静态局部(页面元素位置发生改变),但在每个静态布局中,页面元素不随窗口大小的调整发生变化。可以把自适应布局看作是静态布局的一个系列。

布局特点

屏幕分辨率变化时,页面里面元素的位置会变化而大小不会变化。

使用方式

同一个显示设备

常见自适应布局有:左边定宽右边自适应;右边定宽左边自适应;两边定宽中间自适应,上代码,这里都是用的常用的布局方式。

栗子一:左边固定右边自适应

.warp {
    width: 100%;
    height: 500px;
    display: flex;
}
.left {
    width: 200px;
    background: #ffd255;
}
.right {
    flex: 1;
    background: #ff8411;
}

<div class="warp">
    <div class="left">我是小鱼</div>
    <div class="right">我是大鱼</div>
</div>

image.png

栗子二:左边自适应,右边定宽

这个和栗子一一样哦,只需给left盒子设置flex:1,right盒子设置定宽就OK啦

栗子三:左边自适应,右边定宽

flex 用于设置或检索弹性盒模型对象的子元素如何分配空间
.warp {
    width: 100%;
    height: 800px;
    display: flex;
    position: absolute;
}

.left {
    width: 200px;
    height: 100%;
    float: left;
}
.center{
    float: left;
    height: 100%;
    flex: 1;
}
.right {
    width:200px;
    height: 100%;
    display: table-cell;
    float: left;
}

<div class="warp">
    <div class="left">我是小鱼</div>
    <div class="center">我是鱼</div>
    <div class="right">我是大鱼</div>
</div>

image.png

不同设备

使用 @media 媒体查询给不同尺寸和介质的设备切换不同的样式。在优秀的响应范围设计下可以给适配范围内的设备最好的体验,在同一个设备下实际还是固定的布局。

@media (max-width: 750px) { ...css代码... } 
@media (min-width: 750px) and (max-width: 1334px) { ...css代码... } 

流式布局

网页中主要的划分区域的尺寸使用百分数(搭配min-*、max-*属性使用),分别为不同的屏幕设置布局格式,当屏幕大小改变时,会出现不同的布局,意思就是在这个屏幕下这个元素块在这个地方,但是在那个屏幕下,这个元素块又会出现在那个地方。只是布局改变,元素不变。可以看成是不同屏幕下由多个静态布局组成的。

而流式布局的特点是随着屏幕的改变,页面的布局没有发生大的变化,可以进行适配调整,这个正好与自适应布局相补。使用%百分比定义宽度,高度大都是用px来固定住,可以根据可视区域 (viewport) 和父元素的实时尺寸进行调整,尽可能的适应各种分辨率。往往配合 max-width/min-width 等属性控制尺寸流动范围以免过大或者过小影响阅读。

在移动端开发也是常用布局方式,但缺点明显:主要的问题是如果屏幕尺度跨度太大,那么在相对其原始设计而言过小或过大的屏幕上不能正常显示。因为宽度使用%百分比定义,但是高度和文字大小等大都是用px来固定,所以在大屏幕的手机下显示效果会变成有些页面元素宽度被拉的很长,但是高度、文字大小还是和原来一样

布局特点

屏幕分辨率变化时,页面里元素的大小会变化而且布局不变。

经典的双飞翼布局

.container {
    min-width: 600px;
    color: white;
}
.left {
    float: left;
    width: 200px;
    height: 400px;
    background: #ffad55;
    margin-left: -100%;
}
.center {
    float: left;
    width: 100%;
    height: 500px;
    background: #ffd255;
}

.center .inner {
    margin: 0 200px;
    height: 400px;
}
.right {
    float: left;
    width: 200px;
    height: 400px;
    background: #60ff55;
    margin-left: -200px;
}

效果↓

image.png

这里给大家解释一下,我给container盒子设置了min-width: 600px,因为双飞翼的出现就是为了解决圣杯布局的弊端提出的,当浏览器宽度缩短到使得中间子元素的宽度比左右子元素宽度小的时候,这时候布局就会出现问题。所以我们在使用圣杯布局的时候一定要设置整个容器的最小宽度。

响应式布局

随着CSS3出现了媒体查询技术,又出现了响应式设计的概念。响应式设计的目标是确保一个页面在所有终端上(各种尺寸的PC、手机、手表、冰箱的Web浏览器等等)都能显示出令人满意的效果,对CSS编写者而言,在实现上不拘泥于具体手法,但通常是糅合了流式布局+弹性布局,再搭配媒体查询技术使用。——分别为不同的屏幕分辨率定义布局,同时,在每个布局中,应用流式布局的理念,即页面元素宽度随着窗口调整而自动适配。即:创建多个流体式布局,分别对应一个屏幕分辨率范围。可以把响应式布局看作是流式布局和自适应布局设计理念的融合。

布局特点

每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变。

媒体查询

Media Queries Level 3规范中,媒体查询的能力被扩展,除了设备的类型,我们可以还获取到诸如窗口宽度、屏幕方向或分辨率等媒体特性(media features):

width – 输出设备渲染区域(如可视区域的宽度或打印机纸盒的宽度)的宽度 
height – 输出设备渲染区域(如可视区域的高度或打印机纸盒的高度)的高度 
device-width – 输出设备的宽度(整个屏幕或页的高度,而不是仅是渲染区域) 
device-height – 输出设备的高度(整个屏幕或页的高度,而不是仅是渲染区域)
orientation – 设备处于横屏(宽度大于高度)模式还是竖屏(高度大于宽度)模式 
aspect-ratio – 输出设备目标显示区域的宽高比 
device-aspect-ratio – 输出设备的宽高比 
resolution – 输出设备的分辨率(像素密度) 
color – 检查设备支持多少种颜色等 
color-index – 输出设备中颜色查询表中的条目数量 
monochrome – 指定了一个黑白(灰度)设备每个像素的比特数 
scan – 检查电视输出设备是顺序扫描还是隔行扫描 
grid – 判断输出设备是网格设备还是位图设备

使用方法

设备宽度在这个区间将按照指定的样式执行
@media (min-width: 750px) and (max-width: 1334px)  {    
    .container {        
        font-size: 25px;    
    }
}

绑定在style标签上的媒体查询
<style type="text/css" media="screen and (max-width: 750px)">    
    body {        
        font-size: 25px;    
    } 
</style>

弹性布局

rem/em

这个大家应该也已经很熟悉了,特别是写移动端的小伙伴,使用 em 或 rem 单位进行相对布局,相对%百分比更加灵活,同时可以支持浏览器的字体大小调整和缩放等的正常显示。

区别

rem 的字体大小相对的是HTML根元素

em 字体大小是相对于最近的被设定过字体大小的祖先元素

栗子↓

html {
    font-size: 26px;
}

<div style="font-size: 48px;">
    <div style="font-size: 32px;">
        <p style="font-size: .5rem;">小鱼 我是rem</p>
        <p style="font-size: .5em;">大鱼 我是em</p>
    </div>
</div>

image.png

image.png

这两张图看出来了吧,小鱼的字体大小为13px,只和根元素的字体大小有关。大鱼的字体大小为16px,由最近的被设定过字体大小的祖先元素所定

Flex

什么是Flex在这里就不再赘述了,可以看看我之前写过的一篇 十分钟解决你对Flex的疑惑

直接给大家举个栗子

比如说要实现这么一个效果↓

image.png

代码

.warp {
    display: flex;
    flex-wrap: wrap;
    border: 1px solid rgb(176, 144, 71);
}

.item {
    width: 209px;
    height: 125px;
    margin: 0 12px 30px 0;
}
.item:nth-child(4n) {
    margin-right: 0;
}

效果

image.png

只需要设置 flex-wrap: wrap 让它换行就可以。

解决最后一列的间距问题

如果item的宽度是固定的,那么直接用nth-child获取元素第4,8个取消右边距,当然前提是每个item的宽度是固定的,因为你知道一排要放几个。

但是平时在工作中有可能需要做响应式,就是我不确定一排能放多少个,因为item的宽度是动态计算的。这样有两种方式,第一是取消父盒子的padding-right。第二种是设置父盒子的margin-right为负值,这个值的大小是item的右边距,相当于就是把父盒子往右边扯了一个margin距离,在视觉上来达到这个效果。

end 总结

  1. 如果只做pc端,那么静态布局(定宽度)是最好的选择;
  2. 如果做移动端,且设计对高度和元素间距要求不高,那么弹性布局(rem+js)是最好的选择,一份css+一份js调节font-size搞定;
  3. 如果pc,移动要兼容,而且要求很高那么响应式布局还是最好的选择,前提是设计根据不同的高宽做不同的设计,响应式根据媒体查询做不同的布局。

image.png