Notes

This is a collection of short notes about random things I learn during my day-to-day work. Things I find noteworthy, helpful, interesting, surprising, or just really cool.
  • 15

    Convert RegExp to JSON

    Regular expressions are converted to empty objects by JSON.stringify:

    const config = {
      test: /\.js$/,
    };
    
    JSON.stringify(config) // {"test": {}}

    You can workaround this by defining a toJSON function, which serializes the RegExp as a string:

    RegExp.prototype.toJSON = RegExp.prototype.toString;
    
    JSON.stringify(config) // {"test": "/\\.js$/"}

    Or you can define a replacer function which you pass as a second parameter:

    const replacer = (key, value) => {
      if (value instanceof RegExp) {
        return value.toString()
      }
    
      return value
    }
    
    JSON.stringify(config, replacer) // {"test": "/\\.js$/"}

    Resources

  • 14

    HTML output tag

    HTML has an <output> tag, that can be used to insert some result of a user action or calculation. Assistive technologies use this as an aria-live region, which means it is announced as soon as some content is injected into the element.

    Resources

  • 13

    Overscroll behavior

    There is a CSS property called overscroll-behavior. It can prevent the body from scrolling while you are inside of a nested scrollable container - also known as "scroll chaining". Useful for modals or fixed sidebars.

    Resources

  • 12

    Pretty JSON

    JSON.stringify accepts a third parameter space to allow the JSON to be nicely formatted:

    JSON.stringify({
      key: 'value' 
    })
    
    // {"key":"value"}
    
    JSON.stringify({key: 'value'}, null, 2)
    
    // {
    //   "key": "value"
    // }

    This makes a big difference when you try to read a long nested object.

    Resources

  • 11

    getComputedStyle

    You can get all computed styles of an element in JavaScript with getComputedStyle().

    Resources

  • 10

    CSS isolation

    You can use isolation: isolate; on an element to explicitly create a new stacking context in CSS.

    Resources

  • 9

    CSS selector lists and pseudo-classes

    A single unsupported CSS selector in a selector list invalidates the whole rule.

    Say we are in a browser, that doesn't understand the :focus-visible pseudo-class and we apply the following rules:

    button:focus {
      outline: 2px solid blue;
    }
    
    button:focus-visible {
      outline: 2px solid red;
    }

    When focusing the button with a keyboard, the outline will be blue, because the second rule will be ignored.

    But what if we do this?

    button:focus,
    button:focus-visible {
      outline: 2px solid green;
    }

    No styles will be applied at all, because the browser can't just ignore parts of the selector, so it will skip the entire rule.

    Resources

  • 8

    console.assert

    You can use console.assert(assertion, message) to conditionally write a message to the console, if the assertion in the first parameter returns false.

    Resources

  • 7

    valueAsNumber and valueAsDate

    Inputs of type number or range have a valueAsNumber property that always returns its value as a number instead of a string. Useful, if you want to do some calculation with the value. For example:

    document.querySelector('input[type="number"]').addEventListener('change', (event) => {
      console.log(event.target.valueAsNumber + 1);
      console.log(event.target.value + 1);
    })

    Changing the input to 1 would result in an output of 2 and 11 respectively.

    Likewise an input of type date has a valueAsDate property, that returns a Date object.

    Resources

  • 6

    clamp()

    The CSS function clamp() can be used for responsive typography. For example, the following would set the font-size to be 5vw, but only within a range of 2.5rem and 4rem.

    h1 {
      font-size: clamp(2.5rem, 5vw, 4rem);
    }

    Resources

  • 5

    contain

    CSS has a property called contain to tell the browser about your layout, so that it can optimize for performance.

    Resources

  • 4

    Private class members

    Variables or methods on JavaScript classes can be declared as private by prefixing them with a #. For example:

    class MyClass {
      #myPrivateVariable = 'something private';
    
      #myPrivateMethod = function () {
        // something private
      }
    }

    Resources

  • 3

    Writing mode agnostic CSS properties

    Padding, margin and other layout properties can be defined with respect to the current writing mode with *-inline-start, *-inline-end, *-block-start and *-block-end. Or, to set both values of one direction (vertical and horizontal) you can simply use *-inline and *-block.

    Resources

  • 2

    Reserved keywords in gulp-uglify

    You can exclude keywords from being uglified in gulp-uglify with the mangle.reserved option.

    For example, in Drupal there is a translation function Drupal.t(). It works by Drupal searching for the function via regular expression. Therefore, it wouldn't work if the name was changed to something else. Here is how you can resolve this:

    const options = {
      mangle: {
        reserved: ['Drupal']
      }
    };
    
    gulp.task('uglify', function() {
      return gulp.src('src/*.js')
        .pipe(uglify(options)),
        .pipe(gulp.dest('dist'));
    });

    Resources

  • 1

    for ... else

    Twig has an else clause in for loops, that is rendered when the array to loop through is empty.

    <ul>
      {% for post in posts %}
        <li>{{post.title}}</li>
      {% else %}
        <li>No posts available.</li>
      {% endfor %}
    </ul>

    Resources