响应式设计学习笔记

在响应式设计中,浏览器并不是根据物理硬件的像素宽度而工作的,而是根据DIPs宽度工作,DIPs全称为“Device Independent Pixels”,DIP也是一种计量单位,该值将像素值与实际距离联系起来,dip的值表示的是屏幕上同样大小的空间,即比如两个手机的2dip,这个值不管设备的像素密度是多少,显示的大小都是一样。

但其中有一个转换的比值叫DPR(Device Pixels Ratio),可以通过浏览器的window.devicePixelRatio属性查询到。比如其Chrome book的DPR为2,而chrome book的硬件像素为2560,那么实际Dpis为1280。

从上面的内容得知,视窗宽度(即css像素值)是由下列公式组成:
\frac{实际像素(物理像素)}{像素比}
可以通过设置视窗的值来让浏览器知道我们的意图,比如下面的代码:

  <meta  name="viewport"  content="width=device-width,initial-scale=1">  

其中,name的值为viewport,即告诉浏览器设置视窗,其content中的内容则是设置视窗的值,其中有两个值:

  1. 第一个值”content=width=device”的意思是告诉浏览器将视窗的大小设置为设备的宽度,这样就能够让该页面匹配不同屏幕尺寸
  2. 第二个值”initial-scale=1″的意思是添加初始化缩放比例属性,即告诉浏览器相对像素与css像素的比例为1:1,这样的好处在于,如果不设置该缩放的值,有可能设备在变化横置或者纵置的时候,还是保持之前的大小,以及在缩放的时候也无法自动调整布局。

因为在不同设备上的css像素取值多种多样,所以不能只用视窗宽度属性就能解决所有的显示问题,因为过大的css宽度或者绝对定位,会让元素太大不适应屏幕,而这个时候就得使用相对单位,因为所有的相对单位都是属于基于某个元素。

css允许其元素溢出其容器,如果设置的大小超过了其容器的大小,就会溢出,如果在其他小于设置大小的屏幕上浏览的时候,就会产生左右滑动的溢出,所以设置相对单位就可以保证其元素小于其容器。

需要注意的是:css选项中max-width(height)会覆盖其单独设置的height和width的值。

正常的手指为10mm,大约等于40个css像素,所以在考虑设置按钮像素的时候可以设置为48*48px,而最好保持按钮和按钮之间有大概40px的间隔,以保证不会触发误按。

而在设计响应式的时候尽量做到不用直接用height和width值,因为他们是固定值,所以应该尽量用max和min设置大小。

设计响应式的页面的时候应该是从小到大的设备进行设计,因为这样可以考虑到在小屏幕下,会仔细的考虑哪些信息的重要性,而从大到小,可能会漏掉很多的关键信息,还有可能就是,从小到大的时候,做到中间尺寸的设备的时候,你可能也就不需要更大尺寸的设备了。并且有部分老的设备是不支持媒体查询的,所以从小到大,会有很多优势。

单位em是一个相对单位,常见用于设置内间距,比如按钮或者a标签内的文字,比如下面的这段代码,就代表了相对于当前a标签的字体的1.5倍间距,而第二个值inherit则表示继承自父组件,意思就是上下由我们定义为字体大小的1.5倍,而左右的内间距属性则继承父级。

  footer a {   padding: 1.5em;  }  

除此之外,只是使用视窗设置和相对单位,会造成由于小屏幕看着很好的页面,而到大页面的时候会造成损失,比如图片过于拉伸,页面内容显示单一等问题,这个时候就需要采用媒体查询,媒体查询的作用是可以让我们用一些简单的逻辑来选择性的加载css文件,比如下面的代码设置了屏幕尺寸大于500的css像素才加载该css。

  <link  rel="stylesheet" media="screen and (min-width:500px)"  href="/css/master.css">  

另外,还有两种媒体查询的方式,分别为css文件内部查询,以及css文件内部导入查询,不论在什么情况下,应该尽量避免使用css文件内部导入查询,下面的代码分别为css内部查询和css内部导入查询:

/*内部查询*/
@media screen and (min-width: 500px) {
    body {
        background-color: green;
    }
}

/*内部导入查询*/
@import url("no.css") only screen and (min-width: 500px);

第二种导入的方式是因为首先需要加载css,然后再去查询是否满足要求,如果满足还要再加载另外一个css,这个时候性能非常浪费,除此之外import的优先级是非常高的,所以应该避免。

之外,css链接媒体查询和@media查询之间也需要衡量使用哪一种,因为这两种方式各有千秋,比如css链接查询会造成增加多余的小文件,而@media的方式则会增加css文件的大小,并且改变页面布局的点,一般称为断点。

最常用的媒体查询条件为max-width和min-width,另外还有其他的一部分人使用的是max-device-width和min-device-width,但这样是极其不推荐的,因为min(max)-width是基于浏览器窗口大小,而min(max)-device-width是基于设备可视区域的大小。

Flexbox响应式布局

flexbox是一种响应式布局,该布局能够自动填充空白区域,如果一个元素周围出现了空白它会自动填补上,而如果空间变得拥挤,它会缩小占据最小空间,好处在于当我们设置了一个容器的宽度为固定宽度的时候,如果这个容器溢出了,那么这个时候flex会自动换行。

Flexbox布局需要将父组件的display设置为flex,并且设置flex-wrap属性为wrap,这个时候而里面的组件将自动进行flexbox布局。其中display为布局设置,这里设置为flex,而flex-wrap则是设置在flex布局下,如果容器溢出,将以多行显示还是以单行显示,这里选择的wrap则为多行显示。

Flexbox布局的自动换行是按照顺序进行的,但是有一个属性order可以设置换行的顺序,这样我们就可以结合媒体查询来达到将一些重要的信息展示在最前面,不重要的放在后面,而不用我们手动调整,比如下面的代码,当页面大于600px的时候,将class属性为green的盒子提前到第一行。

该图为原本的顺序:

img

设置了以下的代码以及将大小扩大到大于600px的顺序:

  @media screen and (min-width: 600px) {
      .light {
          order: 3;
      }

      .dark {
          order: 2;
      }

      .green {
          order: 1;
      }
  }

img

响应式网页设计

响应式网页大致分为四种模式,并且都是基于Flexbox实现的,这四种分别为:

  1. 大体流动型模型
  2. 掉落列模型
  3. 活动布局模型
  4. 画布溢出模型

掉落列模型:该模型是四种当中最简单的一种,拿下面的布局图片来说,其在最小宽度的时候,将每个元素都纵向堆放,一个一个纵向排列,随着宽度变大,在第一个断点的时候将两列显示在一排,然后再单独显示一排。当达到了第二个断点的时候,这三个元素会重排列为一个一行三列的布局。如果在进行加大宽度而元素将达到最大宽度,这个时候将添加两侧的外边距。

img

其实现的html代码为:

    <div class="container">
        <div class="box  dark_blue"></div>
        <div class="box  light_blue"></div>
        <div class="box  green"></div>
    </div>

css代码为:

  .container {
      display: flex;
      flex-wrap: wrap;
  }

  … @media screen and (min-width: 450px) {
      .light_blue {
          width: 75%;
      }

      .dark_blue {
          width: 25%;
      }
  }

  @media screen and (min-width: 550px) {

      .light_blue,
      .green {
          width: 25%;
      }

      .dark_blue {
          width: 50%;
      }
  }

大体流动型模型:大体流动型模型更像网格系统,因为大体流动型模型有很多列,并且列的响应方式也是不同,拿下面的布局图片来说,其在最小宽度的时候和掉落列相同,将每个元素都纵向堆放,一个一个纵向排列,随着宽度变大,网格模型开始出现。如果在进行加大宽度而元素将达到最大宽度,这个时候将添加两侧的外边距,而内容不再扩展。

img

其实现的html代码为:

 <div class="container">
     <div class="box  dark_blue"></div>
     <div class="box  light_blue"></div>
     <div class="box  green"></div>
     <div class="box  red"></div>
     <div class="box  orange"></div>
 </div>

css代码为:

  .container {
      display: flex;
      flex-wrap: wrap;
  }

  … @media screen and (min width: 450px) {

      .light_blue,
      .green {
          width: 50%;
      }
  }

  @media screen and (min-width: 550px) {

      .red,
      .green,
      .orange {
          width: 33.33333%;
      }

      .dark_blue,
      .light_blue {
          width: 50%;
      }
  }

  @media screen and (min-width: 700px) {
      .container {
          width: 700px;
          margin-left: auto;
          margin-right: auto;
      }
  }

活动布局模型:活动布局模型是很灵活的一种响应式模型,该模型可以让出现的元素更加灵活,比如下图中,当小于500px的时候,和上面几种一致,将每行按一列进行排列,当达到其他的断点的时候,就不是简单的排列,而是通过order来控制其排列的方式。

img

实现的html代码如何下:

  <div class="container">
      <div class="box  dark_blue"></div>
      <div class="container" id="container2">
          <div class="box  light_blue"></div>
          <div class="box  green"></div>
      </div>
      <div class="box  red"></div>
  </div>

css代码:

  .container {
      width: 100%;
      display: flex;
      flex-wrap: wrap;
  }

  … @media screen and (min-width: 500px) {

      .dark_blue,
      #container2 {
          width: 50%;
      }
  }

  @media screen and (min-width: 600px) {
      .red {
          width: 25%;
          order: -1;
      }

      .dark_blue {
          width: 25%;
          order: 1;
      }
  }

  @media screen and (min-width: 900px) {
      .container {
          width: 900px;
          margin-left: auto;
          margin-right: auto;
      }
  }

画布溢出模型:画布溢出模型中内容并不是竖直堆放的,而是将一些不常用的区域,如菜单、导航栏等放在屏幕以外,只有将屏幕放到足够大的时候才会显示出来。而在小尺寸的屏幕上,溢出画布的内容通常会通过用户点击才出现,比如博客的导航栏等。 比如下图中的导航栏,用到了position属性来定义绝对定位,然后通过transform属性将元素溢出画布,而随后设置transition属性将transform事件的变化加入过度效果,除此之外还要借用js代码来实现,该类型的比较相对于其他三种是比较复杂的类型。

实现的html代码如下:

    <nav id="drawer" class="dark_blue">
        <h2>This is nav</h2>
        <p>this is test text</p>
    </nav>

    <main class="light_blue">
        <a id="menu">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                <path d="M2 6h20v3H2zm0 5h20v3H2zm0 5h20v3H2z"></path>
            </svg>
        </a>
        <p>this is content</p>
    </main>
    </div>

css代码:

  html,
  body,
  main {
      height: 100%;
      width: 100%;
      margin-left: auto;
      margin-right: auto;
  }

  .dark_blue {
      background-color: #2A457A;
      color: #efefef;
  }

  .light_blue {
      background-color: #099DD9;
  }

  nav {
      width: 300px;
      height: 100%;
      position: absolute;
      transform: translate(-300px, 0);
      transition: transform 0.3s ease;
  }

  nav.open {
      transform: translate(0, 0);
  }

  a#menu svg {
      width: 40px;
      fill: #000;
  }

  @media screen and (min-width: 600px) {
      nav {
          position: relative;
          transform: translate(0, 0);
      }

      body {
          display: flex;
          flex-flow: row nowrap;
      }

      main {
          width: auto;
          flex-grow: 1;
      }
  }

js代码:

      menu.addEventListener('click', function(e) {
              drawer.classList.toggle('open');
              e.stopPropagation();
          }

      ) document.getElementsByTagName('main')[0].addEventListener('click', function(e) {
              drawer.classList.remove('open');
              e.stopPropagation();
          }

      )

Leave a Reply

Your email address will not be published. Required fields are marked *