1

My JS code sets a variable on the page:

  if (error) {
    document.querySelector('body')?.style.setProperty('--pickererror', `'${ error }'`);
  }

My SCSS code uses that variable for some content:


  $error: var(--pickererror);

  // ERROR MESSAGE
  .picker-toolbar::before {
    content: $error;
    color: red;
    padding: 5px 35px 0px 35px;
    text-align: center;
  }

  .picker-toolbar {
    @if str-length($error) > 0 {
      order: 1 !important;
    }
  }

The ::before section works completely. However the @if clause executes even if there is no error, and the .picker-toolbar is always at order: 1.

I have checked that --pickererror is not present when there's no JS error. I've tried any number of permutations, such as

  1. Putting the @if line before the .picker-toolbar line
  2. Simply using @if $error
  3. Using @if var(--pickererror) in place of the $error variable.

How do I make this work?

4
  • 1
    I could be wrong on this but I don't think that @if is getting evaluated at runtime when the custom property --pickererror changes. I think you'd be better off applying a second class to whatever element has the .picker-toolbar to change the order. Commented Feb 25, 2020 at 16:50
  • Sass is precompiled so that if won't exists in the actual css the site uses, why not just use the js to add a class to any picker toolbars that have an error Commented Feb 25, 2020 at 16:59
  • All the .picker-xxx elements are managed by a 3rd party component, in my React code. I've been having trouble getting refs which I suppose is what I'd need to add classes and things like that. Sounds like that's the only possible route though? Commented Feb 25, 2020 at 17:04
  • Without seeing the rest of the code specific to rendering the picker, then I would agree with your statement about the refs (or maybe that component/library has some API or renderProps to tie into) Commented Feb 25, 2020 at 19:34

1 Answer 1

1

What if you remove the logic from your stylesheet entirely, and instead rely on the dynamic property value from your JavaScript?

For example:

body {
  --pickererror: 0; // Default value for the "order" property
}

If your JavaScript detects an error, the --pickererror is given a value of 1 !important;

if (error) {
  document.querySelector('body').style.setProperty('--pickererror', '1', 'important');
}

And in your stylesheet, you only need a single rule that changes the order if the JavaScript says so.

.picker-toolbar {
  order: var(--pickererror, 0); // Defaults to "0" also if the variable doesn't exist
}

I realize this only makes sense if you are using --pickererror mostly as a boolean (I thought since you're checking if its length is greater than 0). If you're actually using the string value, it would be better to create an --error-order variable for this single purpose I guess.

Sign up to request clarification or add additional context in comments.

1 Comment

That is a great idea, and I'm sure it will work, and I'll mark it as the answer. I may not use it, because it seems to violate separation of concerns, putting all that styling info in the JS instead of just the logic that dictates it. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.