Concrete Sass Examples

When I started using Sass I was mostly using  nesting and variables. In my own experience this is also what I’ve seen to be the most commonly used features.

I want to illustrate some of it’s other features and how they can be used with practical examples.

@for and @if rules

The @for and @if rules can be used to quickly generate a lot of CSS selectors. Things that would have been possible but impractical and would have been hard to maintain.

For example to make a CSS implementation of  a progress meter, I used the @for and @if rules.

@for $pct from 0 through 100 {
    .progress-#{$pct} {
      width: getWidth($pct);

      &.tresholds {
        @if $pct < 33 {
          background-color: greenyellow;
        } @else if $pct < 66 {
          background-color: yellow;
        } @else {
          background-color: red;
        }
      }
    }
}

This quickly generates all 100 CSS selectors with colours varying depending on the progress.

You can see the full example here: CSS Progress Meters CodePen.

Another good use of the @for rule is for creating multiple @keyframes in CSS animations.

@function

Functions can be used to return values which is useful when dealing with dynamic rules like those created with @for or to calculate a value using a variable. This way if this value changes in the future you only need to change the variable and not all of the derived values.

For example (this is taken from the same progress meters CodePen):

$meter-width: 120px;

@function getWidth($pct) {
  @return $meter-width / 100 * $pct;
}

In this case the getWidth function will return the width for a given percentage. In the previous progress meter example we use this to get the width at each iteration in our for loop.

Also if we change the value of the $meter-width variable we won’t have to change our scss file besides that single value change.

Using Sass variables with CSS’ calc

CSS’ calc function is great, particularly when doing things like:

width: calc(100% - 5em);

You can still use your Sass variables in the calc function by using the following syntax:

$meter-width: 120px;

width: calc(100% - #{$meter-width});

Mixins

Mixins allow you to include a bunch of rules at once in a selector. Similar to @extend but one of the things that differentiate them is the fact that mixins can have parameters.

The Sass website mentions vendor prefixes as a good use of mixins. In this CSS triangles CodePen, I demonstrate another use. I used mixins for creating triangles using the the CSS Triangle trick.

If you define these mixins in a base scss file, you can then easily create all kind of CSS triangles.

%arrow {
  height: 0;
  width: 0;
}

@mixin css-triangle-trick-up($size, $color) {
  border-bottom: $size solid $color;
  border-left: $size solid transparent;
  border-right: $size solid transparent;
}

@mixin css-triangle-trick-down($size, $color) {
  border-top: $size solid $color;
  border-left: $size solid transparent;
  border-right: $size solid transparent;
}

.arrow-up {
  @extend %arrow;
  @include css-triangle-trick-up(30px, white);
}

.arrow-red-down {
  @extend %arrow;
  @include css-triangle-trick-down(40px, red);
}

The CodePen also includes examples of the @for rule and @extend.

Conclusion

There is more to Sass than what I have shown here, but still Sass is one of those subjects where there aren’t a ton of things to master. It’s quick and easy to learn the different features it offers and well worth the effort.

Making PDF.js work with digital signatures

Out of the box PDF.js doesn’t support displaying signatures on PDF files. This is strange since it’s such a common scenario and it’s been requested many times over the years.

Thankfully there’s a simple solution to this. You need to modify the pdf.worker.js file with the following modification.

In the var WidgetAnnotation = /*#__PURE__*/ function, look for the following code:

if (data.fieldType === 'Sig') {
  data.fieldValue = null;
  _this3.setFlags(_util.AnnotationFlag.HIDDEN);
}

And comment out the setFlags line like this:

if (data.fieldType === 'Sig') {
  data.fieldValue = null;
  // _this3.setFlags(_util.AnnotationFlag.HIDDEN);
}

You don’t need to make any modifications to the pdf.js file itself just the pdf.worker.js file.

To do this you download PDF.js from the project page. Take the pdf.worker.js file from the build folder and make the modification. In your web project, use the local modified version of this file but keep referencing the base file through a CDN (or locally if you wish).

Don’t forget to minify your modified worker file afterwards.

Of course, you’ll have to make this manual modification each time you update PDF.js.

Final Fantasy like screen transition effect

transition-effect

I’ve created a small project where I tried to produce an effect similar to the Final Fantasy 8 screen transition effect.

You can see a video of the original effect here and my project in action here.

The code is accessible through the GitHub repository.

Whilst I’m a Firefox user I had to resort to refreshing the page on Firefox as it leaked an amount of memory the size of the canvas’ image data. This leak wasn’t present on Chrome, Edge or Safari.

I’m writing directly to the image data like a buffer, which I found out is far from optimal. It’s far better to stick to drawing primitives from the API (much faster) but this ultimately limits what you can do which is why I stuck with direct operations on the image data.

Never let stray errors in the console

When doing web development I fix all the errors that show up in the console. Often they don’t seem to impede the actual use of the software, but nevertheless I think it’s a good practice to fix them all. This following example should illustrate why.

I was doing some maintenance on an Angular project at work. I noticed that there were a couple of errors showing up in the console, but the web site still worked great, even with the errors.

The reason I was working on this project was because of a bug that was reported by QA. There was a display error that was happening and it was related to animations that were used in the Angular transitions, these are used when switching from one component to another. The error manifested itself with Android phones and iPhones. This bug probably slipped by because everything was working fine on desktop browsers.

After investigating, I saw that there was an error in the console about calling a property on undefined. On a view, this can be fixed using the ?. operator. The view used the ?. operator elsewhere but there was one place it was missing. I was sure this couldn’t be what was messing up the display of the animated transition.

I searched and searched but couldn’t find the problem.

So I decided that while I was there, I might as well fix this error that showed up in the console. I changed the . operator for ?. and lo and behold this also fixed the display problem.

By correcting it, it also corrected the other problem, which was probably caused by having an error during the Angular rendering.

This example demonstrates that you should never let console errors live, even if they don’t seem to have any negative effect on the web site.