响应式布局

返回目录

Element Query

合理的单位搭配

Absolute Size & Percent:绝对尺寸与百分比尺寸

在移动端开发中,笔者最早是倾向于用百分比布局,这样相较于传统的绝对布局肯定是具有一定灵活性,

Responsive Size:响应式尺寸

Media Query:媒介查询

>

Media Query By SCSS

Responsive Menu

老实说,笔者一直觉得响应式开发最成功的应用就是菜单了,这里介绍简单的响应式菜单的开发方式,借鉴了W3School的教程,首先,HTML 的元素布局为:

<ul class="topnav">
  <li><a href="#home">Home</a></li>
  <li><a href="#news">News</a></li>
  <li><a href="#contact">Contact</a></li>
  <li><a href="#about">About</a></li>
  <li class="icon">
    <a href="javascript:void(0);" onclick="myFunction()">&#9776;</a>
  </li>
</ul>

然后我们可以添加基本的样式:

/* Remove margins and padding from the list, and add a black background color */
ul.topnav {
    list-style-type: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: #333;
}

/* Float the list items side by side */
ul.topnav li {float: left;}

/* Style the links inside the list items */
ul.topnav li a {
    display: inline-block;
    color: #f2f2f2;
    text-align: center;
    padding: 14px 16px;
    text-decoration: none;
    transition: 0.3s;
    font-size: 17px;
}

/* Change background color of links on hover */
ul.topnav li a:hover {background-color: #111;}

/* Hide the list item that contains the link that should open and close the topnav on small screens */
ul.topnav li.icon {display: none;}

然后通过 Media Query 进行不同的尺寸下的样式设置:

/* When the screen is less than 680 pixels wide, hide all list items, except for the first one ("Home"). Show the list item that contains the link to open and close the topnav (li.icon) */
@media screen and (max-width:680px) {
  ul.topnav li:not(:first-child) {display: none;}
  ul.topnav li.icon {
    float: right;
    display: inline-block;
  }
}

/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens */
@media screen and (max-width:680px) {
  ul.topnav.responsive {position: relative;}
  ul.topnav.responsive li.icon {
    position: absolute;
    right: 0;
    top: 0;
  }
  ul.topnav.responsive li {
    float: none;
    display: inline;
  }
  ul.topnav.responsive li a {
    display: block;
    text-align: left;
  }
}

对于实际的效果的例子在这里

Flexible Units:灵活的尺寸单位

 Viewport Size:基于 Viewport 的单位

1vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = 1vw or 1vh, whichever is smaller
1vmax = 1vw or 1vh, whichever is larger

总而言之,就笔者目前的认知而言,虽然在下文中也会介绍几种关于 Viewport Size 的 Polyfill,不过总体而言笔者还不是很建议现在就大范围地使用 Viewport Size。

viewport-units-buggyfill
vminpoly

整体而言该 Polyfill 的完善度与社区活跃度皆不如上者,建议有需要的还是参考下上面那个 Polyfill。

FontSize:字体

>

Fixed Size

To avoid mobile browsers (iOS Safari, et al.) from zooming in on HTML form elements when a ` drop-down is tapped, addfont-size` to the selector rule:

input[type="text"],
input[type="number"],
select,
textarea {
  font-size: 16px;
}

Flexible Size

The type font size in a responsive layout should be able to adjust with each viewport. You can calculate the font size based on the viewport height and width using :root:

:root {
  font-size: calc(1vw + 1vh + .5vmin);
}

Now you can utilize the root em unit based on the value calculated by :root:

body {
  font: 1em/1.6 sans-serif;
}

:root {
  font-size: calc(1vw + 1vh + .25vmin);
}
body {
  font: 1em/1.75 "Open Sans", sans-serif;
}
.container {
  padding: 0 1em
}
code {
  background: #eee;
  border-radius: 3px;
}
em {
  background: #ffeb3b;
  font-style: normal;
}
code,
em {
  padding: .1em .2em;
}

合理的单位搭配

在响应式开发中,很多人都会建议不要使用 px 这种绝对值作为尺寸,不过这也是因人而异的,过度的使用相对值也会导致开发的复杂度与不可预测性的增加。老实说,最傻瓜的开发方案就是在一套视觉稿基础上使用绝对值开发,然后使用下文介绍的按比例缩放的技巧去适应各个屏幕。
For layout type things like the sizes of boxes, you want to use % because you will typically have several columns sized as a percentage of their parent that will stack on top of each other at a certain breakpoint (width:100%). No other unit will allow you to fill 100% of the space like % does. But with the min-height, max-height, min-width, max-width CSS keys.
For padding/margins use em, normally you will want to space your elements out relative to the size of your text. With em (the with of an ‘M’ character) you can quite easily say I want approximately 1 character spacing here.
For borders you can use px or em, there is a difference though. If you want your border to look like it’s one pixel wide on all devices, use 1px. It may not be one pixel on all devices however, high density displays convert 1px into 2px for example. If you want your border to be a size based on your font, use em.
dabblet

For fonts use em (or %), the use of em carries through parents to children and it just a nicer unit to work with over px.
For the next generation
vw and vh. The vw is 1/100th of the window’s width and the vh is 1/100th of the window’s height. For responsiveness they are going to be the new units.

在阅读本文的时候,反而希望你能先忘却关于 CSS、Web 开发那些你已经知道的东西,我们今天讨论的并不是多么复杂深奥的内容,如果你觉得准备好了那我们可以从下面这个简单的点图开始:

上面这些点分布的有些随意,分分合合,有近有远,我们的问题就是如何将这些点划分入到五个组中。最简单的,我们可以在那些相距较远的两个点之间设置为分隔区划分到不同的组合中。

上面这几个圈都是我随手画出来的,你当然可以选择其他的划分方式,譬如将最右边的两个点划分到一个分组中。其实这个问题并无所谓错误答案,不过如果你以如下方式划分的话:

看上去是不是觉得怪怪的?我问这个问题也不是无中生有,当我们需要为不同尺寸的屏幕设置不同的 CSS 样式稿时,会有人喜欢按照最常见的尺寸作为分割点,即 320px,768px 与 1024px。

不知道你有没有听过或者说过下面这些话:中等屏幕的话是不是按照 768px 来划分?还是应该把 768px 也划分到中等屏幕的范围内?不过这个尺寸是 iPad 横屏状态下的尺寸,应该算是大屏幕了吧?唔那大屏幕就是 768px 和以上尺寸咯?然后 320px 左右的是小屏幕?那 319px 算啥?区分蚂蚁的吗?本文的主旨即使讨论如何选择合适的分割点与分隔组。

选择合适的分隔点

你在幼儿园里就会画上面的这些圆吧,我现在用矩形度量来详细阐述下:

我们在这里选择了 600px,900px,1200px 以及 1800px 作为分割点,这些分隔组包含了最常见的 14 个机型:

我们把这两张图合并下,可以得出下面这个更适合你的老板、设计师、开发者以及测试人员看的一张图:

用更直观的方式命名你的分组

你愿意的话,也可以使用Papa-Bear 与 Baby-Bear来称呼你选定的分割点。不过当你和设计师一起讨论网站在不同屏幕上的展示效果时,肯定希望双方都能够在脑海中形成感性直观的认知。如果你用平板竖屏尺寸来形容的话,那到底是 iPad 还是 Surface 呢?特别是现在这种手机越来越大,平板越来越小的情况,你很难用单纯的平板或者手机来划分尺寸。不过好消息是苹果已经不做新产品了,他们只是不断地将按钮、耳机口从现在的产品中移除。这边我也不好给出什么建议,只能说设计师和产品之间需要多多沟通。

声明式的设置响应式布局

声明式的概念在前端很是流行,譬如著名的 React 就是典型的声明式组件库。声明式编程应用到 CSS 中即是 CSS 应当定义 What it wants,而不是 How it should。我们上面讨论过的一个关于分割点的容易混淆之处就是分割点同时代表了某个范围。譬如$large:600px这种定义在large这个词本身代表一个范围值的时候就会混淆。因此在具体的某个组件或者标签中,我们应该对其隐藏具体的尺寸设置,譬如:

@mixin for-phone-only {
  @media (max-width: 599px) { @content; }
}
@mixin for-tablet-portrait-up {
  @media (min-width: 600px) { @content; }
}
@mixin for-tablet-portait-only {
  @media (min-width: 600px) and (max-width: 899px) { @content; }
}
@mixin for-tablet-landscape-up {
  @media (min-width: 900px) { @content; }
}
@mixin for-tablet-landscape-only {
  @media (min-width: 900px) and (max-width: 1199px) { @content; }
}
@mixin for-desktop-up {
  @media (min-width: 1200px) { @content; }
}
@mixin for-desktop-only {
  @media (min-width: 1200px) and (max-width: 1799px) { @content; }
}
@mixin for-big-desktop-up {
  @media (min-width: 1800px) { @content; }
}

// usage
.my-box {
  padding: 10px;

  @include for-desktop-up {
    padding: 20px;
  }
}

你会发现在上面的定义中我很推荐使用-up-only后缀,在具体使用样式的地方:

.phone-only {
  @include for-phone-only { background: purple; }
}

.tablet-portait-only {
  @include for-tablet-portait-only { background: purple; }
}

.tablet-portrait-up {
  @include for-tablet-portrait-up { background: purple; }
}

.tablet-landscape-only {
  @include for-tablet-landscape-only { background: purple; }
}

.tablet-landscape-up {
  @include for-tablet-landscape-up { background: purple; }
}

.desktop-only {
  @include for-desktop-only { background: purple; }
}

.desktop-up {
  @include for-desktop-up { background: purple; }
}

.big-desktop-up {
  @include for-big-desktop-up { background: purple; }
}

不过这种方式在需要大量自定义媒介查询搭配的时候就显得不是那么灵活,我们可以提供更加细粒度的控制方式:

@mixin for-size($size) {
  @if $size == phone-only {
    @media (max-width: 599px) { @content; }
  } @else if $size == tablet-portrait-up {
    @media (min-width: 600px) { @content; }
  } @else if $size == tablet-portait-only {
    @media (min-width: 600px) and (max-width: 899px) { @content; }
  } @else if $size == tablet-landscape-up {
    @media (min-width: 900px) { @content; }
  } @else if $size == tablet-landscape-only {
    @media (min-width: 900px) and (max-width: 1199px) { @content; }
  } @else if $size == desktop-up {
    @media (min-width: 1200px) { @content; }
  } @else if $size == desktop-only {
    @media (min-width: 1200px) and (max-width: 1799px) { @content; }
  } @else if $size == big-desktop-up {
    @media (min-width: 1800px) { @content; }
  }
}

// usage
.my-box {
  padding: 10px;

  @include for-size(desktop-up) {
    padding: 20px;
  }
}

这种方式自然能够达成预期的效果,不过如果某个粗心的开发者传入了某个未预定义的范围名,那么久尴尬了,因此我们还是建议不要传入某个具体的尺寸,而是传入某个范围:

@mixin for-size($range) {
  $phone-upper-boundary: 600px;
  $tablet-portrait-upper-boundary: 900px;
  $tablet-landscape-upper-boundary: 1200px;
  $desktop-upper-boundary: 1800px;

  @if $range == phone-only {
    @media (max-width: #{$phone-upper-boundary - 1}) { @content; }
  } @else if $range == tablet-portrait-up {
    @media (min-width: $phone-upper-boundary) { @content; }
  } @else if $range == tablet-portait-only {
    @media (min-width: $phone-upper-boundary) and (max-width: #{$tablet-portrait-upper-boundary - 1}) { @content; }
  } @else if $range == tablet-landscape-up {
    @media (min-width: $tablet-landscape-upper-boundary) { @content; }
  } @else if $range == tablet-landscape-only {
    @media (min-width: $tablet-portrait-upper-boundary) and (max-width: $tablet-landscape-upper-boundary - 1px) { @content; }
  } @else if $range == desktop-up {
    @media (min-width: $tablet-landscape-upper-boundary) { @content; }
  } @else if $range == desktop-only {
    @media (min-width: $tablet-landscape-upper-boundary) and (max-width: $desktop-upper-boundary - 1px) { @content; }
  } @else if $range == big-desktop-up {
    @media (min-width: $desktop-upper-boundary) { @content; }
  }
}

// usage
.my-box {
  padding: 10px;

  @include for-size(desktop-up) {
    padding: 20px;
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值