HTML

A few HTML tips

A while ago I wrote an article with some CSS tips, now it’s time to give some polish to our HTML! In this article I’ll share some tips and advice about HTML code. Some of this guidance will be best suited for beginners – how to properly build paragraphs, use headings, or improve forms, but we will also discuss SVG sprites for icons, a somewhat more advanced topic.

Text

Paragraphs

Most of our writing is structured in paragraphs, and there is an HTML element for that: <p>. Do not use the line break tag <br> to separate blocks of texts into pseudo-paragraphs, since line breaks are not meant for that.

Avoid:

Cupcake ipsum dolor sit. Amet chupa chups chupa chups sesame snaps. Ice cream pie jelly
beans muffin donut marzipan oat cake.

<br>

Gummi bears tart cotton candy icing. Muffin bear claw carrot cake jelly jujubes pudding
chocolate cake cheesecake toffee.

Recommended:

<p>Cupcake ipsum dolor sit. Amet chupa chups chupa chups sesame snaps. Ice cream
pie jelly beans muffin donut marzipan oat cake.</p>

<p>Gummi bears tart cotton candy icing. Muffin bear claw carrot cake jelly jujubes
pudding chocolate cake cheesecake toffee.</p>

A legit use for line breaks would be, for instance, to break verses of a poem or song:

<p>So close, no matter how far<br>
Couldn’t be much more from the hearth<br>
Forever trusting who we are<br>
And nothing else matters</p>

Headings

Headings tags, from <h1> to <h6>, have an implicit rank assigned to them, from 1 (most important) to 6 (less important).

To handle semantics properly, pick your heading rank in sequential order, not just because of the size that the browser will use to render the heading. You can – and should!– use CSS for this, and pick a suitable rank instead.

Avoid:

<article>
    <h1>Monkey Island</h1>
    <h4>Look behind you! A three-headed monkey!</h4>
    <!-- ... -->
</article>

Recommended:

<article>
    <h1>Monkey Island</h1>
    <h2>Look behind you! A three-headed monkey!</h2>
    <!-- ... -->
</article>

Another thing to take into account is how to create subheadings or tag lines to accompany headings. The W3C recommendation is to use regular text markup rather than a lower-rank heading.

Avoid:

<header>
    <h1>Star Wars VII</h1>
    <h2>The Force Awakens</h2>
</header>

Recommended:

<header>
    <h1>Star Wars VII</h1>
    <p>The Force Awakens</p>
</header>

Forms

Placeholders

The placeholder attribute in <input> form elements will let you show an example value to the user that is automatically erased once the user types anything in the field. Placeholders are meant to show examples of formatting valid for a field.

Unfortunately, in the wild there are a lot of placeholders acting as <label> elements, informing of what the field is instead of serving as an example of a valid input value. This practice is not accessible, and you should avoid it.

Avoid:

<input type="email" placeholder="Your e-mail" name="mail">

Recommended:

<label>
    Your e-mail:
    <input type="email" placeholder="darth.vader@empire.gov" name="mail">
</label>

Keyboards in mobile devices

It is crucial to provide typing hints for people browsing from a mobile device, like a phone or a tablet. We can easily achieve this by picking the correct type for our <input> elements.

For instance, type="number" will make a mobile phone display the numeric keypad instead of the regular alphanumeric keyboard. The same goes for type="email", type="tel", etc.

Avoid:

<label>Phone number: <input type="text" name="mobile"></label>

Recommended:

<label>Phone number: <input type="tel" name="mobile"></label>

Here is a comparison: on the left, the keyboard that shows up when using type="text"; on the right, the keyboard for type="tel".

keyboard comparison

Images

Say hi to SVG files! Not only can you use vector graphics in <img> tags like this:

<img src="acolyte_cartoon.svg" alt="acolyte">

You can also use SVG sprites to implement vector icons in your website, instead of using a Web Font – which is a hack, and might not yield perfect results. This is because browsers treat Web Font icons as text, and not as images. And there are other potential problems, like content/ad blockers disabling the download of Web Fonts. If you would like to learn more about this, watch this talk by Sarah Semark about why using SVG for icons is better than using a Web Font. You can also read more about this technique on CSS-Tricks.

The idea of SVG sprites is very similar to CSS sprites. The implementation consists of merging all your SVG assets in a single image file. In the case of SVG, every asset is wrapped in a <symbol> tag, like this:

<svg>
    <symbol id="social-twitter" viewBox="...">
        <!-- actual image data here -->
    </symbol>
</svg>

Then, the icon can be used in your HTML with a <svg> tag like this, so we point to the symbol ID in the SVG file:

<svg class="social-icon">
    <use xlink:href="icons.svg#social-twitter />
</svg>

Does creating an SVG spritesheet seem tedious? Well, that’s why there are tools like gulp-svgstore to automate the process and generate a spritesheet from your individual asset files.

And remember, since we are using a <svg> tag instead of an <img> to include the picture, we can then use CSS to apply styles. So all the cool things you can do with Web Font icons, can be done with these SVG icons as well!

.social-icon {
    fill: #000;
    transition: all 0.2s;
}

.social-icon:hover {
    fill: #00f;
}

There are some CSS limitations though: when using SVG this way, with <use> linking to a <symbol>, the image gets injected in Shadow DOM and we lose some CSS capabilities. In this case, we can’t cherry-pick which elements of the SVG to apply the styling to, and some properties (e.g., fill) will only be applied to those elements that have them undefined. But hey, you can’t do this with Web Font icons either!

In the demo below, you can see an example of a SVG sprite in action. When you mouse over the image, the torch’s fire will change its color via CSS.

See the Pen SVG acolyte demo by ladybenko (@ladybenko) on CodePen.


I hope that these tips are helpful. If you have any questions, or would like to share your own tip, please leave a comment!

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

HTML 5 game development video series

Do you want to develop a game? Here’s an introductory video series to get you started on HTML 5 game development!

Why HTML 5

The first video offers some reasons to consider making a game for the web: the power of having no friction in distribution, the freedom from siloed marketplaces, the choice of tools and APIs that are available to you, etc.

Engines and libraries

The second video provides an overview of the current engines and libraries you can use to create your game. We cover pure JavaScript libraries (such as Phaser) as well as multi-platform engines that can export to HTML 5 (such as Unity).

Firefox developer tools

Next in series, we have a hands-on video that shows how to use the developer tools in Firefox Developer Edition to debug and profile your game. Modifying code on the fly, adapting our game to different screen sizes, debugging… it’s all here!

Tips for game jams

Last, there is a video for all of you joining a game jam –these competitions where you develop a game over a weekend. I have participated in many, and I know first-hand how hard and challenging game jams are! I hope these tips might be of help.

And don’t forget, if you create an HTML 5 game, tell us about it here. I’d love to play it!

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

HTML 5 games: Tilemaps

I recently joined the Developer Relations team at Mozilla, and my current focus is to help to create content for MDN about HTML 5 game development. I’m very excited about this, since creating games is a passion of mine. I switched to HTML5 game development to increase the reach of my games – which, by the way, is also a great thing to do if you are participating in a game jam.

Part of what we have been working on is a set of MDN articles about 2D tilemaps, a popular technique in game development – both in classic games and also recent ones.

Take this screenshot, for instance:

Mockup of a tile-based game - by Kenney

Game mockup out of an open-source tileset by Kenney

See how the game level is made up of smaller, square images? These smaller pieces are called tiles. A lot of games are based on tiles, visually and/or logically: Super Mario Bros, SimCity, Final Fantasy Tactics, Civilization, etc.

The “Tiles and Tilemaps overview” article provides a foundation about how tilemaps work. You will find it useful regardless of how you use them in your game (your own implementation or a 3rd-party) –or even the programming language or technology!

We have also written articles about how to implement tilemaps using the Canvas API:

Accompanying those articles there is a set of live demos you can check out, along with their source code. But there is one for you to try right here: click on the image below and then use the arrow keys to move the character.

We will keep working on creating new MDN content for HTML5 game development and keep you updated. I hope you enjoy it!

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Creating a mobile app from a simple HTML site: Part 4

How to polish your app and prepare it for market

In previous sections of this step-by-step series (Part 1, Part 2, and Part 3) we’ve created an app that loads multiple school plans from the server.

What we have so far is functional, but still has a number of issues, including two which are major: no offline mode and a hard-coded configuration. In this closing post, we’ll work on all of these issues.

If you haven’t built up the examples from the previous parts, use stage7 app and stage7 server as a starting point. To get started, follow the instructions on how to load any stage in this tutorial.

Refactoring

First, let’s do some refactoring. We’ll add a User object type to make it easier to choose which user’s plan to display. This will allow us to remove some more code from the app’s main logic flow, making the code cleaner and more modular. This object will load data from the server to create the plan UI. At the moment, rendering is done in app.onDeviceReady and app.renderData methods. Our new onDeviceReady method creates an app.user object and runs the methods needed to get and render plans. Replace the existing onDeviceReady method with the following:

onDeviceReady: function() {
    app.user = new User('johndoe');
    app.user.getPlans();

    app.activateFingerSwipe();
},

Next, delete the app.renderData method completely. We will store this functionality inside our new User object instead, as you’ll see below.

Next, at the beginning of the index.js file (before the definition of Plan), add the following code to define the User object:

function User(userid) {
    this.id = userid;
    this.plans = [];
}

User.prototype.getPlans = function() {
    var self = this;
    var request = new XMLHttpRequest({
        mozAnon: true,
        mozSystem: true});
    request.onload = function() {
        var plans = JSON.parse(this.responseText);
        for (var i = 0; i < plans.length; i++) {
            self.plans.push(new Plan(plans[i]));
        }
        self.displayPlans();
    };
    request.open("get", app.getPlansURL + this.id, true);
    request.send();
};

User.prototype.displayPlans = function() {
    var self = this;
    navigator.globalization.getDateNames(function(dayOfWeek){
        var deck = document.getElementById('plan-group');
        var tabbar = document.getElementById('plan-group-menu');
        for (var i = 0; i < self.plans.length; i++) {
            self.plans[i].createUI(deck, tabbar, dayOfWeek);
        }
    }, function() {}, {type: 'narrow', item: 'days'});
};

This contains functionality previously found in renderData and onDeviceReady. After the plan’s JSON is loaded from the server we iterate over the list and create a list of Plan objects in user.plans. We then call user.displayPlans, which creates the required DOM environment and invokes plan.createUI for each element of user.plans.

You may notice that the above code uses app.getPlansURL to allow the XHR call to find the JSON. Previously the URL was hardcoded into request.open("get", "http://127.0.0.1:8080/plans/johndoe", true);. Since it’s better to keep settings in one place we’ll add this as a parameter of the app object instead.

Add the following into your code:

var app = {
    getPlansURL: "http://127.0.0.1:8080/plans/",
    // ....
}

Now try preparing your app again with the cordova prepare terminal command, starting your server, and reloading the app in WebIDE (as we’ve done in previous articles). The app should work as before.

Offline mode

Let’s turn our attention to making the app work offline.

There are several technologies available to store data on the device. I’ve decided to use the localStorage API, as the data we need to store is basically just simple strings and doesn’t need any complex structuring. As this is a key/value store, objects need to be stringified (represented as a string). I will use only two functions — setItem() and getItem(). For example, storing a user id would require you to call localStorage.setItem('user_id', user.id);.

There are two values we definitely need to store in the phone memory — the ids of the current user and the plans. To make the app fully open and allow users to use servers not provided by the app creators we also need to store the server address. We’ll start by storing the plans. The user id and server will be still hardcoded. Let’s add a new method — User.loadPlans — and call that from app.onDeviceReady, instead of calling both user.getPlans() and app.user.displayPlans. We will decide if the plans need to be loaded from the server and then display the plans by calling User.displayPlans() from User.loadPlans.

First update onDeviceReady again, to this:

onDeviceReady: function() {
    app.user = new User('johndoe');
    app.user.loadPlans();
    app.activateFingerSwipe();
},

Now add in the following definition for the loadPlans method, up near your other User object-defining code:

User.prototype.loadPlans = function() {
    var plans = localStorage.getItem('plans');
    if (plans === null) {
        return this.getPlans();
    }
    console.log('DEBUG: plans loaded from device');
    this.initiatePlans(plans);
    this.displayPlans();
};

The above method calls another new method — initiatePlans. This parses the JSON representation of the plans and initiates Plan objects inside the User.plans array. In the future we would like to be able to reload the plans from the server, but the existing code always adds new plans instead of replacing them.

Add the following definition just below where you added the loadPlans code:

User.prototype.initiatePlans = function(plansString) {
    var plans = JSON.parse(plansString);
    for (var i = 0; i < plans.length; i++) {
        this.plans.push(new Plan(plans[i]));
    }
}

We also need to store the plans on the client. The best point to do this is right after the plans have been loaded from the server. We will call localStorage.setItem('plans', this.responseText) inside the success response function of getPlans. We must also remember to call the initiatePlans method.

Update your getPlans definition to the following:

User.prototype.getPlans = function() {
    var self = this;
    var request = new XMLHttpRequest({
        mozAnon: true,
        mozSystem: true});
    request.onload = function() {
        console.log('DEBUG: plans loaded from server');
        self.initiatePlans(this.responseText);
        localStorage.setItem('plans', this.responseText);
        self.displayPlans();
    };
    request.onerror = function(error) {
        console.log('DEBUG: Failed to get plans from ``' + app.getPlansURL + '``', error);
    };
    request.open("get", app.getPlansURL + this.id, true);
    request.send();
};

At this moment, successful loading of the user’s plans happens only once. Since school plans change occasionally (usually twice a year) you should be able to reload the plans from the server any time you want. We can use User.getPlans to return updated plans, but first we need to remove existing plans from the UI, otherwise multiple copies will be displayed.

Let’s create User.reloadPlans — add the code below your existing User object-defining code:

User.prototype.reloadPlans = function() {
    // remove UI from plans
    for (var i = 0; i < this.plans.length; i++) {
        this.plans[i].removeUI();
    }
    // clean this.plans
    this.plans = [];
    // clean device storage
    localStorage.setItem('plans', '[]');
    // load plans from server
    this.getPlans();
};

There is a new method to add to the Plan object too — Plan.removeUI — which simply calls Element.remove() on a plan’s card and tab. Add this below your previous Plan object-defining code:

Plan.prototype.removeUI = function() {
    this.card.remove();
    this.tab.remove();
};

This is a good time to test if the code has really reloaded. Run cordova prepare again on your code, and reload it in WebIDE.

We’ve got two console.log statements inside loadPlans and getPlans to let us know if the plans are loaded from device’s storage or the server. To initiate a reload run this code in Console:

app.user.reloadPlans()

Note: Brick reports an error at this point, as the link between each tab and card has been lost inside the internal system. Please ignore this error. Once again, our app still works.

reloadPlans from Console

Let’s make the reload functional by adding a UI element to reload the plans. In index.html, wrap a div#topbar around the brick-tabbar. First, add a reload button:

<div id="reload-button"></div>
<div id="topbar">
    <brick-tabbar id="plan-group-menu">
    </brick-tabbar>
</div>

Now we’ll make the button float to the left and use calc to set the size of the div#topbar. This makes Brick’s tabbar calculate the size when layout is changed (portrait or horizontal). In css/index.css, add the following at the bottom of the file:

#topbar {
	width: calc(100% - 45px);
}

#reload-button {
	float: left;
	/* height of the tabbar */
	width: 45px;
	height: 45px;
	background-image: url('../img/reload.svg');
	background-size: 25px 25px;
	background-repeat: no-repeat;
	background-position: center center;
}

We will download some Gaia icons to use within the application. At this stage, you should save the reload.svg file inside your img folder.

Last detail: Listen to the touchstart event on the #reload-button and call app.user.reloadPlans. Let’s add an app.assignButtons method:

assignButtons: function(){
    var reloadButton = document.getElementById('reload-button');
    reloadButton.addEventListener('touchstart', function() {
        app.user.reloadPlans();
    }, false);
},

We need to call it from app.deviceReady before or after app.activateFingerSwipe().

onDeviceReady: function() {
    // ...
    app.activateFingerSwipe();
    app.assignButtons();
},

At this point, save your code, prepare your cordova app, and reload it in WebIDE. You should see something like this:

reload button

Here you can find current code for app and server.

Settings page

Currently all of the identity information (the address of the server and user id) is hardcoded in the app. If the app is to be used with others, we provide functionality for users to set this data without editing the code. We will implement a settings page, using Brick’s flipbox component to change from content to settings and vice versa.

First we must tell the app to load the component. Let’s change index.html to load the flipbox widget by adding the following line into the HTML <head> section:

<link rel="import" href="app/bower_components/brick-flipbox/dist/brick-flipbox.html">

Some changes must happen inside the HTML <body> as well. brick-topbar and brick-deck need to be placed inside switchable sections of the same flipbox, and the reload button also moves to inside the settings. Replace everything you’ve got in your <body> so far with the following (although you need to leave the <script> elements in place at the bottom):

<brick-flipbox>
    <section id="plans">
        <div id="settings-button"></div>
        <div id="topbar">
            <brick-tabbar id="plan-group-menu">
            </brick-tabbar>
        </div>
        <brick-deck id="plan-group">
        </brick-deck>
    </section>
    <section id="settings">
        <div id="settings-off-button"></div>
        <h2>Settings</h2>
    </section>
</brick-flipbox>

The idea is to switch to the “settings” view on pressing a settings-button, and then back to the “plans” view with the settings-off-button.

Here’s how to wire up this new functionality. First up, inside your app definition code add a toggleSettings() function, just before the definition of assignButtons():

toggleSettings: function() {
    app.flipbox.toggle();
},

Update assignButtons() itself to the following (we are leaving the reloadButton code here, as we’ll need it again soon enough):

assignButtons: function() {
    app.flipbox = document.querySelector('brick-flipbox');
    var settingsButton = document.getElementById('settings-button');
    var settingsOffButton = document.getElementById('settings-off-button');
    settingsButton.addEventListener('click', app.toggleSettings);
    settingsOffButton.addEventListener('click', app.toggleSettings);
        
    var reloadButton = document.getElementById('reload-button');
    reloadButton.addEventListener('touchstart', function() {
        app.user.reloadPlans();
    }, false);
},

Next: we need to retrieve some more icons for the app. Save the settings.svg and back.svg files inside your img folder.

Let’s update our css/index.css file too, to add the additional icons in and style our new features. Add the following at the bottom of that file:

#form-settings {
    font-size: 1.4rem;
    padding: 1rem;
}
#settings-button, #settings-off-button {
    float: left;
    width: 45px;
    height: 45px;
    background-size: 25px 25px;
    background-repeat: no-repeat;
    background-position: center center;
}
#settings-button {
    background-image: url('../img/settings.svg');
}
#settings-off-button {
    background-image: url('../img/back.svg');
    border-right: 1px solid #ccc;
    margin-right: 15px;
}
brick-flipbox {
    width: 100%;
    height: 100%;
}

If you now prepare your cordova app again with cordova prepare, and reload the app inside WebIDE, you should see something like this:

flipbox working

Adding a settings form

To add a form and some data, replace your current <section id="settings"></section> element with the following:

<section id="settings">
    <div id="settings-off-button"></div>
    <h2>Settings</h2>
    <form id="form-settings">
        <p><label for="input-server">Server</label></p>
        <p><input type="text" id="input-server" placeholder="http://example.com/"/></p>
        <p><label for="input-user" id="label-user">User ID</label></p>
        <p><input type="text" id="input-user" placeholder="johndoe"/></p>
        <p><button id="reload-button">RELOAD ALL</button></p>
    </form>
</section>

Making it look good is easy! We’ll use some ready-made CSS available in Firefox OS Building Blocks. Download input_areas.css and buttons.css and save them in your www/css directory.

Then add the following to your HTML <head>, to apply the new CSS to your markup.

<link rel="stylesheet" type="text/css" href="css/input_areas.css">
<link rel="stylesheet" type="text/css" href="css/buttons.css">

Go into the css/index.css file and delete the #reload-button { ... } rule to make the “RELOAD ALL” button display correctly.

Run cordova prepare again and reload the app in WebIDE, and you should see something like this:

settings

We’ve got the view — now to support it. When the app first installs there will be no setting, so the app will have no idea how to load the data. Instead of showing empty plans we immediately toggle the view to the settings. Update your onDeviceReady function as shown:

onDeviceReady: function() {
    app.plansServer = localStorage.getItem('plansServer');
    app.userID = localStorage.getItem('userID');
    app.activateFingerSwipe();
    app.assignButtons();

    if (app.plansServer && app.userID) {
        app.user = new User(app.userID);
        app.user.loadPlans();
    } else {
        app.toggleSettings();
    }
},

The app needs to read the data from our form inputs, so save them into the phone’s storage, and reload after the change. Let’s add this functionality at the end of the app.assignButtons function. First we will stop the form from submitting (otherwise our app would just reload the index.html instead of redrawing the content). Add the following code to the end of the assignButtons function, just before the closing },:

document.getElementById('form-settings').addEventListener('submit', function(e) {
    e.preventDefault();
}, false)

We will read and set the input value for the server. I’ve decided to read the input value on the blur event. It is dispatched when the user touches any other DOM Element on the page. When this happens, the server value is stored in the device’s storage. If app.plansServer exists on app launch, we set the default input value. The same has to happen for the userID, but there is a special step. Either we change the app.user or create a new one if none exists. Add the following just above the previous block of code you added:

var serverInput = document.getElementById('input-server');
serverInput.addEventListener('blur', function() {
    app.plansServer = serverInput.value || null;
    localStorage.setItem('plansServer', app.plansServer);
});
if (app.plansServer) {
    serverInput.value = app.plansServer;    
}

var userInput = document.getElementById('input-user');
userInput.addEventListener('blur', function() {
    app.userID = userInput.value || null;
    if (app.userID) {
        if (app.user) {
            app.user.id = app.userID;
        } else {
            app.user = new User('app.userID');
        }
        localStorage.setItem('userID', app.userID);
    }
});
if (app.userID) {
    userInput.value = app.userID;    
}

After preparing your app and reloading it in WebIDE, you should now see the settings working as expected. The settings screen appears automatically if no plans are found in the localstorage, allowing you to enter your server and userID details.

Test it with the following settings:

  • Server: http://127.0.0.1:8080
  • User ID: johndoe

The only inconvenience is that you need to switch back to the plans view manually once Settings are loaded. In addition, you might get an error if you don’t blur out of both form fields.

settings are working

Improving the settings UX

In fact, switching back to the plans view should be done automatically after plans are successfully loaded. We can implement this by adding a callback to the User.getPlans function, and including it in the call made from User.reloadPlans:

First, update your getPlans() function definition to the following:

User.prototype.getPlans = function(callback) {
    var self = this;
    var url = app.plansServer + '/plans/' + this.id;
    var request = new XMLHttpRequest({
        mozAnon: true,
        mozSystem: true});
    request.onload = function() {
        console.log('DEBUG: plans loaded from server');
        self.initiatePlans(this.responseText);
        localStorage.setItem('plans', this.responseText);
        self.displayPlans();
        if (callback) {
            callback();
        }
    };
    request.open("get", url, true);
    request.send();
};

Next, in User.reloadPlans add the callback function as an argument of the this.getPlans call:

this.getPlans(app.toggleSettings);

Again, try saving, preparing, and reloading your new code. You should now see that the app displays the plans view automatically when correct server and user information is entered and available. (It switches to the Settings view only if there is no error in self.initiatePlans(this.responseText).).

final

Where do we go from here

Congratulations! You’ve reached the end of this 4-part tutorial, and you should now have your own working prototype of a fun school plan application.

There is still plenty to do to improve the app. Here are some ideas to explore:

  • Writing JSON files is not a comfortable task. It would be better to add new functionality that lets you edit plans on the server. Assigning them to the user on the server opens new possibilities, and this would just require an action to sync the user account on both server and client.
  • Displaying hours would also be nice.
  • It would be cool to implement a reminder alarm for some school activities.

Try implementing these yourself, or build out other improvements for your own school scheduling app. Let us know how it goes.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

HTML 5 Forms

By Mark DuBois
Director of Education

Details, details, details

 

It is April, 2015 as I write this post. HTML5 is supported by the majority of modern browsers. HTML5 contains a lot of semantic markup. For those who don’t know – semantic markup means that the HTML markup reinforces the meaning of the information on the web page. Yes, I often encounter pages written in an antiquated view of HTML. As a web designer or developer, I would think we should take advantage of these capabilities as often as possible/ practical. It doesn’t take more than a few moments when developing a page.

Permit me to provide a simple example. I often complete forms on my smartphone. I can’t count the number of times I have to use additional keys because someone who designed the form I am trying to complete had no understanding of the capabilities of HTML5. For example, one can code for a text input element which contains email. One can code this in multiple ways. Given this is 2015, I think the appropriate attribute should be type=”email” instead of type=”text” (and here is why).

I created two very simple forms. In the first example, I chose to use a semantic attribute. Note how the phone keyboard automatically detected that and provided a keyboard with the @ symbol included (very handy when entering an email address)

mark dubois form image

 

 

 

 

However, many forms I encounter use the older approach of type=”text” (note the keyboard which then pops up). I now have to tap another key (123) to get to the @ symbol. This is an extra step. It slows me down. I personally find it frustrating. Beyond that, search engines won’t know this input field is for email addresses.

Yes, this is a ridiculously simple example. I did this for a couple of reasons.
First, we are in the middle of a number of web design contests. Aspiring professionals should be developing good habits and practices. They should know all the semantic features of HTML5 and employ them where appropriate.
Second, we should all be taking advantages of these improvements. If we want our web page rank to increase on search engines, our pages should validate. Our pages should use semantic markup and so forth. It takes typing 1 extra character to use proper markup for the input field in question (is it really all that difficult to type email instead of text)?

As always, I look forward to your comments.

The post HTML 5 Forms appeared first on Web Professionals.

View full post on Web Professional Minute

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

HTML out of the Browser

Amongst my friends, I’m known as something of a Star Wars nerd. My longtime nick has been cfjedimaster (a combination of two passions, the other being ColdFusion), I work in a room packed to the gills with Star Wars toys, and I’ve actually gotten inked up twice now with Star Wars tats. That being said, it was another movie that had the most influence on my current career – Tron.

Tron_poster

I had already discovered an interest in computers before then, but it was Tron that really crystallized the idea for me. All of sudden I imagined myself being the programmer – creating intelligent programs and dominating the grid. Yeah, I know, I was a nerd back then too.

My dreams, though, ran into reality rather quickly during my time as a Comp Sci major in college. First – I discovered that “Hey, I’m good at math!” means crap all when you hit Calculus 3, and secondly, I discovered that I really wasn’t that interested in the performance of one sort versus another. I switched to English as a major (always a good choice) but kept messing around with computers. It was during this time that I was exposed to Mosaic and the early web.

I quickly jumped into the web as – well – I’ll put it bluntly – easier programming than what I had been exposed to before. I can remember LiveScript. I can remember my first Perl CGI scripts. This wasn’t exactly light cycle coding but it was simpler, fun, and actually cutting edge. I’ve spent a good chunk of my adult life now as a web developer, and while I certainly have delusions of the web being a pristine environment, it has been good to me (and millions of others) and I’m loving to see how much it evolves over time.

One of the most fascinating ways that web technologies have grown is outside of the web itself. In this article I’m going to look at all the various ways we can reuse our web-based technologies (HTML, JavaScript, and CSS) in non-web based environments. While it would be ludicrous to say that one shouldn’t learn other technologies, or that web standards work everywhere and in every situation, I feel strongly that the skills behind the web are ones open to a large variety of people in different disciplines – whether or not you got that PhD in computer science!

Mobile

This is typically the point where I’d discuss how important mobile is, but it’s 2014 and I think we’re past that now. Mobile development has typically involved either Java (Android) or Objective-C (iOS). Developers can also use web standards to build native applications. One solution is Apache Cordova (AKA PhoneGap).

Cordova uses a web view wrapped in a native application to allow web developers to build what are typically referred to as hybrid applications. Along with providing an easy way to get your HTML into an app, Cordova provides a series of different plugins that let you do more than what a typical web page can do on a device. So for example, you have easy access to the camera:

navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
    destinationType: Camera.DestinationType.DATA_URL
});
 
function onSuccess(imageData) {
    var image = document.getElementById('myImage');
    image.src = "data:image/jpeg;base64," + imageData;
}
 
function onFail(message) {
    alert('Failed because: ' + message);
}

You can also work with the accelerometer, GPS, contacts, the file system, and more. Cordova provides a JavaScript API that handles the communication to native code in the back end. Best of all, the same code can be used to build native applications for multiple different platforms (including Firefox OS, now supported in Cordova & PhoneGap).

To be clear, this isn’t a case of being able to take an existing web site and just package it up. Mobile applications are – by definition – completely different from a simple web site. But the fact that you can use your existing knowledge gives the developer a huge head start.

Another example of this (and one that is hopefully well known to readers of this site) is Firefox OS. Unlike Cordova, developers don’t have to wrap their HTML inside a web view wrapper. The entire operating system is web standards based. What makes Firefox OS even more intriguing is support for hosted applications. Firefox OS is a new platform, and the chance that your visitors are using a device with it is probably pretty slim. But with a hosted application I can easily provide support for installation on the device while still running my application off a traditional URL.

Consider a simple demo I built called INeedIt. If you visit this application in Chrome, it just plain works. If you visit it in a mobile browser on Android or iOS – it just works. But visit it with Firefox and code will trigger to ask if you want to install the application. Here is the block that handles this.

if(!$rootScope.checkedInstall &amp;&amp; ("mozApps" in window.navigator)) {
 
    var appUrl = 'http://'+document.location.host+'/manifest.webapp';
    console.log('havent checked and can check');
    var request = window.navigator.mozApps.checkInstalled(appUrl);
 
    //silently ignore
    request.onerror = function(e) {
        console.log('Error checking install '+request.error.name);
    };
 
    request.onsuccess = function(e) {
        if (request.result) {
            console.log("App is installed!");
        }
        else {
            console.log("App is not installed!");
            if(confirm('Would you like to install this as an app?')) {
                console.log('ok, lets try to install'); 
                var installRequest = window.navigator.mozApps.install(appUrl);
 
                installRequest.onerror = function() {
                    console.log('install failure: '+this.error.name);
                    alert('Sorry, install failed.');    
                };
 
                installRequest.onsuccess = function() {
                    console.log('did it');
                    alert('Thanks, app installed!');    
                };
            }
            $rootScope.checkedInstall=true;
        }
    };
 
} else {
    console.log('either checked or non compat');                
}

Pretty simple, right? What I love about this is that the code is 100% ignored outside of Firefox OS but automatically enhanced for folks using that operating system. I risk nothing – but I get the benefit of providing them a way to download and have my application on their device screen.

FF OS prompting you to install the app

Desktop

Of course, there are still a few people who sit in front of a gray box (or laptop) for their day to day work. Many desktop applications have been replaced by web pages, but there are still things that outside the scope of web apps. There are still times when a desktop app makes sense. And fortunately – there’s multiple ways of building them with web standards as well.

So you know the code example I just showed you? The one where Firefox OS users would be given a chance to install the application from the web page? That exact same code works on the desktop as well. While still in development (in fact, the application I built doesn’t work due to a bug with Geolocation), it will eventually allow you to push your web based application both to a mobile Firefox OS user as well as the other billion or so desktop users. Here’s the application installed in my own Applications folder.

INeedIt as a desktop app

As I said though – this is still relatively new and needs to bake a bit longer before you can make active use of it. Something you can use right now is Node Webkit. This open source project allows you to wrap Node.js applications in a desktop shell. Executables can than be created for Windows, Mac, and Linux. You get all the power of a “real” desktop application with the ease of use of web standards as your platform. There’s already a growing list of real applications out there making use of the framework – some I had even used before what realizing they used Node Webkit behind the scenes.

As an example, check out A Wizard’s Lizard, a RGP with random dungeons and great gameplay.

Screen shot - Wizard's Lizard

Native App Extensions

In the previous section we covered applications built with web standards. There are also multiple applications out there today, built natively, that can be extended with web standards. As a web developer you are probably already familiar with Firefox Add-Ons and Chrome extensions. There is an incredibly rich ecosystem of browser extensions for just about any need you can think of. What interests me however is the move to use web standards to open other products as well.

Did you know Photoshop, yes, Photoshop, now has the ability to extended with Node.js? Dubbed “Adobe Generator”, this extensibility layer allows for a script-based interface to the product. One example of this is the ability to generate web assets from layers based on a simple naming scheme. If you’ve ever had to manually create web assets, and update them, from a PSD, you will appreciate this. The entire feature though is driven by JavaScript and all makes use of a public API you can build upon. The code, and samples, are all available via GitHub.

Generator running within Photoshop

What Next?

Coming from the perspective of someone who has been in this industry for way too long, I can say that I feel incredibly lucky that web standards have become such a driving force of innovation and creativity. But it is not luck that has driven this improvement. It is the hard work of many people, companies, and organizations (like Mozilla) that have created the fertile landscape we have before us today. To continue this drive requires all of us to become involved, evangelize to others, and become proponents of a web created by everyone – for everyone.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Firefox Developer Tools: Episode 27 – Edit as HTML, Codemirror & more

Firefox 27 was just uplifted to the Aurora release channel which means we are back to report on new features in Firefox Developer Tools. Below are just some of the new features, you can also take a look at all bugs resolved in DevTools for this release).

JS Debugger: Break on DOM Events

You can now automatically break on a variety of DOM events, without needing to manually set a breakpoint. To do this, click on the “Expand Panes” button on the top right of the debugger panel (right next to the search box). Then flip over to the events tab. Click on an event name to automatically pause the next time it happens. This will only show events that currently have listeners bound from your code. If you click on one of the headings, like “Mouse” or “Keyboard”, then all of the relevant events will be selected.

Inspector improvements

We’ve listened to feedback from web developers and made a number of enhancements to the Inspector:

Edit as HTML

Now in the inspector, you can right click on an element and open up an editor that allows you to set the outerHTML on an element.

Select default color format

You no have an option to select the default color format in the option panel:

Color swatch previews

The Developer Tools now offer color swatch previews that show up in the rule view:

Image previews for background image urls

Highly requested, we now offer image previews for background image URLs:

In addition to above improvements, Mutated DOM elements are now highlighted in the Inspector.

Keep an eye out for more tooltips coming soon, and feel free to chime in if you have any others you’d like to see!

Codemirror

Codemirror is a popular HTML5-based code editor component used on web sites. It is customizable and theme-able. The Firefox Devtools now use CodeMirror in various places: Style editor, Debugger, Inspector (Edit as HTML) and Scratchpad.

From the Option panel, the user can select which theme to use (dark or light).

WebConsole: Reflow Logging

When the layout is invalidated (CSS or DOM changes), gecko needs to re-compute the position of some nodes. This computation doesn’t happen immediatly. It’s triggered for various reasons. For example, if you do “node.clientTop”, gecko needs to do this computation. This computation is called a “reflow”. Reflows are expensive. Avoiding reflows is important for responsiveness.

To enable reflow logging, check the “Log” option under the “CSS” menu in the Console tab. Now, everytime a reflow happens, a log will be printed with the name of the JS function that triggered this reflow (if caused by JS).

That’s all for this time. Hope you like the new improvements!

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Homeopathic HTML solutions

Our lives as web developers are amazing. Information flows plentiful and is ever increasing and our quiver of tools to play with ever replenishing. Every week there is some new, groundbreaking thing happening and web technologies are promising amazing access to hardware and making our lives much simpler.

Instead of picking and choosing from these offerings and using the right one for the job, we seem to spend an extraordinary amount of time re-creating the same solutions in several technologies. Not because it is needed, but because we can.

This becomes almost painfully ironic when you see articles that are a massive pat on our own backs for using “plain HTML”, “vanilla JavaScript” or “pure CSS” that utterly and totally miss the mark of using these technologies. Or just omit or misunderstand enough to be broken and a worse performer than a “closed technology” solution.

back patting machine

Examples like these are beautifully styled forms that utterly fail to have labels that do what labels do – connect input elements with descriptive text (both in assistive technology and by making the text clickable in browsers) – as the author failed to understand that you need to nest elements inside labels or connect them with a for/id attribute coupling.

Other examples are creating complex graphical animations and paint with I, B or DIV elements. These are impressive, but no, they are not – at all – semantic HTML. True, SPAN and DIV are defined as elements with no meaning for us to use any which way we want to and I and B are defined as “visual” elements that could display anything. However, nowhere is a definition that adding a lot of nested empty elements is a good idea. That’s like raspberrying, watermelon or capybara your hedgehog in aparagus, right? What? The last sentence didn’t make sense? Don’t worry, there is probably some conversion tool that will make it useful – sadly enough you don’t have access to it right now, though. This is what you do when you use HTML to paint in the browser. You abstract away meaning and make it dependent on other technologies.

Semantic HTML means a few things, none of which are covered by exercises like that:

  • You deal in content. Semantic HTML describes content. It is not a tool to paint with. You could easily create an image using a table with a cell with a background colour as each pixel. It wouldn’t make sense though as a table is meant to give tabular data its structure and describe the relationship of the data parts to each other. Images do not have that need, what they need is an alternative text.
  • You give content meaning. A P tag around a block of text says that this is a paragraph. It says it to people, browsers and assistive technology. It even means it displays with whitespace around it when there is no CSS and it allows you to collapse it in editors. A DIV with a class of “paragraph” does the same for human readers, but only makes sense visually with CSS and none to assistive technology.
  • You increase maintainability. You keep everything that is to be changed when it comes to content in the HTML. You do not have text labels in JavaScript or generate textual information in CSS with pseudo content. That way people don’t have to wonder where a text on the screen came from when they need to change, translate or remove it. CMS have no issue separating content from presentation to make it easy for people to edit pages when you used semantic HTML. When all you use is DIVs with classes, CMS editors will choke.
  • Semantic HTML is a sign of quality and future thinking – it is true: browsers do not care a bit if an element is a DIV or a P. Maintainers do though. And browsers and rendering software or marked up content comes and goes. Semantic HTML is there for humans, computers, search engines, conversion tools and many other things. You can create incredibly terse and nonsensical code and browsers will still do something with it. What you sacrifice though is readability. Sometimes in order to make things easier to understand, you need to write more. That is not a waste, it means you care about what you do and don’t leave it to machines to translate for you for other machines to display.

In order to reap the rewards of clean and semantic markup, you need to think about meaning first and then about code or markup. Writing intelligent, beneficial HTML is an exercise in organising and describing; you could say labeling. It is not about using HTML as the tool to create things that look impressive.

So next time you feel like showing off that you can do things “in plain HTML”, consider the consequences. Think if what you did in HTML really gives the content meaning or if you just painted with tags. We won’t succeed in promoting open technologies as the obvious and better alternative if we abuse them to reach a goal they were not meant for. This is especially important in terms of performance. Every DOM access, every reflow is costly. Let’s use them sparingly.

What we need is more rewards for doing the right thing. That’s why articles like Heydon Pickering’s “Semantic CSS With Intelligent Selectors” are so important. They don’t wave a flag for semantic HTML – instead they make it beneficial to do the right thing. We need more of those, giving people rewards for learning and understanding HTML before they apply it. What we don’t need is more experiments proving things can be done in a technology that wasn’t meant for them. These can be inspiring and are fun to do, but they don’t help the cause in the long run.

View full post on Christian Heilmann

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)