CSS-In-JS

这篇具有很好参考价值的文章主要介绍了CSS-In-JS。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

git地址

什么是CSS-IN-JS

实际上这就是一种解决方案,在这种解决方案中,它提倡我们使用JavaScript代码去编写CSS代码,也就是说它提倡我们集成 CSS 代码在 JavaScript ⽂件中.

一.为什么会有CSS-IN-JS

CSS-IN-JS 是 WEB 项⽬中将 CSS 代码捆绑在 JavaScript 代码中的解决⽅案.

1.1 缺乏作用域

实际上在现有的react项目中,我们已经把html代码和JavaScript代码写在一起了,如果在采用CSS-In-Js解决方案的话,我们就是把html代码、css代码以及JavaScript代码写在一起了.这与我们当前的认知是背道而驰的,在我们当前的认知当中,应该把css代码,JavaScript代码,html代码进行分离编写.这里面的原因是什么呢?实际上是开发方式的变化.以前我们开发前端项目的时候都是以页面为单位的,比如说我们要开发一个首页,一个列表页或者开发一个详情页,这时候的css文件都是通过link标签引入到html文件中的,由于css本身没有作用域的概念,所以css文件中的代码都会作用到html文件中.这在当时是没有问题的,但是现在我们在开发项目的时候都是以组件为单位的,既然是以组件为单位的,我们就希望css代码就只应用于某一个组件,也就是css代码只在某个组件内生效.组件与组件中的css代码不会产生冲突.如果要实现这样的效果,就需要css有作用域的概念,但是css本身没有这个概念,如果采用CSS-IN-JS方案的话,我们就可以通过JavaScript的作用域去模拟css作用域,这样的话css代码就可以只应用于组件内部了.

1.2 增加组件的独立性和可移植性.

如果说我们把css代码都写在不同的css文件中,当我们想把这个组件想放到其他的地方的时候,在移动的过程中,我们可能会少复制某一个css文件,如果采用CSS-IN-JS方案的话,我们把所有的CSS代码都写在了JavaScript当中,这样的话这个组件就是一个单独的文件,当我们想去移动这个组件的时候,我们只要去移动这个文件本身就行了,而不用去当心它是否还会有其它的依赖文件.

1.3 缺乏动态功能

CSS本身缺乏动态功能,不能根据条件去给某一个元素添加样式如果写在JavaScript中,就可以用JavaScript的动态功能去添加样式了.

总结:旨在解决 CSS本身的局限性, 例如缺乏动态功能, 作⽤域和可移植性.

二.CSS-IN-JS 介绍

2.1 优点

  1. 让 CSS 代码拥有独⽴的作⽤域, 阻⽌ CSS 代码泄露到组件外部, 防⽌样式冲突.
  2. 让组件更具可移植性, 实现开箱即⽤, 轻松创建松耦合的应⽤程序
  3. 让组件更具可重⽤性, 只需编写⼀次即可, 可以在任何地⽅运⾏. 不仅可以在同⼀应⽤程序中重⽤组件, ⽽且可以在使 ⽤相同框架构建的其他应⽤程序中重⽤组件.
  4. 让样式具有动态功能, 可以将复杂的逻辑应⽤于样式规则, 如果要创建需要动态功能的复杂UI, 它是理想的解决⽅案.

2.2 缺点

  1. 为项⽬增加了额外的复杂性.
  2. ⾃动⽣成的选择器⼤⼤降低了代码的可读性

三.Emotion 库

3.1 Emotion 介绍

Emotion 是⼀个旨在使⽤ JavaScript 编写 CSS 样式的库.

npm install @emotion/core @emotion/styled

使用:

import React from "react";
export default function EmoDefault() {
	//添加一个css属性,接收一个对象作为参数,在这个对象中我们就可以写css样式了
    return (<div css={{ width: '200px', height: '50px', background: 'red' }}>EmoDefault</div>)
}

写完后我们发现样式并没有生效,这是因为在默认情况下,我们的项目并不知道如何去解析css属性,所以我们还需要做一下babel配置

3.2 css属性支持

css属性支持有两种配置方式:

  • 1 JSX Pragma

通知 babel, 不再需要将 jsx 语法转换为 React.createElement ⽅法, ⽽是需要转换为 jsx ⽅法

Input Output
Before <img src='1.png' /> React.createElement('img',{src:'1.png'})
After <img src='1.png' /> jsx('img',{src:'1.png'})
/** @jsx/jsx */
import {jsx} from '@emotion/core'
  • 2.Babel Preset(推荐)
  1. npm run eject
  2. npm i @emotion/babel-preset-css-prop
  3. 在 package.json ⽂件中找到 babel 属性, 加⼊如下内容
"babel": {
    "presets": [
      "react-app",
      "@emotion/babel-preset-css-prop"
    ]
  }

3.3 css ⽅法

css方法的作用也是为元素去添加样式,css方法和css属性是配合在一起使用的,通过css方法,我们可以把原本写在行内的样式拿到外部去写

css-in-js,javascript,css,前端

调用css方法会返回一个这样的对象,name就是会给标签加上的类,styles就是加上的样式

css方法有两种调用方式:

import { css } from "@emotion/core";
import React from "react";
//第一种:String Styles(以模板字符串的方式去写样式)(推荐)
const style=css`
    width:200px;
    height:50px;
    background:red
`
//第二种:Object Styles(以对象的方式去写样式)
const style2=css({
    width:200,
	height:50,
	background:'red'
})

export default function CssFunc(){
    return (
        <>
            <div css={style}>css方法调用-模板字符串</div>
            <div css={style2}>css方法调用-对象</div>
        </>
    )
}

3.4 属性优先级

props 对象中的 css 属性优先级⾼于组件内部的 css 属性.

在调⽤组件时可以在覆盖组件默认样式.

import { css } from "@emotion/core";
import React from "react";
const style=css`
    width:200px;
    height:50px;
    background:red
`
function Child(props){
    return (
        <>
            <div css={style}>css优先级</div> 
        </>
    )
}
export default function CssPriority(){
    return (
        <Child />
    )
}

我们看到的效果是这样的

css-in-js,javascript,css,前端

然后我们做些修改

import { css } from "@emotion/core";
import React from "react";
const style=css`
    width:200px;
    height:50px;
    background:red
`
const style2=css`
    background:orange
`
function Child(props){
    return ( 
        	//会把App.js中传递过来的css对原有的css进行覆盖
            <div css={style} {...props}>css优先级</div>  
    )
}
export default function CssPriority(){
 	//这个css其实就是子组件里的props.css
    return (
        <Child css={style2} />
    )
}

然后我们再看效果

css-in-js,javascript,css,前端

所以props 对象中的 css 属性优先级⾼于组件内部的 css 属性.

3.5 Styled Components 样式化组件

样式化组件就是⽤来构建⽤户界⾯的,是 emotion 库提供的另⼀种为元素添加样式的⽅式,它可以把普通的标签升级为一个带自定义样式的组件.

styled是一个对象,在这个对象下面有很多的方法,对应的是标签名称,调用这个方法会把对应的标签转化为样式化组件.

3.5.1 创建样式化组件

样式化组件有两种创建方式:

import styled from "@emotion/styled";
import React from "react";
//第一种:String Styles(模板字符串方式)
const Button = styled.button`
  width:130px;
  height:40px;
  background:red;
  color:black
`
//第二种: Object Styles(对象方式)
const Container = styled.div({
  width: '100%',
  height: 100,
  background: 'red',
  color:'yellow'
})

export default function CssComponent() {
  return (
      <>
          <Container>
              样式化组件-对象写法
              <Button> 样式化组件-字符串写法</Button>
          </Container>
      </>
  )
}

css-in-js,javascript,css,前端

3.5.2 根据 props 属性覆盖样式

  import styled from "@emotion/styled";
  import React from "react";
   //第一种:String Styles(模板字符串方式)
  const Button = styled.button`
      width:130px;
      height:40px;
      background:red;
      color:${props => props.ftColor || 'black'}
  `
  //第二种:Object Styles(对象方式)
  // const Container = styled.div(props=>({
  //     width: '100%',
  //     height: 100,
  //     background:props.bgColor||'red',
  //     color: 'yellow'
  // }))
  //第三种写法:Object Styles(对象方式),第一个参数是一个对象,就是默认的样式配置,第二个参数是一个箭头函数,返回一个对象,有这个属性的时候会对上面的进行覆盖
  const Container = styled.div({
      width: '100%',
      height: 100,
      color: 'yellow'
  }, props => ({
      background: props.bgColor || 'red',
  }))
  
  export default function CssComponent() {
      return (
          <>
              <Container bgColor='blue'>
                  样式化组件根据 props 属性覆盖样式-对象写法
                  <Button ftColor='blue'> 样式化组件根据 props 属性覆盖样式-字符串写法</Button>
              </Container>
          </>
      )
  }

css-in-js,javascript,css,前端

3.5.3 为任何组件添加样式

包括了普通的react组件

1.创建一个组件

function ReactCom() {
    return (
        <div>
            为react组件添加样式
        </div>
    )
}

2.使用styled方法返回一个新组件

//把组件当做参数传入styled方法里,模板字符串里写的样式就是为组件添加的样式
const CssReactCompStr=styled(ReactCom)`
    heihgt:100px;
    color:red
`
//对象写法
const CssReactCompObj=styled(ReactCom)({
    heihgt:100,
    color:'orange'
})

3.添加className

//调用了styled方法之后,普通组件的props里会有className,我们把它赋给里面的标签
function ReactCom({className}) {
    return (
        <div className={className}>
            为react组件添加样式
        </div>
    )
}

css-in-js,javascript,css,前端

3.5.4 通过⽗组件设置⼦组件样式

需求:当子组件单独调用的时候和子组件被父组件包裹的时候显示的样式要不一样

import React from "react";
import styled from "@emotion/styled";
const Child = styled.div`
    color:red
`
//通过${}{}去定义特定的子组件,比方说${Child}{color:green},当这个子组件被Father包裹的时候应用里面的样式
//模板字符串写法
const Father = styled.div`
    ${Child}{
        color:green
    }
`
//对象写法
// const Father = styled.div({
//     [Child]: {
//         color: 'green'
//     }
// })
export default function CssFC() {
    return (
        <>
            <Child>子组件单独使用</Child>
            <Father><Child>子组件被父组件包裹</Child></Father>
        </>
    )
}

css-in-js,javascript,css,前端

3.5.5 嵌套选择器 &

& 表示元素本身

import React from "react";
import styled from "@emotion/styled";
//&>span 表示这个Container的子级span
const Container = styled.div`
    color:red;
    &>span{
        color:pink
    }
` 
export default function CssNesting() {
    return (
        <Container>
            外层样式
            <span>span样式</span>
        </Container>
    )
}

css-in-js,javascript,css,前端

3.5.6 as属性

要使⽤组件中的样式, 但要更改呈现的元素, 可以使⽤ as 属性

例子:比方说我定义了一个样式化组件Button,我想使用里面的样式,但是我不想用button这个标签,想换成a标签

import React from "react";
import styled from "@emotion/styled";
const Button = styled.button`
    color:red;
`
export default function CssAs() {
    return (
        <Button as='a' href='https://www.baidu.com/'>as属性</Button>
    )
}

css-in-js,javascript,css,前端

3.6 样式组合

在样式组合中, 后调⽤的样式优先级⾼于先调⽤的样式.

如下:

import React from "react";
import { css } from "@emotion/core";
const style=css`
    color:red;
    background:yellow;
`
const style2=css`
    color:black;
`
export default function CssComb() {
    return (
    	//style2中的样式优先级会高于style
        <div css={[style,style2]}>css样式组合</div>
    )
}

css-in-js,javascript,css,前端

3.7 全局样式

定义全局样式需要借助于Global组件

CssGlobal.js

import React from "react";
export default function CssGlobal() {
    return (
        <a href='https://www.baidu.com/'>测试全局样式的a标记</a>
    )
}

App.js

import { css,Global } from '@emotion/core';
import CssGlobal from './pages/CssGlobal';
const globalStyles=css`
  body{
    margin:0;
  }
  a{
    text-decoration:none;
    background:yellow;
  }
`
function App() {
  return (
    <div >
      <Global styles={globalStyles}/>
      <CssGlobal />
    </div>
  )
}

export default App;

css-in-js,javascript,css,前端

3.8 关键帧动画

import React from "react";
import { css,keyframes } from "@emotion/core";
//通过keyframes方法创建个动画,跟css动画一样的写法
const ani=keyframes`
    0%{
        width:20px;
        background:red;
    }
    100%{
        width:200px;
        background:yellow;
    }

`
const style=css`
    height:50px;
    color:red;
    animation:${ani} 5s ease infinite;
`
export default function CSSAnimation() {
    return (
        <div css={style}>关键帧动画</div>
    )
}

3.9 主题

下载主题模块

npm i emotion-theming

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
//	1.引⼊ ThemeProvider 组件,这个组件的作用就是存储主题样式的,方便其它组件去获取主题样式
import { ThemeProvider } from 'emotion-theming';
//	2.添加主题内容
const theme = {
  colors: {
    primary: 'tomato'
  }
};

ReactDOM.render(
	//3.将 ThemeProvider 放置在视图在最外层,将主题内容赋值给theme属性
  <ThemeProvider theme={theme}><App /></ThemeProvider>,
  document.getElementById('root')
);

组件获取主题样式

import React from "react";
import { css } from "@emotion/core";
import { useTheme } from "emotion-theming";
//第一种方式获取
const themeColor = props => css`
    color:${props.colors.primary}
`

export default function CssTheme() {
    //第二种方式获取,通过调用钩子函数返回我们定义的那个主题对象
    const theme = useTheme()
    console.log(theme)
    const themeFont=css
    return (
        <>
            <div css={themeColor}>向css属性传递一个函数</div>
            <div css={{fontSize: theme.font}}>使用钩子函数</div>
        </>
        
    )
}

css-in-js,javascript,css,前端文章来源地址https://www.toymoban.com/news/detail-762241.html

到了这里,关于CSS-In-JS的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【开发环境】VSCode 安装插件 ( 简体中文插件 | Open in Browser 插件 | Auto Rename Tag 插件 | JS-CSS-HTML Formatter 插件 )

    在 VSCode 中 , 左侧的 按钮 是 扩展 按钮 , 使用 Ctrl + Shift + X 也可以快速进入插件安装界面 ; 在弹出的 扩展 面板中 , 可以搜索和安装插件 ; 在扩展工具面板中 , 搜索 Chinese , 可以看到 简体中文 插件 , 安装该插件后 , 界面会变为简体中文界面 ; 安装完毕后 , 重启 VSCode 即可完成

    2024年02月13日
    浏览(50)
  • 步入React前厅 - Css In React

    目录 扩展学习资料 行内样式 引入样式表 CSS Module @/src/components/common.module.css @/src/components/listitem.module.css css管理进阶 Css管理工具 练习 资料名称 链接 css module CSS Modules 用法教程 - 阮一峰的网络日志       在React中使用css预编译 https://juejin.im/post/5c3d67066fb9a049f06a8323      sty

    2024年02月13日
    浏览(73)
  • 前端全集Ⅰ---- HTML/CSS/JavaScript

    Web:全球广域网,也称万维网,能够通过浏览器访问的网站 Web网站的工作流程:(前后端分离模式) 网页有哪些组成? 文字、图片、视频、音频、超链接 前端代码通过浏览器的解析和渲染变成用户看到的页面,对网页进行解析渲染的部分就是浏览器的内核 Web标准 不同的浏

    2024年02月15日
    浏览(76)
  • 【前端异常】JavaScript错误处理:分析 Uncaught(in promise) error

    在开发过程中,JavaScript的错误处理是一个老生常谈的话题。当应用程序发生未捕获的异常时,Uncaught(in promise) error是其中最常见的错误类型。这篇文章将从多个方面详细阐述这种错误类型的原因与解决方案。 Promise是一种用于异步编程的原生JavaScript对象。它提供了一种处理异

    2024年02月05日
    浏览(90)
  • 前端= 结构(HTML)+ 样式(CSS)+ 行为(JavaScript)

    前端开发确实涵盖了行为(JavaScript)、样式(CSS)和结构(HTML)这三个主要方面。这三个方面在前端开发中密切协作,共同构建用户界面和用户体验。 结构(Structure):HTML 是用于定义页面结构的标记语言。通过使用 HTML 标签,可以创建网页的基本骨架,包括标题、段落、

    2024年02月13日
    浏览(63)
  • [前端开发] 常见的 HTML CSS JavaScript 事件

    代码示例指路 常见的 HTML、CSS、JavaScript 事件代码示例 在 Web 开发中,事件是用户与网页交互的重要方式之一。通过事件,用户可以与页面元素进行交互,触发相应的功能或效果。本文将介绍常见的 HTML、CSS、JavaScript 事件,以及事件对象和事件代理的概念。 鼠标事件 鼠标事

    2024年02月19日
    浏览(56)
  • 前端随笔:HTML/CSS/JavaScript和Vue

    最近因为工作需要,需要接触一些前端的东西。之前虽然大体上了解过 HTML 、 CSS 和 JavaScript ,也知道 HTML 定义了内容、 CSS 定义了样式、 JavaScript 定义了行为,但是却没有详细的学习过前端三件套的细节。而最近的工作中需要使用 Vue ,并且想到未来的工作中使用 Vue 能够更

    2024年02月16日
    浏览(44)
  • 前端:运用HTML+CSS+JavaScript实现拼图游戏

    前一段时间突然来了一个想法,就是运用前端知识实现一个拼图游戏,但是不知道具体怎样实现。今天,想到既然实现不了现实中我们看到的那种拼块,那么就用正方形来代替吧! 效果如下: 想到就是当小的图片块放到合适的位置上时,表示拼图完成。 1. 前端布局 运用cs

    2024年02月08日
    浏览(62)
  • HTML+CSS+JS 学习笔记(三)———Javascript(中)

    🌱博客主页:大寄一场. 🌱系列专栏:前端 🌱往期回顾:HTML+CSS+JS 学习笔记(三)———Javascript(上) 😘博客制作不易欢迎各位👍点赞+⭐收藏+➕关注 目录  JavaScript中的函数 函数的定义和调用 函数的定义  函数的调用 嵌套函数  递归函数  变量的作用域 全局变量和局部

    2024年02月06日
    浏览(81)
  • html、css 和 JS(JavaScript) 的相互关联

    工作所需,需要承担一些字体矢量动效玩法实现;调研发现前端可以快速实现一些矢量动画效果; 本文旨在介绍前端的三大利器(HTML / CSS / JS)的区别和联系,就当个引子 HTML CSS JS 介绍 HTML是超文本标记语言的简称,它是一种不严谨的、简单的标识性语言。它用各种标签将页

    2024年02月10日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包