Trevor
Trevor

Reputation: 320

"npm run build" failed in React app due to calc(width) in css?

I'm building a React app that has progress bars from Bootstrap.

<div className="progress">
  <div className="progress-bar"
    role="progressbar"
    aria-valuenow="60"
    aria-valuemin="0"
    aria-valuemax="100"
    style={{ width: "60%" }}
  />
</div>

and CSS

.progress {
  height: 5px;
  background-color: #9c9c9c; }

.progress-bar {
  height: 5px;
  background-color: blue;
  animation: animated-progress 3s ease-out; }

@keyframes animated-progress {
  from {
    width: 0; }
  to {
    width: calc(width); } }

This is the complete code in codesandbox

I got the idea of using calc(width) to get element's width from this StackOverflow answer

It's working fine during development. However, when I run the command npm run build for production, I got the following error

Lexical error on line 1: Unrecognized text.
  Erroneous area:
1: width
^..^
CompileError: Begins at CSS selector undefined


npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `react-scripts build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:

I know this error is caused by calc(width), because I was able to build if I changed from calc(width) to calc(60%). As you may realize, doing something like calc(60%) is not a good approach to hard code the width.

Upvotes: 0

Views: 1868

Answers (2)

Yatrix
Yatrix

Reputation: 13775

The error says it all. width is not recognized, i.e., it doesn't exist. That's why it works when you pass in a value. If you want to use a css variable, you have to declare it.

width: calc(width); is basically, width:calc(undefined);

Also, hard-coding the width isn't necessarily a bad thing. As with most things in programming, it depends.

Edit

Passing in a value to calc doesn't make any sense. calc is useful for calculating expressions, e.g., calc (50% - 10px). If you're going to pass in a percentage, just set the percentage.

Response to comment

I don't believe it's working as you suggest, but that it's not bombing your page. In your sandbox, I did this:

@keyframes animated-progress {
  from {
    width: 0;
  }
  to {
    width: calc(thisDoesNotActuallyWork);
  }
}

and the page looked the same way. No console errors, no white screen -- it looked like this:

enter image description here

which is what it looked like when width was used.

I reassure you that if you don't declare a variable and set it to something, code tends to not work. How it fails depends, though.

Upvotes: 1

Dan Knights
Dan Knights

Reputation: 8368

In the SO link you posted, they're referring to Sass which uses variables and interpolation like this:

$width: 100%;
height: calc(#{$width} * 1.778);

However, that post doesn't use the correct syntax, i.e., declaring variables with a $ at the start, so I can see where you got confused.

With CSS you can declare variables with a different syntax:

--width: 100%;
height: calc(var(--width) * 1.778);

Though, it's worth noting:

...that the selector given to the ruleset defines the scope that the custom property can be used in. A common best practice is to define custom properties on the :root pseudo-class, so that it can be applied globally across your HTML document

So you could define the variable globally and it's easier to maintain if used in other parts of your CSS:

:root {
  --width: 100%;
}

Upvotes: 0

Related Questions