Conditional CSS doesn’t work in Chrome

Jeremy Keith’s Conditional CSS technique currently doesn’t work in Chrome.

@media all and (min-width: 45em) {
    body:after {
        content: 'widescreen';
        display: none;
    }
}

The problem is with how Chrome will not generate pseudo elements when set to display: none.

My current solution/hack is to fallback to the head font-size code, as Opera now supports this.

@media screen and (min-width: 45em) {
    head {
        font-family: widescreen;
    }
}

Thx @overflowhidden for the assist.

Canvas spinning fan

The white noise you hear in this Vine is the sound of my laptop fan whirling away at top speed. This animation is rendered in <canvas>, in Chrome. While the animation does have thousands of particles being rendered, I hadn’t expected the top-speed fan.

I’ve been able to pinpoint its cause. The animation was using the width of an image, this.img.width, for every particle, every frame. Setting this value to a separate property this.imgWidth has slowed down the fan significantly. I speculate that this issue is similar to reflow triggers.

Clearly, debugging via hardware machinations is not a good strategy. I still struggle with making sense of anything in the Chrome Developer Tools around rendering performance — especially for a rendering like this one, involving thousands of particles over thousands of frames.

Firefox doesn’t support canvas composite darker

Firefox doesn’t support canvas globalCompositeOperation darker. As it turns out, the darker composite value was removed from the canvas spec in 2007. See the globalCompositeOperation examples on MDN.

The closest solution is to use difference (which oddly enough isn’t in the spec), which Firefox (currently v28) does support. But difference is different from darker. difference subtracts channel values, darker multiplies them. If you’re using primary colors (#f00, #f0f, etc.) it may work.

IE10 supports neither.

See the Pen darker/difference canvas composite by David DeSandro (@desandro) on CodePen.

Safari rounds off fractional pixels

I’m looking to measure the width of an element with width: 66.666%, whose container is width: 300px. Most browsers return a fractional pixel value, i.e. 199.98px. Safari rounds off the fractional pixel value to 199px. It’s a bit odd, as I would expect it would at least round up to 200px when the value is that close.

See demo:

See the Pen getComputedStyle width 66.666% by David DeSandro (@desandro) on CodePen.

I’ve opened WebKit bug #126844 to capture this behavior.

I have found that using calc() values produces more expected results. If I change the width of the element to width: calc( 100% * 2 / 3 ), Safari returns with 200px. It’s still problematic, but it’s an improvement.

See the Pen getComputedStyle width calc( 100% * 2/3) by David DeSandro (@desandro) on CodePen.

Static site S3 workflow

After a snafu with my previous hosting company, I’ve been using Amazon’s static site service on S3.

Site is built in build/. I’ve been using Grunt mostly, but this would work just as well for Jekyll sites.

I use s3cmd to transfer the files. Everything in build/ gets uploaded.

s3cmd sync build/. s3://masonry.desandro.com

This command is saved in a Makefile. See masonry-docs/Makefile.

make deploy

So after set up, making a site takes one or two commands

grunt
make deploy

See this workflow in use:


This workflow is especially straightforward. At one time I did try a git post-receive hook (like one Nicolas Gallagher explains), but this felt murky, _ssh_ing to a remote box, managing two git instances. Sticking with straight-up file transfering is dumb enough that I can understanding it. Adding a separate workflow for deployment on top of git seems like duplicated effort, but there’s a benefit to separating these tasks. In my head, they’re separate.

Transition end propertyName

When listening to transition End event, the event object comes with propertyName. This is useful when detecting just what transition has completed.

elem.addEventListener( 'transitionend' function( event ) {
  console.log( event.propertyName + 'transition completed' );
});

Also interesting is how the transition end event will only trigger once if a property gets changed again, during a previous transition.

See the Pen transtionEnd by David DeSandro (@desandro) on CodePen

Flex box with collapsed height

By default, flex box makes item elements inherit the height of their container. To disable this behavior, and collapse item heights, use align: start (or the proper variation there-of).

.row {
  /* flex box */
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;   
  /* align start, disable vertical height */
  -webkit-box-align: start;
     -moz-box-align: start; /* FF <=20 */
     -ms-flex-align: start; /* IE10 */
  -webkit-align-items: flex-start;
          align-items: flex-start;
}
Check out this Pen!

Refresh button in IE developer tools

Internet Explorer’s HTML developer tool will not display changes to the DOM until you click the Refresh button. This goes for newly appended elements, changes to classes, and other changes.

Internet Explorer developer tool refresh button

Try out this demo. New items won’t appear in the inspector until you refresh.

Thx to KillianJK on GitHub for putting in the due diligence to get to the bottom of this.

touch.identifier = 0

In the touch event API, each touch object has a unique identifier property. This allows you to keep track of which touch is which when listening to touch events. Try out jsfiddle.net/desandro/WnnG9/8/show/light on a touch device.

document.body.addEventListener( 'touchstart', function( event ) {
  // dismiss after-touches
  if ( isTouching ) {
    return;
  }
  event.preventDefault();
  // only care about the first touch
  var touch = event.changedTouches[0];
  identifier = touch.identifier;
  log('touch START; indentifer ' + touch.identifier );
  window.addEventListener( 'touchmove', onTouchMove, false );
  window.addEventListener( 'touchend', onTouchEnd, false );
  isTouching = true;
}, false );

function getTouch( event ) {
  // cycle through every change touch and get one that matches
  for ( var i=0, len = event.changedTouches.length; i < len; i++ ) {
    var touch = event.changedTouches[i];
    if ( touch.identifier === identifier ) {
      return touch;
    }
  }
}

function onTouchMove( event ) {
  // get matched touch
  var touch = getTouch( event );
  if ( !touch ) {
    return;
  }
  log( 'touch move ' + touch.pageX + ' ' + touch.pageY );
}

I ran into a bug because I was short-cutting checking touch.idenfitier. iOS uses a unique number for each every touch, like 166930777, 166930778, 166930779. It looks like Opera Mobile (and possibly Android) isn’t as granular with these identifiers, instead using 0, 1, 2 for each gesture event, then using 0, 1, 2 for the next one. I ran into a gotcha on that first touch, when it’s a falsy value touch.identifier = 0.

Collapsing margins

Collapsing margins is an ancient property of the CSS Box Model, which I am just now comprehending. In short, with two block elements, will collapse the margins between them collapse to the greater margin. But this only applies to block elements. Floated and inline-block elements will keep margins un-collapsed.

See example on CodePen.