10 web snippets

Preloading images with JavaScript

If your web app dynamically displays certain images and you don't want to make sure that the images are downloaded before they are first displayed, you can pre-fetch the images using some simple javascript.

For single-page apps, this should be sufficient:

function preload_images(urls) {
  urls.forEach( function(i, url ) {
    (new Image()).src = url;

preload_images( [ 'image1.jpg', 'image2.png', 'image3.tiff' ] );

If you want to add a slight delay (so other web assets can load first) use something like:

setTimeout( function() { preload_images( [ 'image1.jpg', 'image2.png', 'image3.tiff' ] ); }, 500) ;

The single-page-app method above loads each image in the array into memory. However, browsers generally won't cache these images, so if the user navigates to another page without viewing the images, they will be lost.

To make the images cachable, it helps to add the image that is created into the actual DOM tree for the page. Here's one way:

function preload_images(urls) {
  var newdiv = document.createElement("div")
  if(newdiv.setAttribute) {
  } else if(newdiv.style && newdiv.style.setAttribute) {
  } else if(newdiv.style) {
    newdiv.style.cssText = "display:none;";
  } else {
    newdiv.style = "display:none;"
  urls.forEach( function(i, url ) {
    var newimg = new Image();
    newimg.src = url
Published 13 Mar 2014


A General Purpose SQL-to-HTML Routine for CoffeeScript/JavaScript/Node.js

Using node-mysql or similar, the following CoffeeScript routine will generate an HTML table containing the data in a SQL result set, including column headings:

  connection.query query, bindvars, (err,rows,fields)->
    if err?
      buffer = '<table border=1><tr>'
      for field in fields
        buffer += "<th>#{field.name}</th>"
      buffer += '</tr>'
      for row in rows
        buffer += '<tr>'
        for field in fields
          buffer += "<td>#{row[field.name]}</td>"
        buffer += '</tr>'
      buffer += '</table>'
Published 8 Feb 2014


breaking non-space (zero-width space)

To insert a zero-width space character (as a hint to the layout engine that it could insert a line break here) in HTML:


Or in Latex:

Published 6 Apr 2014
Tagged html, tex-latex and web.


Backup or mirror a website using wget

To create a local mirror or backup of a website with wget, run:

wget -r -l 5 -k -w 1 --random-wait <URL>


  • -r (or --recursive) will cause wget to recursively download files
  • -l N (or --level=N) will limit recursion to at most N levels below the root document (defaults to 5, use inf for infinite recursion)
  • -k (or --convert-links) will cause wget to convert links in the downloaded documents so that the files can be viewed locally
  • -w (or --wait=N) will cause wget to wait N seconds between requests
  • --random-wait will cause wget to randomly vary the wait time to 0.5x to 1.5x the value specified by --wait

Some additional notes:

  • --mirror (or -m) can be used as a shortcut for -r -N -l inf --no-remove-listing which enables infinite recursion and preserves both the server timestamps and FTP directory listings.
  • -np (--no-parent) can be used to limit wget to files below a specific "directory" (path).
Published 10 Feb 2014


Pre-generate pages or load a web cache using wget

Many web frameworks and template engines will defer the generation the HTML version of a document the first time it is accessed. This can make the first hit on a given page significantly slower than subsequent hits.

You can use wget to pre-cache web pages using a command such as:

wget -r -l 3 -nd --delete-after <URL>


  • -r (or --recursive) will cause wget to recursively download files
  • -l N (or --level=N) will limit recursion to at most N levels below the root document (defaults to 5, use inf for infinite recursion)
  • -nd (or --no-directories) will prevent wget from creating local directories to match the server-side paths
  • --delete-after will cause wget to delete each file as soon as it is downloaded (so the command leaves no traces behind.)
Published 10 Feb 2014


Uploading a file with curl

To submit the file at foo to a web service as multi-part form data using curl:

curl -X POST -F "file=@\"foo\"" ''

The file part is the name of the corresponding form field.

Note that you can submit multiple files:

curl -X POST -F "f1=@\"foo\"&f2=@\"bar\"" ''

Or add additional body or query string parameters:

curl -X POST -F "f1=@\"foo\"&x=y" ''
Published 31 Dec 2015
Tagged curl, web and tool.


Cross-browser CSS transitions

.foo {
  transition:         opacity .25s ease-in-out;
  -webkit-transition: opacity .25s ease-in-out;
  -moz-transition:    opacity .25s ease-in-out;
  -o-transition:      opacity .25s ease-in-out;

Where the right-hand side has the general form:


Transitions can chained:

 .foo { transition: opacity .25s ease-in-out, height 1s linear }

Transition timing functions

  • linear - constant rate of change between states.

    cubic-bezier(0.0, 0.0, 1.0, 1.0)

  • ease - (the default) slow acceleration, then faster, before rapidly slowing again at the end.

    cubic-bezier(0.25, 0.1, 0.25, 1.0)

  • ease-in-out - like ease but accelerating/decelerating more rapidly (with a shorter transition between acceleration and deceleration).

    cubic-bezier(0.42, 0, 0.58, 1.0)

  • ease-in - equivalent to the first half of ease-in-out; rapid accelerating then transitioning to a constant rate of change at the end.

    cubic-bezier(0.42, 0, 1, 1.0)

  • ease-out - equivalent to the second half of ease-in-out; a constant rate of change transitioning rapid deceleration at the end.

    cubic-bezier(0.42, 0, 0.58, 1.0)

  • cubic-bezier(x1,y1,x2,y2) - follows cubic B├ęzier curve using the control points (0,0), (x1,y1), (x2,y2) and (1,1).

  • steps( n, [start|end] ) - stepwise function with n steps

How to read cubic-bezier functions

Imagine the transition as a stepwise function starting at (0,0) and ending at (1,1) and with two steps in between. The cubic-bezier(x1,y1,x2,y2) function specifies the points in the middle. In other words, x1 and x2 are the times at which the second and third steps happen, respectively (expressed as a fraction of the total transition duration) and y1 and y2 are how far along the transition is at x1 and x2, respectively (expressed as a fraction of the total transition "distance"). Very loosely, the cubic-bezier function "smooths" those steps.

These are nicely demonstrated here.

Tagged css, html, web and design.


Presentational CSS Classes

These are the opposite of semantic markup, but I find them useful:

.align-both   { text-align: justify; }
.align-center { text-align: center; }
.align-left   { text-align: left; }
.align-right  { text-align: right; }
.float-left   { float: left; }
.float-right  { float: right; }
.nobr         { white-space: nowrap; }
.small        { font-size: 80%; } /* should really sync with the <small> tag rules */
Tagged css, html, web and design.


Fixing CSS Resets

CSS reset frameworks often strip out all formatting. These CSS rules contain some re-resets:

/* I understand the theory behind replacing <i> and <b> with <em> and <strong>, but c'mon, really? */
i     { font-style: italic; }
b     { font-weight: bold; }
small { font-size: 80%; }

/* Make superscripts and subscripts actually do something: */
sup, sub { height: 0; line-height: 1; vertical-align: baseline; _vertical-align: bottom; position: relative; }
sup      {    bottom: 1ex; }
sub      {    top: .5ex; }

/* Mono-spaced types. */
pre, code, kbd, samp, tt { font-family: 'droid sans mono slashed', 'droid sans mono dotted', 'droid sans mono', monospace, monospace; }
Tagged css, html, web and design.


Vertically centering block elements with CSS.

Via phrogz.net.

<style type="text/css">
    #wrapper { position:relative; } /* position:absolute is also ok */
    #wrapped { position:absolute; top:50%; height:10em; margin-top:-5em; }  /* margin-top = -1 * height/2 */
<div id="wrapper">
    <div id="wrapped">
        <p>Block content.</p>
        <p>But still vertically centered.</p>
Tagged css, html, web and design.


This page was generated at 4:16 PM on 26 Feb 2018.
Copyright © 1999 - 2018 Rodney Waldhoff.