Why XHTML is still the best answer for web publishing

Brad Neuberg wrote an article about making ePub3 “play nice” with HTML5. I read it and initially agreed with it but, upon second reading and some thought I disagree with the essence of his argument.

Brad opens his argument with the following two bullet points:

  • The first is a version of HTML5 that uses XML’s rules: everything has to be well formed and there can’t be any mistakes in how you create your markup. This is commonly known as XHTML5, to indicate the HTML5 standard but based on XML. XHTML5 tends to be used in specialized back end systems to do text processing as there are fairly sophisticated tools for working with it, and it also turns out to be what EPUB3 uses.
  • The second is tag soup HTML5: you don’t have to close your tags and processing is much looser and closer to the older HTML4 standard. Tag soup HTML5 dominates the open web; it’s probably 99.9% of all the content you would access with a conventional web browser.

He further argumes that because tag soup is the dominant use of HTML5 that all tools should be using it and that XHTML 5 should only be used in back end systems.

In twitter conversation he argues, erroneously in my opinion, that it was the strictness and the restrictions it placed on content authors that caused the split with WHATWG and the creation of HTML 5. It was the move to an XML only environment and the creation of a completely separate mime type (application/xhtml+xml) for XHTML applications that caused the split.

Very few, if any, authors actually publish XHTML. They publish HTML in XHTML compatibility mode without actually changng the mime type of HTML documents or setting up the appropriate default namespace as required for XHTML compliance

First, the future is creating high quality markup in HTML5 and then publishing it into different channels.

In that we agree.

We need a common base to create our content, but let’s also remember that HTML or XHTML cannot do everything.

Creating good coding habbits

If name spaces were not an issue, I would still have an issue with tag soup HTML: it promotes laziness and it makes the code hard to read and understand.

Look at the following example:

<html>
<title>Sample document</title>

<h1>Sample document

<p>Lorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem <em> and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random text</p>

<p>Lorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem <em> and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random text

<p>Lorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random textLorem <em><b>and some random text</em></b> Lorem Ipsum and some random textLorem Ipsum and some random textLorem Ipsum and some random text

In the example above, a more or less classic example of a tag soup web document we can see the following issues:

  • There is no distinction between the head and the body of the document
  • The charset of the document is not defined
  • There re mutiple instances of incorrectly nested tags

HTML5 provides mechanisms for user agents to work around inconsistencies outline above. It does not encourage authors to use this system to write HTML content.

Why does this new HTML spec legitimise tag soup?

Actually it doesn’t. This is a misconception that comes from the confusion between conformance requirements for documents, and the requirements for user agents.

Due to the fundamental design principle of supporting existing content, the spec must define how to handle all HTML, regardless of whether documents are conforming or not. Therefore, the spec defines (or will define) precisely how to handle and recover from erroneous markup, much of which would be considered tag soup.

For example, the spec defines algorithms for dealing with syntax errors such as incorrectly nested tags, which will ensure that a well structured DOM tree can be produced.

Defining that is essential for one day achieving interoperability between browsers and reducing the dependence upon reverse engineering each other.

However, the conformance requirements for authors are defined separately from the processing requirements. Just because browsers are required to handle erroneous content, it does not make such markup conforming.

For example, user agents will be required to support the marquee element, but authors must not use the marquee element in conforming documents.

It is important to make the distinction between the rules that apply to user agents and the rules that apply to authors for producing conforming documents. They are completely orthogonal.

From: wiki.whatwg.org/wiki/FAQ#Why_does_this_new_HTML_spec_legitimise_tag_soup.3F

Specific requirements for authoring HTML5 documents can be found here: Conformance requirements for authors. It again reinforces the idea that because it is possible to create malformed tag soup documents you shouldn’t do it.

Elements from other XML-based name spaces

We can not add these elements to a tag soup-based html document. Whether this is a major issue will depend on your project needs but unless WHATWG/W3C provide an alternative, name spaces are the way to go

ePub 3 uses elements from the following namespaces in order to add functionality to ePub-based publications.

Prefix Namespace URI
epub http://www.idpf.org/2007/ops
m (MathML) http://www.w3.org/1998/Math/MathML
pls http://www.w3.org/2005/01/pronunciation-lexicon
ssml (Speech Synthesis Markup Language) http://www.w3.org/2001/10/synthesis
svg (Scalable Vector Graphics) http://www.w3.org/2000/svg

An example of XML vocabularies used in ePub 3 documents. Taken from EPUB Content Documents 3.0

Javascript support for namespaced content

While technically it would be possible to convert epub:type to epub-type I fail to see the reason why we should. Both Javascript and CSS allow us to query for ePub namespaced (or any other kind of) attributes. we can either query bu class containing the attribute:

//select the first element that has the "content" class name
  var content = document.getElementsByClassName("content")[0];
  //a returns undefined but it still stores the correct value
  var a = content.getAttributeNS('http://www.idpf.org/2007/ops', 'type');
  alert(a); // shows the value of type for that element

We can also wrap our code in ePub specific containers. ePub make available the navigator.epubReadingSystem property which we can use to execute all our ePub realted code without affecting the rest of our script.

// If the user agent is an ePub Reading System
  if (navigator.epubReadingSystem) {
    feature = touch-events;
    // Test for the touch events feature
    var conformTest = navigator.epubReadingSystem.hasFeature(feature);
    // Output if the feature is supported
    alert("Feature " + feature + " supported?: " + conformTest);
}

See http://code.google.com/p/epub-revision/wiki/epubReadingSystem for more information.

CSS

As far as CSS is concerned namespace support was introduced as a draft document in June of 2013. Support is not widespread but when it is, we’ll be able to do something like this:

@namespace "http://www.w3.org/1999/xhtml"; /* This defines the default namespace*/
@namespace epub "http://www.idpf.org/2007/ops"; /* this defines the namespace "epub" */

table {
  border: 1px solid black
}
epub|type {
  display: block;
}

WebGL: The New Frontier (for some)

Not too long ago there was a demo of the Epic Citadel OpenGL demo translated to JavaScript and played inside a web browser. The code was ported from C++ to ASM, a subset of JavaScript optimized for performance using and then fed into a web browser for rendering and display.

Even if we leave the conversion from C++ to JavaScript aside for the moment. You’re running a high end game inside a web browser… without plugins!

Think about it. We can now do 3D animations that take advantage of your computer’s GPU to render high quality 3D objects, animations and transitions that rival work done with professional 3D software (and you can even import files from Maya, Blender and others into a WebGL environment).

What is WebGL

WebGL is a cross-platform, royalty-free web standard for a low-level 3D graphics API based on OpenGL ES 2.0, exposed through the HTML5 Canvas element as Document Object Model interfaces. Developers familiar with OpenGL ES 2.0 will recognize WebGL as a Shader-based API using GLSL, with constructs that are semantically similar to those of the underlying OpenGL ES 2.0 API. It stays very close to the OpenGL ES 2.0 specification, with some concessions made for what developers expect out of memory-managed languages such as JavaScript.
From: http://www.khronos.org/webgl/

WebGL is a JavaScript API that allows us to implement interactive 3D graphics, straight in the browser. For an example of what WebGL can do, take a look at this WebGL demo video (viewable in all browsers!)
WebGL runs as a specific context for the HTML <canvas> element, which gives you access to hardware-accelerated 3D rendering in JavaScript. Because it runs in the <canvas> element, WebGL also has full integration with all DOM interfaces. The API is based on OpenGL ES 2.0, which means that it is possible to run WebGL on many different devices, such as desktop computers, mobile phones and TVs.
From: http://dev.opera.com/articles/view/an-introduction-to-webgl/

Why should we care?

Besides the obvious implications of having 3D graphics online without having to use plugins imagine how much more expressive we can make our content if we can mix 2d and 3d content. WebGL means that we’re no longer tied to plugins to create AAA-game type experiences for the web platform (look at the Epic Citadel for a refresher), incorporate 3D rendered content into your 2D web content (product configurators like the +360 Car Visualizer come to mind),
web native architectural or anatomical visualizations or just awesome animation work like thisway.js a WebGL remale of an older flash based demo or Mr. Doob’s extensive libraries of demos and examples.

As the WebGL techology stack matures we’ll see more and more examples and creative uses of the technology. I hope we’ll see more editors and tools that will make it easuer for non-experts to create interactive content.

Before we start

Before you try creating your own WebGL It’s a good idea to go to http://analyticalgraphicsinc.github.io/webglreport/ to test whether your browser and computer support WebGL.

Building WebGL content

There are two ways to create WebGL content. They each hve their advantages and drawbacks that will be pointed out as we progress through the diffrent creation processes.

The hard way

The hard way is to create content using WebGL primitives and coding everything ourselves as show in https://developer.mozilla.org/en-US/docs/Web/WebGL/Adding_2D_content_to_a_WebGL_context and https://developer.mozilla.org/en-US/docs/Web/WebGL/Animating_objects_with_WebGL. You can see the ammount of code and specialized items we need to build in order to create the content.

Take a look at the Mozilla WebGL tutorial as an illustration of the complexities involved in creating WebGL with the raw libraries and interfaces.

If interested in the full complexities of writing raw WebGL code, look at the source code for https://developer.mozilla.org/samples/webgl/sample7/index.html to see WebGL code and the additional complexities. We’ll revisit part of the examples above when we talk about custom CSS filters.

The pen below also illustrates the complexities of writing bare WebGL

See the Pen HLxbB by Carlos Araya (@caraya) on CodePen.

For a more complete look at the workings of WebGL look at Mike Bostock’s WebGL Tutorial series:

If you are a game programmer or a game developer this will be the level you’ll be working at and other platforms, libraries and frameworks will not be necessary for your work. If you’re someone who is not familiar with coding to the bare metal or who is not familiar with matrix algebra there are solutions for us.

The easy way

Fortunately there are libraries that hide the complexities of WebGL and give you a more user friendly interface to work with. I’ve chosen to work with Three.JS, a library developed by Ricardo Cabello also known as Mr Doob.

The following code uses Three.js to create a wireframe animated cube:

[codepen_embed height=”516″ theme_id=”2039″ slug_hash=”JlEfG” default_tab=”js”]
var camera, scene, renderer;
var geometry, material, mesh;

init();
animate();

function init() {

camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 800;

scene = new THREE.Scene();

geometry = new THREE.CubeGeometry(200, 200, 200);
// We have to use MeshBasicMaterial so we can see the color
// Otherwise it's all black and waits for the light to hit it
material = new THREE.MeshBasicMaterial({
color: 0xAA00AA,
wireframe: true
});

mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);

document.body.appendChild(renderer.domElement);

}

function animate() {
// note: three.js includes requestAnimationFrame shim
requestAnimationFrame(animate);

// Play with the rotation values
mesh.rotation.x += 0.01;
mesh.rotation.y -= 0.002;

renderer.render(scene, camera);
}

See the Pen Basic WebGL example using Three.js by Carlos Araya (@caraya) on CodePen.
[/codepen_embed]

As you can see, Three.js abstracts all the matrix/linear algebra and all the shader programming giving you just the elements that ou need to create content. This has both advantages and drawbacks.

Mike Bostock writes in his introduction to WebGL tutorial:

Every introductory WebGL tutorial I could find uses utility libraries (e.g., Sylvester) in efforts to make the examples easier to understand. While encapsulating common patterns is desirable when writing production code, I find this practice highly counterproductive to learning because it forces me to learn the utility library first (another layer of abstraction) before I can understand the underlying standard. Even worse when accompanying examples use minified JavaScript.

On the other hand many people, myself included, just want something that works. I am less interested in the underlying structure (that may come in time as I become more proficient with the library way of doing WebGL) than I am in seeing results happen.

See the section WebGL resources for a partial list of other WebGL libraries.

Building a 3D scene

For this example we will use Three.js to build an interactive scene where we will be able to use the keyboard to move a cube around the screen. We will break the scripts in sections to make it easier to explain and work with.

The script is at the end of the <body> tag so we don’t ensure that the body is loaded.

Basic setup

The first thing we do is define the element where our WebGL content is going to live. We follow that with linking to the scripts we will use in the project:

  • three.min.r58.js is the minimized version of Three.js. In developmnet I normally use the uncompressed version
  • OrbitControls.js controls the movement of the camera used in the scene
  • Detector.js is the WebGL detection library
  • threex.keyboardstate.js will help with key down event detection
  • threex.windowresize.js automatically redraws the rendering when the window is resized
<!-- This is the element that will host our WebGL content -->
  <div id="display"></div>

<!-- Script links -->
<script src="lib/three.min.r58.js"></script>
<script src="lib/OrbitControls.js"></script>
<script src="lib/Detector.js"></script>
<script src="lib/threex.keyboardstate.js"></script>
<script src="lib/threex.windowresize.js"></script>

Variables, scene and camera setup

Now tht we setup the links to the scripts that we’ll use in this application we can declare variables and call the functions that will actually do the heavy lifting for us: init() and animate


// General three.js variables
var camera, scene, renderer;
// Model specific variables
// Floor
var floor, floorGeometry, floorTexture;
// light sources
var light, light2;
// Space for additional material
var movingCubeTexture, movingCubeGeometry, movingCubeTexture;
// Window measurement
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
// additional variables
var controls = new THREE.OrbitControls();
var clock = new THREE.Clock();
var keyboard = new THREEx.KeyboardState();

init();
animate();

Initializing our scene

The first step in rendering our scene is to set everything up. In the code below:

Step 1 does two things. It sets up the scene, the root element for our model and it sets the camera, the object that will act as our eyes into the rendered model.

For this particular example I’ve chosen a perspective camera which is the one used most often. This tutorial covers perspective as used in WebGL and Three.js; it is a technical article but I believe it provides a good overview of what is a complex subject.

Once the camera is created, we set its position (camera.position.set)and where the camera is pointing to (camera.lookAt)

function init()
{
// Step 1: Add Scene
scene = new THREE.Scene();
// Now we can set the camera using the elements defined above
// We can also reduce the number of variables by putting the values directly into the camera variable below
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 10000);
scene.add(camera);
// The position.set value for the camera will setup the initial field of vision for the model
camera.position.set(0, -450, 150);
camera.lookAt(scene.position);

Step 2 sets up the renderer for our model. Using Detector.js we test if the browser supports WebGL. If it does then we setup Three.js CanvasRenderer, one of the many renderers available through Three.js.

Also note that even a modern browser can fail to support WebGL if it’s running on older hardware or if the browser is not configured properly (older versions of Chrome required you to enable WebGL support through flags in order to display WebGL content and versions of Internet Explorer before 11 did not support WebGL at all).

At this point we also set up the THREEx.WindowResize using both the renderer and the camera. Behind the scenes, WindowResize will recompute values to resize our rendered model without us having to write code.

// Step 2: Set up the renderer
// We use the WebGL detector library we referenced in our scripts  to test if WebGL is supported or not
// If it is supported then we use the WebGL renderer with antialiasing
// If there is no WebGL support we fall back to the canvas renderer
if ( Detector.webgl ) {
  renderer = new THREE.WebGLRenderer( {antialias:true} );
 }  else {
     renderer = new THREE.CanvasRenderer();
}
// Set the size of the renderer to the full size of the screen
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
// Set up the contaier element in Javascript
var container = document.getElementById( 'display' );
THREEx.WindowResize(renderer, camera);
// CONTROLS
controls = new THREE.OrbitControls( camera, renderer.domElement );
// Add the child renderer as the container's child element
container.appendChild( renderer.domElement );

Step 3 is where we actually add the objects to our rendering process. They all follow the same basic process:

  1. We define a material (texture) for the object
  2. We Define a geometry (shape) it will take
  3. We combine the material and the geometry to create a mesh
  4. We add the mesh to the scene

The texture floor has some additional characteristics:

  1. We load an image to use as the texture
  2. We set the texture to repeat 10 times on each plane.

The sphere mesh on step 3b is positioned on the Z coordinates.

// Step 3 : Add  objects
// Step 3a: Add the textured floor
floorTexture = new THREE.ImageUtils.loadTexture( 'images/checkerboard.jpg' );
floorTexture.wrapS = THREE.RepeatWrapping;
floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set( 10, 10 );
floorMaterial = new THREE.MeshPhongMaterial( { map: floorTexture } );
floorGeometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
floor = new THREE.Mesh(floorGeometry, floorMaterial);
scene.add(floor);

// Step 3b: Add model specific objects
movingCubeGeometry = new THREE.CubeGeometry( 50, 50, 50, 50);
movingCubeMaterial = new THREE.MeshBasicMaterial( {color: 0xff00ff} );
movingCube = new THREE.Mesh(movingCubeGeometry, movingCubeMaterial);
movingCube.position.z = 35;
movingCube.position.x = 0

scene.add(movingCube);

In step 4, we add lights to the model in a way very similar to how we added the objects in step 3.

  1. Create the light and assign a color upon creation
  2. Set the position of the light using an X, Y, Z coordinate system
  3. Add the lights to the scene
// Step 4: Add light sources
// Add 2 light sources.
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 90 ,450 ).normalize();
light2 = new THREE.DirectionalLight( 0xffffff);
light2.position.set( 0, 90, 450 ).normalize();
scene.add(light);
scene.add(light2);
}

Keyboard Interactivity

Right now we’ve built a cube over a checkered background plane… but we can’t move it. That’s what the animate function will do… it will setup the keyboard bindings.

Animate is a wrapper around 2 additional functions; render and update. The render() function just call our renderer to draw the frame of our application. The update function is where the heavy duty work happens.

function animate() {
  requestAnimationFrame( animate );
  render();
  update();
}

function render() {
  renderer.render( scene, camera );
}

The update() function sets up 2 variables: delta is a time-based value that will be used to calculate the distance of any movement that happens later in the function. The variable moveDistance uses delta to calculate the exact distance of each movement (200 * the delta value)

Now that we’ve set up the value for the distance moved we test which key was pressed and change the coordinate values (x, y or z coordinates) and then prepare for the next update cycle.

The reset value is simpler. We reset all coordinates to 0.

function update() {
  var delta = clock.getDelta(); // seconds.
  var moveDistance = 200 * delta; // 200 pixels per second
  //var rotateAngle = Math.PI / 2 * delta;   // pi/2 radians (90 degrees) per second

  // global coordinates
  if ( keyboard.pressed("left") )
    movingCube.position.x -= moveDistance;
  if ( keyboard.pressed("right") )
    movingCube.position.x += moveDistance;
  if ( keyboard.pressed("up") )
    movingCube.position.y += moveDistance;
  if ( keyboard.pressed("down") )
    movingCube.position.y -= moveDistance;
  if ( keyboard.pressed ("w"))
    movingCube.position.z += moveDistance;
  if ( keyboard.pressed ("s"))
    movingCube.position.z -= moveDistance;
  // reset (let's see if this works)
  if ( keyboard.pressed ("z")) {
    movingCube.position.x = 0;
    movingCube.position.y = 0;
    movingCube.position.z = 50;
  }
  controls.update();
}

Adding audio

In a future project I want to experiment with adding audio to our models. The best audio API I’ve found is the WebAudio API submitted by Google to the World Wide Web Consortium

Getting started with the WebAudio API discusses my experiments with the WebAudio API.

Playing with editors

Three.js editors and authoring tools are just starting to appear. From my perspective some of the most promising are:

Examples

WebGL Libraries and Frameworks

From: Dev.Opera’s Introduction to WebGL article and Tony Parisi’s Introduction to WebGL at SFHTML5 Meetup

Three.js (Three Github repo)
Three.js is a lightweight 3D engine with a very low level of complexity — in a good way. The engine can render using <canvas>, <svg> and WebGL. This is some info on how to get started, which has a nice description of the elements in a scene. And here is the Three.js API documentation. Three.js is also the most popular WebGL library in terms of number of users, so you can count on an enthusiastic community (#three.js on irc.freenode.net) to help you out if you get stuck with something.
PhiloGL (PhiloGL Github repo)
PhiloGL is built with a focus on JavaScript good practices and idioms. Its modules cover a number of categories from program and shader management to XHR, JSONP, effects, web workers and much more. There is an extensive set of PhiloGL lessons that you can go through to get started. And the PhiloGL documentation is pretty thorough too.
GLGE (GLGE Github repo)
GLGE has some more complex features, like skeletal animation and animated materials. You can find a list of GLGE features on their project website. And here is a link to the GLGE API documentation.
J3D (J3D Github repo)
J3D allows you not only to create your own scenes but also to export scenes from Unity to WebGL. The J3D "Hello cube" tutorial can help you get started. Also have a look at this tutorial on how to export from Unity to J3D.
tQuery (Github repo)
tQuery ( is a library that sits on top of Three.js and is meant as a lightweight content and extension creation tool. The author, Jerome Etienne has created several extensions to Three.js that are available on his Github repository (https://github.com/jeromeetienne)
SceneJS (Github repo
This library is an extensible WebGL-based engine for high-detail 3D visualisation using JavaScript.

BabylonJS (Github repo)
The library produces high quality animations. If your comfortable being limited to windows machines to create your libraries and customizations this may be the library for you.
VoodooJS (Github repo)
Voodoo is designed to make it easier to intergrate 2D and 3D content in the same page.
Vizi (Github repo)
The framework that got me interested in WebGL frameworks. Originally developed by Tony Parisi in conjunction with his book Programming web 3D web applications with HTML5 and WebGL it presents a component based view of WebGL development. It suffers from a lack of documentation (it has yet to hit a 1.0 release) but otherwise it’s worth the learning curve.

Typography II: Fonts to the page

We have typography on the web!

As John Allsopp points out in his blog Happy 17th Birthday CSS we have come a long way but we still have very far to go.

When I first started playing with web design back in 1996 the web was just plain. It was meant as a way to exchange information, not produce the high-end, high-gloss content we see today.

Surprisingly enough we’ve had the ability to embed fonts for over a decade. CSS2 included the ability to embed fonts when it was first released but it wasn’t highly used until CSS3 came out and fount foundries decided that there was money to be made online.

New elements in HTML5 and CSS3 (web fonts among them) allow some wonderful work to be done online without having to resort to images or overtly complicated CSS and Javascript tricks to make it look somewhat like what the designer had originally envisioned.

Examples of good web typography

Licensing: the big pain in the ass

Unfortunately every time we want to work with web fonts the ugly licensing monster raises its head. It’s not just a matter of purchasing the font, converting it to the correct formats (see How do we add fonts to the web? for the actual formats and process involved) but it also involves making sure that the font license allows you to use the font with @font-face techniques (read the EULA that comes with your font to make sure).

@font-face Embedding (Linking)

I didn’t include the @font-face font embedding method in the list above because it’s a different animal. @font-face doesn’t use PHP, JavaScript or Flash to embed the font. It solely relies on CSS and a compatible browser (see @font-face and 15 Free Fonts You Can Use Today for more information).

Information around the web isn’t exactly clear on this but my opinion is that the @font-face method isn’t really “embedding” but instead linking because you’re simply telling the browser where the actua font file is via CSS. This means the font file is directly accessable to your visitors, making this method quite different than the ones listed above.

Even if the font license permits font embedding, it may not permit embedding with @font-face because this method allows direct access to the font file. Microsoft uses the .eot font format (Embedded OpenType) as a solution to this problem. EOT is supposed to respect the flags in the font files for embedding and can be limited to specific domains. Non-IE browsers however, have not adopted this technology and don’t plan to. That means you’ll need to use a .ttf or .otf version of the font for non-IE browsers if you want true cross-browser compatibility.

If you decide to use @font-face, be absolutely, positively sure that the font license allows it. It should specifically state the use of @font-face is permitted and if there are any additional restrictions (ie. give credit somewhere).

From http://blog.themeforest.net/general/font-licensing-for-the-web/

Can I use an Adobe font on the web?

Adobe’s current End-User License Agreement (EULA) for fonts does not permit font linking with @font-face using any font format, including, but not limited to, desktop (“raw”) fonts and the Web Open Font Format (WOFF). Adobe provides select Adobe Web Fonts for use on the web through the Adobe Typekit® web font service, where web font usage is governed by the Typekit service Terms of Use.

A font’s usage permissions are specified in your EULA that accompanied the font when you acquired it. Refer to your EULA to determine the type of usage permitted.

From: http://www.adobe.com/products/type/font-licensing/licensing-faq.html

Typekit and other similar services provide an alternative licensing model. When you use Typekit-like services the fonts remain on the company’s server and you link to them using special Javascript that is specific to a user’s account.

What is Typekit?

The Adobe Typekit service provides secure, subscription-based web font hosting for web designers and developers, made possible by the @font-face rule. Typekit subscribers have access to a collection of fonts that can be used on basically any web site. You can view the Adobe Web Fonts available on the Typekit service on Adobe’s foundry page.

Although Typekit relies on the @font-face rule to work, it is different from web fonts used by end users. Fonts remain protected on the Typekit servers and are dynamically delivered to browsers in the appropriate format to ensure an optimal and consistent typographic experience. Typekit offers user-friendly integration with CSS and HTML code, and other optimizations, like font subsetting.

From: http://www.adobe.com/products/type/font-licensing/licensing-faq.html

You can pick fonts where the license specifically allow unrestricted use of the software. For example the Ubuntu font license states that:

This licence allows the licensed fonts to be used, studied, modified and redistributed freely. The fonts, including any derivative works, can be bundled, embedded, and redistributed provided the terms of this licence are met. The fonts and derivatives, however, cannot be released under any other licence. The requirement for fonts to remain under this licence does not require any document created using the fonts or their derivatives to be published under this licence, as long as the primary purpose of the document is not to be a vehicle for the distribution of the fonts.

From http://font.ubuntu.com/license

A final alternative is a service like Google fonts that provides easy access to a growing number of fonts. Like with the Typekit service, the fonts are still hosted on Google’s servers and it provides you with links to use in your CSS or Javascript.

http://nicewebtype.com/notes/2009/07/19/type-sellers-web-fonts-and-typekit/

Is cost an option? (my font pricing horror story)

I’ve loved Stone Sans Humanist ever since I first saw it used in an MIT Press book (The Second Self by Sherry Turkle, I belive). I loved the way that it flowed on the page and how it looked. I didn’t know any better to know the technical aspects of the font. I only knew I really liked it.

Fast forward 12 years. I’m working on an eBook project and I decided I wanted to use my favorite font in my own project. Not only the font wasn’t available for embedding at the time but the cost to license the font for embedding in an eBook was prohibitive at the time and it was very restrictive.

That is the primary reason why I’ve turned to free/open source fonts for most of my work. I’ve also subscribed to the full Typekit service to make sure that the fonts I want are available for the projects I work on even this will not solve the problem because not all fonts are available for all providers (sadly Stone Sans Humanist is not available through Typekit nor through the vendor’s free font service; you).

Where do I find fonts for embedding?

Below is a partial (and already outdated) list of fonts that are available for embedding. This small list does not include Google Fonts or Typekit (which provides a limited free service)

Where do we find good and free fonts?

The list below include fonts and font collections I’ve used in projects in the past

Practice

How do we add fonts to a web page?

One of the first things we need to realize is that there are multiple fonts for a given type. For most people making a font bold is just a matter of highlighting the text and pressing Command (or Control) + B but for graphic designers and other people who work with type (online and off) that is sacrilege. When you make a font bold you’re actually assigning a bold font to the text.

Font and CSS declarations

[codepen_embed height=”689″ theme_id=”2039″ slug_hash=”DJsCB” default_tab=”css”]
@font-face {
font-family: "Your typeface";
src: url("type/filename.eot");
src: local("☺"),
url("type/filename.woff") format("woff"),
url("type/filename.otf") format("opentype"),
url("type/filename.svg#filename") format("svg");
}

@font-face {
font-family: "Your bold typeface";
src: url("type/filename-bold.eot");
src: local("☺"),
url("type/filename-bold.woff") format("woff"),
url("type/filename-bold.otf") format("opentype"),
url("type/filename-bold.svg#filename-bold") format("svg");

@font-face {
font-family: "Your italic typeface";
src: url("type/filename-ital.eot");
src: local("☺"),
url("type/filename-ital.woff") format("woff"),
url("type/filename-ital.otf") format("opentype"),
url("type/filename-ital.svg#filename-ital") format("svg");
}

h2 { font-family: "Your typeface", Georgia, serif; }
h2 em { font-family: "Your italic typeface", Georgia, serif; }
em { font-style: italic; }

See the Pen Example font-face declaractions by Carlos Araya (@caraya) on CodePen.
[/codepen_embed]

See Paul Irish’s @fontface gotchas/ for some early pitfalls of @fontface use

The different font formats used above are explained in the following table:

String Font Format Common extensions
“woff” WOFF (Web Open Font Format) .woff
“truetype” TrueType .ttf
“opentype” OpenType .ttf, .otf
“embedded-opentype” Embedded OpenType .eot
“svg” SVG Font .svg, .svgz

Typekit

Typekit assigns each user’s kit (one or more fonts packed together) a unique ID that is part of the script yuou are asked to use. The script looks something like this:

[codepen_embed height=”257″ theme_id=”2039″ slug_hash=”uIypz” default_tab=”html”]
<script type="text/javascript" src="//use.typekit.net/pxl2jwi.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>

See the Pen Typekit font import by Carlos Araya (@caraya) on CodePen.
[/codepen_embed]

The code above will only work for a single website, specified on the account where the kit was created from.

Google Fonts

Google Fonts allow you to embed fonts in one of three ways:

HTML Link in the head of your document along with your style sheets and scripts.

[codepen_embed height=”146″ theme_id=”2039″ slug_hash=”mdjnc” default_tab=”html”]
<link href='http://fonts.googleapis.com/css?family=Alegreya+Sans+SC:500,500italic|Exo+2:400,100,400italic' rel='stylesheet' type='text/css'>

See the Pen Google Fonts HTML Link by Carlos Araya (@caraya) on CodePen.
[/codepen_embed]

CSS Import from your CSS files.

[codepen_embed height=”150″ theme_id=”2039″ slug_hash=”CKdlu” default_tab=”css”]
@import url(http://fonts.googleapis.com/css?family=Alegreya+Sans+SC:500,500italic|Exo+2:400,100,400italic);

<

p>See the Pen Google Fonts CSS Import by Carlos Araya (@caraya) on CodePen.
[/codepen_embed]

Javascript import from within your scripts.

[codepen_embed height=”359″ theme_id=”2039″ slug_hash=”EtaHc” default_tab=”js”]
WebFontConfig = {
google: { families: [ 'Alegreya+Sans+SC:500,500italic:latin', 'Exo+2:400,100,400italic:latin' ] }
};
(function() {
var wf = document.createElement('script');
wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
'://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
wf.type = 'text/javascript';
wf.async = 'true';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wf, s);
})();

See the Pen Javascript Google Font Loading by Carlos Araya (@caraya) on CodePen.
[/codepen_embed]

One font does not fit all: Formats, details and workarounds

Using the following @font-face declarations we have taken care of the defaults for each @font-face declaration by making the bold and italic fonts actualy be bold and italics and, unless the font is actually condensed or stretched, make it explicit that it’s a normal font, not stretched or compressed (if we need to change this we can do it for specific elements).

Another issue to consider is that not all browsers support the same fonts (surprise, surprise). Internet Explorer supports Embedded Open Type fonts, Firefox prefers WOFF, Chrome, Safari and Opera prefer OTF (Open Type Font) or TTF (True Type Fonts) fonts and iOS prefers SVG (Scalable Vector Graphics) fonts.

I built the @font-face declarations below using Paul Irish Bulletproof @font-face syntax.

The original article is a little dated but it is still the best way to work with @font-face declarations on the web because it preserves the same font across all browsers and devices.

@font-face {
  font-family: "Your typeface";
  src: url("type/filename.eot");
  src: local("☺"),
    url("type/filename.woff") format("woff"),
    url("type/filename.otf") format("opentype"),
    url("type/filename.svg#filename") format("svg");
  font-weight: normal;
  font-style: nomal;
  font-stretch: normal;
}

@font-face {
  font-family: "Your bold typeface";
  src: url("type/filename-bold.eot");
  src: local("☺"),
    url("type/filename-bold.woff") format("woff"),
    url("type/filename-bold.otf") format("opentype"),
    url("type/filename-bold.svg#filename-bold") format("svg");
  font-weight: bold;
  font-style: nomal;
  font-stretch: normal;
}

@font-face {
  font-family: "Your italic typeface";
  src: url("type/filename-ital.eot");
  src: local("☺"),
    url("type/filename-ital.woff") format("woff"),
    url("type/filename-ital.otf") format("opentype"),
    url("type/filename-ital.svg#filename-ital") format("svg");
  font-weight: normal;
  font-style: italic;
  font-stretch: normal;
  }

See the Pen Multiple @font-face assignments in a single CSS file by Carlos Araya (@caraya) on CodePen.

We can then fine tune our styles by setting properties for elements and selectors as needed. I usually start with setting up a default font and size/line height that will be carried throughout the document. I also provide a stack of backup fonts so that the browser will use the first font in the stack that is available to display the content, finally dalling back to one of the predefined font families (sans-serif, serif, fantasy, cursive, monospace)

[codepen_embed height=”257″ theme_id=”2039″ slug_hash=”tuaGn” default_tab=”css”]
html {
font-family: "Your typeface", Georgia, sans-serif;
font-size: 62.5%;
line-height: 1.5;
}

See the Pen Finetuning elemements with @font-face defined fonts by Carlos Araya (@caraya) on CodePen.
[/codepen_embed]

Fighting FOUT

The Flash of Unstyled Text is a phenomenon in Firefox and Opera that few web designers are fond of. When you apply a custom typeface via @font-face, there is a brief moment, when loading the page, where the font hasn’t been downloaded and applied yet, and the next font in the font-family stack is used. This causes a flash of a different (typically less good looking) font, before it gets upgraded.

Unless you’re designing for ancient browsers (Firefox 3.5 and 3.6 and Opera from th at same time period) FOUT shouldn’t be that big an issue anymore.

If you still need to account for that, you can follow the instructions fom Paul Irish

Styles and typographical elements

Italics

Once we have decided on what font stack we will use, we can create our general styles. For example, to create an Italic level 1 heading (<h1>) we could code it like this:

[codepen_embed height=”162″ theme_id=”2039″ slug_hash=”xyEwA” default_tab=”css”]
h1.italics {
font-family: "Your italic typeface", Georgia, sans-serif;
font-style: italic;
}

See the Pen Setting up italics fonts for H1 tag using @font-face defined fonts by Carlos Araya (@caraya) on CodePen.
[/codepen_embed]

Bold

If we need a bold text for some emphasis we can make our strong tags bolder by using something like:

[codepen_embed height=”143″ theme_id=”2039″ slug_hash=”DAsLt” default_tab=”css”]
h1.strong: {
font-weight: 700;
}

See the Pen Assiging bold weight with a @font-face defined font by Carlos Araya (@caraya) on CodePen.
[/codepen_embed]

In addition to the standard bold value, CSS allows us to use the value bolder and numerical values from 100 to 700. The differences may be subtle but they are important as seen in the example below:

Comparison between different font weights

See the Pen Comparison between numeric values of the font-weight property by Carlos Araya (@caraya) on CodePen.

The result of the rule above will depend either on available font faces within a font family or weights defined by the browser.

Text-decoration

The text-decoration property has a set of predefined values that we can use deepnding on what visual result we want to accomplish. The valid values are:

  • underline
  • overline
  • line-through
  • none

One additional consideration is that we need to make sure to differentiate the page’s hyperlinks from the content that we choose to underline. Otherwise it’ll be confusing for our users when they try to click on underlined content and nothing happens. See the section on hyperlinks related pseudoclasses for more information.

.underline {text-decoration: underline;}

.overline {text-decoration: overline;}

.strikethrough {text-decoration: line-through;}

.none {text-decoration: none;}

Different types of Underlines using the CSS above

[codepen_embed height=”257″ theme_id=”2039″ slug_hash=”hylaK” default_tab=”result”]See the Pen Different styles of underline supported with the text-decoration CSS property by Carlos Araya (@caraya) on CodePen.[/codepen_embed]

Font-stretch

The font-stretch property, available in CSS3, selects a normal, condensed or expanded face from a font. In order to see the result of the selection, the font being used has to have a face that matches the value given.

The font-stretch property will not work on just any font, but only on fonts that are designed with different faces matching the defined sizes and that is available on the user’s computer or loaded with a @face-font rule.

font-stretch accepts one of the following values:

  • ultra-condensed
  • extra-condensed
  • condensed
  • semi-condensed
  • normal
  • semi-expanded
  • expanded
  • extra-expanded
  • ultra-expanded

Example of font-stretch

.expanded {
    font-stretch: expanded;
}

[codepen_embed height=”145″ theme_id=”2039″ slug_hash=”fGDFw” default_tab=”result”]See the Pen Controlling front stretching using CSS by Carlos Araya (@caraya) on CodePen.[/codepen_embed]

Font-variant

The font-variant property allows you to change the targeted text to small caps. It is available in CSS2 and CSS3 with the later assigning additional values to the property.

The values available in CSS2 are:

  • normal (the default)
  • small-caps

CSS3 introduced additional values for this property that are dependenant on features from Open Type being available on the font we are using.

  • all-small-caps Enables display of small capitals for both upper and lowercase letters (OpenType features: c2sc, smcp)
  • petite-caps Enables display of petite capitals (OpenType feature: pcap)
  • all-petite-caps Enables display of petite capitals for both upper and lowercase letters (OpenType features: c2pc, pcap)
  • unicase Enables display of mixture of small capitals for uppercase letters with normal lowercase letters (OpenType feature: unic)
  • titling-caps Enables display of titling capitals (OpenType feature: titl). Uppercase letter glyphs are often designed for use with lowercase letters. When used in all uppercase titling sequences they can appear too strong. Titling capitals are designed specifically for this situation.

These are small caps

THESE ARE REGULAR CAPS

Other attributes we can work with

kerning and letter-spacing

In typography, kerning (less commonly mortising) is the process of adjusting the spacing between characters in a proportional font, usually to achieve a visually pleasing result. Kerning adjusts the space between individual letter forms, while tracking (letter-spacing) adjusts spacing uniformly over a range of characters.1 In a well-kerned font, the two-dimensional blank spaces between each pair of characters all have similar area.

http://en.wikipedia.org/wiki/Kerning

The font-kerning property is supposed to provide optical kerning for the font being used. It is not widely supported (if at all). I’d suggest using letter-spacing instead. It may not have the same fine grained control Kenrning does but it’s better than nothing.

Letter spacing is more widely supported and allows you to control the spacing between letters in an element or class. Look at the example below.

<style>
p.narrow { letter-spacing: 0.4em }
p.wide {letter-spacing: 1.5em}
</style>

text-align

As the name implies text align controls the horizontal placement of text on the screen. There are 8 possible values, they are:

  • start: The same as left if direction is left-to-right and right if direction is right-to-left.
  • end: The same as right if direction is left-to-right and left if direction is right-to-left.
  • left: The inline contents are aligned to the left edge of the line box.
  • right: The inline contents are aligned to the right edge of the line box.
  • center: The inline contents are centered within the line box.
  • : The first occurrence of the one-char string is the element used for alignment. the keyword that follows or precedes it indicates how it is aligned. This allows to align numeric values on the decimal point, for instance. This property is not currently supported in any major browser.
  • justify: The text is justified. Text should line up their left and right edges to the left and right content edges of the paragraph.
  • match-parent: Similar to inherit with the difference that the value start and end are calculated according the parent’s direction and are replaced by the adequate left or right value. This is only supported in Chrome.

text-indent

This property indicates hw far you push the first line of text from the starting border (depending on direction of the text). Additional values control whether the indent is a hanging indent and whether it applies to only the first line or the entire block of text.

  • Fixed value (i.e: 2em): Indentation is specified as a fixed value. Negative values are allowed
  • Percentage (i.e: 20%): Indentation is a percentage of the containing block width.
  • each-line: Indentation affects the first line of the block container as well as each line after a forced line break , but does not affect lines after a soft wrap break . Introduced in the CSS3 Text Module and not currently implemented in any major browser.
  • hanging: Inverts which lines are indented. All lines except the first line will be indented. Introduced in the CSS3 Text Module and not currently implemented in any major browser.

color

See Expressing Colors in CSS below

Some typography related pseudo classes

Hyperlink related pseudo classes

Although I wouldn’t recommend it we can make some drastic changes to the way links behave and look when they are clicked or after they are visited. The link seudo classes and what they control are:

  • :link controls the link when it’s not being used (there’s no user interaction)
  • :visited applies after the link has been clicked on
  • :hover applies when the mouse is hovering over the link
  • :active applies when the link is being clicked (the state after you over over the link but before it changes to visited)

<

p>In order to style appropriately links, you need to put the :hover rule after the :link and :visited rules but before the :active one, as defined by the LVHA-order: :link — :visited — :hover — :active.

a:link { color: #666666; text-decoration: none; } 
a:visited { color: #333333; } 
a:hover { text-decoration: underline; } 
a:active { color: #000000; }

[codepen_embed height=”110″ theme_id=”2039″ slug_hash=”bdFKE” default_tab=”result”]See the Pen Styling links with CSS by Carlos Araya (@caraya) on CodePen.[/codepen_embed]

::first-letter and ::first-line

The ::fisrt-letter pseudo class allows you to style the first letter of a paragraph or a chapter differently than the rest of the content. This is commonly used to create Drop Cap effects. We can limit what paragraphs get a drop cap by using the :first-child pseudo element like in the

div.dcexample p:first-child:first-letter {
  float: left;
  color: #903;
  font-size: 75px;
  line-height: 60px;
  padding-top: 4px;
  padding-right: 8px;
  padding-left: 3px;
  font-family: Georgia; }

[codepen_embed height=”316″ theme_id=”2039″ slug_hash=”bihyn” default_tab=”result”]See the Pen Styling First Letter of a Chapter using CSS :first-letter pseudo class by Carlos Araya (@caraya) on CodePen.[/codepen_embed]

::first-line does something similar but with the entire first line of the matching element. This matches when printed publiccations some times have a first line of a chapter in a slightly larger font than nthe rest of the text. In the example below we’ve set the text of the first line to 1.3 em.

div.flexample p:first-child:first-line {
  font-size: 1.3em;
  color: #666;
}

[codepen_embed height=”320″ theme_id=”2039″ slug_hash=”DbnIk” default_tab=”result”]See the Pen DbnIk by Carlos Araya (@caraya) on CodePen.[/codepen_embed]

Units of measuremet in CSS

CSS Units of Measurement

Expression colors in CSS

Expressing colors in CSS

Regions, Shapes and Exclusions

CSS regions, exclusions, shapes and new publishing paradigms

More stuff to play with: CSS Paged Media

paged media article

Typography doesn’t not replace the designer’s judgment

Links and Resources