这一期中咱们主要来聊聊全屏的事情。对于全屏的布局,你们可能首先想到的是100%
(或100vw
)来实现,但若是你要在一个限宽的容器中实现一个全屏效果呢?好比说,一个Banner区全屏显示。相似这样的效果在PC端是很是常见的一个效果。可能会有不少同窗会说,这样的效果有什么好聊的,不是很是简单的Layout吗?其实仍是有点事情可聊的。若是你感兴趣,不仿继续往下阅读。javascript
在Web布局中,特别是在PC端中,经常能够看到这样的设计风格:内容居中,而后Banner区全屏。这也就是标题所说的效果,限宽的容器中实现全屏效果。那么问题来了,在实际中如何实如今限宽的容器中实现全屏效果。好比下面的设计风格:css
看到上图的效果,咱们可能首先会想到从HTML结构上来作相应的处理:html
<div class="banner">
<div class="container">
</div>
</div>
复制代码
对应的CSS样式:vue
.banner .container {
width: 100%
}
复制代码
若是对于多个区域全屏和多个区域限宽居中呢?若是仍是从结构上作处理的话,可能会:java
<header>
<div class="wrapper">
</div>
</header>
<div class="full-width">
<div class="wrapper">
</div>
</div>
复制代码
CSS并不会太复杂:css3
.full-width {
width: 100%;
}
.wrap {
width: 80%;
max-width: 24em;
margin: 0 auto;
}
复制代码
这其实很简单。若是咱们换过一个环境或提升限制条件呢?假设你是在为一个CMS系统作开发(你并无自主修改HTML的权限)。即你的结构有能都是这样的一个模式:git
<div class="container">
<header></header>
<div clas="banner"></div>
<main></main>
<footer></footer>
</div>
复制代码
在.container
中设置一个限制宽度,好比:github
.container {
width: 80%;
max-width: 80vw;
margin: 0 auto;
}
复制代码
基于这样的一个Layout结构,若是header
、.banner
和footer
区域须要全屏显示。在不修改HTML结构的状况之下,如何实现须要的效果。web
你们是否还记得等高布局,在等高布局的实现方案中就有一个负margin
和正padding
相互抵销的方案。那么若是仅实现一个全屏的背景颜色也可使用该方案:正则表达式
header {
margin: 0 -9999rem;
padding: 1rem 9999rem;
}
复制代码
和前面的一个方案相似,只不过把正padding
换成了border
:
.banner {
border-left: 600rem solid maroon;
border-right: 600rem solid maroon;
margin: 0 -600rem;
}
复制代码
使用vw
和calc()
二者的结合可让事情变得更为简单,好比:
.full-width {
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
}
复制代码
在CSS中,咱们能够借助transform
中的translate()
来替代left
和right
,上面的示例代码能够变成:
.full-width {
width: 100vw;
transform: translateX(calc(( 960px - 100vw ) / 2)); // 假设限宽的容器宽度为960px
}
复制代码
上面的代码我们继续优化一下:960px
至关于100%
,这样一来960px / 2
也就至关于50%
;对应的100vw / 2
就变成了50vw
。这样上面的代码就变成了:
.full-width {
margin-left: calc(50% - 50vw);
margin-right: calc(50% - 50vw);
}
复制代码
若是你使用Sass这样的CSS处理器,你还能够将其封装成一个@mixin
:
@mixin full-width($support-type: margin,$min-width:null){
@if $support-type == 'margin' {
margin-left: calc(-50vw + 50%);
margin-right: calc(-50vw + 50%);
// margin-left: calc(-100vw / 2 + #{$min-width} / 2);
// margin-right: calc(-100vw / 2 + #{$min-width} / 2);
}
@if $support-type == 'position' {
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
}
@if $support-type == 'translate' {
width: 100vw;
transform: translateX(calc((#{$min-width} - 100vw)/2));
}
}
复制代码
有了上述定义的混合宏,在实际使用的时候,只须要向下面这样调用:
.full-width {
@include full-width(margin,960px);
}
复制代码
使用vw
和calc()
函数来实现限宽容器中任何一个单一元素实现全屏布局。另外,vw
还能够配合伪元素、padding
或者说百分比和padding
也能够实现一些相似的布局效果:
有关于这方面更详细的介绍能够阅读:
在Web技巧第四期中末尾向你们介绍了CSS中重要的属性之一display
,在将来的display
中可使用两个值。而@Rachel Andrew花了三篇文章的篇幅来介绍CSS的display
属性:
若是想对display
有一个深刻的了解,那么这几篇文章对你是有较大的参考价值或者文章中相关的内容是很是值得咱们去深挖。固然,想更深刻的把display
聊的清楚一些,那么咱们颇有必要花更多的时间来梳理。若是你感兴趣的话,欢迎关注后续相关的更新,我将会花一到两篇的篇幅和你们从新来聊display
。若是你不想等的过久,除了上面的文章以外,下面这几篇文章也是有助于你更好的理解display
:
在《Web中的图标》一文中主要和你们一块儿聊了聊Web中的图标(Icon图标)如何应该,应该怎么去选择。虽然SVG的Icon在实际使用中已经很是的成熟了:
但仍是有不少同窗在使用字体图标,并且有关于字体图标相关的介绍也很是的多:
但字体图标的使用过程当中会存在不少的问题。@zachleat在《The Scoville Scale of Web Font Loading Opinions》为Web字体加载作了一个主题的介绍,并且有关于这方面的优秀教程,在互联网上大把:
而字体图标和字体加载存在必定的兼容性问题。简单地说,字体图标彷佛存在Web标准以外。换句话说就是font-display
没有与图标字体兼容的有效值。
加载字体图标时,一般不但愿有一个降级文本(回退文本)渲染。它不是典型的无样式文本(FOUT)场景。若是字体图标没有回退文本渲染,谁都不知道字体加载未成功的时候会看到什么。
你可有在访问有字体图标的Web页面时,字体未加载或加载失败时看不到图标,而是一个带颜色的方框。
使用字体图标都会借助CSS的@font-face
属性,在@font-face
指令中使用font-display
来加载自定义字体。这个属性能够添加如下的值:
auto
:默认值。典型的浏览器字体加载的行为会发生,也就是使用自定义字体的文本会先被隐藏,直到字体加载结束才会显示swap
:后备文本当即显示直到自定义字体加载完成后再使用自定义字体渲染文本。在大多数状况下,这就是咱们所追求的效果fallback
:这个能够说是auto
和swap
的一种折中方式。须要使用自定义字体渲染的文本会在较短的时间不可见,若是自定义字体尚未加载结束,那么就先加载无样式的文本。一旦自定义字体加载结束,那么文本就会被正确赋予样式optional
:效果和fallback
几乎同样,都是先在极短的时间内文本不可见,而后再加载无样式的文本。不过optional
选项可让浏览器自由决定是否使用自定义字体,而这个决定很大程度上取决于浏览器的链接速度。若是速度很慢,那你的自定义字体可能就不会被使用block
:为字体提供一个短暂的阻塞周期和无限的交换周期,它将使用不可见的文本长达3s
,并显示回退文本,直到Web字体加载完成。这是最佳选项,但仍然不是很好有关于font-display
更详细的介绍能够阅读《font-display
的用法》一文。
要解决这些问题,可使用CSS字体加载API强制不可见的文本,直到图标字体成功加载。或者使用使用SVG图标。
@David Walsh整理了使用JavaScript的几个小技巧。
经过...new Set()
获得一个惟一值的数组:
var j = [...new Set([1, 2, 3, 3])]
>> [1, 2, 3]
复制代码
经过map
和filter
来过滤掉数组中的布尔值(好比0
、undefined
、null
、false
等):
myArray.map(item => {
//...
}).filter(Boolean)
复制代码
好比:
[0, undefined, false, 1, 23].map(item=>{ return item }).filter(Boolean)
>> [1, 23]
复制代码
可使用{}
来建立一个看起来像空的对象,但该对象仍然有一个__proto__
和hasOwnProperty
和其余对象方法。然而,有一种方法能够建立一个纯"dictionary"对象:
let dict = Object.create(null)
dict.__proto__ === "undefined"
>> false
复制代码
在JavaScript中合并多个对象的需求一直存在,特别是当咱们开始建立类和带有选项的组件时:
const person = {
name: 'David Walsh',
gender: 'Male'
}
const tools = {
computer: 'Mac',
editor: 'Atom'
}
const attributes = {
handsomeness: 'Extreme',
hair: 'Brown',
eye: 'Blue'
}
const summary = {...person, ...tools, ...attributes}
复制代码
可以为函数参数设置默认值是JavaScript的一个很棒的功能,但看看这个技巧,它要求为给定的参数传递值:
const isRequired = () => {
throw new Error('param is required')
}
const hello = (name = isRequired()) => {
console.log(`hello ${name}`)
}
复制代码
解构是一个很是受欢迎的JavaScript,但有时咱们更喜欢用其余的名称引用这些属性,因此咱们能够利用别名:
const obj = { x: 1}
const { x } = obj
const {x: otherName} = obj
复制代码
多年来,咱们编写粗糙的正则表达式来获取查询字符串值,但那些日子已经一去不复返了,输入URLSearchParams
API便可:
// Assuming "?post=1234&action=edit"
var urlParams = new URLSearchParams(window.location.search);
console.log(urlParams.has('post')); // true
console.log(urlParams.get('action')); // "edit"
console.log(urlParams.getAll('action')); // ["edit"]
console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?post=1234&action=edit&active=1"
复制代码
有关于数组和对象更多的介绍能够点击:
这一期中咱们主要一块儿聊了聊如何在限宽的容器中让某部分实现全屏显示,除了在结构上实现所需的效果以外,还能够在单个元素上借助一些CSS的特性来完成,好比负margin
和正padding
、或者负margin
和border
这样的互负抵销的方式;也可使用vw
和calc()
让事情变得还更简单。
display
是CSS的重要内容之一,@Rachel Andrew的三篇博文,让咱们对CSS的display
有了一个更深层次的理解,在今年的布局或者在使用display
会变得更明了。另外图标是Web中经常使用的一部分,这里罗列了字体图标使用的一些教程以及如何借助font-display
来让字体加载让用户有一个更好的体验。虽然font-display
能够对字体加载作一些优化,但使用字体图标依旧是有一些缺陷的,建议你们仍是考虑使用SVG图标。
最后,把@David Walsh整理的几个JavaScript小技巧列入到这一期,但愿这些小技巧能在实际开发中给你们带来一些帮助。