Automatic typography substitution

After reading the series of Death to Typewriters articles on Meduim, I decided to have a go at implementing their automatic character substition rules in JavaScript. Following the guide provided at Death to Typewriters: Automatic replacement and clean-up, I created a simple function that can be called as you type, or when text is pasted, into a text area. Certain character combinations and locations are looked for and replaced with other characters such as correct quotes, arrows and ellipsis. I have put the code up on GitHub with a little bit of documentation.

READ MORE

New website for Nemen Visual

I have just launched a new website for Nemen Visual. The new site is a big departure from the old site which I created over 3 years ago. I took the redesign as an opportunity to explore some new techniques and modernise it a bit.

No more WordPress

The first major change is that is no longer built on WordPress. This time around I decided to go back to static HTML pages. One reason I used WordPress (or just using PHP in general) is the ability to separate the page elements such head headers and footers into separate files and re-use them. Now with all the advancements on the front end tooling world such as Node and Grunt – it is quite easy to set up a system that can generate static pages by compiling seperate HTML files. This gives me full control over how each page is displayed but with the flexiblilty of separating out reusable components such as navigation, headers and footers – which are then compiled into static pages.

Less

All the css is written in Less and compiled to CSS using Grunt. This allowed me to do page theming using variables.

Grunt

I am using Grunt to compile the pages into static HTML files, as well as create theme CSS files from the Less files. Using Grunt Include I can put the markup for repeated elements such as the navigation or footer, into a separate files and then compile them into static pages.

SVG

SVG is used for the logo, and some other small design elements on the page so they appear crisp on all devices.

Responsive

The website is now responsive – allowing you to view it on any device from a desktop to a phone. I wanted to learn how to use the new ‘picture’ element so I have used this on some of the folio pages to ‘art direct’ some of the images on different screen sizes.

Hexagonal grid

I wanted to try creating a hexagonally packed grid, and so I used this on the home page to display folio items. A hexagonally packed grid differs from a regular square grid in that instead of stacking like blocks, items are stacked like hexagons:

packing

 

There are probably some other things that I have forgotten so that is all for now…

Check out the new site

CSS Diamond grid

Following on from the last post I decided to play a bit more with the hexagonal grid and created a diamond grid. It works similar to the last grid except it uses squares rotated 45 degrees, so it is basically a regular grid tipped on its side with even-odd number alternating rows.

Here is a live demo of the grid:

READ MORE

CSS Hexagonal packed grid

Most grids are square packed – that is each cell is stacked like a block which is great, but if you are after something slightly different maybe you should try a hexagonally packed grid. I will show you how to create a hexagonally packed grid using only CSS. But first, here is the difference between a square and a hexagonal packed grid:

packing

View demo

 

READ MORE

A LESS mixin for a transition with a prefixed transition-property

The most common mixin you will find in LESS for CSS3 transitions is something like the following:

1
2
3
4
5
6
7
.transition (@prop, @time, @ease) {
    -webkit-transition: @prop @time @ease;
       -moz-transition: @prop @time @ease;
        -ms-transition: @prop @time @ease;
         -o-transition: @prop @time @ease;
            transition: @prop @time @ease;
}

The proplem with this is that if you want to transition a property that requires a prefix such as transform:

1
.transition(transform, 0.5s, ease-out)

You will end up with:

1
2
3
4
5
-webkit-transition: transform 0.5s ease-out;
   -moz-transition: transform 0.5s ease-out;
    -ms-transition: transform 0.5s ease-out;
     -o-transition: transform 0.5s ease-out;
        transition: transform 0.5s ease-out;

This is not what you want, you need to have the transition-property prefixed as well as the transition. Below is a mixin that I came up with that will solve this problem:

1
2
3
4
5
6
7
.transitionPrefixProp (@prop, @time, @ease) {
    -webkit-transition: e("-webkit-@{prop}") @time @ease;
       -moz-transition:    e("-moz-@{prop}") @time @ease;
        -ms-transition:     e("-ms-@{prop}") @time @ease;
         -o-transition:      e("-o-@{prop}") @time @ease;
            transition:                @prop @time @ease;
}

Which will output:

1
2
3
4
5
-webkit-transition: -webkit-transform 0.5s ease-out;
   -moz-transition:    -moz-transform 0.5s ease-out;
    -ms-transition:     -ms-transform 0.5s ease-out;
     -o-transition:      -o-transform 0.5s ease-out;
        transition:         transform 0.5s ease-out;

This is kind of a brute force approach by adding all prefixes regardless of whether they are required, but it does work well.

Accessing command line arguments with Grunt

I needed to be able to set up a watch task with Grunt to only watch a specific client sub directory. This directory would change depending on the client I was working on and new clients were constantly added so I need a way to watch the specific client that I was working on only, without hard coding all the clients into separate tasks. The only thing I could think of doing this was to pass some sort of parameters when starting the watch task.

This is how I set it up. It might not be the best method but it works for me.

First I had to set a value in the grunt configuration, which would be taken from the command line args. With Grunt you can get them them using:

1
grunt.option('someCommandLineArg');

You can also set a configuration value using:

1
grunt.config.set('myValue', 'someValue');

So combining those two methods, the following will get a command line arg called “watchDir” (and assign a default value of src if it was not specified) and set it in the grunt config. I added this line after initConfig in my Gruntfile:

1
grunt.config.set('watchDir', grunt.option('watchDir') || 'src');

You can then access this property using a template string in your task:

1
2
3
4
5
6
watch: {
      less: {
        files: ['clients/<%= watchDir %>/**/*.less'],
        tasks: ['less']
      }
}

When running the Grunt task, we can specify the option “watchDir” by adding two dashes in front and setting it equal to the desired value:

1
grunt watch --watchDir="clientX"

The watch task above would in this case watch the following directory:

1
'clients/clientX/**/*.less'

This allows you to set up a generic task that can be pointed to different directories when it is started.

Inspiring Inspiration #12

A collection of cool video, motion graphics and interface design, mostly if not all from Vimeo…

READ MORE

Webcam to canvas or data URI with HTML5 and Javascript

This post has been sitting around unfinished since April so I thought I should finish it and get it out there.

In this post I am going to show how you can capture an image from a webcam via JavaScript and convert it to a Data URI which can then be saved in a database or displayed in an IMG tag.

Note: This is more of a proof of concept rather than a best practices example so the code is a bit messy and hacked together from various sources.

I have only tested this on Safari for iOS 6 and latest Chrome with a webcam. It may or may no work in other browsers.

View demo

All explanations for the the code and markup are in the code comments, so please read them for more detail.

READ MORE

Hover shine effect with pure CSS

This is a simple example of a mouse-over shine effect I created using purely CSS. It uses a CSS generated element and CSS3 transitions to animate the effect. See the comments in the markup below for further explanation of how it works.

Live demo:

Click Me

Simple HTML markup:

1
<div class="myButton">Click Me</div>

And the CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* normal button style */
.myButton {
    width: 110px;
    height: 30px;
    background-color:#0099cc;
    text-align: center;
    color: #FFF;
    position: relative;
}
/* button hover style if required */
.myButton:hover {
   
}
/* generated element for shine effect.
 * normal state is semi-transparent
 * white but with zero width. Set no
 * transition here for no mouse-leave
 * animations. Otherwise the effect
 * will play in reverse when your mouse
 * leaves the element
 */

.myButton:after {
    content: "";
    position: absolute;
    top: 0px;
    left: 0px;
    width: 0%;
    height: 100%;
    background-color: rgba(255,255,255,0.4);
    -webkit-transition: none;
    -moz-transition: none;
    -ms-transition: none;
    -o-transition: none;
    transition: none;
   
}
/* on hover we animate the width to
 * 100% and opacity to 0 so the element
 * grows and fades out
 */

.myButton:hover:after {
    width: 120%;
    background-color: rgba(255,255,255,0);
    -webkit-transition: all 0.3s ease-out;
    -moz-transition: all 0.3s ease-out;
    -ms-transition: all 0.3s ease-out;
    -o-transition: all 0.3s ease-out;
    transition: all 0.3s ease-out;
}

Comparing custom font display with @font-face

This is a little experiment I conducted comparing the way different browsers render custom fonts through @font-face. What I found was that the two browsers that displayed them best were IE8 and Firefox 4 Beta. The worst browsers were Opera and Safari. Opera seemed to make the characters extra skinny, and Safari made the characters thicker. Coming in the middle were Chrome and Firefox 3.6 which displayed the text with the correct thickness but with harder edges than the FF4 Beta and IE8. Have a look at the images below for a comparison.

Chrome

Safari

Firefox 3.6

Firefox 4 Beta

Internet Explorer 8

Opera