在React Native中使用CSS变量

3,268 阅读10分钟

在移动应用中,设计和造型是与网页开发同样重要的方面。谁不喜欢一个有吸引力和视觉效果的用户界面?

React Native应用中的样式设计决定了React组件或元素在移动屏幕或浏览器上的显示方式。开发人员有几种选择来为他们的React Native组件设计样式。

styled-components是React和React Native的一个流行的库,它使开发者能够通过编写JavaScript和CSS的混合物,在他们的应用程序中使用组件级的样式,称为CSS-in-JS。因此,styled-components是一个工具,在React和React Native应用程序的组件和样式之间架起桥梁。我们将在本篇文章的后面章节中使用这个库。

例如,一个开发者可以使用普通的JavaScript对象来创建样式。

const styles = {
textformat: {
    fontFamily: 'Lora',
    fontSize: 25,
    color: 'maroon',
    textAlign:'center',
    marginTop: 40,
   }
};

然后,这可以通过style 属性(prop)应用于React Native组件,如下所示。

<Text style = {styles.textformat}>Hi there</Text>

React Native团队引入了StyleSheet API作为CSS样式表的替代方法。从今天起,他们推荐使用该API,原因如下。

  • 通过将样式定义从render() 功能中转移出来,使代码更容易理解
  • 通过命名样式,你可以为render() 函数中的低级组件增加意义

因此,React Native中的StyleSheet API提供了一种简洁的方式来抽象各种组件的样式,这反过来又导致了一个更好看的UI。React Native中的样式设计通过CSS自定义属性(也称为CSS变量)得到了进一步加强。我们将在这篇文章中探讨CSS变量,并利用StyleSheet API。

为什么我们在React Native中需要CSS变量?

开发者可以定义CSS自定义属性来存储自定义样式设置。作为一个开发者,你想寻找方法使你的应用程序现代化,加快生产力,并尽可能地应用可重复使用的策略。

使用CSS自定义属性或CSS变量来实现样式设置是实现这一目标的方法之一。使用CSS变量,你可以一次将相同的样式应用于多个组件。你可以把它们附加到一个选择器上,这样它们就可以被该选择器的所有后代所继承。你甚至可以使用自定义属性集为整个应用程序设计一个主题。

通过CSS变量,你可以实现一些造型效果,而这些效果是普通的JavaScript无法实现的。CSS变量在React Native中实现动画时也相当有用。

明智地使用CSS变量也可以在很大程度上提高React Native应用程序的可维护性。因为它们是变量,所以可以适当地、有意义地命名,然后在需要的时候轻松引用。

假设你今天开发了一个带有CSS变量的应用程序forecolor ,并将其应用于一堆文本组件和按钮。六个月后,你被要求将前景颜色改为更深的颜色。由于早先定义了CSS变量,现在跟踪该变量并仅将单一的值更新为深色,在所有必要的组件中传递所需的变化就变得容易多了。

因此,使用CSS变量对你的代码的可维护性产生了很大的影响。

如何声明CSS变量

你可以按以下方式声明一个CSS变量。

--forecolor: magenta;

然后可以像这样使用它。

color: var(--forecolor);   

使用CSS变量的准则

  • 一个CSS变量总是以两个连字符的前缀开始。--

  • 你可以在CSS变量中存储颜色、对齐方式、字体系列、尺寸以及更多的内容。

  • 一个CSS变量总是用var 函数来调用。

  • 与使用逗号的StyleSheet.create() 所指定的属性不同,CSS变量定义中的每个属性都用分号来分隔,比如:

      --forecolor: magenta;
      --fontSize: 25px;
      --font-family: 'Lora';
    
    
  • 你可以通过JavaScript以编程方式设置或检索CSS变量。

将CSS变量付诸实施

让我们假设你有一个React Native应用程序,你想把CSS样式应用到paragraph 元素和Text 组件。

创建你的HTML标记,如下所示。

<div id="react-root"></div>
<p> Testing CSS variables</p>

然后,用CSS变量创建你的CSS/SCSS代码,如下所示。

:root {
  --forecolor: magenta;
  --fontSize: 25px;
  --font-family: 'Lora';
}
p{  
  color: var(--forecolor);   
  font-family: var(--font-family);
   text-align: center;
  font-size: 25px;
  marginTop: 40;
  }

在这里,你首先定义了三个CSS变量:forecolor,fontSize, 和font-family 。然后你用这些变量为paragraph 元素设置值。

这里给出了相应的应用程序的JavaScript。

const { Text, View, StyleSheet } = ReactNative;  
const App = () => {    
  return (
    
      Demonstrating CSS Vars in React Native!
    
  );
};

const styles = StyleSheet.create({
    text: {
      fontFamily: 'Lora',
      fontSize: 25,
      color: 'maroon',
      textAlign:'center',
      marginTop: 40,
   }
});

ReactDOM.render(, document.getElementById("react-root"));

请注意,Text 组件的样式只用StyleSheet.create() 来定义。

整个应用程序的代码可以在我为这篇文章创建的CodePen中找到:CSSVarsDemo01。执行它可以产生这样的输出。

参见CodePen上Mamta Dalal(@mamta_d)
的Pen
CSSVarsDemo01。

如果你仔细看看上面CSS部分的CSS变量声明和它们的用法,你可能会想知道有什么大不了的。你几乎可以直接为段落元素设置这些样式值,而不是用这种方式。那么,这里的大赢家是什么?

这样做的好处是,同样的根样式现在可以应用于任何其他元素,以及React Native组件。我们将在下一节中探讨这个问题。

在React Native中使用CSS变量来创建全局样式

我们将制作一些全局样式变量,这些变量可以在pText 上重复使用。

HTML标记保持不变,但我们的CSS已经改变。

:root {
  --forecolor: magenta;
  --fontSize: 25px;
  --font-family: 'Lora';
}
p{  
  color: var(--forecolor);   
  font-family: var(--font-family);
  text-align: center;
  font-size: 25px;
  marginTop: 40;
  }
.main{
  color: maroon;   
  font-family: var(--font-family);
  text-align: center;
  font-size: 25px;
  }

在这里,我们在一个名为main 的类中定义了一组额外的CSS变量。让我们看看我们如何在JavaScript中使用它。

const { Text, View, StyleSheet } = ReactNative;
const App = () => {    
  return (
    

观察一下加粗的线条。它们表明包含CSS变量的main 类现在如何在我们的JavaScript代码中被用来对组件应用样式。

由于整个View 被包围在<div> 块中,任何在View 中定义的组件都将被应用同样的样式。

视口中的结果将与前面看到的相似,只是我们实现的方式不同。

Our output for our second CSS Variables demo

这个例子的代码可以在CSSVarDemo02中找到。

使用CSS变量与styled-components>的关系

如果我们想在原生组件之外使用styled-components库,或者代替原生组件呢?你也可以将CSS变量应用于这些组件。

styled-components库可以通过CDN链接或通过npm install 命令安装。

让我们看看如何做到这一点。我们将使用与前面相同的HTML标记,但我们将修改CSS。

:root {
  --forecolor: indigo;
  --bgcolor: orchid;
  --fontSize: 15px;
  --font-family: 'Lora';
}
p{  
  color: var(--forecolor);   
  font-family: var(--font-family);
  text-align: center;
  font-size: 15px;
  marginTop: 40;
  }

JavaScript代码将使用本地组件(ViewText )和一个来自风格化组件库的组件(Button )。

const {Text, View, StyleSheet} = ReactNative;
const styled = window.styled.default;

const Button = styled.button`
  background: var(--bgcolor);
  font-size: var(--fontSize);
  border: 3px solid purple;
  border-radius: 100%;
  display: inline-flex;
  height: 84px;
  width: 84px;
  align-items:center;
  margin: 30px 0px 0 0px;
  justify-content: center;
  align-self: center`;


const App = () => {    
  return (
    <View>
        <Button>Begin Game!</Button>
    </View>
  );
};

const styles = StyleSheet.create({
container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
    paddingLeft: 16,
    paddingRight: 16
 },
});
ReactDOM.render(<App />, document.getElementById("react-root"));

Button 组件有一些来自styled-components的预定义样式,但它使用CSS变量bgcolorfontSize 来设置按钮的背景颜色和字体大小。

如果没有设置任何样式或定义任何CSS变量,styled-componentsButton 将看起来像这样。
Our demo app without CSS variables

在定义和应用我们的CSS变量后,结果将是。
Our third demo using CSS Variables and styled-components

你也可以用普通的JavaScript对象来定义这些样式,但如果你的应用程序使用多个组件和多个屏幕,使用CSS变量将是一个很好的策略。这是因为你可以确保所有的按钮背景和其他按钮属性在整个应用程序中是一致的--与其总是要在不同的屏幕上为不同的组件调用字体大小,你可以通过为它设置一个CSS变量来保持统一的大小。

这个应用程序的代码可以在CSSVarDemo03中找到。

在运行时设置和检索CSS变量

也可以通过JavaScript在运行时以编程方式设置和检索CSS变量。当你想根据某些条件或输入动态地改变样式时,这就很有用。

考虑一个场景,你想根据用户在React组件中的输入,将文本的显示颜色改为特定颜色。你还希望这一点发生在应用程序中的所有文本元素上。你可以通过JavaScript代码动态更新CSS变量来实现这一点。

重复我们前面的例子,保持HTML标记和CSS声明不变;只改变styled-components中的按钮组件的JavaScript。

<Button onClick={() =>  {          
          console.log(`Current background color:`);

//Retrieve the background color from the CSS variable
          const bg = getComputedStyle(document.documentElement).getPropertyValue('--bgcolor');
          console.log(bg);      


// Set the CSS variable value to a new value
          console.log(`Setting background color to: green`);
          document.documentElement.style.setProperty('--bgcolor', 'green');}}
          > Begin Game!</Button>

点击按钮后,控制台显示以下输出。
The console logs these changes on click

这个应用程序的代码可以在CSSVarDemo04中找到。

现在,让我们再添加一个按钮和一个ScrollView 组件,创建一个全局主题,并将其应用于button 组件、ScrollView 组件以及Textparagraph 元素。

我们的CSS为我们的globalthemeparagraph 元素定义了同样的样式。

:root {
  --forecolor: maroon;
  --bgcolor: orchid;
  --font-family: 'Lora';
}
.globaltheme, p{  
  color: var(--forecolor);   
  font-family: var(--font-family);
  text-align: center;
  font-size: 15px;  
}

JavaScript代码需要补充一些内容。

const { Text, ScrollView, View, StyleSheet} = ReactNative;
const styled = window.styled.default;

const Button = styled.button`
  background: var(--bgcolor);
  font-size: var(--fontSize);
  border: 8px solid navy;
  border-radius: 100%;
  display: inline-flex;
  height: 84px;
  width: 84px;
  align-items:center;
  margin: 30px 0px 0 0px;
  justify-Content: center;
  align-self: center`;


const App = () => {    
  return (
    <div className="globaltheme">
    <View>
      <Button onClick={() =>  {console.log(`Updating color to: green`);
  document.documentElement.style.setProperty('--bgcolor', 'green');}}
          >Begin Game!</Button>     
      <Button onClick={() =>  {console.log(`Exiting`);  }}
          >Exit</Button>      
      <ScrollView >
       <Text style={styles.listItem}>'Beginner Level 1'</Text>
         <Text style={styles.listItem}>'Intermediate Level'</Text>
         <Text style={styles.listItem}>'Advanced/Expert Level'</Text>
      </ScrollView>
    </View>
      </div>
  );
};

const styles = StyleSheet.create({
container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
    paddingLeft: 16,
    paddingRight: 16
 },
  listItem: {
    backgroundColor: "orange",
    borderWidth: 4,
    borderColor: "navy",
    padding: 5,
  },
});
ReactDOM.render(<App />, document.getElementById("react-root"));

该代码的结果是。

Theming multiple components with the same CSS Variable

正如你所看到的,字体大小、字体家族和前景颜色的道具被统一应用于paragraph 元素、ScrollView 列表项和按钮。

这个应用程序的代码可以在CSSVarDemo05中找到。

关于CSS变量和性能的说明

在你的应用程序中使用过多的CSS变量,并通过JavaScript频繁地改变它们,你应该谨慎行事,因为在某些时候,它们也可能对性能产生不利的影响。

CSS变量对性能的影响是众所周知的,但如果你有兴趣的话,这里有一个基准,考察了大量的CSS变量对性能的影响。

总结

CSS变量为React Native开发者提供了许多好处。它们很容易使用,并且可以大大改善生产力和视觉效果。

提示和最佳实践

给你的CSS变量起个有意义的名字,用它们来区分应用程序中的逻辑部分和设计部分,这将是一个好的做法。简单地说,我们可以分别定义变量和属性,而不是把它们放在一起。

变量,就其定义而言,也意味着其中包含的值有可能在应用过程中发生变化--因此,将可能发生变化的样式值放在CSS变量下。而当你需要做出改变时,你可以直接使用选择器和媒体查询来改变这些值。

在你的:root 选择器下保留一些(但不要太多)全局范围的属性是有意义的。

进一步阅读

虽然这些文章不是针对React Native的,但你可以对它们进行调整,以便在你的React Native应用中使用。