Search code examples
htmlcssreactjsbackground-image

CSS `background-image` not working with `all: unset`?


I'm working on a stylized <hr /> in a library that I'm writing.

This library has a root element/component that uses all: initial to populate things like font-size which is used to change the relative size of the component. However, I'm running into a problem where I want to use all: unset on all other components.

This seems to break (in production but not storybook?) the background-image that I have set on my <hr />.

Here is a self contained example:

export default function App() {
  const [toggle, setToggle] = React.useState(true);

  return (
    <div style={{ all: 'initial' }}>
      <h1>
        Why is <code>background-image</code> not shoing here?
      </h1>
      <hr
        style={{
          ...(toggle ? { all: 'unset' } : {}),
          border: 'none',
          backgroundRepeat: `no-repeat`,
          backgroundSize: `100% 0.05em`,
          backgroundPosition: `center`,
          backgroundImage: `linear-gradient( 90deg, rgba(0,0,0,0) 0%, hsl(0, 200%, 90%) 10%, hsl(0, 200%, 90%) 48%, rgba(0,0,0,0) 48%, rgba(0,0,0,0) 50%, rgba(0,0,0,0) 52%, hsl(0, 200%, 90%) 52%, hsl(0, 200%, 90%) 90%, rgba(0,0,0,0) 100%)`,
          color: `hsl(0, 0%, 20%)`,
          textAlign: `center`,
          height: `0.75em`,
        }}
      />

      <button
        onClick={() => {
          setToggle((t) => !t);
        }}
      >
        {!toggle ? "Add 'all: unset'" : "Remove 'all unset'"}
      </button>
    </div>
  );
}

Here is a StackBlitz of the problem as well.

What am I missing here? It has to be an unset property, right? But I haven't been able to find the one that's causing this behavior.

This happens regardless of React/JSX/webpack.


Solution

  • Has 2 problems:

    About all of CSS:

    it sets all the properties of course including the base ones so you have to manually set them after unset:

    <hr
            style={{
              ...(toggle ? { all: 'unset' } : {}),
    
    +         width: '100%',
    +         display: 'block',
    +         position: 'relative',
    
              border: 'none',
              backgroundRepeat: `no-repeat`,
              backgroundSize: `100% 0.05em`,
              backgroundPosition: `center`,
              backgroundImage: `linear-gradient( 90deg, rgba(0,0,0,0) 0%, hsl(0, 200%, 90%) 10%, hsl(0, 200%, 90%) 48%, rgba(0,0,0,0) 48%, rgba(0,0,0,0) 50%, rgba(0,0,0,0) 52%, hsl(0, 200%, 90%) 52%, hsl(0, 200%, 90%) 90%, rgba(0,0,0,0) 100%)`,
              color: `hsl(0, 0%, 20%)`,
              textAlign: `center`,
              height: `0.75em`,
            }}
          />
    

    About all of React:

    about all instead of putting all: <value> in html react lists all unset attributes which causes other attributes to be removed the solution is to use class instead of object for style

    if you only render once without turning all on and off then you don't need to worry about this problem