2018 年已经过了一周,总结一下 2017 年在公司 wiki 上写的一篇关于 css 布局的知识,当时也借鉴了几个大神写的 css 布局知识,和自己在项目中遇到的坑。废话不多说。请看以下的干货。
大屏展示:
小屏展示:
实现过程中需要注意的是:
- <style type="text/css">
- .left{
- float: left;
- width: 100%;
- height: 200px;
- background-color: red;
- }
- .left-content{
- margin-left: 30%;
- }
- .right{
- float: left;
- width: 30%;
- margin-left: -100%;
- height: 200px;
- background-color: green;
- }
- .layout0{
- clear: both;
- width: 100px;
- height: 100px;
- background-color: yellow;
- }
- </style>
- <body>
- <div id="body">
- <div class="left">
- <div class="left-content">
- 设置子元素的margin,然后父元素必须浮动。
- 用父元素包裹,主要是因为right会覆盖left,从而导致left内容不可以看到,如果直接在left上设置margin或者padding会导致布局变化,因此只能再用一个div包裹内容,并且去除right覆盖的宽度。
- </div>
- </div>
- <div class="right">-margin必须大于或等于自身的宽度才会上移</div>
- <div class="layout0"></div>
- </div>
- </body>
1. 自适应的容器需要容器包裹住,否则容器内的内容会被覆盖。
2. right 容器的负边距必须大于或等于自身的宽度才会上移。
3. 如果 right 容器负边距等于自身的宽度它会靠右对齐,如果负边距等于 - 100%,则会靠左对齐。
- <style type="text/css">
- .left{
- float: left;
- width: 200px;
- height: 200px;
- background-color: yellow;
- }
- .right{
- padding-left: 200px;
- height: 200px;
- background-color: red;
- }
- @media (min-width: 650px) and (max-width: 1000px){
- .left{
- width: 150px;
- }
- .right{
- margin-left: 150px;
- }
- }
- @media (max-width: 640px){
- .left{
- width: 100px;
- }
- .right{
- margin-left: 100px;
- }
- }
- </style>
- <body>
- <div id="main">
- <div class="left">左边固定宽度,右边自适应</div>
- <div class="right"></div>
- </div>
- </body>
实现过程中需要注意的是: 1. left 需要脱离文档流,而 right 只需要正常显示就可以。
2. left 只是覆盖在 right 上边,因此想要让 right 内容完整显示需要给 right padding-left 或者 margin-left。
大屏展示:
小屏展示:
实现过程中需要注意:
- <style type="text/css">
- #head{
- height: 200px;
- background-color: yellow;
- }
- #body{
- width: 100%;
- float: left;
- }
- .main{
- background-color: green;
- min-height: 200px;
- margin: 0 210px;
- }
- .left{
- float: left;
- background-color: red;
- width: 200px;
- height: 200px;
- margin-left: -100%;
- }
- .right{
- float: right;
- background-color: blue;
- width: 200px;
- height: 200px;
- margin-left: -200px;
- }
- #footer{
- clear: both;
- height: 200px;
- background-color: orange;
- }
- </style>
- <body>
- <div id="head">即左右固定,中间自适应,它可以利用margin-left为负数来实现,它的实现原理就是margin为负值可以改变float元素的排列位置</div>
- <div id="body">
- <div class="main">当多个元素同时从标准流中脱离开来时,如果前一个元素的宽度为100%宽度,后面的元素通过负边距可以实现上移。当负的边距超过自身的宽度将上移,只要没有超过自身宽度就不会上移</div>
- </div>
- <div class="left"></div>
- <div class="right"></div>
- <div id="footer"></div>
- </body>
1. 中间自适应的 div 需要放在 left 和 right 容器前面并且内容 div 需要用父容器包裹
2. left 和 right 容器向同一个方向浮动。
实现过程中需要注意:
- <style type="text/css">
- #head{
- height: 200px;
- background-color: yellow;
- }
- #body{
- overflow: hidden;
- }
- .left{
- float: left;
- background-color: red;
- width: 200px;
- height: 200px;
- }
- .right{
- float: right;
- background-color: blue;
- width: 200px;
- height: 200px;
- }
- .main{
- background-color: green;
- height: 200px;
- margin: 0 210px;
- }
- #footer{
- clear: both;
- height: 200px;
- background-color: orange;
- }
- </style>
- <body>
- <div id="head">左右固定宽度并且向两边浮动,中间的div设置两边的margin</div>
- <div id="body">
- <div class="left"></div>
- <div class="right"></div>
- <div class="main">该方案有一个缺陷,在小屏幕情况下回导致right被挤下去,main没有了</div>
- </div>
- <div id="footer"></div>
- </body>
1. 该方式只需要注意中间自适应的 div 需要放在 left 和 right 容器的后面。
2. left 和 right 容器向两边浮动。
- <!DOCTYPE html>
- <html>
- <meta charset="utf-8">
- <head>
- <title>使用flex 实现"双飞翼布局"</title>
- </head>
- <style type="text/css">
- #main{
- display: flex;
- display: -webkit-flex;//谷歌浏览器加前缀
- flex-flow: row nowrap;
- justify-content: flex-start;
- align-items: center;
- }
- .left{
- flex: 0 0 auto;
- width:100px;
- height: 200px;
- background-color: red;
- word-wrap: break-word;
- overflow: hidden;
- }
- .main{
- flex: 1 1 auto;
- height: 200px;
- background-color: green;
- }
- .right{
- flex: 0 0 auto;
- width: 100px;
- height: 200px;
- background-color: yellow;
- }
- </style>
- <body>
- <div id="main">
- <div class="left">flex 语法我参照了阮一峰关于flex语法介绍 http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html</div>
- <div class="main"></div>
- <div class="right"></div>
- </div>
- </body>
- </html>
如果未了解过 flex 布局请移至文末点击链接查看 阮一峰大神写的关于 flex 语法
这边就不絮絮叨叨的讲一些基础的 css 定位知识了(ps: 不会的请自行到 w3c 官网查阅),我主要来讲解一下工作中遇到的坑。以免其他人和我一样掉入坑中。
在上图中我可以发现中间黑色的小框是基于父级来定位,并且宽度也基于父容器的 50%。详细的请看下面代码:
- <!DOCTYPE html>
- <html>
- <head>
- <title>关于position的定位的坑</title>
- </head>
- <style type="text/css">
- body{
- margin: 0;
- padding: 0;
- }
- i{
- font-style: normal;
- cursor: pointer;
- }
- #delete-button{
- position: absolute;
- left: 45%;
- top: 45%;
- text-align: center;
- vertical-align: middle;
- height: 50px;
- margin: auto;
- cursor: pointer;
- }
- #delete-button > i{
- display: inline-block;
- width: 32px;
- height: 32px;
- border-radius: 16px;
- background-color: orange;
- color: red;
- font-size: 32px;
- vertical-align: middle;
- line-height: 28px;
- }
- /*第一个模态框的样式*/
- #layout{
- display: none;
- width: 100%;
- height: 100%;
- }
- /*使用flex布局水平竖直居中*/
- /*#layout-box{
- position: fixed;
- width: 100%;
- height: 100%;
- left: 0;
- top: 0;
- display: flex;
- display: -webkit-flex;
- flex-flow: column nowrap;
- justify-content: center;
- align-items: center;
- background-color: rgba(0,0,0,0.3);
- }*/
- /*使用postion 和 transform 水平垂直居中*/
- #layout-box{
- position: fixed;
- width: 100%;
- height: 100%;
- background-color: rgba(0,0,0,0.3);
- }
- .modal-dialog{
- position: absolute;
- left: 50%;
- top: 50%;
- width: 500px;
- height: 200px;
- border-radius: 10px;
- transform: translate(-50%, -50%);
- -webkit-transform: translate(-50%, -50%);
- -moz-transform: translate(-50%, -50%);
- -o-transform: translate(-50%, -50%);
- background-color: #fff;
- }
- .dialog-title{
- text-align: center;
- color: #333;
- font-size: 28px;
- margin-bottom: 10px;
- }
- .dialog-content{
- text-align: center;
- color: #666;
- font-size: 18px;
- }
- .dialog-button{
- margin-top: 20px;
- width: 100%;
- color: #333;
- }
- .dialog-button >.button-box{
- display: inline-block;
- width: 48%;
- text-align: center;
- }
- .button-box span{
- display: inline-block;
- padding: 10px;
- color: #fff;
- border-radius: 6px;
- cursor: pointer;
- }
- #confirm{
- background-color: #27ad9a;
- }
- #cancel{
- background-color: red;
- }
- /*添加按钮的样式*/
- #add-button > i{
- display: inline-block;
- width: 32px;
- height: 32px;
- border-radius: 16px;
- background-color: #27ad9a;
- color: #fff;
- font-size: 32px;
- vertical-align: middle;
- line-height: 28px;
- text-align: center;
- }
- #add-button{
- display: inline-block;
- cursor: pointer;
- }
- /*第二个模态框的样式*/
- .layout2{
- display: none;
- position: fixed;
- width: 100%;
- height: 100%;
- left: 0;
- top: 0;
- background-color: rgba(0,0,0,0.2);
- }
- .modal-dialog2{
- position: fixed;
- left: 50%;
- top: 50%;
- width: 50%;
- height: 50%;
- border-radius: 10px;
- transform: translate(-50%, -50%);
- -webkit-transform: translate(-50%, -50%);
- -moz-transform: translate(-50%, -50%);
- -o-transform: translate(-50%, -50%);
- background-color: rgba(0,0,0,0.2);
- }
- .modal-dialog2 > span{
- display: block;
- }
- .modal-text{
- float: left;
- }
- #close{
- color: red;
- font-size: 24px;
- float: right;
- cursor: pointer;
- }
- </style>
- <body>
- <div id="delete-button"><i>-</i>删除</div>
- <div id="layout">
- <div id="layout-box">
- <div class="modal-dialog">
- <div class="dialog-title">提示</div>
- <div class="dialog-content">是否删除该项,点击确定</div>
- <div class="dialog-button">
- <div class="button-box">
- <span id="confirm">确定</span>
- </div>
- <div class="button-box">
- <span id="cancel">取消</span>
- </div>
- </div>
- <div id="add-button"><i>+</i>添加</div>
- <div class="layout2">
- <div class="modal-dialog2">
- <span class="modal-text">你是我的小可爱</span>
- <span id="close">关闭</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </body>
- <script type="text/javascript">
- document.getElementById("delete-button").onclick= function(){
- var layout = document.getElementById("layout")
- layout.style.display = "block"
- }
- document.getElementById("confirm").onclick=function(){
- var layout = document.getElementById("layout")
- layout.style.display = "none"
- }
- document.getElementById("cancel").onclick=function(){
- var layout = document.getElementById("layout")
- layout.style.display = "none"
- }
- document.getElementById("add-button").onclick=function(){
- var layout = document.getElementsByClassName("layout2")
- layout[0].style.display = "block"
- }
- document.getElementById("close").onclick=function(){
- var layout = document.getElementsByClassName("layout2")
- layout[0].style.display = "none"
- }
- </script>
- </html>
如果我们尝试把父容器上的 transform 属性去除,我们可以看到 子容器没有基于父容器定位,而是基于 body 定位的,宽度也是基于 body 给的 50% 宽度。效果图如下:
详细请看代码:
- <!DOCTYPE html>
- <html>
- <head>
- <title>关于position的定位的坑</title>
- </head>
- <style type="text/css">
- body{
- margin: 0;
- padding: 0;
- }
- i{
- font-style: normal;
- cursor: pointer;
- }
- #delete-button{
- position: absolute;
- left: 45%;
- top: 45%;
- text-align: center;
- vertical-align: middle;
- height: 50px;
- margin: auto;
- cursor: pointer;
- }
- #delete-button > i{
- display: inline-block;
- width: 32px;
- height: 32px;
- border-radius: 16px;
- background-color: orange;
- color: red;
- font-size: 32px;
- vertical-align: middle;
- line-height: 28px;
- }
- /*第一个模态框的样式*/
- #layout{
- display: none;
- width: 100%;
- height: 100%;
- }
- /*使用flex布局水平竖直居中*/
- #layout-box{
- position: fixed;
- width: 100%;
- height: 100%;
- left: 0;
- top: 0;
- display: flex;
- display: -webkit-flex;
- flex-flow: column nowrap;
- justify-content: center;
- align-items: center;
- background-color: rgba(0,0,0,0.3);
- }
- /*使用postion 和 transform 水平垂直居中*/
- .modal-dialog{
- width: 500px;
- height: 200px;
- border-radius: 10px;
- background-color: #fff;
- }
- .dialog-title{
- text-align: center;
- color: #333;
- font-size: 28px;
- margin-bottom: 10px;
- }
- .dialog-content{
- text-align: center;
- color: #666;
- font-size: 18px;
- }
- .dialog-button{
- margin-top: 20px;
- width: 100%;
- color: #333;
- }
- .dialog-button >.button-box{
- display: inline-block;
- width: 48%;
- text-align: center;
- }
- .button-box span{
- display: inline-block;
- padding: 10px;
- color: #fff;
- border-radius: 6px;
- cursor: pointer;
- }
- #confirm{
- background-color: #27ad9a;
- }
- #cancel{
- background-color: red;
- }
- /*添加按钮的样式*/
- #add-button > i{
- display: inline-block;
- width: 32px;
- height: 32px;
- border-radius: 16px;
- background-color: #27ad9a;
- color: #fff;
- font-size: 32px;
- vertical-align: middle;
- line-height: 28px;
- text-align: center;
- }
- #add-button{
- display: inline-block;
- cursor: pointer;
- }
- /*第二个模态框的样式*/
- .layout2{
- display: none;
- position: fixed;
- width: 100%;
- height: 100%;
- left: 0;
- top: 0;
- background-color: rgba(0,0,0,0.2);
- }
- .modal-dialog2{
- position: fixed;
- left: 50%;
- top: 50%;
- width: 50%;
- height: 50%;
- border-radius: 10px;
- transform: translate(-50%, -50%);
- -webkit-transform: translate(-50%, -50%);
- -moz-transform: translate(-50%, -50%);
- -o-transform: translate(-50%, -50%);
- background-color: rgba(0,0,0,0.2);
- }
- .modal-dialog2 > span{
- display: block;
- }
- .modal-text{
- float: left;
- }
- #close{
- color: red;
- font-size: 24px;
- float: right;
- cursor: pointer;
- }
- </style>
- <body>
- <div id="delete-button"><i>-</i>删除</div>
- <div id="layout">
- <div id="layout-box">
- <div class="modal-dialog">
- <div class="dialog-title">提示</div>
- <div class="dialog-content">是否删除该项,点击确定</div>
- <div class="dialog-button">
- <div class="button-box">
- <span id="confirm">确定</span>
- </div>
- <div class="button-box">
- <span id="cancel">取消</span>
- </div>
- </div>
- <div id="add-button"><i>+</i>添加</div>
- <div class="layout2">
- <div class="modal-dialog2">
- <span class="modal-text">你是我的小可爱</span>
- <span id="close">关闭</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </body>
- <script type="text/javascript">
- document.getElementById("delete-button").onclick= function(){
- var layout = document.getElementById("layout")
- layout.style.display = "block"
- }
- document.getElementById("confirm").onclick=function(){
- var layout = document.getElementById("layout")
- layout.style.display = "none"
- }
- document.getElementById("cancel").onclick=function(){
- var layout = document.getElementById("layout")
- layout.style.display = "none"
- }
- document.getElementById("add-button").onclick=function(){
- var layout = document.getElementsByClassName("layout2")
- layout[0].style.display = "block"
- }
- document.getElementById("close").onclick=function(){
- var layout = document.getElementsByClassName("layout2")
- layout[0].style.display = "none"
- }
- </script>
- </html>
** 一、** 在 webkit 内核浏览器中 给 fixed 加上防抖样式 - webkit - transform: translateZ(0);
** 二、** 设置 html 和 body 的 css {height:100%;overflow:auto;margin:0;} 这个影响全局样式不建议使用。
三、 在 fiexd 内设置 position:absolute,如下:
- <div style="position:fiexd;bottom:0px;">
- <div style="position:absolute;">
- </div>
- </div>
主要在 css 文件中写入
- @media screen and (max-width:600px){
- 写入当屏幕小于或等于600px时的样式
- }
- @media screen and (min-width:900px){
- 写入当屏幕大于或等于900px时的样式
- }
- @media screen and (min-width:600px) and (max-width:900px){
- 写入当屏幕在600px-900px之间的样式
- }
- @media screen and (max-device-width: 480px){
- 写入最大设备宽度为480px,比如说iPhone上的显示,这里的max-device-width所指的是设备的实际分辨率,也就是指可视面积分辨率
- }
- @media only screen and (-webkit-min-device-pixel-ratio: 2){
- 写入专门针对iPhone4的移动设备样式
- }
- @media all and (orientation:portrait){
- 写入设备在纵向时的样式
- }
- @media all and (orientation:landscape){
- 写入设备在横向时的样式
- }
- @media not print and (max-width: 1200px){
- not是用来排除某种制定的媒体类型
- 写入在除打印设备和设备宽度小于1200px下的所有设备的样式
- }
- @media only screen and (max-device-width:240px){
- only用来定某种特定的媒体类型,可以用来排除不支持媒体查询的浏览器。
- 写入只能在最大设备宽度为240px的屏幕下使用的样式
- }
CSS 黑魔法小技巧,让你少写不必要的 JS,代码更优雅 实用的 60 个 CSS 代码片段 解决 CSS position:fixed 抖动问题 介绍了各手机的像素密度_(-webkit-min-device-pixel-ratio)_响应式布局
张鑫旭关于设备像素比 devicePixelRatio 简单介绍 CSS3-- 媒体查询 @media起初我并不注重 css 学习,但项目中每张页面都要做响应式,所以为了自己少写 css 代码,提高工作效率,并减少冗余 css,我不得不好好了解 css 布局,来应对各种 UI 图纸和响应式。同时写这篇文章,也希望各位,不要再去踩相同的坑。初次写文章,如若文中有什么不对的地方,还望指正,谢谢各位看官大佬们。
来源: https://juejin.im/post/5a260aaa6fb9a0451b0464f0