Pure CSS dynamic multiline paragraph placeholder

Whoa! Long post title for a long story about:

  • how to get a container height of exact n line-heights (tldr; use display:grid with grid-template-rows)
  • how to make use of it by creating a cool dynamic paragraph placeholder with quite elegant CSS an HTML

How did this start?

I was assigned to a task that required placeholders for image and number of lines of text below.

The number of lines can vary but is constant for each of the code execution.

To make it as easy as possible, it’s a no-brainer. Just a few lines of js which would create fake lines with dummy content, make it transparent and put some gray background. Done.

Since I don’t like doing things in js if I know there might be a pure CSS way, I started to think if it’s even possible.

Thanks to new CSS standards which are quite powerful, it is. Here’s the short explanation.

Line-height unit/value? Doesn’t exists

First must-have for the placeholder is to make the empty container to be the exact same height as filled one, so we avoid jumping of the UI which is never a good idea.

To meet this requirement, we need to know how many lines of text we expect.

For this scenario, we assume that’s a given value. For most use cases, like product cards, excerpts, user infoboxes, it’s usually defined by the design.

For others, it would be still given, since for a long text we would rather want to show just two or three lines of placeholder. For those cases, the content is usually in some main container, so jumping would be avoided by its nature.

But how do I make the container height exactly the same as it would have real content?

There are two simple ways of sizing the container which yet doesn’t have the real content.

Render a dummy, transparent content

By rendering a dummy, transparent content you have 100% guarantee that the browser would render it in the same way as it would be a real content.

A problem with that approach is that the content might be accessed by the screen readers (aria-hidden is the solution). But, additionally, you need to build the HTML and render it, then destroy this DOM node and create a new one when the real content is there. Not the biggest performance issue, but also not something you really want to do.

Leave the container empty, render the same size as before pseudo-element

You can also leave the container empty and render exact same and empty container as a  before pseudo-element.

First intuitive thought would be to use some relative units like em, or ex.

This approach won’t work since there is no such unit in CSS. All the relative units are either related to:

  • container (%)
  • viewport (vh, vw)
  • or font (em, rem, ex, ch…)

There is no unit that would strictly relate to line-height, like 1lh, or 1cap.

But there is a trick that covers this particular case: grid fraction.

1 row fraction happens to have a default height same a line-height

When defining a grid you can tell how many grid rows you want to “prepare” and those are rendered even if there is no related content.

So, usual HTML grid definition looks like this:

<style>
    .grid {
        display: grid;
        grid-template-rows: repeat(2, 1fr);
    }
</style>
<div class="grid">
    <div class="row"></div>
    <div class="row"></div>
</div>

To prepare an empty container that has the same size as it would contain three lines of text the HTML looks like this:

<style>
    .content.content--placeholder:before {
        content: "\a0";
        display: grid;
        grid-template-rows: repeat(var(--expected-lines), 1fr);
    }
</style>
<div class="content content--placeholder" style="--expected-lines: 3"></div>

The browser renders an empty container, with a :before pseudo-element. The pseudo-element renders one line of text, a non breaking space which is invisible (both for visual and screen readers) but makes the line actually render.

Additionally, the content is a grid with a number of rows which is passed as a CSS variable given from the HTML style attribute.

With only this code, the browser renders the container with the exact same size as it would render three lines of real text.

Time for a CSS only placeholder

Rendering a placeholder in CSS at this point is just a pure entertainment. By having a possibility of rendering gradients it’s quite easy to generate a few grey lines.

<style>
    .content.content--placeholder {
        content: "\a0";
        display: grid;
        grid-template-rows: repeat(var(--expected-lines), 1fr);
        background: linear-gradient(to bottom, rgba(197,197,197,0) 0%,rgba(197,197,197,0) 18%,rgba(197,197,197,0) 19%,rgba(197,197,197,0.5) 20%,rgba(197,197,197,0.5) 50%,rgba(197,197,197,0.5) 80%,rgba(197,197,197,0.5) 81%,rgba(197,197,197,0) 82%,rgba(197,197,197,0) 100%) repeat;
        background-size: 100% calc(100% / var(--expected-lines))
    }
</style>
<div class="content content--placeholder" style="--expected-lines: 3"></div>

The background is a linear gradient created with ColorZilla generator. The size of the background is 100% wide and height is a result of dividing 100% by the number of lines we want to render.

Result

Now, the only job for javascript is to define how many lines the placeholder should show by manipulating the CSS variable. Then, when the content is ready to be shown, to render the content and remove the class which triggers the :before element.

You can find a working demo on the GitHub page (source code).

How not to be a rookie and let your users use their localised domains

In the previous article, it’s explained why you don’t want to use a localized e-mail address. This article explains the opposite – how to implement IDN in your app.

Why even bother?

You might ask, why implement something for a small fraction of users?

It is true, that in most cases it would not make a lot of sense to please someone, maybe.

But if your app targets a broad audience in many different countries, then you still might want to support people who happen to work for this company: http://中国互联网络信息中心.中国 and maybe want to sign up for your services.

The majority of the world population do not speak English. A huge number of people might not even have or like English keyboard.

Additionally, supporting it on your side is plain simple.

Web app

As mentioned in the previous article, html email validation doesn’t allow users to put localized e-mail as an input.

That might be a blocker in the registration process since not everyone is using Chrome and now everyone can convert Unicode to punycode ASCII by hand.

To fix that, simply add novalidate attribute to your <form> element. You have a server validation and your sign up form is very simple, so it won’t harm the user experience, right?

Server

Server implementation is even simpler. You just need to sanitize incoming email address by converting a right hand side (domain name) into punycode.

There is not risk of double encoding since punycode will not encode ASCII into anything else.

Second step is to make sure whenever the e-mail is shown in the UI, it would be converted to unicode again.

It can be done right before user data is sent to an app for display purposes. Ideally not sooner.

In general, it’s better to use ASCII when communicating between machines.

Further reads

http://unicode.org/faq/idn.html 
Some day browsers will implement correct email validation.

Why you don’t want e-mail in internationalised domain

1. Looks good, but not everyone can type it

You might think that “my-wörk.de” is a cool name for your website and hä[email protected]örk.de is even better (Unicode in username is currently not available), but the problem is that not everyone knows how to type umlauts.

Some people say it’s possible on Windows with an English keyboard, but I think it’s just an urban legend.

2. Sooner or later you will not register an account (or log in)

The browser support for IDN (Internationalized Domain Name) is awesome… when typing a website address in the URL bar. It’s a completely different story when speaking about forms.

Firefox and Safari send email input as a raw string (wörk stays wörk). Chrome converts the domain name to Punycode on the fly (wörk is sent to a server as “xn--wrk-sna”).

For websites which don’t support Punycode domains on the server, it’s possible to register an account using Chrome. It will be possible to log using Chrome. Except you try to log in using Chrome on iOS (it uses Safari webview).

Additionally, you might not even register an account as well if a website uses an email input type.

3. HTML “email validation” specification

In short words: HTML defines a regex for email validation. This regex doesn’t implement IDN. You will not be able to put your e-mail in an e-mail sign up form. If a website uses <input type="email" /> (which is very, very common).

Again, this doesn’t apply to Chrome on a desktop and Android which converts it on the fly.

4. Many websites and servers are not prepared for it

Even though IDN 2008 specification is made in… 2008, it’s very common that developers don’t bother supporting it. Managers don’t bother even more since it’s not common to see such domains (or 🇵🇱.to) and it’s not likely that someone would complain (except some wild external QA team).

 

 

 

Permanently blocked port on Macos High Sierra

Short note with quick solution.

For some time my react app was constantly refusing to run on localhost:3000. For some time I thought that maybe there’s some forgotten node process still running in the background.

After some investigation I found that something changed on MacOS High Sierra networking setup and localhost is often not resolved to 127.0.0.1.

Adding 127.0.0.0.1 localhost into /etc/hosts seems like a solution for this issue.

Promise is not just simplified callbacks pattern

Since ES6 popularity grows, Javascript Promises use is getting more and more attention.

Many forget that Promise is not just a nice way to simplify callbacks it’s much more – keeping the resolution state as long as the Promise is kept in a memory.

Let’s imagine a scenario that we have a module that will fetch some information from localStorage or from a server is the localStorage entry one is missing.

Also, let’s assume this information won’t be updated for entire runtime of the app (e.x. feature flag).

Then, we could do something like this:

const featureFlagFoo = () => {
  return new Promise((resolve, reject) => {
    const cacheKey = 'featureFlagFoo';
    const cached = localStorage.getItem(cacheKey);
    if (typeof cached !== 'undefined') {
      // cached value, resolve immediately
      resolve(cached);
      return;
    }
    // no cached value, fetch, save, resolve
    someAjaxLib.fetch()
      .then((data) => {
        const value = data.foo;
        localStorage.setItem(cacheKey, value);
        resolve(value);
      })
      .catch((err) => {
        reject(err);
      })
  })
};
const featureFlagFooPromise = featureFlagFoo.catch((err) => handleError(err));

export default featureFlagFooPromise;

This way, the resolver kicks in already during the first execution of the code. Then your code can import the promise and most the resolve function will be executed faster since it’s either resolved immediately, or the fetching started before your code actually asked for it.

import fooPromise from './someFooPromise.js';

fooPromise.then(() => doSuccess).catch((err) => showError(err));

Both resolve/reject resolutions are remembered by the Promise. It’s required however since latest node versions to always define failed state callbacks, therefore it needs to be defined at least in the module.

CSS image transition and memory leaks

CSS transitions are features we all love and admire. They allow us to communicate with browser rendering engine and make cool things we were never able to do so fast and easy.

We also assume that we just have to use CSS as an API and don’t really need to care about memory management. Everything should be handled by the browser, we just say what we want from the engine.

However, there are some things we should always have in mind to make the UI smooth and also nice to watch.

One of the “things” is the magic translate3d(0,0,0) hack which forced the browser to use GPU (if available) for rendering the element with this property applied.

It is also possible to make everything completely wrong if we don’t know what is really happening under the hood (or how specific engine handle specific transitions).

IMG causes memory leak

For a regular job I work with webviews. We are focused o creating cool e-commerce apps for merchants around the world. Recently we experiment with single view approach hybrid apps. Results are pretty good, we noticed huge speed improvement, however developing an app in single view approach also opened our eyes on things we didn’t consider before.

One of the issues was memory management.

Single view application loads every page in one single webview (or browser tab if it runs inside browser). It means there’s need to really take care about memory leaks. It’s more important to manage event listeners, object destructions and rendering process. What is flushed from memory automatically in multiview app when page is removed from stack, may stay forever in single view one.

After some tests we found out that app takes far too much memory after some time of usage and is eventually killed by jetsam (ios memory watchdog). We didn’t have huge DOM (we did test it though and memory management works awesome for 600 tested Framework7 pages in DOM).

The reason behind this was jpeg rendering layers which were never flushed.

It seems like in iOS 9, when opacity is applied directly to an image, another GPU layer is created to handle transitions, which is also never released. Even if the image is removed from DOM.

Fix for this issue is pretty simple (apply opacity transitions to image parent, not image itself), however research on this took some hours.

Lesson learned. Do not apply opacity to an image itself.

 

Cunning way of sanitizing options

There are times in developer’s life when we have to deal with some huge function prototypes and there is absolutely now way to make it easier or more simple.

In those times there might come a need to use incoming options (or params) object thought multiple of shared private functions.

There is good practice to always sanitize incoming data. Validation is also nice, but sanitizing is enough for trusted environment. If the worst case is that something won’t work exactly as developer expected, but still will works for a user, there’s no need to throw Exception and break the whole thing.

If private functions share some options parameters (like endpoint url data) it’s good to sanitize it just once and use them as trusted ones afterwards.

I had this problem couple of months ago and after thinking a lot how to make it clever without causing additional CPU overhead, I figure out the following pattern:


var HugeClass = function () {
 	
    this.publicMethod = function (options){
       
        options = _sanitizeOptions(options);
        
        var foo = _privateFunction1(options),
            foo2 = _privateFunction2(options);
        
    }
    
    function _privateFunction1(options) {
       	options = _sanitizeOptions(options);
        // do smth
        
    }
    
    function _privateFunction2(options) {
        options = _sanitizeOptions(options);
        // do smth
    }
    
    function _sanitizeOptions(options){
        if (options instanceof SanitizedOptions) {
         	return options;   
        }
        
     	var requiredBooleans = ['foo', 'bar'];
        
        requiredBooleans.forEach(function(keyName){
         	if (keyName in options) {
             	options[keyName] = !!options[keyName];   
            } else {
             	options[keyName] = false;   
            }
        });
        
        var sanitized = $.extend(new SanitizedOptions(), options);
        
        return sanitized;
    }
    
    var SanitizedOptions = function(){};
    
}

Every time options are being used, function asks the “sanitizeOptions” for basic sanitization.

The sanitizeOptions method checks if the options are already sanitized and if it’s true just return them as trusted ones. Of not, do the sanitization and flag them as SanitizedOptions instance.

Of course it might be enough to just add another property like options.sanitized = true; but this is not as secure as marking the object as another instance.

First of all, property can be set or change from anywhere (outside, inside, naming conflict, etc.).

Second of all, SanitizedOptions function is unique per the class. It’s impossible to make your own SanitizedOptions from the outside. It’s because “a instanceof B” checks if a was created by function B which has reference somewhere in the memory. It’s not checking the name of the function, it’s checking the memory reference.

Simple javascript singleton pattern that works everywhere

What’s singleton and when to use it?

Object prototypes and instances

Before describing the singleton pattern and getting in to examples how to use it in Javascript, it’s good to repeat how the objects are created in javascript.

Types, instances and object

Some say all “things” in javascript are objects, and this is almost true, even if there are some exceptions for “primitive types” like Number, Bolean etc.

As Nick Morgan pointed out, javascript makes our lives better and is able to “wrap” the primitive values to an object on demand when developer tries to access the public methods or properties.

Thanks to this, instead of creating new string like this

var foo = new String('foo');

we can just use this:

var foo = 'foo';

If result is almost the same, how to check if javascript doesn’t really created the object when we just use foo = ‘foo’ method? Well, you check the “type” of both variables. For first case the type will be “object”. For the second one, “string” (primitive value).

However if you’ll check what is the constructor of variable foo from this example (foo.constructor), for both cases it would be String function.

Function because javascript objects are created by executing the functions.

Thanks to this we can simulate the traditional behavior  of classes enhancing our code with public or private properties, do something on object creation the same way as php __construct() do or implementing the software patterns like Singleton.

OK, so what is type, instance and object?

Long story short, when you ask javascript what is the type of variable foo (typeof foo) it will return the name of primitive type of the variable. If you created foo using second method, it will return the “string” type. If you created it using the function String, it will return “object” type.

Shouldn’t it be “String” from a name of the class?

No, because compiler when asked to create new String(‘foo’) creates the object using String function (native in this case). 

Sometimes it’s good to have the one – Singleton

Singleton is a pattern of creating object that forbids to create more than one instance. Even if there would be a try to create another instance within same runtime, constructor should return the previously created instance.

When to use it?

You should create singleton class only when you are positive that there should be one and only one object. The object you create is unique at least for a runtime and also, is meant to be used by “others”.

To get an example use case, let’s take a user object. For most cases user is unique for the runtime (you can be logged to single account at a time), user properties are meant to be shared with entire environment and it’s better to not read data from anywhere every time some algorithm wan’t to know what is the logged user ID. Also, if we are dealing with a client side app, it’s should be also ok to keep the user object in memory all the time, instead of creating one on demand.

User Singleton javascript object

In many sources all over the internet you can find numbers of different solutions. However, most of then have some defects. Some of them are not Singleton at all, some only works when developer uses it in a right way. I call it singleton and it happens when developer can get already created instance using something like getInstance method, but is also still able to create new object with “new FunctionName”.

To make it really good and bullet proof, I often use following pattern.

/**
 * User object prototype is evaluated 
 * right after read, so everything what's
 * inside is both local and stored in memory
 * forever.
 * 
 * If this function is used to create an object
 * there's a guarantee that UserSingleton will
 * be executed just once per runtime.
 *
 * There's no way to change the User.prototype.instance
 * property, or remove the object from memory without
 * removing whole object constructor.
 */
var User = (function() {

    function UserWrapper() {
        var created = null;

        function UserSingleton() {
            this.getCreated = function() {
                return created;
            }
        }

        if (!User.prototype.instance) {
            created = new Date();
            UserWrapper.prototype.instance = new UserSingleton();
        }

        return UserWrapper.prototype.instance;
    }

    UserWrapper.prototype.instance;

    return UserWrapper;
})();

Above pattern guarantees that nobody will be able to create another User object within the same runtime (idiot-proof). Of course if developer wants this to be possible it can still be done by extending the UserWrapper with public method which. Since everything inside self-executing function is in the same local scope, it can still be done, but only intentionally and internally.