display:flex 踩坑之旅

1,532 阅读2分钟

自动知道flex布局之后,感觉自己发现了新大陆。比较之前诸如水平居中,垂直居中的需求实现,简直不要太简单。从此走上了flex布局脑残粉的不归路。

入坑的经典案例

第一个使用flex感觉巨爽的是,用它实现一个如下的树状结构图。

不用使用大量的绝对定位,相对定位的属性设置。各种flex基础属性完美实现。对flex越发爱不释手。加上接触的项目对样式要求也不高,出现问题缝缝补补也就将就了。

踩坑

最新的一个项目中,要实现移动端页面开发,为了减少开发量,使用了很多公共组件。延续之前的样式缝补策略,发现牵一发动全身,崩溃掉。决定好好研究下出现问题的原因。

问题1. 元素塌陷:

当内容高度超过页面高度时,出现元素塌陷。

父元素设置了display: flex 后。如果父元素压缩,各子元素按照所占比例进行等比压缩。

1. 正常显示

<!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>Document</title>  
        <style>    
            html,body {      
                height: 100%;    
            }    
            * {      margin: 0;    }    
            #root {      
                display: flex;      
                flex-direction: column;      
                height: 400px;    
            }    
            .status, .navbar, .content {      
                color: aliceblue;      
                text-align: center;    
            }    
            .status {      
                background: blue;      
                height: 50px;    
            }    
            .navbar {      
                background: green;      
                height: 100px;    
            }    
            .content {      
                background: darkmagenta;      
                height: 250px;     
            }  
        </style>
    </head>
    <body>  
        <div id="root">    
            <div class="status"></div>    
            <div class="navbar">NavBar</div>    
            <div class="content">Content</div>  
        </div>
    </body>
</html>

显示效果如下:

2. 父元素高度减少

如果设置#root的高度为200px,子元素等比压缩

#root {
    height: 200px;
}

效果图如下:

3. 父元素压缩到0px或者低于实际内容高度

其显示的高度是所有子元素的有效内容高度。如果其中子元素无实际内容,则不再显示。

#root {
    height: 0px;
}

效果如下:

解决1: 防止元素塌陷

设置不允许塌陷的子元素如下:

#root{
    height: 0;
}
.navbar, .status {
   flex-shrink: 0;
}

效果如下:

问题2: 单个子元素靠右

子元素设置:

{
   margin-left: auto;
}

<!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>Document</title>  
            <style>    
                #root {      
                    display: flex;      
                    flex-direction: row;    
                }    
                .status {      
                    background: blue;      
                    width: 50px;      
                    height: 50px;      
                    margin-left: auto;    
                }  
            </style>
        </head>
        <body>  
            <div id="root">    
                <div class="status"></div>  
            </div>
        </body>    
</html>

效果如下: