CSS原生布局方式

css-layout

前言

网页原生布局的方法其实网上有很多,大概为Flow(流动布局模型)、Float(浮动布局模型)、Layer(层级布局模型)。

Flow布局

流动布局模型其实就是默认的网页布局模式。也就是说网页在默认状态下的HTML网页元素都是根据流动模型来分布网页内容的。
流动布局将会有两个比较典型的特征,
第一,块级元素都会在所处的最近父级容器元素内自上而下按顺序垂直顺延分布,因为在默认状态下,块级元素的宽度都是100%(即父级元素宽度的100%)。实际上,块状元素都会以行的形式占据位置。如下代码所示,

<html>
    <body>
        <h1>我是h1</h1>
        <div>我是div</div>
    </body>
</html>

如上述代码所示,在没有外在样式的影响下,h1和div的宽度都将是100%(为页面的默认宽度)。
第二,在流动模型下,内联元素都会在所处的最近父级容器元素内从左到右水平分布显示。

<html>
    <body>
        <a>我是a</a>
        <span>我是span</span>
    </body>
</html>

内联元素不会像块级元素那样独自的占据一行。

Float布局

任何元素在默认的情况下都是处于整个文档流中的,不会浮动的。当我们给某一个元素设置浮动时,即可让该元素摆脱当前文档流,成为浮动元素。
如下代码,给div元素设置浮动,让两个div并排显示。

div{
    width:200px;
    height:200px;
    border:2px red solid;
    float:left;
}
<div id="div1">我是div1</div>
<div id="div2">我是div2</div>

这里有一点需要注意,如果我给div设置的浮动是float: right,那么div1将会贴在右侧,而div2将会贴在div1的左侧。

Layer布局

什么是层级布局模型?

层级布局模型就像是图像软件PhotoShop中非常流行的图层编辑功能一样,每个图层能够精确定位操作,但在网页设计领域,由于网页大小的活动性,层级布局模型没能受到热捧。但是在网页上局部使用层级布局还是有其方便之处的。
应用层级布局,往往需要定位属性的配合。CSS中有3种定位类型,

  • 绝对定位(position: absolute)
  • 相对定位(position: relative)
  • 固定定位(position: fixed)

绝对定位

如果想为元素设置层级布局模型中的绝对定位,需要设置position:absolute(表示绝对定位),这条语句的作用将元素从文档流中拖出来,然后使用left、right、top、bottom属性相对于其最接近的一个具有定位属性的父包含块进行绝对定位。如果不存在这样的包含块,则相对于body元素,即相对于浏览器窗口。

相对定位

如果想为元素设置层级布局模型中的相对定位,需要设置position:relative(表示相对定位),它通过left、right、top、bottom属性确定元素在正常文档流中的偏移位置。相对定位完成的过程是首先按static(float)方式生成一个元素(并且元素像层一样浮动了起来),然后相对于以前的位置移动,移动的方向和幅度由left、right、top、bottom属性确定,偏移前的位置保留不动。
相对定位与绝对定位最大的区别在于,前者没有脱离当前文档流而后者已经脱离了当前文档流。脱离当前文档流的意思是,该元素的前后元素在计算位置和偏移时将不再计算该元素的大小和位置。

固定定位

position: fixed,表示固定定位,与absolute定位类型类似,但它的相对移动的坐标是视图(屏幕内的网页窗口)本身。由于视图本身是固定的,它不会随浏览器窗口的滚动条滚动而变化,除非你在屏幕中移动浏览器窗口的屏幕位置,或改变浏览器窗口的显示大小,因此固定定位的元素会始终位于浏览器窗口内视图的某个位置,不会受文档流动影响,这与background-attachment:fixed;(用于定位背景图片的位置)属性功能相同。
固定定位在某一种场景下很有用,当我们需要在页面的某一位置固定的展示某一元素,且不受页面滚动条的影响。比如,常见的“返回顶部”之类的按钮。

混合使用

现代网页布局中,经常将相对定位和绝对定位混合使用,以达到更加灵活的目的。如下代码,

<style>
#box1{
    width:200px;
    height:200px;
    position:relative; /* 前辈元素的定位必须设置为relative */
}
#box2{
    position:absolute; /* 相对于最近的一个定位设置为relative的前辈元素的绝对定位 */
    top:20px;
    left:30px;
}
</style>
<div id="box1">
    <div id="box2">相对参照元素进行定位</div>
</div>

即,box2相对于box1是绝对定位的。当改变box1的位置时,box1内部的子元素是不会发生变化的,因为他们都是相对box1绝对定位的。

常见布局方式(两列)

两列情况暂定左侧宽为100PX

方法一:

 float + calc()
.right {
    width: calc(100% - 100px);
}

方法二:

position / float + margin-left
//html部分同上
//css
.left {
  position:absolute;left: 0; /*或 float:left; */
  width: 100px;
  background: blue;
}
.right{
  margin-left: 100px;
  background: red;
  text-align:center;
}

两列布局中,左边固定,右边自适应如何实现。

1.左浮动,右边用margin-left长度为左边的固定宽度,宽为100%

2.利用的是创建一个新的BFC(块级格式化上下文)来防止文字环绕的原理来实现的。BFC就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响。它可以通过以下任何一种方式来创建:

  • float的值不为none
  • position的值不为static或者relative
  • display的值为 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一个
  • overflow的值不为visible

三列布局左右固定中间自适应

圣杯

思路

首先有三行,头部和尾部各占一行,中间内容区一行,头尾不重要
中间内容分为三列对应三个div,为了先展示中间的主要内容所以把中间那列放前面,然后是左和右对应的div
中间内容自适应宽度为100%,此时已经把3个div所在的父容器占满了,所以想办法让左右2个div放置在左右侧,
左侧采取margin-left取-100%让其在最左侧,

右侧同理取值-200px(像素值为宽度大小),保证刚好占满自身宽度
这时候测试发现已经有自适应效果了,但是缩小到一定程度页面就出问题了,左右不在了,
所以加上最低宽度就是左右2个DIV的宽度(另外得考虑浏览器默认的body下的margin为8px,做了样式重置不考虑)
这时候发现中间的内容文字被左右遮挡了,对父容器用pading左右值为左右元素宽度,
为什么不对中间的DIV设置padding,我发现设置了不起作用,具体的原因我暂时也搞不懂来龙去脉,
发现padding后左右有留白,这个时候左边需要用 left: -200px;position: relative;来设置DIV位置,
办法确实巧妙。右边实现同理。

这时候发现已经大致有了点样子了,效果也看的到,此时典型的三栏布局,左右固定,中间内容自适应已经完成。

总结:

其实这个布局已经有点年头(圣杯布局),通过左右两块DIV来遮挡了中间div宽度为100%的区域,
然后压缩了三个DIV共有的父容器,来实现对中间内容展示的完善,也使左右2个不在遮挡中间了。
然后我又趁机试了下z-index属性,这里有个小问题要注意(要让z-index起作用有个小小前提,
就是元素的position属性要是relative,absolute或是fixed)

我之前的想法是让中间的内容置于顶层,不受div会因为某种hack导致位置变更遮挡了中间内容。
只需要设置下z-index属性值即可,左右可不设置,也可以设置以防万一,不同浏览器对z-index的默认值解析不同,可能会导致问题。

基本的布局架构就是如此,根据实际项目需求在此架构上完善,或者以后遇到这种类似的问题能打开思路,便算是有点收获了。

核心代码

  <style>
        body {
            /*因为浏览器默认body为margin:8px所以多加了16px*/
            min-width: 616px;
        }
        
        header {
            width: 100%;
            height: 40px;
            background-color: darkseagreen;
        }
        
        .container {
            /*height: 200px;*/
            /*overflow: hidden;*/
            padding: 0 200px;
        }
        
        .middle {
            width: 100%;
            height: 200px;
            background-color: deeppink;
            float: left;
            /*position: relative;*/
        }
        
        .left {
            width: 200px;
            height: 200px;
            background-color: blue;
            float: left;
            margin-left: -100%;
            left: -200px;
            position: relative;
        }
        
        .right {
            width: 200px;
            height: 200px;
            background-color: darkorchid;
            float: left;
            margin-left: -200px;
            right: -200px;
            position: relative;
        }
        
        footer {
            clear: both;
            width: 100%;
            height: 30px;
            background-color: darkslategray;
        }
    </style>

<header>
        <h4>Header内容区</h4>
    </header>
    <div class="container">
        <div class="middle">
            <h4>中间弹性区</h4>
            <p>
                我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容
            </p>
        </div>
        <div class="left">
            <h4>左边栏</h4>
        </div>
        <div class="right">
            <h4>右边栏</h4>
        </div>
    </div>
    <footer>
        <h4>Footer内容区</h4>
    </footer>

双飞翼

思路

双飞翼布局的方式跟圣杯在前部分是一样,不同之处主要在于如何处理中间的内容块被遮挡的问题
圣杯用padding的思路,使之压缩,但是父容器压缩,左右DIV位置变更,只能用相对位置进行left
设置位移为元素宽度来调整
而双飞翼的路线为采用的方式相比圣杯的父容器padding,
改变的是中间内容的内层div的外边框,相对来说对布局的破坏不大,
但是要采用这种方式又不破坏页面结构,就只能在中间内容div内部的再加个DIV设置margin或padding.
使之内容变相“压缩”等同padding效果,并且不会改变中间内容DIV外部的结构,只是内部的。
细心的人留意下我注释的代码,这里其实还有个CSS浮动的样式问题,出现这种情况有各种方式清除浮动,
我就不多讲解。大概有6种。

清除浮动(常用)

1.一般目前常用就是用:after伪元素给使用的浮动的父容器设置。

     新浪使用方式
        .clearfix:after{ 
            content: '';
            display: block;
            clear: both;
            height: 0;
            visibility: hidden;
        }
        .clearfix:after{  /*最简方式*/
            content: '';
            display: block;
            clear: both;
        }

2.给父元素定高

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .outer{
            border: 1px solid black;
            width: 300px;
            height: 50px;
        }
        .inner{
            width: 50px;
            height: 50px;
            background-color: #ff4400;
            margin-right: 20px;
            float: left;
        }
        .footer{
            background-color: #005FC3;
            width: 200px;
            height: 100px;
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
    </div>
    <div class="footer"></div>
</body>
</html>

3.利用 overflow:hidden 属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .outer{
            border: 1px solid black;
            width: 300px;
            overflow: hidden;
            zoom: 1;/*兼容 IE*/
        }
        .inner{
            width: 50px;
            height: 50px;
            background-color: #ff4400;
            margin-right: 20px;
            float: left;
        }
        .footer{
            background-color: #005FC3;
            width: 200px;
            height: 100px;
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
    </div>
    <div class="footer"></div>
</body>
</html>

核心代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>双飞翼</title>
    <style>
        header {
            width: 100%;
            height: 40px;
            background-color: darkseagreen;
        }
        
        .container {
            /*height: 200px;*/
            /*overflow: hidden;*/
        }
        
        .middle {
            width: 100%;
            height: 200px;
            background-color: deeppink;
            float: left;
            word-break: break-all;
        }
        
        .left {
            width: 200px;
            height: 200px;
            background-color: blue;
            float: left;
            margin-left: -100%;
        }
        
        .right {
            width: 200px;
            height: 200px;
            background-color: darkorchid;
            float: left;
            margin-left: -200px;
        }
        
        footer {
            width: 100%;
            height: 30px;
            background-color: darkslategray;
            clear: both;
        }
        
        .div-middle {
            margin: 0 200px;
            /*padding: 0 200px;*/
        }
    </style>
</head>

<body>
    <header>
        <h4>Header内容区</h4>
    </header>
    <div class="container">

        <div class="middle">
            <div class="div-middle">
                <h4>中间弹性区</h4>
                <p>
                    我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容我是各种内容
                </p>
            </div>
        </div>
        <div class="left">
            <h4>左边栏</h4>
        </div>
        <div class="right">
            <h4>右边栏</h4>
        </div>
    </div>
    <footer>
        <h4>Footer内容区</h4>
    </footer>
</body>

</html>

End

本篇只做阶段性的初级总结,原谅我没有贴出代码的效果图,以后有机会再扩展并进行效果图片展示,希望大家自己在编辑器下尝试效果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,628评论 1 92
  • 前言 温馨提示:本文较长,图片较多,本来是想写一篇 CSS 布局方式的,但是奈何 CSS 布局方式种类太多并且实现...
    sunshine小小倩阅读 3,003评论 0 59
  • 本文主要是起笔记的作用,内容来自慕课网. 认识CSS样式 CSS全称为“层叠样式表 (Cascading Styl...
    0o冻僵的企鹅o0阅读 2,546评论 0 30
  • 一 外部式css样式 (也可称为外联式)就是把css代码写一个单独的外部文件中,这个css样式文件以“.css...
    KunMitnic阅读 886评论 0 1
  • 进账: 1.感恩大前天进账4400,哇奥,好多钱宝宝,欢迎你们来到我 2.感恩前天进账300元,好开心哦好开心,宇...
    小狐狸娃娃阅读 193评论 0 0