翻译 | 《JavaScript Everywhere》第13章 设置应用程序样式css
你们好呀,我是毛小悠,是一位前端开发工程师。正在翻译一本英文技术书籍。html
为了提升你们的阅读体验,对语句的结构和内容略有调整。若是发现本文中有存在瑕疵的地方,或者你有任何意见或者建议,能够在评论区留言,或者加个人微信:code
_maomao,欢迎相互沟通交流学习。前端
(σ゚∀゚)σ..:*☆哎哟不错哦react
猫王埃尔维斯·科斯特洛(Elvis Costello
)在1978
年的单曲《嘴唇服务》(Lip Service
)中嘲笑这句话:“不要表现得比我高,而要看着你的鞋子。“这种“亲吻”意味着叙述者只要亲吻某人的鞋子,就能察觉出他想要得到更高的社会地位,不管他们的西装多么考究,衣着多么高雅。浏览器
不论是好是坏,某些风俗是人类文化的重要组成部分,咱们都习惯于接受这些类型的社交方式。考古学家甚至发现,旧石器时代的人类用骨头,牙齿,浆果和石头制做了项链和手镯。咱们的衣服不只能够起到保护人体免受各类元素侵害的功能目的,并且还能够与他人传递有关咱们的文化、社会地位、利益等等的信息。微信
没有Web
的默认样式,Web
应用程序仍然能够正常工做,可是经过应用CSS
,咱们能够更清晰地与用户通讯。在本章中,咱们将探讨如何使用CSS-in-JS
样式组件库将布局和样式引入咱们的应用程序。这将使咱们可以在可维护的、基于组件的代码结构中作出更实用、更美观的应用程序。网络
应用程序的许多页面(在咱们的状况下是所有)将共享一个通用布局。例如,咱们应用程序的全部页面都将具备标题、侧边栏和内容区域(图13-1
)。react-router
与其在每一个页面组件中导入共享的布局元素,咱们能够建立专门用于咱们的布局的组件并将每一个页面组件包装在其中。app
图13-1
。页面布局的线框框架
为了建立咱们的组件,咱们将从建立一个新文件src/components/Layout.js
开始。在此文件中,咱们将导入共享组件并布置内容。咱们的React
组件函数将接收一个children
的属性,这将告诉咱们在布局中哪里放置子元素的内容。
让咱们在src/components/Layout.js
中建立咱们的组件:
import React from 'react'; import Header from './Header'; import Navigation from './Navigation'; const Layout = ({ children }) => { return ( <React.Fragment> <Header /> <div className="wrapper"> <Navigation /> <main>{children}</main> </div> </React.Fragment> ); }; export default Layout;
如今在src/pages/index.js
文件中,咱们能够将页面组件包装在新建立的Layout
组件中,以将共享布局应用于每一个页面:
// import React and routing dependencies import React from 'react'; import { BrowserRouter as Router, Route } from 'react-router-dom'; // import shared layout component import Layout from '../components/Layout'; // import routes import Home from './home'; import MyNotes from './mynotes'; import Favorites from './favorites'; // define routes const Pages = () => { return ( <Router> {/* Wrap our routes within the Layout component */} <Layout> <Route exact path="/" component={Home} /> <Route path="/mynotes" component={MyNotes} /> <Route path="/favorites" component={Favorites} /> </Layout> </Router> ); }; export default Pages;
最后一步是删除页面组件中或页面组件内的全部实例。例如,咱们的src/pages/Home.js
文件如今将具备如下简化的代码:
import React from 'react'; const Home = () => { return ( <div> <p>This is the home page</p> </div> ); }; export default Home;
完成此操做后,你能够在浏览器中查看你的应用程序。在路由之间切换时,咱们会在每一个页面上看到咱们的标题和导航连接。目前,它们还没有设置样式,而且咱们的页面没有视觉布局。让咱们在下一部分中探索添加样式。
级联样式表精确命名:它们是一组规则,容许咱们编写Web
样式。样式为“层叠”,表示将呈现最后或最明肯定义的样式。例如:
p { color: green } p { color: red }
该CSS
会将全部段落呈现为红色,从而使颜色:绿色规则被覆盖。这是一个很简单的想法,可是为了不错误,它产生了许多模式和技术。
BEM
(块元素修饰符),OOCSS
(面向对象CSS
)和Atomic CSS
等CSS
结构技术使用说明性的类命名来帮助做用域样式。诸如SASS
(语法很棒的样式表)和Less
(更精简的样式表)之类的预处理器提供了简化CSS
语法并启用模块化文件的工具。尽管它们各有千秋,可是CSS-in-JavaScript
为开发React
或其余JavaScript
驱动的应用程序提供了引人注目的用例。
CSS
和UI
框架是开发应用程序的流行选择,这有充分的理由,它们提供了坚实的样式基础,并经过为常见的应用程序模式提供样式和功能来减小开发人员须要编写的代码量。折衷方案是使用这些框架的应用程序可能在视觉上变得类似,而且可能会增长文件包的大小。可是,这种权衡可能对你来讲是值得的。我我的最喜欢使用React
的一些UI
框架是Ant Design
, Bootstrap
, Grommet
, 和 Rebass
CSS-in-JS
当我第一次遇到CSS-in-JS
时,我最初的反应很吃惊。我在Web
标准时代度过了个人Web
开发生涯的初期阶段。我继续倡导Web
开发的可访问性和合理的逐步加强。十多年来,“关注点分离”一直是个人网络实践的核心。所以,若是你像我同样,只是阅读“ CSS-in-JS
”会使你感到厌恶,那么你并不孤单。可是,一旦我进行了适当的(而且没有判断力的)尝试,我很快就被征服了。CSS-in-JS
使咱们能够轻松地将咱们的用户界面视为一系列组件,这是多年来我一直在尝试结合模块化技术和CSS
预处理器来完成的工做。
在本书中,咱们将使用Styled Components
做为咱们的CSS-in-JS
库。它快速、灵活,正在快速发展中,而且是最受欢迎的CSS-in-JS
库。Airbnb
,Reddit
,Patreon
,Lego
,BBC News
,Atlassian
等公司也使用它。
样式化组件库的工做方式是容许咱们使用JavaScript
的模板字符串语法定义元素的样式。咱们建立一个JavaScript
变量,该变量将引用HTML
元素及其关联的样式。因为听起来很抽象,因此让咱们看一个简单的例子:
import React from 'react'; import styled from 'styled-components' const AlertParagraph = styled.p` color: green; `; const ErrorParagraph = styled.p` color: red; `; const Example = () => { return ( <div> <AlertParagraph>This is green.</AlertParagraph> <ErrorParagraph>This is red.</ErrorParagraph> </div> ); }; export default Example;
如你所见,咱们能够轻松的肯定样式范围。此外,咱们将样式限定到该特定的组件。这有助于咱们避免在应用程序的不一样部分之间发生类名冲突。
建立一个按钮组件
如今咱们对样式化组件有了基本的了解,让咱们将它们集成到咱们的应用程序中。首先,咱们将为元素编写一些样式,这将使咱们可以在整个应用程序中重用该组件。在前面的示例中,咱们将样式与React/JSX
代码集成在一块儿,可是咱们也能够编写独立样式的组件。首先,在src/components/Button.js
处建立一个新文件,从styled-components
中导入样式库,而后将可导出组件设置为模板字符串,以下所示:
import styled from 'styled-components'; const Button = styled.button` /* our styles will go here */ `; export default Button;
放置好组件后,咱们能够用一些样式填充它。添加一些基线按钮样式以及悬停和活动状态样式,以下所示:
import styled from 'styled-components'; const Button = styled.button` display: block; padding: 10px; border: none; border-radius: 5px; font-size: 18px; color: #fff; background-color: #0077cc; cursor: pointer; :hover { opacity: 0.8; } :active { background-color: #005fa3; } `; export default Button;
如今,咱们能够在整个应用程序中使用按钮。例如,要在应用程序的主页上使用它,咱们能够导入组件并在一般使用的任何位置使用元素。
在src/pages/home.js
中:
import React from 'react'; import Button from '../components/Button'; const Home = () => { return ( <div> <p>This is the home page</p> <Button>Click me!</Button> </div> ); }; export default Home;
这样,咱们编写了一个样式化的组件,能够在应用程序中的任何地方使用它。这对于可维护性很是有用,由于咱们能够轻松地找到样式并在咱们的代码库中进行更改。此外,咱们能够将样式化的组件与标记耦合在一块儿,从而容许咱们建立小型、可重用和可维护的组件。
添加全局样式
尽管咱们的许多样式将包含在各个组件中,可是每一个站点或应用程序也具备一组全局样式(诸如CSS
重置,字体和基准颜色之类的东西)。咱们能够建立一个GlobalStyle.js
组件来容纳这些样式。
这将与以前的示例有所不一样,由于咱们将建立样式表,而不是附加到特定HTML
元素的样式。为此,咱们将从styled-components
导入createGlobalStyle
模块。咱们还将导入normalize.css
库,以确保跨浏览器呈现一致的HTML
元素。最后,咱们将为应用程序的HTML
主体和默认连接样式添加一些全局规则。
在src/components/GlobalStyle.js
中:
// import createGlobalStyle and normalize import { createGlobalStyle } from 'styled-components'; import normalize from 'normalize.css'; // we can write our CSS as a JS template literal export default createGlobalStyle` ${normalize} *, *:before, *:after { box-sizing: border-box; } body, html { height: 100%; margin: 0; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; background-color: #fff; line-height: 1.4; } a:link, a:visited { color: #0077cc; } a:hover, a:focus { color: #004499; } code, pre { max-width: 100%; } `;
要应用这些样式,咱们将它们导入到App.js
文件中,并在应用程序中添加元素:
import React from 'react'; import ReactDOM from 'react-dom'; // import global styles import GlobalStyle from '/components/GlobalStyle'; // import routes import Pages from '/pages'; const App = () => { return ( <div> <GlobalStyle /> <Pages /> </div> ); }; ReactDOM.render(<App />, document.getElementById('root'));
这样,咱们的全局样式将应用于应用程序。在浏览器中预览应用程序时,你会看到字体已更改,连接具备新样式以及边距已删除(图13-2
)。
图13-2
咱们的应用程序如今已应用了全局样式
组件样式
如今咱们已经在应用程序中应用了一些全局样式,咱们能够开始对单个组件进行样式化了。在此过程当中,咱们还将介绍应用程序的整体布局。对于咱们样式化的每一个组件,咱们首先要从styled-components
导入样式库。而后,咱们将一些元素样式定义为变量。最后,咱们将在React
组件的JSX
中使用这些元素。
为了不与HTML
元素发生冲突,必须将样式化组件的名称大写。
咱们能够从src/components/Layout.js
开始,在这里咱们将样式添加到应用程序布局的结构和标签中。
import React from 'react'; import styled from 'styled-components'; import Header from './Header'; import Navigation from './Navigation'; // component styles const Wrapper = styled.div` /* We can apply media query styles within the styled component */ /* This will only apply the layout for screens above 700px wide */ @media (min-width: 700px) { display: flex; top: 64px; position: relative; height: calc(100% - 64px); width: 100%; flex: auto; flex-direction: column; } `; const Main = styled.main` position: fixed; height: calc(100% - 185px); width: 100%; padding: 1em; overflow-y: scroll; /* Again apply media query styles to screens above 700px */ @media (min-width: 700px) { flex: 1; margin-left: 220px; height: calc(100% - 64px); width: calc(100% - 220px); } `; const Layout = ({ children }) => { return ( <React.Fragment> <Header /> <Wrapper> <Navigation /> <Main>{children}</Main> </Wrapper> </React.Fragment> ); }; export default Layout;
随着咱们Layout.js
成分齐全,咱们能够在咱们Header.js
和Navigation.js
文件添加一些样式:
在src/components/Header.js
中:
import React from 'react'; import styled from 'styled-components'; import logo from '../img/logo.svg'; const HeaderBar = styled.header` width: 100%; padding: 0.5em 1em; display: flex; height: 64px; position: fixed; align-items: center; background-color: #fff; box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.25); z-index: 1; `; const LogoText = styled.h1` margin: 0; padding: 0; display: inline; `; const Header = () => { return ( <HeaderBar> <img src={logo} alt="Notedly Logo" height="40" /> <LogoText>Notedly</LogoText> </HeaderBar> ); }; export default Header;
最后,在src/components/Navigation.js
中:
import React from 'react'; import { Link } from 'react-router-dom'; import styled from 'styled-components'; const Nav = styled.nav` padding: 1em; background: #f5f4f0; @media (max-width: 700px) { padding-top: 64px; } @media (min-width: 700px) { position: fixed; width: 220px; height: calc(100% - 64px); overflow-y: scroll; } `; const NavList = styled.ul` margin: 0; padding: 0; list-style: none; line-height: 2; /* We can nest styles in styled-components */ /* The following styles will apply to links within the NavList component */ a { text-decoration: none; font-weight: bold; font-size: 1.1em; color: #333; } a:visited { color: #333; } a:hover, a:focus { color: #0077cc; } `; const Navigation = () => { return ( <Nav> <NavList> <li> <Link to="/">Home</Link> </li> <li> <Link to="/mynotes">My Notes</Link> </li> <li> <Link to="/favorites">Favorites</Link> </li> </NavList> </Nav> ); }; export default Navigation;
应用这些样式后,咱们如今有了一个彻底样式化的应用程序(图13-3
)。展望将来,咱们能够在建立单个组件时应用样式。
图13-3
。咱们的应用程序已应用样式
在本章中,咱们向应用程序介绍了布局和样式。使用CSS-in-JS
库中的Styled Components
,咱们能够编写简明扼要的CSS
样式。而后,能够将这些样式应用于单个组件,也能够应用于整个应用程序。在下一章中,咱们将经过实现GraphQL
客户端并调用咱们的API
来开发功能齐全的应用程序。
若是有理解不到位的地方,欢迎你们纠错。若是以为还能够,麻烦你点赞收藏或者分享一下,但愿能够帮到更多人。