交互设计文档示例
by Maciej Nowakowski
通过Maciej Nowakowski
带有交互示例的样式化组件快速指南 (A Quick Guide to Styled Components with Interactive Examples)
“That’s interesting…” I thought when I first read about styled-components. And then I went right back to my tried-and-tested React components.
“这很有趣……”当我第一次阅读有关样式化组件的想法时,我想。 然后我又回到了经过考验的React组件。
But then Max Stoiber, the co-creator of styled-components, showed us his new library at the React in Flip Flops coding bootcamp. “That’s interesting” turned into “That’s mind-blowing!”
但是随后,样式元素的共同创建者Max Stoiber 在Flip Flops编码训练营的React上向我们展示了他的新库。 “那很有趣”变成了“那令人难以置信!”
I could hardly contain my excitement. I finally understood the concept behind styled-components. It opened so many new possibilities for how to style components. It simplified the way to structure web applications. And it enforced the consistency into the styling of React apps.
我几乎无法抑制自己的激动。 我终于了解了样式化组件背后的概念。 它为如何样式化组件提供了许多新的可能性。 它简化了构建Web应用程序的方式。 并且它在React应用程序的样式中实现了一致性。
这一切都始于带标签的模板文字 (It all started with tagged template literals)
You might think I’m a bit old school but I believe that if you want to truly understand any idea, you need to wrap your head around the underlying concepts. We could dive straight into styled components. But first, let’s find out what sparked Max and Glen’s curiosity before they started the project and actually built styled-components.
您可能认为我有点老了,但是我相信,如果您想真正理解任何想法,就需要将头绪围绕在基本概念上。 我们可以直接研究样式化的组件。 但是首先,让我们先找出是什么激发了Max和Glen的好奇心,然后他们才开始项目并实际构建样式化组件。
ES6’s template literals simplify the way how you can mix variables and text. If you take two variables: name
and mood
, with assigned values of “Alice” and “happy” respectively, the template literal:
ES6的模板文字简化了混合变量和文本的方式。 如果采用两个变量: name
和mood
,则分别为它们分配值“ Alice”和“ happy”,模板文字:
const sentence = `${name} is ${mood}.`;
will produce a sentence: “Alice is happy.”
会产生一句话:“爱丽丝很高兴。”
Tagged template literals take the syntax a step further.
带有标记的模板文字使语法更进一步。
Tags are JavaScript functions. But there are two essential differences in comparison to regular functions:
标签是JavaScript函数。 但是与常规功能相比有两个本质区别:
tag functions are called using backticks notation instead of parentheses. In the example below, we are calling the
greetingTag
function by wrapping the arguments in backticks:使用反引号而不是括号来调用标记函数。 在下面的示例中,我们通过将参数包装在反引号中来调用
greetingTag
函数:
greetingTag`${name} is ${mood}.`;
JavaScript treats the template literal — everything between backticks — as function arguments. In the first step, JavaScript transforms the template literal into an array of strings. The strings are followed by extracted variables. If we take the example above, the transformed arguments passed to the
greetingTag
function will look as follows:JavaScript将模板文字(反引号之间的所有内容)视为函数参数。 第一步,JavaScript将模板文字转换为字符串数组。 字符串后跟提取的变量。 如果以上面的示例为例,则传递给
greetingTag
函数的转换后的参数如下所示:
["", " is ", "."], name, mood
The first argument, an array, contains all strings that we placed before, between and after the name
and the mood
variables. In our example, the first string is empty because there is nothing before the name
. The next two arguments, name
and mood
, were extracted from the template literal as variables.
第一个参数是一个数组,包含我们在name
和mood
变量之前,之间和之后放置的所有字符串。 在我们的示例中,第一个字符串为空,因为name
之前没有任何内容。 接下来的两个参数name
和mood
从模板文字中提取为变量。
Now, the greetingTag
function can apply any logic to the texts’ array and the name
and mood
variables and return the desired outcome.
现在, greetingTag
函数可以将任何逻辑应用于文本数组以及name
和mood
变量,并返回所需的结果。
Let’s create a tag function, the greetingTag
, that will take three arguments: a texts
array, a name,
and a mood
variables. And here is the logic it will use: if the value of mood
is "happy”, it will return a regular greeting sentence. In all other cases, it will return the cheer-up version of the greeting:
让我们创建一个标记函数greetingTag
,它将使用三个参数:一个texts
数组,一个name,
和一个mood
变量。 这是它会使用的逻辑:如果mood
的值是“ happy”,它将返回一个常规的问候语;在所有其他情况下,它将返回问候语的振作版本:
const greetingTag = (texts, name, mood) => { if (mood === 'happy') { return `Hi ${name}!`; } else { return `Hi ${name}, you are awesome!`; } } const greeting = greetingTag`${name} is ${mood}.`;
Now, if we assigned “Alice” to the name
and “happy” to the mood
, the greetingTag
function would return: “Hi Alice!”. If we changed the value of the mood
to any other word than “happy” - say “excited” or “cat” —the greetingTag
would return: “Hi Alice, you are awesome!”.
现在,如果我们给name
分配“ Alice”,为mood
分配“ happy”,则greetingTag
函数将返回:“ Hi Alice!”。 如果我们将mood
的值更改为除“ happy”(快乐)或“ cat”(猫)之外的任何其他单词,则greetingTag
将返回:“嗨,爱丽丝,您真棒!”。
But how can you use this knowledge to style React components?
但是,如何使用这些知识来对React组件进行样式设置?
样式化的组件 (Styled components)
This exact question puzzled Max and Glenn while they were looking for a better and more consistent way of styling React components. The Aha! moment came when they realized that tagged template literals accept not only variables but also functions. Like in the example below:
这个确切的问题使Max和Glenn在寻找更好和更一致的React组件样式方法时感到困惑。 啊哈! 当他们意识到带标签的模板文字不仅接受变量而且接受函数的时刻到来了。 像下面的例子一样:
const greeting = greetingTag`${ name => `Hi ${name}!` }`;
Here, the greetingTag
receives a template literal with a function. Once the function is executed by the greetingTag
, the greetingTag
can apply further logic to the returned value and return an outcome.
在这里, greetingTag
接收带有函数的模板文字。 一旦函数由greetingTag
执行,则greetingTag
可以将其他逻辑应用于返回的值并返回结果。
Styled components are also tag functions. But instead of accepting greeting patterns, they accept template literals that contain CSS styles. And instead of greeting sentences, they return React components.
样式化的组件也是标签功能。 但是,它们不接受问候模式,而是接受包含CSS样式的模板文字。 它们返回问候语组件而不是问候语。
Let me show you how it works.
让我告诉你它是如何工作的。
Side note: The code examples below are interactive. You can play around with them, add styles and change assigned values. You can inspect different files by clicking on their tabs. Or press the orange, blue-orange or blue button at the top to switch between different views.
边注: 下面的代码示例是交互式的。 您可以使用它们,添加样式并更改分配的值。 您可以通过单击其他文件的选项卡来检查它们。 或按顶部的橙色,蓝橙色或蓝色按钮在不同视图之间切换。
If you want to use styled components in your application, you have to install styled-components
first:
如果要在应用程序中使用样式化的组件,则必须先安装styled-components
:
npm install --save styled-components
Below, I created a styled component Title
:
在下面,我创建了一个样式化的组件Title
:
The styled.h1
is a tag function. It returns a React component that is identical to the one below:
styled.h1
是标记函数。 它返回一个与以下组件相同的React组件:
import React from 'react'; const Title = ({children}) => <h1>{children}</h1>
The beauty of this solution is that styled-components do the heavy lifting for you — your component Title
will have the color
of royalblue
.
此解决方案的优点在于,样式化的组件可以为您完成繁重的工作-您的组件Title
将具有royalblue
的color
。
I know what you’re thinking: if we had to write styles of every single component in this way, that wouldn’t be much different from writing CSS classes. Thankfully, styled components are much smarter!
我知道您在想什么:如果我们必须以这种方式编写每个组件的样式,则与编写CSS类没有什么不同。 幸运的是,样式化的组件要聪明得多!
Imagine that you would like to keep your headers black most of the time and only sporadically highlight them using a different color. With styled components, we can create a color-aware Title
that will be black
by default and change to royalblue
whenever we pass it a primary
prop:
想象一下,您想在大多数情况下将标题保留为黑色,而仅使用不同的颜色偶尔将其突出显示。 使用样式化的组件,我们可以创建一个可识别颜色的Title
,默认情况下将为black
,并在每次通过primary
道具时将其更改为royalblue
:
You can pass props to the Title
like to any other React component. Here, the second Title
receives the primary
prop. We can access the props inside a styled component declaration. That opens a whole new world of possibilities.
您可以像其他任何React组件一样将props传递给Title
。 在这里,第二个Title
获得primary
道具。 我们可以在样式化的组件声明中访问props。 这为可能性开辟了一个全新的世界。
Above, I defined the styled component Title.
Because the props
are accessible inside the styled component declaration, we can decide which color our component will be. The function uses the ternary operator and returns royalblue
when the primary
property is true
and black
otherwise.
在上面,我定义了样式化的组件Title.
因为可以在样式化的组件声明中访问props
,所以我们可以决定组件将使用哪种颜色。 该函数使用三元运算符,并且当primary
属性为true
时返回royalblue
,否则返回black
。
You don’t have to write it explicitly as in:
您不必像下面这样显式地编写它:
<Title primary={true}>Hi Bob, you are awesome!</Title>
Passing the primary
prop without an assignment is like passing primary={true}
.
在没有分配的情况下传递primary
道具就像传递primary={true}
。
Since the door is now wide open, let’s make our Title
more universal. Sometimes you may need your Title
to use smaller fonts and sometimes bigger. Sometimes you may want it to have a normal weight and sometimes you may want it to stand out and give it a bold font weight. And sometimes you may want to capitalize or uppercase the Title
.
由于现在这扇门是敞开的,因此让我们更广泛地使用“ Title
。 有时您可能需要Title
来使用较小的字体,有时使用较大的字体。 有时您可能希望它具有正常的粗细,而有时您可能希望它脱颖而出并为其加粗字体。 有时您可能想将Title
变为大写或大写。
Styled components allow you to create a single universal component. Then you can use it everywhere without thinking about styles anymore:
样式化的组件允许您创建一个通用组件。 然后,您可以在任何地方使用它,而无需考虑样式:
In the example above, the font-size
is assigned explicit values: 48px
or 32px
. Such code is hard to maintain when the codebase grows.
在上面的示例中, font-size
被分配了显式值: 48px
或32px
。 当代码库增长时,此类代码很难维护。
主题 (Themes)
When you create a set of styled components for later use, you want to enforce consistent styling across the application. It’s always worthwhile to set the styling rules. Preferably, in a separate file. Later, when you have to change the styles, instead of re-visiting all your components, you can alter styling in just one place.
当创建一组样式化的组件以供以后使用时,您希望在整个应用程序中实施一致的样式。 设置样式规则总是值得的。 最好在单独的文件中。 以后,当您不得不更改样式时,不必重新访问所有组件,而只需在一个地方更改样式即可。
Styled components give you a tool to do exactly that — themes.
样式化的组件为您提供了一种可以准确地实现此目的的工具-主题。
A theme
is a JavaScript object where you can define styling parameters:
theme
是一个JavaScript对象,您可以在其中定义样式参数:
const theme = { colors: { primary: "royalblue", secondary: "teal", text: "black" }, fontSize: { xl: "2.4rem", lg: "1.8rem", md: "1.3rem", nm: "1rem", sm: "0.75rem" } }
The theme
above defines colors
and fontSize
properties. You will be able to access them in all styled components across the application.
上面的theme
定义了colors
和fontSize
属性。 您将能够在应用程序的所有样式化组件中访问它们。
But first, you need to make the application aware of the theme
. You have to pass it as a prop to the ThemeProvider
— a wrapper component provided by styled components:
但是首先,您需要使应用程序知道theme
。 您必须将它作为道具传递给ThemeProvider
由样式化组件提供的包装器组件:
import { ThemeProvider } from "styled-components"; import theme from "./theme.js";
const App = () => ( <ThemeProvider theme={theme}> <div> <Title>Hi, Alice!</Title> </div> </ThemeProvider> )
Let’s take the previous example to learn how to use a theme
and how to access its properties inside styled components.
让我们以前面的示例为例,学习如何使用theme
以及如何在样式化组件内部访问其属性。
In the Title
, you can access the theme
object via the props.theme
. For example, to select the Title
's color, you check first if a given attribute has been passed to the Title
(primary
or secondary
). Then return the corresponding color
value declared in the theme
. If none has been passed, you return a standard text
color.
在Title
,您可以通过props.theme
访问theme
对象。 例如,要选择Title
的颜色,请首先检查给定的属性是否已传递给Title
( primary
或secondary
)。 然后返回在theme
声明的相应color
值。 如果没有通过,则返回标准text
颜色。
The Title
can now decide also about its font sizes. It checks first if an xl
, lg
, md
or sm
prop has been passed and — based on that — assigns appropriate value to the font-size
property. If no prop has been passed, it will assign the value of fontSize.nm
defined in the theme
.
Title
现在也可以决定其字体大小。 它首先检查是否已传递xl
, lg
, md
或sm
属性,并基于此属性将适当的值分配给font-size
属性。 如果未传递任何道具,它将分配在theme
定义的fontSize.nm
的值。
We have just created a flexible Title
component. Now, you can use it without having to worry about CSS. You can decide on its look exclusively by passing a specific set of props
.
我们刚刚创建了一个灵活的Title
组件。 现在,您可以使用它而不必担心CSS。 您可以通过传递一组特定的props
来专门决定其外观。
扩展样式组件 (Extending styled-components)
Creating just one Title
component is not enough. For example, on a blog page, you will need an h1
tag for a post title and an h2
tag for subtitles. You need also paragraphs to display text.
仅创建一个Title
组件是不够的。 例如,在博客页面上,您将需要一个h1
标签(用于帖子标题)和一个h2
标签(用于字幕)。 您还需要段落来显示文本。
Styled components are easily extendable. You can create a new Subtitle
component with an h2
tag and copying and pasting all the styling rules from the Title.
Or you can extend the Title
component with the withComponent
helper method. The Subtitle
will have all the properties of a Title
but will use an h2
tag:
样式化的组件易于扩展。 您可以使用h2
标签创建一个新的Subtitle
组件,并复制和粘贴Title.
所有样式规则Title.
或者,您可以使用withComponent
helper方法扩展Title
组件。 Subtitle
将具有Title
所有属性,但将使用h2
标签:
const Subtitle = Title.withComponent("h2");
You can extend the Title
to create the Text
component with a p
tag and — at the same time — fix its color
as a theme.text
and set the line-height
to 1.65
? Here, too, styled-components shine:
您可以扩展Title
以创建带有p
标签的Text
组件,并同时将其color
固定为theme.text
并将line-height
设置为1.65
? 同样,样式化组件也会在这里发光:
const Paragraph = Title.withComponent("p");const Text = Paragraph.extend` color: ${props => props.theme.colors.text}; line-height: 1.65;
First, we created an intermediary Paragraph
component that will have all the styling rules of the Title.
However, we will use the p
tag and then the Text
component that extends the Paragraph
and sets its color
and line-height
properties. Below you can inspect the code for the Title
, Subtitle
, and Text
components:
首先,我们创建了一个中间Paragraph
组件,它将具有Title.
所有样式规则Title.
但是,我们将使用p
标签,然后使用Text
组件来扩展Paragraph
并设置其color
和line-height
属性。 您可以在下面检查Title
, Subtitle
和Text
组件的代码:
Styled components allow you to write a regular CSS in JavaScript. Additionally, you can nest the CSS styles and pseudo-classes. You can add media-queries and attributes. Finally using the injectGlobal
helper method, you can inject global styling rules and import fonts.
样式化的组件允许您使用JavaScript编写常规CSS。 此外,您可以嵌套CSS样式和伪类。 您可以添加媒体查询和属性。 最后,使用injectGlobal
helper方法,您可以注入全局样式规则并导入字体。
伪类 (Pseudo-classes)
To learn how to use the pseudo-classes, let’s create a Button
component that will change the color when we hover the mouse over it.
要学习如何使用伪类,让我们创建一个Button
组件,当将鼠标悬停在其上时,它将更改颜色。
Above, I nested the &:hover
pseudo-class to change the color
whenever you hover the mouse over the button. You can use any pseudo-class available in CSS in the same way.
上面,我嵌套了&:hover
伪类,以在每次将鼠标悬停在按钮上时更改color
。 您可以以相同的方式使用CSS中可用的任何伪类。
使用样式化组件注入全局样式 (Injecting global styles with styled-components)
Instead of importing the global styles file, you can use the injectGlobal
helper to add global styles to your application. First, you have to import the injectGlobal
helper:
除了导入全局样式文件,您还可以使用injectGlobal
帮助器将全局样式添加到您的应用程序。 首先,您必须导入injectGlobal
帮助器:
import styled, { ThemeProvider, injectGlobal } from "styled-components";
In the example below, I am using injectGlobal
to:
在下面的示例中,我使用injectGlobal
来:
import fonts and set the
font-family
for all elements to “Montserrat”.导入字体并将所有元素的
font-family
设置为“蒙特塞拉特”。- reset margins, paddings, and borders. 重置边距,内边距和边框。
change the root element
font-size
using the media-query for the screen size lower thanscreen.medium
andscreen.mobile.
Both are defined in thetheme.
使用media-query更改根元素的
font-size
,以使屏幕尺寸小于screen.medium
和screen.mobile.
两者都在theme.
中定义theme.
Styled components themes enforce consistency. To learn more, explore one of the best documentations I’ve ever seen: Styled Components Docs.
样式化的组件主题可增强一致性。 要了解更多信息,请浏览我见过的最好的文档之一: 样式化组件文档 。
Thanks to Max and Glen’s curiosity, styled components offer you an amazing set of tools to style React applications. The styled components ecosystem is booming. Visit the Ecosystem page to explore the ready-to-use components and grid systems. Examine the many other tools built with styled components.
由于Max和Glen的好奇心,样式化的组件为您提供了一套惊人的工具来对React应用程序进行样式化。 样式化的组件生态系统正在蓬勃发展。 访问“ 生态系统”页面,以探索现成的组件和网格系统。 检查使用样式化组件构建的许多其他工具。
结论 (Conclusion)
In this tutorial, you’ve learned how the tagged template literals work. You’ve also learned how to use styled components to build universal React components. You now understand know how to use a theme to implement the consistent styles of your next application.
在本教程中,您学习了带标签的模板文字如何工作。 您还学习了如何使用样式化的组件来构建通用的React组件。 现在您已经了解了如何使用主题来实现下一个应用程序的一致样式。
Styled components is a new way of styling React applications. Out of the box, styled components:
样式化组件是样式化React应用程序的新方法。 开箱即用的样式化组件:
- let you build reusable and universal components 让您构建可重复使用的通用组件
- enforce the consistency of styling 加强样式的一致性
- allow you to nest styles 允许您嵌套样式
- add vendor prefixes when necessary 必要时添加供应商前缀
- are simply awesome! 简直太棒了!
If you liked this article, ? even 50 times — I would really appreciate it and it makes a huge difference to me.
如果您喜欢这篇文章,? 甚至5 0次 -我真的很感激,这对我来说是巨大的改变。
I published recently a free React tutorial for beginners. If you want to learn how to build a web application from scratch it’s a great starting point. You will learn how to build an app to help you find the best movie to watch ? Sweet Pumpkins
我最近为初学者发布了一个免费的React教程。 如果您想学习如何从头开始构建Web应用程序,那么这是一个很好的起点。 您将学习如何构建应用程序以帮助您找到最佳的电影? 甜南瓜
交互设计文档示例