常见布局和页面结构技巧

常见布局和页面结构技巧

Posted by SkioFox on May 30, 2017

响应式布局

开发响应式网站有两个选择原则:渐进增强(progressive enhancement)和优雅降级(graceful degradation)。

  1. meta标签

移动端布局的标配meta,正确了处理了视口宽度与设备宽度的问题以及页面大小。

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

  1. 媒体查询

    avatar

    • 通过link标签引用不同的css(and、not、only关键字)
     <!-- 当页页宽度小于或等于375px,就调用solution_schoolNet.css样式表来渲染页面。 -->
     <link rel="stylesheet" media="screen and (max-width: 375px)" href="solution_schoolNet.css" />
     <!-- 当页页宽度大于或等于900px,就调用solution_schoolNet.css样式表来渲染页面。 -->
     <link rel="stylesheet" media="screen and (min-width:900px)" href="solution_smartCampus.css"/>
     <!-- 当页页宽度在414px和736px之间时,就调用solution_wifi.css样式表来渲染页面。 -->
     <link rel="stylesheet" media="screen and (min-width:414px) and (max-width:736px)" href="solution_wifi.css"/>
     <!-- 设备屏幕的输出宽度Device Width,这里的max-device-width所指的是设备的实际分辨率 -->
     <link rel="stylesheet" media="screen and (max-device-width: 480px)" href="iphone.css" type="text/css" />
     <!-- not关键字是用来排除某种制定的媒体类型,换句话来说就是用于排除符合表达式的设备。 -->
     <link rel="stylesheet" media="not print and (max-width: 1200px)" href="print.css" type="text/css" />
     <!-- only用来定某种特定的媒体类型,可以用来排除不支持媒体查询的浏览器。 -->
     <link rel="stylesheet" media="only screen and (max-device-width:240px)" href="android240.css" type="text/css" />
    
    • 在css中使用media,如下是一些使用示例
     @media screen and(min-width: 320px)and(max-width: 359px){ 
         html{ 
             font-size: 12.8px; 
         } 
     } 
     @media screen and(min-width: 360px)and(max-width: 374px){ 
         html{ 
             font-size: 14.4px; 
         } 
     } 
     @media screen and(min-width: 375px)and(max-width: 385px){ 
         html{ 
             font-size: 15px; 
         } 
     } 
     @media screen and(min-width: 386px)and(max-width: 392px) { 
         html { 
             font-size: 15.44px; 
         } 
     } 
     @media screen and(min-width: 393px)and(max-width: 400px){ 
         html{ 
             font-size: 16px; 
         } 
     } 
     @media screen and(min-width: 401px)and(max-width: 414px){ 
         html{ 
             font-size: 16.48px; 
         } 
     } 
     @media screen and(min-width: 750px)and(max-width: 799px){ 
         html{ 
             font-size: 30.72px; 
         } 
     } 
    
     @media screen and (orientation: portrait) {
         /*竖屏 css*/
     } 
     @media screen and (orientation: landscape) {
         /*横屏 css*/
     }
     @media screen and (min-width:1366px){
         /*pc端 css*/
     }
        
     /*iphone 5/5s/5se */
     @media screen and (max-width:569px){
         top: 7%;
         left: 18%;
     }
     /*iphone 6/7/8 */
     @media screen and (min-width:569px) and (max-width:668px){
         top: 12%;
         left: 20%;
     }
     /*iphone 6p/7p/8p */
     @media screen and (min-width:668px) and (max-width:737px){
         top: 14%;
         left: 20%;
     }
     /*iphone x */
     @media screen and (min-width:737px) and (max-width:813px){
         top: 12%;
         left: 21%;
     }
     /*ipad*/
     @media screen and (min-width:813px) and (max-width:1025px){
         top: 22%;
         left: 21%;
     }
     /*ipad pro*/
     @media screen and (min-width:1024px){
         top: 25%;
         left: 21%;
     }
    
    
     /* 超小屏幕(手机,小于 768px) */
     @media only screen and (max-width: 768px) { ... }
        
     /* 小屏幕(平板,大于等于 768px) */
     @media only screen and (min-width: 768px) and (max-width: 768px) { ... }
        
     /* 中等屏幕(桌面显示器,大于等于 992px) */
     @media only screen and (min-width: 992px) and (max-width: 992px) { ... }
        
     /* 大屏幕(大桌面显示器,大于等于 1200px) */
     @media only screen and (min-width: 1200px) { ... }
    
    • 常用媒体查询属性

      avatar

    • 响应式轮播图和图片

      • 轮播图有很多插件可以支持如owl.carousel
      • 图片响应式
        • 根据设备大小加载不同的图片
          • js或者服务器

            判断设备大小加载对应图片=>监听window的resize和load事件,加载不同的图片。通过cookie传递设备信息,服务器端传回对应图片。

          • srcset(会综合考虑图片和dpr去选择图片)

                  <img class="image" src="img/480.png" srcset="img/480.png 480w, img/800.png 800w, img/1600.png 1600w">
                  <!-- 当父元素的宽度不是100%,这时的图片加载就会出现问题 如设置父元素50% -->
            
          • srcset配合sizes

                  <img class="image" src="img/480.png" srcset="img/480.png 480w, img/800.png 800w, img/1600.png 1600w" sizes="100vw">
                  <!-- sizes就是为了解决上诉问题 100vw代表图片的尺寸就是100%视口(viewport)的宽度 父元素设置width:50%,设置sizes="50vw" -->
                  <!-- 当图片宽度需要条件变化时,sizes="(min-width:800px), 100vw" sizes也可以根据条件变化,表示大于800图片是800px的尺寸,小于800时撑满饰扣宽度-->
            
          • picture

                  <picture>
                      <source media="(max-width:36rem)" srcset="img/test1.jpg 768w"/>
                      <!-- 宽度大于35rem加载 -->
                      <!-- <source srcset="img/test2.jpg 1440w"/> -->
                      <!-- 横屏 -->
                      <source media="(orientation: landscape)" srcset="img/test1.jpg 768w"/>
                      <!-- 默认 -->
                      <img class="image" src="img/test.jpg" />
                  </picture>
            
          • svg矢量图
        • 依据media加载背景图片适配分辨率

                // 背景图片
                bg-image($url)
                    background-image: url($url + "@2x.png")
                    @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3)
                        background-image: url($url + "@3x.png")
          
    • 表格的响应式布局处理方式(尤其是很多列的表格)
      • 隐藏表格中不重要的列
      • 将横向的表格变为纵向的表格(行列转置)
      • 将表格的每一项作为表单的格式展示(每一项展开,左边是列名,右边是值)
    • 横竖排列切换
         <div class="content">
             <div class="inner"></div>
             <div class="inner"></div>
             <div class="inner"></div>
             <div class="inner"></div>
             <div class="inner"></div>
         </div>
    
         .content {
             width:100%;
             height:200px;
             background:yellow;
         }
         .inner:nth-child(1){
             background: blue
         }
         .inner:nth-child(2){
             background: red
         }
         .inner:nth-child(3){
             background: green
         }
         .inner:nth-child(4){
             background: black
         }
    
         @media screen and (max-width: 320px) {
             .inner {
                 width: 25%;
                 height: 100%;
                 float: left;
             }
         }
         @media screen and (min-width: 321px) {
             .inner {
                 width: 100%;
                 height: 100px;
             }
         }
    

    react-responsive结合react和media可以做pc端和移动端适配的网站

  2. 圣杯布局

    圣杯布局(Holy Grail Layout)指的是一种最常见的网站布局。页面从上到下,分成三个部分:头部(header),躯干(body),尾部(footer)。其中躯干又水平分成三栏,从左到右为:导航、主栏、副栏。

  • 方案一(flex布局) ```html
...
...
...
```css
.HolyGrail {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

header,
footer {
  flex: 1;
}

.HolyGrail-body {
  display: flex;
  flex: 1;
}

.HolyGrail-content {
  flex: 1;
}

.HolyGrail-nav, .HolyGrail-ads {
  /* 两个边栏的宽度设为12em */
  flex: 0 0 12em;
}

.HolyGrail-nav {
  /* 导航放到最左边 */
  order: -1;
}
  • 方案二(float布局:margin为负值 , position: relative定位)

    主体部分是由container包裹的center,left,right三列,其中center定义在最前面。

<div id="header"></div>
<div id="container">
  <div id="center" class="column"></div>
  <div id="left" class="column"></div>
  <div id="right" class="column"></div>
</div>
<div id="footer"></div>
body {
    /* 必需的页面最小宽度200+150+200=550px */
  min-width: 550px;
}

#container {
  padding-left: 200px; 
  padding-right: 150px;
}

#container .column {
  float: left;
}

#center {
    /* 自适应关键 */
  width: 100%;
}

#left {
  width: 200px; 
  /* 将浮动的left挤到center同一行的前面 */
  margin-left: -100%;
    /* 定位 */
  position: relative;
  right: 200px;
}

#right {
  width: 150px; 
  margin-right: -150px; 
}

#footer {
  clear: both;
}
  1. 双飞翼(双飞布局)

    双飞翼布局和圣杯布局一样,都是实现的三栏布局,两边的盒子宽度固定,中间盒子自适应。中间部分在DOM结构上优先,以便先行渲染。

    双飞翼布局的DOM结构与圣杯布局的区别是用container仅包裹住center。

<body>
  <div id="header"></div>
  <div id="container" class="column">
    <div id="center"></div>
  </div>
  <div id="left" class="column"></div>
  <div id="right" class="column"></div>
  <div id="footer"></div>
<body>
body {
    /* 双飞翼布局没有用到position:relative进行定位,所以最小页面宽度应该为200+150=350px 但是当页面宽度缩小到350px附近时,会挤占中间栏的宽度,使得其内容被右侧栏覆盖.因此在设置最小页面宽度时,应该适当增加一些宽度以供中间栏使用(假设为150px)*/
  min-width: 500px;
}

#container {
  width: 100%;
}

.column {
  float: left;
}
        
#center {
  margin-left: 200px;
  margin-right: 150px;
}
        
#left {
  width: 200px; 
  margin-left: -100%;
}
        
#right {
  width: 150px; 
  margin-left: -150px;
}
        
#footer {
  clear: both;
}
  1. 使用calc()方式实现中间自适应且去掉多使用的div ```html
```css
.column {
  float: left;
}
    
#center {
  margin-left: 200px;
  margin-right: 150px;
  width: calc(100% - 350px);
}
  1. 使用border-box式实现中间自适应且去掉多使用的div的三栏布局
.column {
  float: left;
}
    
#center {
  padding-left: 200px;
  padding-right: 150px;
  box-sizing: border-box;
  width: 100%;
}
  1. flex方式实现上述布局
#container {
    display: flex;
}

#center {
    flex: 1;
}

#left {
    flex: 0 0 200px;
    order: -1;
}

#right {
    flex: 0 0 150px;
}
  1. 布局总结

六种布局方式总结:圣杯布局、双飞翼布局、Flex布局、绝对定位布局、表格布局、网格布局。

圣杯布局是指布局从上到下分为header、container、footer,然后container部分定为三栏布局。这种布局方式同样分为header、container、footer。圣杯布局的缺陷在于center是在container的padding中的,因此宽度小的时候会出现混乱。

双飞翼布局给center 部分包裹了一个 container通过设置margin主动地把页面撑开。

Flex布局是由CSS3提供的一种方便的布局方式。

绝对定位布局是给container设置position: relative和overflow: hidden,因为绝对定位的元素的参照物为第一个postion不为static的祖先元素。 left向左浮动,right向右浮动。center使用绝对定位,通过设置left和right并把两边撑开。 center 设置top: 0和bottom: 0使其高度撑开。

表格布局的好处是能使三栏的高度统一。

网格布局可能是最强大的布局方式了,使用起来极其方便,但目前而言,兼容性并不好。网格布局,可以将页面分割成多个区域,或者用来定义内部元素的大小,位置,图层关系。

  1. 补充:两列等高布局

为了实现两列等高,可以给每列加上 padding-bottom:9999px;margin-bottom:-9999px;同时父元素设置overflow:hidden;

  1. 常见兼容处理方式(browserhacks/polifill)