• CSS学习2-布局介绍


    布局介绍

    1.浮动布局

    本例中,body就是外层容器,因为它默认就是100%的网页宽度,所以不用给它添加新的样式。在body内部,整个网页的内容放在了container容器里面,也就是内层容器。对于内层容器,需要设置一个max-width,并将外边距设置为auto,使内容居中,如下代码

    .container {
        max- 1080px;
        margin: 0 auto;
    }
    

    这里使用了max-width,而不是width。因此如果视口宽度小于1080px的话,内层容器就能缩小到1080px以下。换句话说,在小视口上,内层容器会填满屏幕,在大视口下,它会扩展到1080px。这种方式能有效避免在小屏幕上出现水平滚动条。

    浮动元素不同于普通文档流的元素,它们的高度不会加到父元素上。这可能看起来很奇怪,但是恰好体现了浮动的设计初衷。
    
    浮动是为了实现文字围绕浮动元素排列的效果。在段落里浮动图片时,段落的高度并不会增长到能够容纳该图片。也就是说,如果图片比段落文字高,下一段会直接从上一段的文字下面开始,两段文字都会围绕浮动的图片排列。
    

    1.1 理解容器 折叠

    例子中,除了页面标题,其他元素都设置了浮动,所以容器的高度只包含页面标题的高度,浮动的媒体元素则扩展到主元素的白色背景下面。这不是我们想要的,主元素应该向下扩展到灰色的盒子。

    解决的办法是使用跟浮动配套的clear属性。将一个元素放在主容器的末尾,并对它使用clear,这会让容器扩展到浮动元素下面。

     <div style="clear:both"></div>
     <!-- 在main容器的末尾增加一个带有clear属性的空div -->
    

    clear:both声明让该元素移动到浮动元素的下面,而不是侧面。clear的值还可以设置为left或者right,这样只会相应地清除向左或向右浮动的元素。因为空div本身没有浮动,所以容器就会扩展,直到包含它,因此也会包含该div上面的浮动元素。

    但是这种方式不雅。要在HTML里面添加不必要的标记,用纯css方案来实现相同的而效果

    1.2 理解清除浮动

    不用额外的div标签,我们还可以用伪元素来实现。使用::after伪元素选择器,就可以快速地在DOM中在容器尾部添加一个元素,而不用在HTML里添加标记。

    如下所示:

    .clearfix::after { 
        /* 选中容器尾部的伪元素 */
        display: block;
        /* 将伪元素的display设置为非inline,并给定一个content值, */
        /* 以便让为元素出现在文档中, */
        content: " ";
        clear: both;
        /* 让伪元素清除容器的所有浮动 */
    }
    

    请注意,要给包含浮动的元素清除浮动,而不是给别的元素,比如浮动元素本身,或包含浮动元素的后面的兄弟元素。

    这个清除浮动还有个问题没解决:浮动元素的外边距不会折叠到清除浮动容器的外部,非浮动元素的外边距则会正常折叠。比如在前面的页面里,标题“Running tips”紧挨着main元素的顶部,它的外边距在容器外面折叠了。

    一些开发人员跟喜欢使用清除浮动的一个修改版,它能包含所有的外边距。这样更符合预期。使用这个修改版,能防止标题外部的外边距在main元素的外部折叠。

    .clearfix::before,
    .clearfix::after {
        /* 防止伪元素的外边距折叠 */
        display: table;
        content: " ";
    
    }
    .clearfix::after {
        /* 只有after伪元素需要清除浮动 */
        clear: both;
    }
    

    这个版本使用display:table而不是display:block。给::before和::after伪元素都加上这一属性,所有子元素的外边距都会包含在容器的顶部和底部之间。

    清除浮动和display:table
    
    在清除浮动时使用display:table能够包含外边距,是因为利用了CSS的一些特性。创建一个display:table元素,也就是在元素内隐式创建了一个表格行和一个单元格。而且clear属性只能对块级元素生效。表格是块级元素。
    

    1.3 出乎意料的"浮动陷阱"

    页面里面的白色容器已经能够包含浮动的媒体元素了,但是出现了另外一个问题:4个盒子没有如预期那样均匀地占据2行。虽然前2个盒子符合预期,但是第3个盒子出现在了右边,也就是第2个盒子的下面,导致第1个盒子下面出现了一片空白。

    众多的元素浮动到同一侧,如果每个浮动盒子的高度不一样,最后的布局可能 千变万化。同理,改变浏览器的宽度也会造成相同的结果,因为它会导致换行,从而改变元素高度。而我们真正想要的是每行有2个浮动盒子。

    要想修复这个问题很简单:清除第三个浮动元素上面的浮动。更 通用的做法是,清除每行的第一个元素上面的浮动。由于每行有2个盒子,所以只需要清除每行的第奇数个元素上面那行的浮动即可。你可以用:nth-child()伪类选择器来选中这些目标元素。

    .media:nth-child(odd) {
        /* 每个新行清除了上面一行的浮动 */
        clear: left;
    }
    

    接下来给媒体元素加上外边距来拉开距离。

    1.4 BFC

    例子中,每个media块里面,发现它的盒子扩展到了最左边,因为它会包围浮动的 图片。现在文字围绕着图片,但是只要清除了图片底部的浮动,正文就会立刻移动到媒体盒子的左边。而我们真正想要的是将正文的左侧靠着浮动图片的右侧排列。

    为了实现这种布局,需要为正文建立一个块级格式化上下文(BFC)。BFC是网页的一块区域,元素基于这块区域布局。虽然BFC本身是环绕文档流的一部分,但它将内部的内容与外部的上下文 隔离开。这种隔离为创建BFC的元素做出了以下3件事情:

    1. 包含了内部所有元素的上下外边距
    2. 包含了内部所有的浮动元素
    3. 不会跟BFC外面的浮动元素重叠。

    简而言之,BFC里的内容不会跟外部的元素重叠或者相互影响。如果给元素增加clear属性,它只会清除自身所在BFC内的浮动。如果强制给一个元素生成一个新的BFC,他不会跟其他BFC重叠。

    给元素添加以下的任意属性值都会创建BFC.

    float:left或者right,不为none即可。
    overflow:hidden、auto或scroll,不为visible即可。
    display:inline-block、table-cell、table-caption、flex、inline-flex、grid或inline-grid。拥有这些属性的元素称为块级容器。
    position:absolute或position:fixed。
    

    网页的根元素也创建了一个顶级的BFC

    例子中只要给媒体正文创建BFC,网页的布局就会符合预期。通常是给元素设置overflow值-hidden或者auto

    使用overflow:auto通常是创建BFC最简单的一种方式。也可以前面提到的其他方式:但是有些问题需要注意,比如,使用浮动或inline-block方式创建BFC的元素宽度变成100%,因此需要限制一下元素的宽度,防止因为过宽而换行,导致内容移动到浮动图片的下面,相反,使用table-cell方式显示的元素,其宽度只会刚好容纳其中的内容,因此需要设置一个较大的宽度,强制使其填满剩余空间。

    说明:某些情况下,BFC中的内容可能还会与别的BFC的内容重叠。比如,内容溢出了容器或者因为负外边距导致内容被拉到容器下面。

    如下代码,为例子中的代码

    html代码如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link href="./4-1.css" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div class="container">
            <header>
                <h1>Franklin Runnint Club</h1>
            </header>
            <main class="main clearfix">
                <h2>Running tips</h2>
                <div>
                    <div class="media">
                        <img class="media-image" src="./runner.png">
                        <div class="media-body">
                            <h4>Strength</h4>
                            <p>Strenth training is an important part of injury prevention.Focus on your core--especially your abs and glutes.</p>
                        </div>
                       
                    </div>
                    <div class="media">
                        <img class="media-image" src="./shoes.png">
                        <div class="media-body">
                            <h4>Strength</h4>
                            <p>Strenth training is an important part of injury prevention.Focus on your core--especially your abs and
                                glutes.</p>
                        </div>
                    
                    </div>
    
                    <div class="media">
                        <img class="media-image" src="./shoes.png">
                        <div class="media-body">
                            <h4>Strength</h4>
                            <p>Strenth training is an important part of injury prevention.Focus on your core--especially your abs and
                                glutes.</p>
                        </div>
                    
                    </div>
                    <div class="media">
                        <img src="./runner.png">
                        <div>
                            Strength
                            <p>Strenth training is an important part of injury prevention.Focus on your core--especially your abs and
                                glutes.</p>
                        </div>
                    
                    </div>
    
                    <!-- <div style="clear:both"></div>
                   在main容器的末尾增加一个带有clear属性的空div -->
                </div>
            </main>
        </div>
    </body>
    
    </html>
    

    css代码如下:

    :root {
        box-sizing: border-box;
    }
    
    *,
    ::before,
    ::after {
        box-sizing: inherit;
    }
    
    body {
        background-color: #eee;
        font-family: Arial, Helvetica, sans-serif;
    }
    
    body *+* {
        margin-top: 1.5em;
    }
    
    header {
        padding: 1em 1.5em;
        color: #fff;
        background-color: #0072b0;
        border-radius: 0.5em;
        margin-bottom: 1.5em;
        border: 1px solid;
    }
    
    .container {
        max- 1080px;
        margin: 0 auto;
    }
    
    .main {
        background-color: #fff;
        padding: 0 1.5em;
    }
    
    .media {
        background-color: peru;
        float: left;
         calc(50% - 1.5em);
        padding: 1.5em;
        border-radius: 0.5em;
        margin: 0 1.5em 1.5em 0;
    }
    
    .media-image {
        float: left;
        padding-right: 1.5em;
    }
    
    .media-body {
        margin-top: 0;  
        /* 创建一个新的BFC,这样正文就不会跟浮动的图片重叠 */
        overflow: hidden;
    }
    
    .media-body h4{
        margin-top: 0;  
    }
    
    .clearfix::before,
    .clearfix::after {
        /* 防止伪元素的外边距折叠 */
        display: table;
        content: " ";
    
    }
    .clearfix::after {
        /* 只有after伪元素需要清除浮动 */
        clear: both;
    }
    
    .media:nth-child(odd) {
        /* 每个新行清除了上面一行的浮动 */
        clear: left;
    }
    
  • 相关阅读:
    LPT算法--时间调度问题
    Java语法学习1
    用JS动态显示文本
    用JS动态创建一个有序表(根据输入添加子列表项)
    邻接表链式结构的实现和顺序结构的实现
    HDU 1242 特殊化带结构体BFS
    POJ 1562深搜判断连体油田个数
    Uva 8道比较水的数论 (练练英语阅读理解)
    HDU 2024 C语言合法标识符(笑)
    再做POJ2406 KMPnext数组的运用
  • 原文地址:https://www.cnblogs.com/zdjBlog/p/13938195.html
Copyright © 2020-2023  润新知