React Styled 组件:如何基于 props 添加 css 样式?

IT技术 javascript reactjs
2021-05-03 16:03:34

我一直在努力寻找解决我的问题的方法。我在自己的文件中有几个标题标签(H1、H2 等)。我想在基于 prop 调用它们时添加一些 css。有些标题有一个小的边框底部,有些则没有。所以,为了折射我的代码,我想添加一些基于 prop 的 css。我似乎找不到办法。

这是标题 H2 的示例:

import styled from 'styled-components';
import colors from '../../../../colors'; 
import fonts from '../../../../fonts';
import fontWeights from '../../../../fontWeights';

const HeadingH2 = styled.h2`
  color: ${colors.text};
  font-family: ${fonts.montSerrat};
  font-size: 1.6em;
  font-weight: ${fontWeights.light};
  letter-spacing: 0.2em;
  padding-bottom: 0.7em;
  position: relative;
  text-transform: uppercase;
  text-align: center;
  &:after{
    content: "";
    display: block;
    height: 3px;
    width: 45px;
    background-color: currentColor;
    /* position */
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  }
`;

export default HeadingH2

调用标题 H2 的示例:

import React from 'react';
import HeadingH2 from '../../common/headings/heading_h2';
import HeadingBaseline from '../../common/headings_baseline';


// Features
import {SectionContainer, FeaturesContainer} from './features.style';

import Feature from './feature';
import feature1 from '../../../img/features/feature1.png';
import feature2 from '../../../img/features/feature2.png';
import feature3 from '../../../img/features/feature3.png';

// Text
import Text from '../../../content';

const Features = () => {
  return(
    <SectionContainer id={"what"}>
      <HeadingH2>
        What We Do
      </HeadingH2>
    <HeadingBaseline>
      {Text.headingBaseline}
    </HeadingBaseline>
  <FeaturesContainer>
    <Feature 
      src={feature1} 
      headingText={Text.feature1.heading}
      paragraph={Text.feature1.paragraph}
      />
    <Feature 
      src={feature2} 
      headingText={Text.feature2.heading}
      paragraph={Text.feature2.paragraph}
      />
    <Feature 
      src={feature3} 
      headingText={Text.feature3.heading}
      paragraph={Text.feature3.paragraph}
      />
  </FeaturesContainer>
</SectionContainer>
)
};

export default Features;

我想提取以下 CSS 属性

position: relative;
text-transform: uppercase;
text-align: center;
&:after{
 content: "";
 display: block;
 height: 3px;
 width: 45px;
 background-color: currentColor;
 /* position */
 position: absolute;
 bottom: 0;
 left: 50%;
 transform: translateX(-50%);

因此,假设我在单独的文件中具有上述 CSS 规则,如何使用样式组件 HeadingH2 上的props添加/导入它们。

谢谢您的帮助 :)

4个回答

像这样的工作:

const HeadingH2 = styled.h2`
  position: ${props => props.relative && 'relative'};
  padding: ${props => props.paddingBottom ? '0 0 20px 0' : '0'};
}
`;

然后像这样使用:

<HeadingH2 relative paddingBottom />

您还可以使用csshelper fromstyled-components创建SharedStyles.js文件。

演示中,您可以看到它的运行情况。仅以继承组件的样式使用它并不能按预期工作。如果我将其添加到,StyledBase则之后变量未正确添加(悬停样式覆盖停止工作)。这就是为什么我复制${borderBottom}到每个样式组件Heading1/Heading2而不是将其添加到StyledBase.

我认为为标题设置一个级别props是一个好主意,但我会通过创建一个HeadingBase组件并将您的样式添加到一个StyledBase组件中来以不同的方式处理它(另请参阅演示中的代码)。

HeadingBase代码如下所示:

const HeadingBase = ({ className, children, level = 1 }) =>
    React.createElement(`h${level}`, { className }, children);

它是一个基于level传递的props呈现 h1,h2,... 标签的组件(默认为 h1)。h-tagclassName作为props接收(需要样式组件)并包含传递给组件的子项。

SharedStyles.js

import { css } from "styled-components";

export const borderBottom = css`
    &:after{
        content: "";
        display: block;
        height: 3px;
        width: 200px;
        background-color: ${props => props.color || "black"};
        /* position */
        position: absolute;
        bottom: 0;
        left: 50%;
        transform: translateX(-50%);
`;

然后,您可以将其导入并将其import { borderBottom } from "./SharedStyles";添加到您的样式组件中,如下所示:

const Heading1= styled.h1`
    ${borderBottom}
`;

可能的答案:

我在一个单独的文件中添加以下 CSS 规则,如下所示。我创建了一个返回一串文本的函数。我可以导入这个函数并将这些规则添加到我希望的任何组件中。

export const borderBottom = () => {
  return `
   position: relative;
   text-transform: uppercase;
   text-align: center;
   &:after{
    content: "";
    display: block;
    height: 3px;
    width: 45px;
    background-color: currentColor;
    /* position */
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  } 
`
 }

并像这样在我希望的任何标题或组件上使用它:

import styled from 'styled-components';
import colors from '../../../../colors';
import fonts from '../../../../fonts';
import fontWeights from  '../../../../fontWeights';
import {borderBottom} from '../../../../css';

const HeadingH5 = styled.h5`
  color: ${colors.black};
  font-family: ${fonts.montSerrat};
  font-size: 1em;
  font-weight: ${fontWeights.light};
  letter-spacing: 0.1em;
  padding-bottom: 0.45em;
  margin-bottom: 25px;
  ${borderBottom}
`  
;

export default HeadingH5;

这对我有用。欢迎任何其他建议。

你应该明确地检查这个:typestyle

编写动态 css 的最佳方式(对我而言)。与 react 完美配合,即使需要 ssr 也是如此......