【译】CSS继承:介绍

css继承

在现实生活中看到继承行为是常见的。除非有其他因素发挥作用,否则高大的父母常常会有高大的孩子等等。我们可以在CSS中看到类似的东西。

如果将容器元素的颜色设置为绿色,则容器中所有元素的颜色将为绿色,除非某些规则覆盖该颜色值。将某些属性的值从父元素传递给子元素的机制称为继承。

在本文中,你将了解继承的各个方面以及它是如何影响不同元素的外观的。

CSS继承的作用?

CSS继承大大减少了创建网站所需的时间和精力。想象一下,你需要写多少CSS来设置body标签的所有子元素的颜色。这将是耗时的、易错的以及难以维护的。同样,你可以想像如果你被迫在容器的每个子元素上设置font-familyfont-size,那将是一场噩梦。

看下面的示例:

这里我已经在body元素中定义了font-familyfont-sizeline-height属性,但所有这些值都是由嵌套在body中的不同元素继承而来的。
这使得布局的统一性不需要在多个元素上重复相同的属性。

只有某些属性被继承

在现实生活中,不是父母的全部特征都会传给子女。在CSS中也是如此,不是每个CSS属性都默认由子元素继承。实际上,如果所有的属性都是继承的,那么这个效果就好比没有继承,你必须编写大量的CSS来覆盖这些行为。

例如,如果border属性是可继承的,则在单个元素上设置边框将导致在其所有子元素上显示相同的边框。同样,如果子元素从他们的父元素继承了background-image属性,结果就会变得混乱。以下CodePen示例演示了如何使用CSS关键字值来查看这种情况,我将在下一节中讨论:

强制继承

一般来说,是否使属性可继承属于常识。例如,除了上一节中讨论的示例之外,你可能不希望元素的所有子元素都继承其父元素的padding值。但是,如果文本的颜色或用于容器的不同子元素的字体相同,那么你通常会更喜欢。

在某些情况下,特殊的属性可能不会继承,但你可能仍希望从父元素继承。这可以通过将子元素的该属性值设置为inherit来实现:

.some-child {
  color: inherit;
}

假设你想要将网站上所有链接元素的颜色与其父元素上定义的颜色相同。有几种方法可以做到这一点。例如,你可以使用不同的类用于具有不同颜色的链接和容器元素。但是,最简单的方法之一是使用inherit关键字。

一旦链接元素的颜色属性设置为inherit,它们将开始继承父元素的颜色:

p {
  color: #f44336;
}

ul {
  color: #3f51B5;
}

a {
  color: inherit;
}

示例:

使用CSS简写的继承

inherit关键字的一个特性是当你将其应用于简写属性时,它将应用于所有子属性,甚至起初你可能没有实现的那些属性也被强制继承。另外,使用简写时,你也不能指定其中单个子属性继承值。

例如,你可能希望以下CSS应用1px宽度的实线边框,其颜色从父元素继承。然而,声明实际上是无效的:

.example {
  /* 无效 CSS */
  border: 1px solid inherit;
}

类似地,你不能使用简写属性将margin或padding的一边设置为特定值,另一边设置为继承值。这将再一次使声明无效:

.example {
  /* 无效 CSS */
  margin: 10px inherit 20px 15px;
}

这个问题的解决方案是,将想要继承的属性值设置任意值,然后将它相对应的普通属性(非简写)值设为inherit

.example {
  margin : 10px 0 20px 15px;
  margin-right: inherit;
}

缺省简写值

当简写时,其值尚未明确提供的任何缺省子属性将被设置为其初始值(或默认值)。思考下面的CSS:

.container-a {
  font: italic 1.2em/1.75 Lato;
}

.container-a p {
  font: bold 1em Lato;
}

在这里,段落文本将不会从其容器继承font-style的值。 font-style值实际上将被重设为初始值normal。因此,在这种情况下,如果你想要继承父母font的简写,同时仍然确保该段保持粗体,则必须使用普通写法的font-weight属性。

使用DevTools查看继承值

可以使用DevTools来查看元素从其父元素或DOM树中的另一个元素继承的属性。
如前所述,并不是父元素的所有属性都是可继承的。所有可继承的属性也不会将其转到继承链的末尾,而不会被别的其他CSS规则覆盖。

DevTools为你提供不同的视觉提示,以便轻松区分所有这些属性,你可以从下面的截图中看到,截取自SitePoint的CSS:

在DevTools中查看CSS继承

所选元素不可继承的任何属性都会变暗。可继承但被覆盖的属性将以删除线文本显示。

可继承的CSS属性列表

似乎没有一个唯一明确的来源列出所有可继承的CSS属性,但下面可能是一个正确的列表,基于几个来源:

  • border-collapse
  • border-spacing
  • caption-side
  • color
  • cursor
  • direction
  • empty-cells
  • font-family
  • font-size
  • font-style
  • font-variant
  • font-weight
  • font-size-adjust
  • font-stretch
  • font
  • letter-spacing
  • line-height
  • list-style-image
  • list-style-position
  • list-style-type
  • list-style
  • orphans
  • quotes
  • tab-size
  • text-align
  • text-align-last
  • text-decoration-color
  • text-indent
  • text-justify
  • text-shadow
  • text-transform
  • visibility
  • white-space
  • widows
  • word-break
  • word-spacing
  • word-wrap

还有一些与语音相关的CSS属性是可继承的,但不包括在上面的列表中。

以下是可继承属性列表的几个来源:

你还可以在规范中或任何全面的CSS引用中查看单个CSS属性的信息,通常会告诉你该属性是否在默认情况下可继承。

总结

总结一下我讨论过的内容:继承可以避免编写重复的CSS规则,以将同一组属性应用于元素的所有后代。它大大简化了向网页添加样式的过程,因此是CSS的一个很好的特性。

CSS还允许你使用inherit关键字强制对未在默认情况下继承的属性继承。 DevTools可以让你轻松访问元素从其祖先继承的所有属性。这可以帮助你快速找出常见布局相关问题的解决方案。

推荐阅读

Build Responsive Real World Websites with HTML5 and CSS3

HTML & CSS: 200+ Most Important Q&A for Interviews & Exams.

Step By Step HTML and CSS course for beginners

Bootstrap 4 From Scratch With 5 Projects

原文来源:https://www.sitepoint.com/css-inheritance-introduction/

【译】如何使用Chrome开发者工具的移动设备仿真器

网站测试变得越来越复杂。仅仅在几个浏览器中检查功能的日子一去不复返了。你的最新杰作必须在一系列具有不同操作系统,屏幕分辨率和功能的移动、平板和桌面设备上进行严格评估。在极端情况下,它可能需要与原始开发一样长的时间。

该过程进一步被触摸屏、混合设备和高密度显示器复杂化。如果你使用鼠标和键盘在普通的PC上编码,将很难理解你的杰作如何操作。鼠标悬停等功能不一定会起作用,你的应用程序可能无法使用。但是,如何在开发过程中测试你的系统,避免在多个设备之间运行和切换的痛苦?

幸运的是,所有现代浏览器都提供移动设备仿真工具,并且Chrome中的移动设备仿真工具就是最好的工具之一。它可以在不离开舒服的PC开发环境下,帮助你识别早期的问题。

开发工具

启动Chrome,打开要测试的网页,然后打开开发者工具(菜单》更多工具》开发者工具,Mac快捷键是Cmd+Opt+I或F12,Windows和Linux快捷键是Ctrl+Shift+I)。

现在,你可以通过单击左上角的切换设备工具栏图标来启用浏览器仿真器:

启用移动设备仿真器

现在将出现设备仿真:

移动设备仿真器

当选择响应(Responsive)作为设备类型时,可以更改仿真屏幕的尺寸。

触摸启用仿真

将鼠标移到设备上可查看圆形“触摸”光标。这将对基于触摸的JavaScript事件(如touchstarttouchmovetouchend)做出反应。鼠标特定的事件和CSS效果不会做出反应。

按住Shift键,然后单击并移动鼠标以模拟双指缩放操作。

移动仿真器设备工具栏

值得花一点时间来让自己熟悉移动仿真器上方的工具栏和菜单:

移动手机仿真器设备工具栏

默认设置有:

  • 设备类型(或简称响应(Responsive)
  • 当前分辨率
  • 缩放(屏幕可以放大或缩小以更好得适合仿真器面板)
  • 竖屏/横屏切换按钮(假设选择了响应(Responsive)之外的设备)

三点菜单允许你显示或隐藏其他设置:

  • 设备边框(如果可用,手机或平板电脑的外观图形)
  • 媒体查询
  • 像素标尺
  • 设备像素比(例如2.0用于仿真的视网膜屏幕)
  • 设备类型(类别如“mobile”或“tablet”)
  • 网络限制(一种在较慢的连接上限制带宽和测试性能的方法)
  • 捕获包括设备边框(如果显示)的屏幕截图。
  • 最后一个选项允许你重置以上这些设置到默认状态。

移动手机仿真器设备工具栏选项

CSS媒体查询工具栏

工具栏下方的栏显示一系列典型的手机,平板电脑和设备尺寸。当选择响应(Responsive)作为设备的宽度设置时,可以单击此选项。

从三点菜单中选择显示媒体查询(Show media queries),以查看在CSS中设置的所有媒体查询的图形颜色编码表示。

Chrome移动设备仿真器媒体查询

  • 蓝色——以最大宽度的查询
  • 绿色——以一个范围内宽度的查询
  • 橘色——以最小宽度为目标的查询

可以单击任何颜色的条形栏以将仿真器屏幕设置为该宽度。

仿真设备选项

左侧的下拉菜单允许你选择设备。为流行的智能手机和平板电脑提供了几十个预设,包括iPhone,iPad,Kindles,Nexus平板电脑,三星Galaxy等。

并非所有设备都会同时显示在这里 – 选择设备下拉菜单中的编辑(Edit)…,或从开发者工具菜单(F1)中选择设置(Settings),然后选择设备(Devices)标签:

Chrome移动设备仿真器设备

你可以启用或禁用设备或通过以下定义输入你自己的设备:

  • 名称
  • 类型,比如“Mobile”或“Tablet”
  • 浏览器user agent字符串
  • 设备分辨率
  • 像素比(例如iPhone Retina屏幕的像素比是2,其中像素密度是所报告的视口分辨率的两倍高)。

请注意,所有浏览器都使用HTTP headers中的用户代理(UA)字符串来标识自己。这可以在客户端或服务器端上检查,并且在web开发的黑暗日子期间(各个浏览器相互之间不兼容),将用于修改或提供不同的用户体验。在极端情况下,浏览用户将被引导到不同的站点。该技术总是有缺陷的,但由于响应的网页设计技术和完全不可持续的市场上提供的设备数量已经变得很大程度上冗余。

带宽限制模拟

限制(Throttling)下拉菜单允许你模拟移动连接或不可靠的酒店和机场WiFi经常遇到的慢网络速度!你可以使用它来确保你的网站或应用程序快速加载,并在所有环境中保持响应。

网络(Network)标签和Chrome的设备工具栏(启用时)可以使用限制下拉菜单。你可以通过选择限制下拉菜单底部的编辑(Edit…)或从开发者工具菜单(F1)中选择设置(Settings)并选择限制(Throttling)选项卡来设置自己的带宽配置:

Chrome移动设备仿真器带宽

单击添加自定义配置文件(Add custom profile),然后输入:

  • 配置文件名称
  • 下载速度(千比特每秒)
  • 上传速度(千比特每秒)
  • 以毫秒为单位的延迟(在进行网络请求时的典型延迟)

仿真移动传感器

智能手机和平板电脑通常具有传感器,例如在台式设备中不存在的GPS,陀螺仪和加速度计。这些可以在Chrome中通过选择更多工具(More tools),然后从开发工具主三点菜单中选择传感器(Sensors)

Chrome移动设备仿真器带宽

将出现一个新面板,你可以定义:

  • 当前的纬度和经度,或从下拉列表中选择一个主要城市。你也可以选择禁用位置,用来模拟当设备无法获取GPS信号时应用程序的反应。
  • 方向。有几个可用的预设方向,或者可以通过单击和拖动来移动设备图像来改变方向。

远程真实设备调试

最后,Chrome允许你通过USB连接真实的Android设备进行远程设备调试。从开发者工具主三点菜单中选择更多工具(More tools),然后选择远程设备(Remote devices)。确保勾选Discover USB debices,然后连接手机或平板电脑,并按照说明进行操作。

Chrome允许你设置端口转发,以便导航到设备上本地服务器上的网址。 Chrome的预览面板显示设备屏幕的同步视图,你可以使用设备或Chrome本身进行交互。

全方位的开发者工具包括应用程序(Application)选项卡,可用于在离线模式下测试Progressive Web Apps。请注意,不同于需要HTTPS的真实应用程序,Chrome允许PWA通过HTTP连接从本地主机运行。

太棒了!我现在不需要任何设备!

Chrome的移动浏览器模拟器非常实用和强大,但它不能替代在真实设备上与你的网站或应用互动,以评估完整的用户体验。

你也应该知道,没有设备模拟器是完美的。例如,Chrome在iPhone或iPad上显示网页的表示,但不会尝试模拟Safari的标准支持或怪异模式(quirks)。

尽管如此,对于快速和讨厌的移动测试,Chrome的设备模拟器是优秀的。它比在真正的智能手机和平板电脑设备之间切换容易得多,你将拥有所有的开发工具。这将节省工作量。

【译】TypeScript 2.2 候选版发布

TypeScript 2.2即将到来,今天我们发布候选版!

如果你是第一次听说TypeScript,那不要紧的,因为TypeScript是一门在JavaScript的基础上添加可选静态类型的语言。基于JavaScript构建,意味着你不需要学习JavaScript以外太多的知识,并且所有现有的代码你也可以使用TypeScript。同时,TypeScript添加的可选类型可以帮助您捕获讨厌的bug,还有通过启用强大的工具支持能提高工作效率。

今天就试试候选版本,你可以使用NuGet获取,或者使用npm运行

npm install -g typescript@rc

您还可以获取Visual Studio 2015的TypeScript版本候选版本(如果已经安装了Update 3)。对其它编辑器的支持得等到我们正式的2.2版本,但你可以看看在Visual Studio CodeSublime Text 3中如何启用更高版本的TypeScript的指南。

为了告诉你新增了哪些特性,这里有几个值得注意的特性来了解此候选版本。

object类型

有些时候,一个API允许你传递除基本类型外任何类型的值。例如,思考Object.create,除非你传递一个对象或null给第一个参数,否则它抛出一个异常。

// 所有这些在运行时都会抛出错误!
Object.create(undefined);
Object.create(1000);
Object.create("hello world");

如果我们试图想出第一个参数的类型,一个简单的方法可能是Object | null。不幸的是,这并不完全奏效。由于结构类型在TypeScript中工作的方式,numberstringboolean都属于Object

为了解决这个问题,我们创建了新的object类型(注意所有这些字母都是小写的!)。
一个更直白的名称可以叫“非基本”类型。

object类型是“空” – 它没有属性,就像{}类型。
这意味着几乎一切都可以分配给object,除了基本类型外。
换句话说,将与numberbooleanstringsymbolnullundefined类型不兼容。

但这意味着我们现在可以正确地将Object.create的第一个参数类型作为object | null

我们预期object基本类型将帮助捕获一大类bug,并更准确地模拟真实世界规范。

我们非常感谢Herrington Darkholme的援手实现这个特性!

改进了对mixins和组合类的支持

mixin模式在JavaScript生态系统中相当常见,在TypeScript 2.2中,我们对语言进行了一些调整,以更好地支持它。

为了做到这一点,我们在TypeScript 2.2中删除了对类的一些限制,就像能够从构造交集类型的值中扩展一样。它还以交集类型上的签名组合的方式调整一些功能。结果是你可以写一个函数

  1. 接受构造函数
  2. 声明一个继承该构造函数的类
  3. 向该新类添加成员
  4. 并返回类本身。

例如,我们可以编写接受一个类的Timestamped函数,并通过添加一个timestamp成员来扩展它。

/** Any type that can construct *something*. */
export type Constructable = new (...args: any[]) => object;

export function Timestamped<BC extends Constructable>(Base: BC) {
 return class extends Base {
 timestamp = new Date();
 };
}

现在我们可以使用任何类通过Timestamped,快速组成一个新的类型。

class Point {
 x: number;
 y: number;
 constructor(x: number, y: number) {
 this.x = x;
 this.y = y;
 }
}

const TimestampedPoint = Timestamped(Point);

const p = new TimestampedPoint(10, 10);
p.x + p.y;
p.timestamp.getMilliseconds();

类似地,我们可以写一个Tagged函数来添加一个tag成员。这些函数实际上使得很容易组合扩展。制作一个带有标签和时间戳的特殊3D点是相当干净的。

class SpecialPoint extends Tagged(Timestamped(Point)) {
 z: number;
 constructor(x: number, y: number, z: number) {
 super(x, y);
 this.z = z;
 }
}

新的JSX生成模式:react-native

在TypeScript 2.1和更早版本中,--jsx编译参数可以使用两个值:

  • preserve 保留JSX语法,并生成.jsx文件。
  • react 将JSX转换为对React.createElement的调用并生成.js文件。

TypeScript 2.2有一个新的JSX生成模式称为react-native,它处于中间位置。在这个方案下,保留JSX语法,但生成.js文件。

这个新模式包含React Native的加载器,它希望所有输入的文件都是.js文件。它既能满足你保留JSX语法又可以从TypeScript获取.js文件的情况。

下一步

我们无法在本篇博客中列出我们工作的一切,你可以在TypeScript Roadmap中看看还有哪些特性。

我们期望您的反馈帮助TypeScript 2.2固定版本的发布!
如果你遇到任何可能的bug,请随时在这里留下反馈,或在GitHub上提出问题