everything is awesome - cutting the corners off the web
DESCRIPTION
The web is awesome despite it's detractors. But we can't forget our fundamentals when we're trying to forge ahead with new tech. This talk is about how to approach the building blocks of the web in a way that takes advantage of their strengths and avoids their weaknesses.TRANSCRIPT
Everything is Awesome
Cutting the corners off the web.
Really now?
“The Web Is Dying; Apps Are Killing It.”
However…
We’re making this complicated.
HTML
Raw HTML is for Chumps<div data-module-id="12" data-module-name="resp.module.article.ArticleColumnist" data-module-zone="articleheader" class="zonedModule"><hgroup class="columnist-hgroup clearFix"><div class="columnist-header">
<h2 class=" region-cat"><a href="http://online.wsj.com/public/search?article-doc-type=%7BKeywords%7D&HEADER_TEXT=keywords">Keywords</a>
</h2><h1 itemprop="headline">The Web Is Dying; Apps Are Killing It </h1><h2 class="subHed deck">Tech’s Open Range Is Losing Out to Walled Gardens</h2>
</div>
<div class="columnist"><div class="a-size"><img src="http://s.wsj.net/img/mims.jpg" height="76px" width="76px"></div>
<div class="connect byline-dsk"><span class="intro">By</span>
<div class="social-dd"> <span class="c-name" rel="author" itemprop="author">Christopher Mims<span class="bk-box"></span></span><menu class="c-menu">
<li class="twitter"> <iframe scrolling="no" frameborder="0" name="twitter_iframe" id="twitter_iframe" data-dj-
src="http://platform.twitter.com/widgets/follow_button.html?screen_name=mims&show_count=false" style="width: 60px; height: 21px;" allowtransparency="true"></iframe>
<a href="http://www.twitter.com/@mims" target="_blank">@mims</a></li>
<li class="email"><a href="mailto:[email protected]">[email protected]</a></li>
<li class="facebook"> <iframe data-dj-src="http://www.facebook.com/plugins/follow.php?href=https%3A%2F
%2Fwww.facebook.com%2Fchristophermims&layout=button_count&show_faces=false&colorscheme=light&font&width=250&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:250px; height:21px;" allowtransparency="true"></
doctype htmlhtml(lang="en") head title= pageTitle
body h1 Jade - node template engine #container.col if youAreUsingJade p You are amazing else p Get on it! p. Jade is a terse and simple templating language with a strong focus on performance and powerful features.
DRY Templating
• Layout Templates with Extending Blocks
• Includes with Variables
• Good Loops and Conditionals
What HTML is for
• Establishing Content Order
• Providing Accessibility Hooks
• Anchors, Titles, alt tags, ARIA roles
• tabindex ordering
• keyboard focus as a first class concern
Building the FrontendYou do automate this right?
gulp.task(‘dev:styles', function() { gulp.src(PATHS.project + “/main.less") .pipe(less({strictMath: true})) .pipe(gulp.dest(PATHS.assetsOut)) .pipe(connect.reload());});
gulp.task(‘dev:styles', function() { gulp.src(PATHS.project + “/main.less") .pipe(less({strictMath: true})) .pipe(please({ minifier: false, import: false, mqpacker: false })) .pipe(gulp.dest(PATHS.assetsOut)) .pipe(connect.reload());});
gulp.task(‘dev:styles', function() { gulp.src(PATHS.project + “/main.less") .pipe(sourcemaps.init()) .pipe(less({strictMath: true})) .pipe(please({ minifier: false, import: false, mqpacker: false })) .pipe(sourcemaps.write()) .pipe(gulp.dest(PATHS.assetsOut)) .pipe(connect.reload());});
CSS
Just do the Comps?It’s not that simple.
You are building a design system.
Bootstrap/Foundation is just deferring the
problem.
Manage Specificity
Namespace with Purpose
http://csswizardry.com/2014/10/the-specificity-graph/
PreprocessorsWhat’s their role now?
It’s not about prefixes.
• Variables
• Mixins
• Extends
• Creating a DRY visual system.
@paletteBgPrimary: #fff;@paletteNearWhite: #fcfcfc;@paletteBgSecondary: #edf0f2;@paletteBgLight: #edeff0;
@paletteAccent: #f8971d;@paletteDominant: #445560;@paletteDarkDominant: #37454f;@paletteSubtle: #ffca88;@paletteError: #ff0000;@paletteErrorBg: #feebeb;
@paletteBlack: #000;@paletteBodyInk: #818386;@paletteStrongInk: #393a3c;@paletteMidInk: #515151;@paletteFaintInk: #ccc;@paletteReverseInk: #fff;@paletteHairline: #dbe3e8;
Explore Relationships between colours, measurements, layering
@measurementRegionPaddingVertical: rem(57);@measurementRegionPaddingVerticalMobile: rem(18);@measurementRegionPaddingSides: rem(98);@measurementRegionPaddingSidesMobile: rem(32);@measurementRegionPaddingMobile: rem(18 32);@measurementRegionPaddingThin: rem(18 18);@measurementRegionPadding: rem(57 98);
@layerBase: 0;@layerFloat: 0;@layerOverlay: 500;@layerModal: 1000;
Common relationships are everywhere, even if your
designer doesn’t show you.
// mixins.targeted(@rules) { &:hover, &:focus { @rules(); }}
.activated(@rules) { &.is-active, &:active { @rules(); }}
// extends.reset-list-styles { list-style: none; padding-left: 0;}
.ellipse-overflow { text-overflow: ellipsis; overflow: hidden;}
Mixins let you make standard patterns with arguments.
Extends let you make reusable patterns with only a single block of
rules.
CSS is Skin Deep
• Target Classes, avoid tags and attributes where possible.
• Try not to sacrifice control over your markup, bad CSS comes from there.
Postprocessing for Compatibility
• Media Query Packing
• Minification
• px fallbacks for rems (pixrem)
• Prefixing (autoprefixer)
• http://pleeease.io/ (collection of tools)
On Responsiveness
Device Targeting Doesn’t Work
Touch is becoming a primary concern.
:hover :focus :active
iOS pretends it can do :hover - careful with
{display: none}
Rethink Breakpoints
Light on the hill
• Pointer based media queries
• Responsive Images (picture)
• but still no element queries
Javascript is Awesome(ly bad)
Modern Javascript Engines are FAST
DOM is still slow
Mobile requires us to write efficient Javascript
Efficient DOM Rendering
• Batch Operations
• Use transforms & opacity for the best performance of styling, transitions, etc
• Animation used CSS3 with state changes, and Velocity.js where applicable. Stuff IE8 animations or provide a fallback.
Timing
• Callbacks on Events
• requestAnimationFrame
• Careful with setTimeout
Pack your code!
var bt = require("./components/brand_ticker.js");var carousel = require("./components/carousel.js");var mm = require("./components/mobile-menu.js");
window.jQuery(function($) { bt.init(); carousel.init(); mm.init();});
var init = function() { var toggleMenu = function(e) { $(document.body).toggleClass("menu-active*"); e.preventDefault(); }
$(".mobile-menu__toggle").click(toggleMenu);};
module.exports.init = init;
Benefits of Packing
• Proper understanding of dependencies.
• Less prone to copy pasta.
• Easy to build.
Browserifygulp.task(‘dev:scripts', function() { gulp.src(PATHS.project + “/main.js") .pipe(browserify()) .on('prebundle', function(bundle) { bundle.transform(envify({ NODE_ENV: "production" })); })) .pipe(uglify()) .pipe(gulp.dest(PATHS.assetsOut)) .pipe(connect.reload());});
if (process.env.NODE_ENV !== "production") { var debug = require("./debug.js");}
var data = $(“.something”).data(“message”);
if (process.env.NODE_ENV !== "production") { debug.logger(“log this :” + data);}
$(“.some-other-thing”).text(data);
// after envify
if (“production” !== "production") { var debug = require("./debug.js");}
var data = $(“.something”).data(“message”);
if (“production” !== "production") { debug.logger(“log this :” + data);}
$(“.some-other-thing”).text(data);
// during uglify
var data = $(“.something”).data(“message”);$(“.some-other-thing”).text(data);
// after uglify
var a=$(“.something”).data(“message”);$(“.some-other-thing”).text(a);
We’re still figuring this out
• Browserify on big codebases results in 700kb files.
• Maybe okay for Single Page Apps, but for general use, you may still need to split your codebase.
• Options? — http://webpack.github.io http://duojs.org
InternationalisationStop making excuses.
You may not have the resources to localise, but
anyone can internationalise.
{ "app": { "name": "i18next" }, "nav": { "home": "Home", "page1": "Page One", "page2": "Page Two" } }
i18n.init(function(t) { // translate nav $(".nav").i18n(); // programatical access var appName = t("app.name"); });
• Full Phrases, not words.
• Never pluralise out of the translation.
• Trust libraries, don’t roll your own. Translations. Currency. Number Formats. Date times and Time Zones.
DeploymentYou are automating this right?
Staging is now mandatory
Data Flow
• Development
• Development <— Staging (for fixtures)
• Staging —> Production
• Development <— Staging <— Production
Perceptual Diffinghttps://github.com/bslatkin/dpxdt
Staging Production
What’s coming?
Application CacheSingle Page Apps, cached, downloaded once.
IndexedDBWe can store almost anything on the client.
https://www.npmjs.org/package/makedrive
Freaking asm.js
Everything is Awesome
How are you going to be awesome in 2015?
[email protected] @MalucoMarinero
James Rakichless than awesome front end developer but still pretty good