CSS 3D playground

Of course, you have to start with the traditional spinning cube. It’s practically the “Hello World!” of 3D animation:

That’s the easy part. The hard part is using equilateral CSS triangles to build a spinning octahedron:

And then pulling together even more trigonometry to build an icosahedron:

Which was, while confusing at times, a surprisingly fun puzzle to solve.

force browsers to print background colors of elements

Most browsers won’t print background colors, and print-only CSS can (or should) be set to force all text to be black so it looks good on a white background. But what about images? What if you have a logo with white text and a transparent background that’s normally displayed over a dark background? Webkit browsers support the -webkit-print-color-adjust: exact style, but that still leaves out Firefox. Continue reading force browsers to print background colors of elements

multi-select with checkboxes

If you have a very long list of options, neither <select multiple> nor <input type=”checkbox”> is quite ideal. This combines the two using jQuery.

When an option is selected, a checkbox (with label) is automatically created using the same “name” and “value” attributes. When the checkbox is un-checked, it fades away (after a brief delay) and is re-attached to the single-select.

Note that this uses progressive enhancement; if JavaScript is disabled, an ordinary <select multiple> will be provided. If some options are already selected in the HTML, those are extracted as checkboxes automatically. The “required” attribute is also passed along to the checkboxes, if set in the <select>.

Broken images? Show a placeholder instead

In my recent employee directory app, I had an interesting problem with personnel photos: not everybody had one. Those who did had them stored in a single directory as “{{employee.id}}.jpg”, so it was easy to add a link to the image using AngularJS. But it wasn’t easy for JavaScript to detect if the image was missing or not.

I pondered several possible solutions, and decided on this one: Instead of inline images, which show a “broken image” icon when the image can’t be found, I’d use a fixed-size div element and a style attribute to add the employee’s photo as a background-image. When the employee photo couldn’t be found, the background image would simply be invisible. Continue reading Broken images? Show a placeholder instead

CSS-styled strikethrough

The CSS specification lets you specify line-through as a property on a text element, but it doesn’t give you much control over it.  Unlike CSS borders, you can’t control the color (except in Firefox) or thickness of that line.

However, we can simulate this using a CSS :after element. We can even slant the strikethrough line a little, if we’re so inclined (ha!):

s, strike {
  text-decoration: none;/* replacing line-through default */
  position: relative;
  display: inline-block; /* keep it on one line */
s:after, strike:after {
  content: "";  /* required property */
  position: absolute;
  bottom: 0;
  left: 0;
  border-top: 2px solid red;
  height: 45%;  /* adjust depending on line thickness */
     /* or use calc() if you don't need to support IE8: */
  height: calc(50% - 1px); /* half the line thickness */
  width: 100%;
  transform: rotateZ(-4deg);


If you want your text to wrap across multiple lines, we need a different approach. By using a wrapper element we can change the color of the line, but not anything else:

.strike-wrapper {
  text-decoration: line-through;
  color: red;
.strike-wrapper s, .strike-wrapper strike {
  text-decoration: none; /*replacing line-through default*/
  color: black;


two-column form labels and inputs

The usual technique to maintain a two-column form (labels on the left, inputs on the right) is to put the input after the label, fix the width of both elements, and float them to the left. This works well, but I prefer to keep inputs inside of label elements when possible, just to cut down on the number of attributes. (If the input is outside of its label, the input needs an id= attribute and the label needs a matching for= attribute.)

One solution would be to put the text inside the label inside a span, but that’s still adding extra HTML. This solution works by fixing the width of the label and then absolutely-positioning the input element outside of it to the right.

label {
  position: relative;
  display: block;
  overflow: visible; /* if necessary */
  box-sizing: border-box; /* if necessary */
  width: 9em;
  padding-right: 1em;
  margin-bottom: 0.5em;
label select,
label input {
  position: absolute;
  top: 0;
  left: 100%;
  width: 300px;
/* add overriding styles for radio and checkbox inputs

jsFiddle example