翻译:疯狂的技术宅
原文: https://www.creativebloq.com/...
本文首发微信公众号:jingchengyideng
欢迎关注,天天都给你推送新鲜的前端技术文章css
CSS 规范一直在不断发展。尽管在 CSS 新功能的实现很复杂,可是 CSS 工做组仍是决定要把简化版做为新元素添加到规范中。而后由浏览器来实现这些新元素,浏览器自行决定以哪一种顺序去实现它们,这就是为何如今对新功能的支持不匹配的缘由。虽然这可能会使人讨厌,但实际上完成了规范的浏览器要好得多。html
CSS 工做组的成员来自主要浏览器供应商和 Apple 、Adobe等其余技术公司。 Apple 最近推出了新版的 MacOS,并但愿可以在浏览器中检测到新加入的深色模式。为了作到这一点,Apple 推荐了一个新的 5 级媒体查询规范。前端
@media (prefers-color-scheme: light | dark) { … }
使用这个媒体查询,能够检测用户是否正在使用操做系统的浅色或深色模式。不过目前仅支持 Safari Technology Preview 69 及更高版本,但其余浏览器不该落在后面。程序员
为了测试这个功能,你须要升级到 Mojave 10.14(MacOS)并在“系统偏好设置”中选择“深色”。咱们能够经过好几种方式使用这种新的媒体查询来实现不一样的主题。在将在本教程中将会探讨其中的一些内容。面试
首先,咱们须要有一些 HTML 元素来设置样式,因此先到 CodePen 建立一个新文件并添加一些元素。首先添加一个容器,以便将内容集中起来,而后再添加一些标题和文本。将 CSS 设置为使用 Sass 以便在CSS中使用嵌套。segmentfault
<div class="content-container"> <h1>Heading One</h1> <h2>Heading Two</h2> <hr> <p>…</p> <p>…</p> </div>
接下来将会添加一些基本样式,其中包含一些来自Google的字体,这样可以使的页面看起来更好一些。咱们要设置全部基本元素的样式,并应用新的字体大小、颜色和字体。浏览器
body { font-family: 'Merriweather', serif; background-color: #ededed; color: #212121; padding: 1.618rem; line-height: 1.618; font-size: 16px; }
为容器设置一个温馨的阅读样式微信
接下来,为容器设置样式,把内容的行调整为为阅读时温馨的长度。另外还会添加背景颜色和阴影。为了使页面中的内容框居中,在边距属性的左右值上使用关键字 “auto”。ide
.content-container { padding: 1.618rem 3.236rem; max-width: 48.54rem; margin: 3.236rem auto; background-color: #fff; box-shadow: 0 0 12px 6px rgba(0,0,0,0.05); border-radius: .269666667rem; }
选择一种高亮颜色并生成样式测试
大多数网站都会在文本中的某处使用其它颜色,可是目前咱们只有白色和灰色,因此如今要选择一种高亮颜色并用这种颜色的建立样式。咱们使用 span 标签应用颜色,并用它来突出显示文本中的内容。
<span class="text--alpha">Lorem ipsum</span> .text--alpha { color: #c3423f; }
如今有了一些样式,就能够实现媒体查询了
如今咱们有了一个包含一些基本样式的页面,接着实现媒体查询的方法。让咱们包括它并重写一些样式。先从 body 开始。
@media (prefers-color-scheme: dark) { body { background-color: #111; } }
如今你能够覆盖其他的样式
如今能够看到媒体查询正在运行而且 body 的背景颜色已经改变,最后须要覆盖全部剩余的样式。
.content-container { color: white; background-color: #212121; } .text--alpha { color: #50a8d8; }
虽然刚刚完成的 Demo 看上去挺不错,并且能够在小型的网站上进行维护,但这种方法对于更大的项目来讲将会是一场噩梦,由于其中包含有许多不一样的元素,这些元素都须要被重写。同时在上面的例子中大量使用级联,而大型系统可能须要更多的特异性才能定位全部元素。
为了快速实现深色模式,只需用 CSS 滤镜的 “invert”……
那怎样才能解决这个问题呢?咱们可使用 CSS 滤镜的 “invert”,将其应用于 HTML 并反转全部颜色,从而为咱们提供 “深色模式”。
@media (prefers-color-scheme: dark) { html { filter: invert(100%); } }
固然,你的照片看起来会像这样
虽然滤镜方法在咱们文档中的内容上起了做用,可是看起来不太好 —— 例如盒子阴影也被倒置了,这看起来很奇怪。咱们已经失去了对样式的控制,当你用了彩色背景时,会出现一个更大的问题。看看你的照片变成了什么样子。
到目前为止,咱们探索过的方法要么会失去对样式的控制,要么须要大量的维护才能确保全部内容都在深色模式下更新。不过还有一种方法能够解决这个问题:能够用自定义属性来定义颜色,而后使用媒体查询覆盖它们。
为了使用自定义属性,咱们在:root
元素内的CSS顶部定义它们。根元素具备与 HTML 相同的范围,所以能够全局使用。咱们须要肯定变量名称并定义它们的值。
:root { --background-color: #ededed; --page-background: #fff; --text-color: #212121; --color-alpha: #c3423f; }
如今定义了一些能够在CSS中使用的自定义属性。咱们将从正文开始,并应用背景和文本颜色。为了使用自定义属性,咱们用了 var(--custom-property-name)
语法。
body { background-color: var(--background-color); color: var(--text-color); }
使用相同的方法,咱们还能够更新容器的background-color
和text-alpha
类的color
,让它们也使用自定义属性。如今,页面中全部得颜色都使用自定义属性进行控制。
.content-container { background-color: var(--page-background); } .text--alpha { color: var(--color-alpha); }
如今从新添加媒体查询,但此次咱们能够覆盖其中的自定义属性值。把它放在原始根定义以后,在媒体查询中,能够简单地为全部颜色自定义属性选择新值。
@media (prefers-color-scheme: dark) { :root { --background-color: #111; --page-background: #212121; --text-color: #ededed; --color-alpha: #50a8d8; } }
自定义属性使咱们能够彻底控制选择本身的颜色和其余属性。可以对页面容器上的边框阴影进行更新,使其在使用深色模式时不太透明。索引咱们须要为页面阴影建立一个新的自定义属性。
:root { … --page-shadow: 0 0 12px 6px rgba (0,0,0,0.05); }
如今咱们已经有了另外一个自定义属性,接下来须要将它应用于页面上正确的元素。而后覆盖root元素中的值,以下降透明度。
@media (prefers-color-scheme: dark) { :root { … --page-shadow: 0 0 12px 6px rgba(0,0,0,0.33) ; } } .content-container { … box-shadow: var(--page-shadow); }
添加图像并将其浮动到内容旁边
如今将图像添加回咱们的内容,而后能够添加一些基本样式来将图像浮动到内容旁边。
img { width: 100%; height: auto; float: left; max-width: 300px; margin-right: 1.618rem; margin-bottom: 1.618rem; }
能够看到,因为没有使用任何滤镜,因此图像在两个主题之间不会改变。
如今咱们已经得到了自定义属性,能够继续向页面添加元素,并使用变量为它们设置样式。让咱们建立一个按钮类,并在页面中添加一个按钮。
.button { display: inline-flex; font-family: inherit; background-color: var(--color-alpha); color: var(--text-color); padding: 1.618rem 3.236rem; border: 0 none; border-radius: 0.25rem; text-decoration: none; }
使用相同的变量,还能够建立可用于两个主题的悬停样式。为了实现这一点,当用户将鼠标悬停在按钮上并转换这些属性时,咱们将反转颜色。
.button { … transition: background-color 150ms, color 150ms; &:hover { background-color: var(--text-color); color: var(--color-alpha); } }
自定义属性与常规 CSS 元素具备相同的范围,这意味着能够用更加具体的选择器覆盖它们。能够利用这个特性并建立一些做用于按钮的变量。
.button { --button-background: var(--color-alpha); --button-text: var(--background-color); background-color: var(--button-background); color: var(--button-text); … }
使用 scope 为按钮建立不一样的样式和交互
咱们能够利用 scope 为深色和浅色主题的按钮建立不一样的样式和悬停交互。能够根据媒体查询或元素的状态修改变量的值,而不是像往常同样使用新值重复属性。
.button { … &:hover { --button-background: #ae3937; @media (prefers-color-scheme: dark) { --button-background: #2e98d1; --button-text: var(--background- color); } } }