PostHTML Custom Elements de-FOUC Plugin
Mitigate intrinsic Flash of Unstyled Content (FOUC) of Custom Elements V1, by delaying their visibility upon connection.
Before:
< html >
< body >
< custom-element > FOUC autonomous custom element </ custom-element >
< div is = " my-div " > FOUC extended built-in element </ div >
</ body >
</ html >
After:
< html >
< body >
< custom-element style = " visibility: hidden; " > FOUC autonomous custom element </ custom-element >
< div is = " my-div " style = " visibility: hidden; " > FOUC extended built-in element </ div >
</ body >
</ html >
Install
Add PostHTML Custom Elements de-FOUC plugin to your build tool:
npm i posthtml posthtml-custom-elements-defouc
IMPORTANT: don't forget to use with-custom-elements-defouc
higher-order-class for your Custom Element definitions.
Note: Depending at your targeted audience the CSS :defined
pseudo-class may is a better solution.
Of course if you need to support any user with non-capable browsers :defined
won't help you there.
You could handle all undefined custom elements FOUC just by these lines defined within your <head>
section:
: not ( :defined ) {
display : none ;
// or
visibility : hidden ;
// or whatever you came up with
}
Usage
This plugin comes with sane defaults, just add it to your PostHTML pipeline:
const fs = require ( ' fs ' ) ;
const posthtml = require ( ' posthtml ' ) ;
const posthtmlCustomElementsDeFouc = require ( ' posthtml-custom-elements-defouc ' ) ;
posthtml ( )
. use ( posthtmlCustomElementsDeFouc ( { } ) )
. process ( html )
. then ( result => fs . writeFileSync ( ' ./after.html ' , result . html ) ) ;
Options
Optionally you can:
limit this plugin to a specific namespace
disable processing autonomous
Custom Elements or extended builtin
Elements
apply your own custom style
to mitigate FOUC
or use a CSS className
to mitigate FOUC
Limit namespace
Before:
< html >
< body >
< custom-element > content </ custom-element >
< span is = " builtin-element " > content </ span >
< namespace-element > content </ namespace-element >
< span is = " namespace-element " > content </ span >
</ body >
</ html >
Add option:
const fs = require ( ' fs ' ) ;
const posthtml = require ( ' posthtml ' ) ;
const posthtmlCustomElementsDeFouc = require ( ' posthtml-custom-elements-defouc ' ) ;
posthtml ( )
. use ( posthtmlCustomElementsDeFouc ( { namespace : ' namespace ' } ) )
. process ( html )
. then ( result => fs . writeFileSync ( ' ./after.html ' , result . html ) ) ;
After:
< html >
< body >
< custom-element > content </ custom-element >
< span is = " builtin-element " > content </ span >
< namespace-element style = " visibility: hidden " > content </ namespace-element >
< span is = " namespace-element " style = " visibility: hidden " > content </ span >
</ body >
</ html >
Disable autonomous
Before:
< html >
< body >
< custom-element > content </ custom-element >
< span is = " builtin-element " > content </ span >
</ body >
</ html >
Add option:
const fs = require ( ' fs ' ) ;
const posthtml = require ( ' posthtml ' ) ;
const posthtmlCustomElementsDeFouc = require ( ' posthtml-custom-elements-defouc ' ) ;
posthtml ( )
. use ( posthtmlCustomElementsDeFouc ( { autonomous : false } ) )
. process ( html )
. then ( result => fs . writeFileSync ( ' ./after.html ' , result . html ) ) ;
After:
< html >
< body >
< custom-element > content </ custom-element >
< span is = " builtin-element " style = " visibility: hidden " > content </ span >
</ body >
</ html >
Disable builtin
Before:
< html >
< body >
< custom-element > content </ custom-element >
< span is = " builtin-element " > content </ span >
</ body >
</ html >
Add option:
const fs = require ( ' fs ' ) ;
const posthtml = require ( ' posthtml ' ) ;
const posthtmlCustomElementsDeFouc = require ( ' posthtml-custom-elements-defouc ' ) ;
posthtml ( )
. use ( posthtmlCustomElementsDeFouc ( { builtin : false } ) )
. process ( html )
. then ( result => fs . writeFileSync ( ' ./after.html ' , result . html ) ) ;
After:
< html >
< body >
< custom-element style = " visibility: hidden " > content </ custom-element >
< span is = " builtin-element " > content </ span >
</ body >
</ html >
Custom style
style
can be either of type string or a style hash .
Before:
< html >
< body >
< custom-element > content </ custom-element >
</ body >
</ html >
Add option:
const fs = require ( ' fs ' ) ;
const posthtml = require ( ' posthtml ' ) ;
const posthtmlCustomElementsDeFouc = require ( ' posthtml-custom-elements-defouc ' ) ;
posthtml ( )
. use ( posthtmlCustomElementsDeFouc ( { style : { display : ' none ' } } ) )
. process ( html )
. then ( result => fs . writeFileSync ( ' ./after.html ' , result . html ) ) ;
After:
< html >
< body >
< custom-element style = " display: none " > content </ custom-element >
</ body >
</ html >
Custom className
Before:
< html >
< body >
< custom-element > content </ custom-element >
</ body >
</ html >
Add option:
const fs = require ( ' fs ' ) ;
const posthtml = require ( ' posthtml ' ) ;
const posthtmlCustomElementsDeFouc = require ( ' posthtml-custom-elements-defouc ' ) ;
posthtml ( )
. use ( posthtmlCustomElementsDeFouc ( { className : ' foo ' } ) )
. process ( html )
. then ( result => fs . writeFileSync ( ' ./after.html ' , result . html ) ) ;
After:
< html >
< body >
< custom-element class = " foo " > content </ custom-element >
</ body >
</ html >
Contributing
See PostHTML Guidelines and contribution guide .
License MIT
Proudly brought to you by <scale-unlimited>