前端开发 大前端 W3Cbest

一个专注 WEB 开发的技术博客

0%

在创新的2018年已经过去,在2019年看看如何简单做成响应性的网站 如果你未曾听说过CSS变量,那么我告诉你,它就是CSS的一种新功能,可以让你拥有在样式表中使用变量的能力,这样做时并不需要什么特别的设置呦。 从本质上讲,CSS变量可以让你摆脱老式的样式设置:

h1 {
font-size: 30px;
}

navbar>a {
font-size: 30px;
}

…而是主张这样写:

:root {
–base-font-size: 30px;
}
h1 {
font-size: var(–base-font-size);
}
navbar>a {
font-size: var(–base-font-size);
}

这样的语法看起来的确有点怪怪的,但有没有觉得它和less、sass中的变量有点类似呢,但如此一来,只要更改–base-font-size 变量,就能在整个应用中改变字号了。 如果你想把CSS变量学明白,可以在Scrimba网站 这里有免费互动CSS变量课程,该课程包含8个互动截屏。

今天来讲一下如何用CSS变量创建响应布局

这是一段html

  • item 1
  • item 2
  • item 3
  • item 4

 

老方法:

在以前即使不使用CSS变量也可以把这些事情搞定。只是需要把要改变的属性在重新重置一下,需要在媒体查询中拥有自己的选择器,但会招致额外的大量代码,像下面这样:

.item {
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: space-around;
padding: 10px;

li {
    background-color: #ff6f69;
    border: 1px solid #fff;
    font-size: 20px;
    height: 200px;
    list-style-type: none;
    width: 100%;
}

}

@media (min-width: 768px) {
.item {
flex-direction: row;
li {
background-color: #ffcc5c;
font-size: 50px;
height: 300px;
width: 50%;
}
}
}

@media (min-width: 992px) {
.item {
flex-wrap: nowrap;
li {
background-color: #ffeead;
font-size: 100px;
height: 500px;
width: calc(100% / 4);
}
}
}

See the Pen CSS media by w3cbest.com (@w3cbest) on CodePen.

 

新方法

下面让我们来看如何使用CSS变量来解决这个问题。首先,要把我们将重复利用和更改的数值存储在变量的内部:

:root {
–base-color: #ff6f69;
–base-font-size: 20px;
–direction: column;
–width: 100%;
–height: 200px;
}

然后,在整个页面中简单地使用这些变量就行了:

.item {
display: flex;
padding: 10px;
justify-content: space-around;
flex-direction: var(–direction);
flex-wrap: var(–wrap);
li{
list-style-type: none;
border: 1px solid #fff;
height: var(–height);
width: var(–width);
background-color: var(–base-color);
font-size: var(–base-font-size);
}
}

一旦进行了这样的设置之后,我们只要在媒体查询中简单地更改变量值就行了:

@media (min-width: 768px) {
:root {
–base-font-size: 60px;
–base-color: #ffcc5c;
–direction: row;
–height: 300px;
–width: 50%;
–wrap:wrap;
}
}
@media (min-width: 992px) {
:root {
–base-font-size: 100px;
–base-color: #ffeead;
–direction: row;
–height: 500px;
–width: calc(100% / 4);
–wrap:nowrap;
}
}

See the Pen CSS Variables by w3cbest.com (@w3cbest) on CodePen.

  这比我们以往的方法简便多了。只需盯住 :root,而不必为所有的选择器指定值了。 这只是一个简单的例子。设想成熟的网站会是什么样子吧,例如,用 –base-margin 来控制APP四周的多数自由空间。想翻转其值也是很容易的事情,不必用复杂的选择器来填充媒体查询了。 总之,CSS变量绝对是提高响应速度时,所代表的未来。

介绍

我们中的大多数开发人员用来考虑左和右,顶部和底部。这是因为在早期的互联网,它主要用于上传文档,而不是为我们今天知道的复杂的网站结构。 这是原因,没有人认为多语言网站的需求。

概述

旧的盒子模型告诉我们左右上下这四个方向,但在新的模型中,请记住 inline-start inline-end block-start block-end: (LTR)对应关系如下:

  • 左: inline-start
  • 右: inline-end
  • 上: block-start
  • 下: block-end

这些适用于 margin padding border 修饰,比如 margin-left 中,left -> 左 -> inline-start -> margin-inline-start 这有点像把坐标系概念引入了布局,对于不同国家,inline 与 block 的方向是不同的:

  • 在东亚绝大多数国家、英美系国家 padding-inline-start = padding-left
  • 在阿拉伯国家 padding-inline-start = padding-right
  • 在日本 padding-inline-start = padding-top

以中国和英美系国家的阅读顺序为基准的话,阿拉伯国家等于把左右颠倒了,而日本是把网页沿顺时针旋转 90 度。

为什么 inline 表示从左右,block 表示上下呢?还记得 display: inline 吗?此时排版是从左到右排布的,而 display: block 的排版是从上到下的。

宽高

width height 也需要换成 inline-size 与 block-size,(LTR)对应关系如下:

  • width: inline-size
  • min-width: min-inline-size
  • max-width: max-inline-size
  • height: block-size
  • min-height: min-inline-size
  • max-height: max-inline-size

See the Pen width height by w3cbest.com (@w3cbest) on CodePen.

下图是 Box Model 与 Logical 的对比:

CSS Positions

之前Positions属性的名称,top/right/left/bottom,先在所有名称都带有前缀inset: inset-block-start / inset-inline-end inset-block-end / inset-inline-start。 (LTR)对应关系如下:

  • top = inset-block-start
  • bottom = inset-block-end
  • left = inset-inline-start
  • right = inset-inline-end

尽管这样描述起来很复杂:

.popup {
position: fixed;
inset-block-start: 0; /*top - in English*/
inset-block-end: 0; /*bottom - in English*/
inset-inline-start: 0; /*left - in English*/
inset-inline-end: 0; /*right - in English*/
}

但是这种属性支持聚合写法:

.popup {
position: fixed;
inset: 0 0 0 0; /*top, right, bottom, left - in English*/
}

Float

对于 float 的两个值 left right,可以很容易推测出来,会被 inline-start 与 inline-end 取代,(LTR)对应关系如下:

  • float: left = float: inline-start
  • float: right = float: inline-end

Text-align

text-align 也有 left right 属性,分别取代为 start end,(LTR)对应关系如下:

  • text-align :left = text-align: start
  • text-align :right = text-align: end

Css Grid 与 Flexbox

使用 css grid 与 flexbox 布局方案的网页,将在支持的浏览器上自动享受国际化布局调整,不需要改变语法。

Writing-mode

目前为止,看到的是 Css 对排版含义的规范化,Grid 与 Flexbox 由于 API 比较新,定义的较为规范,所以不用变,而旧的 display, position, width, height, float 等 API 需要进行语义化改造。 现在就要聊到最关键的布局国际化部分,我们至今为止遇到的网页都是从上到下的,但其他文化却不同。可以通过配置 writing-mode 让整个网页布局改变:

  • writing-mode: horizontal-tb = 从上到下
  • writing-mode: vertical-rl = 从右到左 比如日本文化
  • writing-mode: vertical-lr = 从左到右 比如蒙古文化

至今还没有见过从下到上的网页,也许这证明了从下到上是最不合理的阅读方式。

Direction

这是一个排版属性,writing-mode 是控制网页方向的,而 direction 是控制文字对齐方向的。 目前只有两个配置:rtl 与 ltr:

html {
direction: rtl;
}

其实 writing-mode 与 direction 结合起来也没什么问题,比如网页布局变成 vertical-rl - 从右到左,那么 direction 的 ltr 就等于是从上到下了。 最后还有一些悬而未决的问题,比如如何开启智能布局?一种方式是:

html {
flow-mode: physical;
/*or*/
flow-mode: logical;
}

另外,像 @meta 配置中的 max-width 也要替换为 max-inline-size, line-height 需要被替换为 line-size,border-width 需要被替换为 border-size 等等。

趋势

整个 Logical Properties 规范看下来是个不可逆的趋势,也代表着 W3C 规范在排版方面的全球化工作。

为什么要改造语法

第一个问题就是这个,我们习以为常的 left top right bottom 语法都需要改成 inline-start block-end 等略微晦涩的语法,而且你可以发现,新语法与旧语法是完全一对一对等的,也就是完全可以交给某个转换程序去做! 可以看出,这是一个习惯问题,W3C 希望重塑国际化布局的语义,而原有的 left top 等无法承担这些语义,所以只好换掉。 新版规范要求开发者做出一个抽象,把自己国家的习惯抽象成习惯无关的描述。但对于每个前端从业者来说,left top 等描述估计已经成为肌肉记忆了,想要改变规范还是挺难的,未来前端社区也许会出现三种解决方案:

  • 保守派 - 利用 babel 将原有语法与新语法做一对一映射转换,比如 position: left -> position: inset-inline-start。这种方案 成本最小,且不改变开发者习惯,所以最有可能被国内公司率先采用。在商业环境推动一件事情,最大的阻力无非是 成本 与 共识,这次的布局规范同时触及了这两个点,可能让团队倾向于做保守派。
  • 兼容派 - 其实就是两面派,利用 babel 工具做映射这一点与保守派相同,但是新代码推荐用新语法编写,如果团队中有人不遵循新规范,也会被工具自动转换为新规范。这种软要求会导致团队布局代码存在两套,但最终效果却没有问题的神奇效果,长远来说不利于维护,但不失为一种较为妥协的策略。
  • 改革派 - 利用脚本,将项目里旧规范替换成新规范,并让团队未来的代码遵循新的布局规范编写。很显然,这派抓住了迁移成本小这个优势,但没有考虑到人这个因素的习惯迁移成本,如何说服其他人理解新规范,并做到让 “未来加入的同事” 也能认同并遵循这套新规范,也许是最大的不确定因素。

为什么 Flex Grid 语法不需改造?

这次改造是冲着 left right width height 等明显带有文化色彩的语法来的。 然而 Flex 语法已经将方向定义转化为抽象的 start 与 end,而 center 是没有歧义的,所以 FlexBox 语法不用改。 而 Grid 是一种拆分单元格的语法,也不涉及具体上下左右的描述,所以也符合国际化语义。

扩展阅读:

Chrome开发工具提供了一套非常棒的工具,可以帮助您在Web平台上进行开发。以下是一些你可能还不知道的建议

在ELEMENTS面板中拖放

在Elements面板中,您可以拖放任何HTML元素并更改其在页面上的位置

引用控制台中当前选择的元素

在Elements面板中选择一个节点,并在控制台中键入$0来引用它。

提示:如果使用jQuery,可以输入$($0)来访问这个元素上的jQuery API。

使用控制台中最后一个操作的值

使用$_引用在控制台中执行的前一个操作的返回值

添加CSS并编辑元素状态

在元素面板中有两个超级有用的按钮。 第一个选项允许您添加一个新的CSS属性,使用您想要的任何选择器,但要预先填充当前选定的元素: 第二个选项允许您为所选元素触发一个状态,这样您就可以看到当它处于活动状态、悬停状态、焦点状态时应用的样式。

找到定义CSS属性的位置

在元素面板中的CSS属性,DevTools将指向定义该属性的地方,即源面板

 

保存并归档修改后的CSS

单击您编辑的CSS文件的名称。检查器将它打开到Sources窗格中,然后您可以在应用的实时编辑中保存它。 这个技巧不适用于使用+或元素添加的新选择器。样式属性,但仅适用于已修改的现有属性。

屏幕截图一个元素

选择一个元素并按下cmd-shift-p(或在Windows中按ctrl-shift-p)打开命令菜单,然后选择Capture node截图

使用CSS选择器查找元素

按下cmd-f(在Windows中ctrl-f)将在Elements面板中打开搜索框。 你可以在里面输入任何字符串来匹配源代码,或者你也可以使用CSS选择器让Chrome为你生成一个图像:

在控制台中SHIFT-ENTER

要在控制台中编写跨越多行代码的命令,请按shift-enter。 一旦你准备好了,按下回车在脚本的最后,以执行它:

清除控制台

您可以使用控制台左上角的clear按钮清除控制台,或者按ctrl-l或cmd-k。

GO TO…

在资源面板:

  • 显示页面加载的所有文件。
  • 显示当前文件中的符号(属性、函数、类)。
  • ctrl-g转到特定的行。

监视表达式

在调试过程中,您将多次检查变量名或表达式,而不是一次又一次地编写变量名或表达式,而是将其添加到监视表达式列表中。

XHR /获取调试

从调试器中打开XHR/Fetch断点面板。 您可以将它设置为在发送XHR / Fetch调用时断开,或者仅在特定的调用上:

对DOM修改的调试

右键单击元素并在子树修改上启用Break:每当脚本遍历该元素的子元素并修改它们时,调试器都会自动停止,以便让您检查发生了什么。

CSS Shapes 简介

CSS Shapes 允许我们通过定义文本内容可以环绕的几何形状、图像和渐变,来创建有趣且独特的布局。本次教程会教你如何使用它们。 在 CSS Shapes 问世之前,为网页设计文本自由环绕的杂志式布局几乎是不可能的。相反,网页设计布局传统上一直用网格、盒子和直线构造。 CSS Shapes 允许我们定义文本环绕的几何形状。这些形状可以是圆、椭圆、简单或复杂的多边形,甚至图像和渐变。Shapes 的一些实际设计应用可能是圆形头像周围显示圆形环绕文本,全屏背景图片的简单部位上面展示文本,以及在文章中显示首字下沉。 现在 CSS Shapes 已经获得了现代浏览器的广泛支持,值得一看的是它们提供的灵活性和功能,以确定它们在你的下一个设计项目中是否能派上用场。

注意:截至攥写本文时,CSS Shapes 支持 Firefox、Chrome、Safari 和 Opera,以及 iOS Safari 和 Chrome for Android 等移动浏览器。Shapes 不支持 IE,对 Microsoft Edge 的支持正在考虑中

CSS Shapes 初探

CSS Shapes 的当前实现是 CSS Shapes Module Level 1,它主要包含 [shape-outside]属性。shape-outside 定义了文本环绕的形状。 考虑到有 shape-outside 属性,你可能会想到还有一个相应的 shape-inside 属性,它包含形状内的文本。shape-inside 属性可能会在将来实现,目前它只是 CSS Shapes Module Level 2里面的一个草案,并没有被任何浏览器实现。 在本文中,我们将演示如何使用<basic-shape>数据类型并使用形状函数值设置它,以及使用半透明URL或渐变设置形状。  

基本形状函数

我们可以通过对shape-outside属性应用以下函数值来定义CSS中的各种基本形状:

  • circle()
  • ellipse()
  • inset()
  • polygon()

为了将shape-outside属性应用到元素上,元素必须是浮动的,并且具有定义的高度和宽度。让我们逐一介绍这四个基本形状,并演示如何使用它们。

circle

我们将从 circle() 函数开始。设想如下场景,有一个圆形的作者头像,我们想让头像左浮动并且作者的描述文本环绕它。仅对头像元素使用 border-radius: 50% 不足以使文本呈圆形;文本仍将把头像当成矩形元素。 通过圆形,我们可以演示文本如何按圆形环绕。 首先我们在一个普通的 div 上创建 circle 样式,并且写几段文字(我使用 Bob Ross 语录作为 Lorem Ipsum 文本)。

Example text...

在circle 样式中,我们将元素浮动到左边,给它一个相等的高度和宽度,并将shape-outside设置为circle()。

.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
}

如果我们访问页面,会看到如下场景。 正如你所看到的,文字围绕着圆形流动,但我们实际上看不到任何形状。将鼠标悬停在Developer Tools中的元素上,将向我们显示正在设置的实际形状。 此时,你可能会认为可以给元素 background 设置颜色或者图片就能看到形状了。我们来试一下。

.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
background: linear-gradient(to top right, #FDB171, #FD987D);
}

不幸的是,给 circle 设置 background 后会显示一个矩形,这是我们一直试图避免的事情。 我们可以清晰地看到文本在它周围环绕,但是元素本身并没有形状。如果我们想要真实地显示形状函数,就必须使用 clip-path 属性。clip-path 采用许多和 shape-outside 相同的值,所以我们可以给它相同的circle()值。

.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
clip-path: circle();
background: linear-gradient(to top right, #FDB171, #FD987D);
}

 

在本文剩下的部分,我将使用 clip-path 帮助我们辨认形状。

circle() 函数接收可选的 radius 参数。在我们的例子中,默认 radius 是 50% 或者 100px。使用 circle(50%) 或者 circle(100px) 都将产生和我们已经完成样例的同样结果。 你可能会注意到文本刚好和形状贴合。我们可以使用 shape-margin 属性给形状添加 margin,它可以设置为px、em、% 和任何其他标准的 CSS 测量单位。

.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle(25%);
shape-margin: 1rem;
clip-path: circle(25%);
background: linear-gradient(to top right, #FDB171, #FD987D);
}

下面是一个circle radius 设置 25% 并且使用 shape-margin 的例子。 除了 radius,形状函数可以使用 at 定位。默认位置是圆的中心,因此 circle() 也可以被显式设置为 circle(50% at 50% 50%) 或 circle(100px at 100px 100px),这两个值分别是水平和垂直位置。 为了搞清楚 position 的作用,我们可以设置水平位置值为 0 来创造一个完美的半圆。

circle(50% at 0 50%);

这种坐标定位系统称为参考框。

稍后我们将学习如何使用图像代替形状或者渐变。现在我们将继续进行下一个形状函数。

Ellipse

ellipse() 和 circle() 函数类似,只是它会创造椭圆。为了演示,我们创建一个 ellipse 元素和样式。

Example text...

.ellipse {
float: left;
shape-outside: ellipse();
clip-path: ellipse();
width: 150px;
height: 300px;
background: linear-gradient(to top right, #F17BB7, #AD84E3);
}

这次,我们设置不同的 height 和 width 创建一个垂直拉长的椭圆。 ellipse() 和 circle()的区别在于,ellipse有两个半径rx和ry,即x轴半径和y轴半径。因此,上述例子也可以写成:

ellipse(75px 150px);

circles 和 ellipses 的位置参数是一样的。除了是测量单位,半径也包括 farthest-side 和 closest-side 的选项。 closest-side 是指从参考框的中心到最近边的长度,相反,farthest-side 是指从参考框的中心到最远边的长度。这意味着如果未设置默认值以外的位置,这两个值将无效。 下面演示了在 ellipse() 上翻转 closest-side 和 farthest-side 的区别,在X轴和Y轴上偏移25%。

ellipse(farthest-side closest-side at 25% 25%)

ellipse(farthest-side closest-side at 25% 25%)

 

Inset

到目前为止我们只处理了圆形的形状,但是我们可以使用 inset() 函数定义内嵌矩形。

Example text...

.inset {
float: left;
shape-outside: inset(75px);
clip-path: inset(75px);
width: 300px;
height: 300px;
background: linear-gradient(#58C2ED, #1B85DC);
}

在本例中,我们将创建一个300px×300px的矩形,并在所有边内嵌75px。这样我们就得到了150px×150px的图像周围有75px的空间。 我们可以看到矩形是内嵌的,文本忽略了内嵌区域。 inset() 形状也可以使用 round 参数接收 border-radius,并且文本会识别圆角,就像本例中所有边都是 25px 内嵌和 75px 圆角。

inset(25px round 75px)

像 padding 或 margin 简写,inset 值以顺时针方式(inset(25px 25px 25px 25px))接收 top right bottom left,并且只传一个值将使四条边都相同(inset(25px))。  

Polygon

形状函数中最有趣和最灵活的是 polygon(),它可以采用一系列 x 和 y 点来制作任何复杂形状。数组里的每个元素代表 _x_i _y_i,将被写成 polygon(x1 y1, x2 y2, x3 y3…) 等等。 我们可以为多边形设置的点集数量最少为 3,这将创建一个三角形。

Example text...

.polygon {
float: left;
shape-outside: polygon(0 0, 0 300px, 200px 300px);
clip-path: polygon(0 0, 0 300px, 200px 300px);
height: 300px;
width: 300px;
background: linear-gradient(to top right, #86F7CC, #67D7F5);
}

  在这个形状中,第一个点是 0 0,div 中最左上角的点。第二个点是 0 300px,它是 div 中最左下角的点。第三个也就是最后一个点是 200px 300px,它在 X 轴的 2/3 处并且也在底部。最终的形状是这样: polygon() 形状函数的一个有趣用法是文本内容可以在两个或以上形状中环绕。因为 polygon() 形状是如此灵活和动态,这给我们制作真正独特的杂志式布局提供了一个最好机会。在本例中,我们将把文本放在两个多边形中。

Example text...

.left {
float: left;
shape-outside: polygon(0 0, 0 300px, 200px 300px);
clip-path: polygon(0 0, 0 300px, 200px 300px);
background: linear-gradient(to top right, #67D7F5, #86F7CC);
height: 300px;
width: 300px;
}
.right {
float: right;
shape-outside: polygon(200px 300px, 300px 300px, 300px 0, 0 0);
clip-path: polygon(200px 300px, 300px 300px, 300px 0, 0 0);
background: linear-gradient(to bottom left, #67D7F5, #86F7CC);
height: 300px;
width: 300px;
}

显然,想要手动创造你自己的复杂形状是非常困难的。幸运的是,你可以用一些工具来创建多边形。Firefox 有一个内置的形状编辑器,你可以在 Inspector 中通过点击多边形使用。 目前,Chrome有一些可以使用的扩展,比如CSS shape Editor。 多边形可以用来剪切图像或其他元素周围的形状。在另一个例子中,我们可以通过在大字母周围绘制多边形来创建首字下沉。

R

Example text...

.letter {
float: left;
font-size: 400px;
font-family: Georgia;
line-height: .8;
margin-top: 20px;
margin-right: 20px;
shape-outside: polygon(5px 14px, 233px 20px, 246px 133px, 189px 167px, 308px 304px, 0px 306px) content-box;
clip-path: polygon(5px 14px, 233px 20px, 246px 133px, 189px 167px, 308px 304px, 0px 306px);
}

URLs

CSS Shapes 一个令人激动的特性是你不必每次都通过形状函数明确定义;你也可以使用半透明图像的 url 来定义形状,这样文本就会自动环绕它。 需要注意的是,所使用的图像必须与CORS兼容,否则您将得到如下所示的错误。

Access to image at ‘file:///users/tania/star.png’ from origin ‘null’
has been blocked by CORS policy: The response is invalid.

  在同一个服务器上提供图像将会保证你不会遇到上面的错误。 与其他示例不同,我们将使用 img 代替 div。这次的 CSS 很简单——只需将url()放到shape-outside属性中,就像使用 background-image 一样。

Example text...

.star {
float: left;
height: 350px;
width: 350px;
shape-outside: url(‘./star.png’)
}

因为我使用了透明背景的星星图像,所以文本知道哪些区域是透明的,哪些区域是不透明的,并相应地对自己进行自适应布局。

Gradients

最后,渐变也可以用来当成形状。渐变和图像一样,就像我们上面使用的图像示例一样,文本也将知道在透明部分环绕。 我们将使用渐变的一个新属性 —— shape-image-threshold。shape-image-threshold 定义形状的 alpha 通道阈值,或者图像透明的百分比值。 我们将制作一个渐变例子,它是 50%/50% 的颜色和透明分割,并且设置 shape-image-threshold 为 .5,意味着超过 50% 不透明的所有像素都应被视为图像的一部分。

Example text...

.gradient {
float: left;
height: 300px;
width: 100%;
background: linear-gradient(to bottom right, #86F7CC, transparent);
shape-outside: linear-gradient(to bottom right, #86F7CC, transparent);
shape-image-threshold: .5;
}

  我们可以看到渐变在不透明和透明的中心完美地对角线分割。

总结

在这篇文章中,我们学习了 CSS Shapes 的三个属性 shape-outside、shape-margin 和 shape-image-threshold。我们也了解到如何使用函数值创建可供文本环绕的圆、椭圆、内嵌矩形以及复杂的多边形,并且演示了形状如何检测图像和渐变的透明部分。 你可以在如下 demo 中找到本文中用到的所有例子,也可以下载源文件

See the Pen CSS Shapes Examples by w3cbest.com (@w3cbest) on CodePen.

文章来源: https://tympanus.net/codrops/2018/11/29/an-introduction-to-css-shapes/ 相关阅读参考:https://alistapart.com/article/css-shapes-101 相关阅读参考:https://www.html5rocks.com/en/tutorials/shapes/getting-started/#toc-manual-shapes

在一个新窗口中打开链接是前端开发中一个很常见的逻辑,它可以将用户引导到一个新的域名。我们可以用 target=”_blank”来实现这个功能。我敢肯定,每个人都会在他的某个项目中使用过 target=”_blank”,但是我不确定是否每个人都知道这种用法的缺陷。 当一个外部链接使用了 target=”_blank”的方式,这个外部链接会打开一个新的浏览器tab。此时,新页面会打开,并且和原始页面占用同一个进程。这也意味着,如果这个新页面有任何性能上的问题,比如有一个很长的加载时间,这也将会影响到原始页面的表现。如果你打开的是一个同域的页面,那么你将可以在新页面访问到原始页面的所有内容,包括 document对象( window.opener.document)。如果你打开的是一个跨域的页面,你虽然无法访问到 document,但是你依然可以访问到 location对象。 这意味着,如果你在你的站点或者文章中,嵌入了通过新窗口打开一个新页面的链接,这个新页面可以使用 window.opener,在一定程度上来修改原始页面。

可以参考这个例子,请导航到此链接

我们来看看上面例子发生了什么?当你点击了链接(在打开的 document中),浏览器会打开这个页面。而这个页面中运行了一段 JavaScript代码:通过 window.opener来修改原始页面(你来自的那个页面)。有点乏味但是这可能是有害的。 那么问题来了:我们如何阻止这种情况的发生呢?在所有使用 target=”_blank”打开新页面的链接上,加上 rel=”noopener”。

 

使用了 rel=”noreferrer”以后,当一个新页面通过一个链接打开后,新页面中的恶意 JavaScript代码将无法通过 window.opener 来访问到原始页面。这将保证新页面运行在一个单独的进程里。 在老浏览器中,你可以使用 rel=”noreferrer”属性,具有同样的效果。但是,这样也会阻止 Refererheader被发送到新页面。

在上面的例子中,使用了 rel=”noreferrer” ,当一个用户点击了这个超链接进入到新页面后,新页面拿不到 referrer信息。这将意味着,新页面不知道用户是从哪里来的。 如果你通过 JavaScript中的 window.open打开一个页面的话,上文所说的都适用,因为你也是打开了一个新的窗口。在这种情况下,你不得不清楚掉 opener对象:

var newWindow = window.open();
newWindow.opener = null;

在我看来,使用第一种解决方案(在每一个 target=”_blank”的链接中加上 rel=”noopener”)是没有什么明显的坏处的。这个问题表明,在你的网页安全性中找到漏洞是多么的容易。 本文主要介绍了在使用 <atarget=”_blank”>标签打开一个新窗口过程中的安全问题。新页面中可以使用 window.opener来控制原始页面。如果新老页面同域,那么在新页面中可以任意操作原始页面。如果是不同域,新页面中依然可以通过 window.opener.location,访问到原始页面的 location对象。 试想一下,你在自己的a页面中,通过 打开新窗口,跳转到了b页面,此刻b页面中有一段代码 window.opener.location=”http://c.com”。这是,a页面就会自动跳转到c页面。如果这个c页面是一个和a页面长得一样的钓鱼网站,那么用户可能就中招了。 解决方法就是:在带有 target=”_blank”的 标签中,加上 rel=”noopener”属性。如果使用 window.open的方式打开页面,将 opener对象置为空。这样的副作用是:在某些低版本浏览器中,新页面中拿不到 referer信息。 原文地址:https://medium.com/front-end-weekly/prevent-sending-http-referer-headers-from-your-website-e30eecfe813a

css实现单行文本溢出显示省略号的方法大家应该在网上已经得到想要的答案了吧,就是用text-overflow:ellipsis属性来实现,当然还需要加宽度width属来兼容部分浏览。

实现方法:

.ellipsize-right{
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
width: 200px;
}

See the Pen ellipsize-right by w3cbest.com (@w3cbest) on CodePen.

css的text-overflow:ellipsis文本溢出显示省略号功能非常棒,但本质上只在文本结尾实现省略字符串,假如我们想在文本的开头实现省略字符串,该怎么办?

那么今天我们就来实现以下这个疑问

.ellipsize-left {
/* 标准CSS省略号 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 200px;
/* 字符串的开头 */
direction: rtl;
text-align: left;
}

See the Pen ellipsize-left by w3cbest.com (@w3cbest) on CodePen.

若要在字符串的开头添加省略号,请使用RTL和text-align来剪辑字符串的开头!

一般在开发管理系统的时候经常会用到表格,在使用表格式时通常会给thead部分的th或td加上背景色然后还有边框颜色,在这种情况下浏览器基本都显示正常的,但是当给th或td加上position: relative时火狐浏览器就会显示th或td的边框被遮盖,只显示一片背景色没有边框,如下请在火狐浏览器查看,

See the Pen 火狐浏览器table边框失效问题1 by w3cbest.com (@w3cbest) on CodePen.

我为什么要在th或td加上position: relative呢,我在开发系统的时候使用bootstrap结合jquery.dataTables,不想使用dataTables自带的图标主题,使用的bootstrap.dataTable 的主题,主题的图标是通过伪类:before和:after实现的,所以加上的position: relative,其实这也是主题的一个小bug,然后导致火狐浏览器只会显示背景色边框完全被遮盖。

解决方法1:

去掉th的背景色,把背景色填充在thend 的 tr上,这样就能完全解决这个问题,如下

.table{
thead{
tr{
background-color: #4587E7;
}
th{
position: relative;
color: #fff;
}
}
}

See the Pen 火狐浏览器table边框失效问题2 by w3cbest.com (@w3cbest) on CodePen.

解决方法2:

给th设置一个z-index-1属性,这样也能完全解决这个问题,如下

.table{
thead{
th{
position: relative;
z-index: -1;
color: #fff;
background-color: #4587e7;
}
}
}

See the Pen 火狐浏览器table边框失效问题3 by w3cbest.com (@w3cbest) on CodePen.

扩展阅读:http://www.w3help.org/zh-cn/causes/RE2007

我们在网页开发中实现一个tips时会有一个小箭头,实现这种方法的文章网上已经泛滥了,但有时实现这个小箭头不止只有单纯的三角它还有描边,今天我们就借那些现有的文章在深入一点来说说如何给tips小箭头描边,本章不涉及svg/canvas,没必要因为我讲的是css。

See the Pen 第一种border描边双层覆盖 by w3cbest.com (@xianzhiding) on CodePen.

.dui-tips{
position: relative;
padding: 10px;
text-align: center;
border: 1px solid #f60;
border-radius: 5px;
background-color: #fff;
}

第一种border描边双层覆盖:

就是大家常用的border,实现原理就是给其中一条边设置颜色宽度及样式,我这里使用了两个伪类进行折叠,将一个白色的覆盖在有颜色的伪类上面,再偏移1px来模拟实现1px的描边效果,代码如下:

.dui-tips {
&:before, &:after {
position: absolute;
left: 50%;
display: table;
width: 0;
height: 0;
content: ‘’;
transform: translate(-50%, 0);
border-width: 10px 10px 0 10px;
border-style: solid;
}
&:before {
z-index: 0;
bottom: -10px;
border-color: #f60 transparent transparent transparent;
}
&:after {
z-index: 1;
bottom: -8px;
border-color: #fff transparent transparent transparent;
}
}

See the Pen 第一种border描边双层覆盖 by w3cbest.com (@xianzhiding) on CodePen.

第二种border描边结合滤镜drop-shadow属性:

第二种是第一种的延伸,使用滤镜filter的drop-shadow描边来实现,box-shadow和drop-shadow实现不规则投影 http://www.w3cbest.com/?p=172

.dui-tips {
&:after {
position: absolute;
left: 50%;
display: table;
width: 0;
height: 0;
content: ‘’;
transform: translate(-50%, 0);
border-width: 10px 10px 0 10px;
border-style: solid;
}
&:after {
bottom: -9px;
border-color: #fff transparent transparent transparent;
filter: drop-shadow(0px 2px 0px #f60);
}
}

See the Pen 第二种border描边结合滤镜drop-shadow属性 by w3cbest.com (@xianzhiding) on CodePen.

第三种通过特殊符号”◆”字体双层覆盖

第三种方法和第一种类似,通过两层颜色叠加在有层级的偏移来实现

.dui-tips {
&:before, &:after {
font-size: 24px;
line-height: 18px;
position: absolute;
left: 50%;
display: table;
content: ‘◆’;
transform: translate(-50%, 0);
text-align: center;
}
&:before {
z-index: 0;
bottom: -10px;
color: #f60;
}
&:after {
z-index: 1;
bottom: -8px;
color: #fff;
}
}

See the Pen 第三种通过特殊符号”◆”字体双层覆盖 by w3cbest.com (@xianzhiding) on CodePen.

第四种通过text-shadow实现

这种放发通过给文子设置1px的阴影来显描边效果

.dui-tips {
&:after {
font-size: 24px;
line-height: 18px;
position: absolute;
left: 50%;
display: table;
content: ‘◆’;
transform: translate(-50%, 0);
text-align: center;
}
&:after {
z-index: 1;
bottom: -8px;
color: #fff;
text-shadow: 0 2px 0 #f60;
}
}

See the Pen 第四种通过text-shadow实现 by w3cbest.com (@xianzhiding) on CodePen.

第五种 background双层覆盖

这种方式设置两个宽度和高度分别为10px的方块背景,再给两层背景分别设置不同的颜色,再通过两层背景颜色叠加,经过层级偏移再有transform的rotate属性旋转角度,来实现箭头的朝向。

.dui-tips {
&:before, &:after {
position: absolute;
left: 50%;
display: table;
width: 10px;
height: 10px;
content: ‘’;
margin-left: -5px;
transform: rotate(-45deg);
}
&:before {
z-index: 0;
bottom: -6px;
background-color: #f60;
}
&:after {
z-index: 1;
bottom: -5px;
background-color: #fff;
}
}

See the Pen 第五种 background双层覆盖 by w3cbest.com (@xianzhiding) on CodePen.

第六种background和border背景描边旋转

此方法就是设置一个宽度和高度分别为10px的方块背景,然后背景相邻的两条边描边再有transform的rotate属性旋转角度,来实现箭头的朝向。

.dui-tips {
&:after {
position: absolute;
left: 50%;
display: table;
width: 10px;
height: 10px;
margin-left: -5px;
content: ‘’;
transform: rotate(-45deg);
}
&:after {
z-index: 1;
bottom: -6px;
border-bottom: 1px solid #f60;
border-left: 1px solid #f60;
background-color: #fff;
}
}

See the Pen 第六种background和border背景描边旋转 by w3cbest.com (@xianzhiding) on CodePen.

第七种background和box-shadow

.dui-tips {
&:after {
position: absolute;
left: 50%;
display: table;
width: 10px;
height: 10px;
content: ‘’;
margin-left: -5px;
transform: rotate(-45deg);
}
&:after {
z-index: 1;
bottom: -5px;
background-color: #fff;
box-shadow: -1px 1px 0 #f60;
}
}

See the Pen 第七种background和box-shadow by w3cbest.com (@xianzhiding) on CodePen.

第八种linear-gradient

.dui-tips{
&:before, &:after{
position: absolute;
left: 50%;
display: table;
width: 10px;
height: 10px;
content: ‘’;
margin-left: -5px;
transform: rotate(-135deg);
}
&:before {
z-index: 0;
bottom: -6px;
background: linear-gradient(-45deg, transparent 7px, #f60 0);
}
&:after {
z-index: 1;
bottom: -5px;
background: linear-gradient(-45deg, transparent 7px, #fff 0);
}
}

See the Pen 第八种linear-gradient by w3cbest.com (@xianzhiding) on CodePen.

第九种linear-gradient和box-shadow

.dui-tips{
&:after{
position: absolute;
left: 50%;
display: table;
width: 10px;
height: 10px;
content: ‘’;
margin-left: -5px;
transform: rotate(-135deg);
}
&:after {
z-index: 1;
bottom: -5px;
background: linear-gradient(-45deg, transparent 7px, #fff 0);
box-shadow: -1px -1px 0 #f60
}
}

See the Pen 第九种linear-gradient和box-shadow by w3cbest.com (@xianzhiding) on CodePen.

第十种linear-gradient和border

.dui-tips{
&:after{
position: absolute;
left: 50%;
display: table;
width: 10px;
height: 10px;
content: ‘’;
margin-left: -5px;
transform: rotate(-135deg);
}
&:after {
z-index: 1;
bottom: -6px;
background: linear-gradient(-45deg, transparent 7px, #fff 0);
border-top: 1px solid #f60;
border-left: 1px solid #f60;
}
}

See the Pen 第十种linear-gradient和border by w3cbest.com (@xianzhiding) on CodePen.

第十一种ouline

.dui-tips {
&:before, &:after {
position: absolute;
left: 50%;
display: table;
width: 0;
height: 0;
content: ‘’;
transform: rotate(45deg);
outline-style: solid;
outline-width: 5px;
}
&:before {
z-index: 0;
bottom: -1px;
outline-color: #f60;
}
&:after {
z-index: 1;
bottom: 0;
outline-color: #fff;
}
}

See the Pen 第十一种outline by w3cbest.com (@w3cbest) on CodePen.

你知道我们可以在浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能吗?

现在大多数电脑的显卡都支持硬件加速。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。

在桌面端和移动端用CSS3开启硬件加速

CSS animations, transforms 以及 transitions 不会自动开启GPU加速,而是由浏览器的缓慢的软件渲染引擎来执行。那我们怎样才可以切换到GPU模式呢,很多浏览器提供了某些触发的CSS规则。

现在,像Chrome, FireFox, Safari, IE9+和最新版本的Opera都支持硬件加速,当它们检测到页面中某个DOM元素应用了某些CSS规则时就会开启,最显著的特征的元素的3D变换。

例如:

.cube {
-webkit-transform: translate3d(250px,250px,250px)
rotate3d(250px,250px,250px,-120deg)
scale3d(0.5, 0.5, 0.5);
}

可是在一些情况下,我们并不需要对元素应用3D变换的效果,那怎么办呢?这时候我们可以使用个小技巧“欺骗”浏览器来开启硬件加速。

虽然我们可能不想对元素应用3D变换,可我们一样可以开启3D引擎。例如我们可以用transform: translateZ(0); 来开启硬件加速 。

.cube {
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
/* Other transform properties here */
}

在 Chrome and Safari中,当我们使用CSS transforms 或者 animations时可能会有页面闪烁的效果,下面的代码可以修复此情况:

.cube {
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;
/* Other transform properties here */
}

在webkit内核的浏览器中,另一个行之有效的方法是

.cube {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
/* Other transform properties here */
}

原生的移动端应用(Native mobile applications)总是可以很好的运用GPU,这是为什么它比网页应用(Web apps)表现更好的原因。硬件加速在移动端尤其有用,因为它可以有效的减少资源的利用(麦时注:移动端本身资源有限)。

总结

只对我们需要实现动画效果的元素应用以上方法,如果仅仅为了开启硬件加速而随便乱用,那是不明智的。

小心使用这些方法,如果通过你的测试,结果确是提高了性能,你才可以使用这些方法。使用GPU可能会导致严重的性能问题,因为它增加了内存的使用,而且它会减少移动端设备的电池寿命。

你有在项目中使用过这些方法吗?如果有,请分享你的精彩案例吧。

转载:Increase Your Site’s Performance with Hardware-Accelerated CSS

“我们都经历过重构app,将每个页面分配给团队中的一个人,实现协同开发,但是页面的结构和样式,每个人都会按照自己的方式来实现,这样就很不方便团队的管理,每个人写的都不一样,代码管理困难,您是否有用于创建和实施SASS项目的建议,或者技巧,博客之类的?”

我曾经也有过这样的苦恼,试图让一大群开发人员在没有现有代码标准或风格指南的情况下达成共识,现在我觉得你最好的选择就是先构建标准框架。但是这样可能和应用程序的当前部分之间存在巨大差异,但是在后续的开发中,无论是修复错误还是重构,你都可以问“这符合我们的CSS标准吗?”

第一步

我们必须了解什么是模块化CSS,以及他的好处是什么?不是自己吹嘘。我的这篇演讲可以有助于开发人员更好的理解它的概念。除此之外,我还会向团队推荐SMACSS书籍。 我很幸运能让一位经理开办一个强制性的读书俱乐部,团队中的每个人都必须阅读一本书并参加会议讨论。

第二步

一旦围绕模块化CSS的优势达成某种程度的共识,就可以将您团队的代码标准整合在一起。您既可以自己编写,也可以采用其他团队的。 我强烈推荐Harry Robert的CSS指南,或许补充了Hugo Giraudel的Sass指南。
我一直在为Tempest制作CSS标准文档,我对此感到非常满意。 这是一个很不情愿的工作,试图记录和标准化几年的现有代码实践。 如果我从头开始,我可能会很难切换到BEM命名约定和StyleLint默认格式规则。 不是因为它们是最好的标准,而是因为它们是既定标准,更容易达成一致。

第三步

创建模式库,记录您的模式并将其列在中心位置有两个原因:首先,它可以帮助您的设计人员查看已存在的模式并避免重复。 其次,它可以帮助您的开发人员开始考虑可重用模块与独特页面。

关于通用的Sass技巧:

  • 多使用mixins,【Use mixing instead】;
  • 尽可能的使用变量,理想情况下,您几乎没有在Sass文件中看到硬编码的数字。 这样可以更容易地避免幻数,并且在代码审查提供方便。
  • 将变量保存在中央_variables.scss文件中,以便于查找,并帮助团队记住Sass中的变量是全局变量。
  • 使用main.css文件来负责加载其他Sass文件, 这有助于鼓励您的团队编写更小,更好的范围Sass文件并避免膨胀。
  • 理性情况下,每个模块都应该独立,不受其他模块的影响。 如果每个模块都有自己的Sass partial,那么强制执行此操作的一种方法是随机更改部分加载的顺序。如果这个规则被打破,那么你模块是有漏洞的。

这是一个非常广泛的主题,有许多截然不同的观点。 最重要的是让您的团队同意标准,无论标准是什么。 在一天结束时,你不能阻止一个开发者去做一些非团队标准的事,但是团队有了统一的标准后管理团队的代码规范就容易多了。

译文:How to Define CSS Standards for a Team