【问题标题】:How to declare SCSS <length> type attribute selector by REACT property如何通过 REACT 属性声明 SCSS <length> 类型属性选择器
【发布时间】:2020-09-17 02:31:28
【问题描述】:

基本上我想创建一个可重用的组件,可以在反应中从外部稍微修改:

SomewhereElse.tsx

...
<FooComponent width={200}>
...

FooComponent.tsx

interface IFooProps {
  //default width of 150px
  width?: 150;
  //default margin of 5px
  margin?: 5;
}

interface IFooState{
  checked: boolean;
}

class FooComponent extends Component<IFooProps, IFooState> {
    constructor(props: IFooProps) {
        super(props);
        ...
    }

...

    render(): ReactElement {
        return (
          <div className="foo-component"
              data-width={this.props.width + 'px'}
          >
          ...

FooComponent.scss

.foo-component {
    ...
    width: attr(data-width length);
    ...

但是在运行应用程序(chrome)时它总是给我以下错误:

...请考虑我需要一个“数字”作为属性,因为我正在根据该数字对某些内部组件进行一些计算,因此所有内容都可以组合在一起。

编辑:

使用“style”对我不起作用,因为我的 scss 中有一些 ::before ::after 功能在使用 style 时会损坏,因为它们偶尔会根据宽度修改“right:”。

为了更好地理解,这是我的基础: https://www.sitepoint.com/react-toggle-switch-reusable-component/

【问题讨论】:

  • data-width?这是为了什么..?
  • 重置 --var() css customproperties 以更新规则的值可能更容易。可能的相关帖子stackoverflow.com/questions/59231839/… & stackoverflow.com/questions/46323117/…
  • @wentjun 它是一个属性选择器。您可以使用它们为不同的组件动态定义值或插入专门为某个组件的值。
  • @Spektakulatius Yepp 我知道是……!我只是想知道你为什么使用 data- 属性,因为它在 React 中不常用,因为还有其他对 React 友好的方式来绑定数据/样式

标签: css reactjs typescript react-native sass


【解决方案1】:

回答你的问题

请找到带有属性选择器的解决方案,或者告诉我由于 X 原因这是不可能的(最好是链接到文档)。

不,虽然它非常有用,但根据我的研究,目前不可能

MDN about CSS attr():

注意:attr() 函数可以与任何 CSS 属性一起使用,但对内容以外的属性的支持是实验性的,对 type-or-unit 参数的支持是稀疏的。

根据caniuse.com about css3-attr,可以在任何CSS 属性上使用attr()(除了content,并通过&lt;type_or_unit&gt; 将其用于非字符串值(例如数字、颜色),如“CSS值和单位级别 3"目前不受所有浏览器支持

另请参阅“CSS 值和单元模块级别 4”的当前草案声明:

以下功能存在风险,可能会在 CR 期间被删除:toggle()attr() [...]

(来源:https://drafts.csswg.org/css-values/#status

在 Chromium 问题中,我发现了一个我不知道的有趣资源的链接:web-platform-tests dashboard for css-values。查看以attr- 为前缀的(失败的)测试,尤其是attr-length-valid.htmlattr-px-valid.html

但有希望:Chromium 团队最近(2020 年 5 月 15 日)发布了一个 Intent to Implement and Ship: CSS advanced attr() function

实现对 CSS Level 4 中指定的 attr() 的扩充,即允许在所有 CSS 属性中使用各种类型(除了 )和使用(除了伪元素“内容”)。

注意:与第 3 级相比,CSS 第 4 级对 attr() 进行了大量修改,以简化实现。我们将遵循 CSS4。 [...]

动机:这是一项要求很高的功能,在 crbug.com/246571 获得了 77 颗星。 [...]

铬跟踪Issue 246571: Implement CSS3 attribute / attr references )

Firefox 还显示 最近 活动,请参阅 Firefox 跟踪 Bug 435426 [meta] Implement CSS Values 3 extensions to attr(),他们至少指的是 Chromiums 当前的努力。

(WebKit Bug 26609 - Support CSS3 attr() function 没有显示任何活动,这可能会破坏交易)

【讨论】:

    【解决方案2】:

    根据 G-Cyrillus 的建议,我找到了使用 CSS 自定义属性的可能解决方案。不幸的是,我没有找到使用属性选择器的解决方案,因此我可以坚持使用一种解决方案类型。

    在 scss 文件“父”类中添加您的自定义属性,例如:

    .foo-component {
        --customwidth: 150px;
        --custommargin: 5px;
    
        width: var(--customwidth, 150px);
        ...
        &-inner {
            margin-left: var(--custommargin, 5px);
        }
        ...
    }
    

    声明自定义属性后,可以将其与var(&lt;propertyname&gt;, &lt;initialvalue&gt;) 一起使用。

    在 React 中,您可以稍微修改 render(),例如:

     render(): ReactElement {
        //set the custom properties for width, margin and slider position
        let cssProperties = {};
        cssProperties['--customwidth'] = this.props.width == null ? '150px' : this.props.width + 'px';
        cssProperties['--custommargin'] = this.props.margin == null ? '150px' : this.props.margin + 'px';
        cssProperties['--switchposition'] = (this.props.width == null ? 115 : this.props.width - 35) + 'px';
    
        return (
          <div className="foo-component" style={cssProperties}>
          ...
    }
    

    这将分别适用于每个组件。

    【讨论】:

      【解决方案3】:

      更简单的方法是使用内联样式:

             return (
                <div className="foo-component"
                    style=`width:${this.props.width};`
                >
      

      【讨论】:

      • 您是否考虑过也使用 CSS-IN-JS 或 styled-components 之类的东西?如果您想直接在组件上使用道具进行样式设置,它肯定会加快您的速度
      • 很抱歉,这不能满足我的需求,因为我正在使用 ::before 和 ::after 之类的东西,它们有时会改变值。所以使用固定的“宽度”会破坏这种行为。
      • 你试过使用document.documentElement.style.setProperty吗?也许您可以在组件加载时覆盖您的 CSS 变量。有关此的更多信息:davidwalsh.name/css-variables-javascript
      【解决方案4】:

      使用 attr 您需要通过在 scss 样式中提供选择器来指定属性

      .foo-component[data-width] {
          ...
          width: attr(data-width length);
          ...
      

      如果你有多个这样的属性,你可以这样写

      .foo-component[data-width][data-margin] {
          ...
          width: attr(data-width length);
          margin: attr(data-margin number);
          ...
      

      详情请查看MDN docs

      【讨论】:

        猜你喜欢
        • 2019-12-22
        • 2011-11-05
        • 2018-02-15
        • 1970-01-01
        • 1970-01-01
        • 2017-02-12
        • 2015-07-07
        • 1970-01-01
        • 2017-05-12
        相关资源
        最近更新 更多