Building the interface for wearecolony.com
Background
What is We Are Colony?
-
VOD platform for independent film
-
Content organised into "Companions"
-
Startup that has been invested in by the Zone exec
-
Part of the Seedcamp family
- Won Technology Strategy Board SMART Award
- Won NESTA Digital R&D Fund for the Arts
Back-end platform
-
.NET application
- IIS
-
Razor templates
-
AWS EC2/Cloudfront/Elastic Beanstalk
Front-end templates
- Separate repository
- No database/building/back-end devs free from me!
- Easy to keep src/img directories in sync with main repository
- Keeping markup in sync slightly harder
PHP
- PHP 5.4.0 includes webserver (no apache setup needed)
-
I use phpserver dotfile function (http://dotfiles.github.io/)
# Start a PHP server from a directory, optionally specifying the port
# (Requires PHP 5.4.0+.)
function phpserver() {
local port="${1:-4000}"
local ip=$(ipconfig getifaddr en4) #ensure correct interface with ifconfig
sleep 1 && open "http://${ip}:${port}/" &
php -S "${ip}:${port}"
}
Grunt
-
Compass
-
LiveReload
-
RequireJS
-
Webfont
Styling
Modules!
Current Sass file breakdown
- 3 Utility
-
14 Generic
-
2 Interfaces
-
51 Modules (!)
-
5 Pages
Functions
Units/Typography
My brain doesn't work in ems/rems/ratios
@function em($target, $context: $font-size) {
@return ($target / $context) * 1em;
}
@function rem($target, $context: $font-size) {
@return ($target / $context) * 1rem;
}
@function lh($target, $context: $font-size) {
@return $target / $context;
}
// Global variables set in _config.scss: $font-size: 16px;
// Example
.example-selector {
font-size: em(22px);
line-height: lh(50px, 22px);
margin-bottom: em(20px, 22px);
}
Functions
Grid
- We're (sort of) not using one
-
Found I was overriding grid styles more often than not
- Really I just wanted something to calculate width
@function cw($columns, $context: $font-size) { @return ($columns * em($width-column, $context)) + (($columns - 1) * em($space-s, $context)); } // Global variables set in _config.scss: $font-size: 16px; $space-s: 20px; $width-column: 60px;
// Examples .example-selector { width: cw(8); } .example-heading-selector { font-size: em(22px); max-width: cw(6, 22px); }
Mixins
Breakpoints
- Included inside selectors
- Works great with modular approach
- Also great with cw function
@mixin bp($point) {
@media (max-width: ($point + em(2 * $space-s))) {
@content;
}
}
// Global variables set in _config.scss: $space-s: 20px;
// Example
.example-selector {
position: absolute;
@include bp(cw(6)) {
position: relative;
}
}
Priorities and alternatives
Got the idea from mailchimp
Use classes to denote (and style appropriately) element variations in a similar manner to heading tags h1 to h6
More important elements have a higher priority, variations within priority levels are alternatives
<button class="p1">Buy now</button>
<button class="p2">Not so important button</button>
<button class="p2 a1">Not so important button variation</button>
Alternative classes became my default go-to class name
JavaScript
jQuery
Old-school server-side rendering
Tried a few different approaches: Angular, JSON api with Mustache templates
Settled on server side rendering of page templates progressively enhanced with JavaScript because Colony is all about the content
Twitter found it cut load times to 1/5th:
https://blog.twitter.com/2012/improving-performance-on-twittercom
URLs point directly to the right content, Paul Irish talked about the effect of Imgur using JSON APIs on their (slow) page speed in Fluent 2014 keynote:
Data behaviors (are awesome)
Technique I got turned on to when working at AREA17
- JavaScript functionality split into separate 'behaviors' (carousel, slider, asset)
- Behaviors linked to markup by data-behavior attribute
// Example markup
<div class="asset-bucket" data-behavior="slider">
<h2 class="heading-p4">Video & Audio</h2>
<div class="items assets">
<div class="item-wrapper">
<a href="/pages/companion-explore-vod.php" class="item asset" data-behavior="asset">
...
</a>
I put it into the AMD pattern for RequireJS:
Data behaviors
Pub Sub
- Sometimes behaviors need to talk to each other
-
Behaviors loaded in the order they appear in the markup not necessarily the order you want/expect
- Want to keep things modular and loosely coupled
- Pub Sub pattern is essentially custom events
- 'Topics' (names of the events) are published when you want to notify the app that something has happened/something should happen
- Can optionally pass associated data
- I used jQuery Tiny Pub Sub (12 lines of code)
// asset.js: In asset behavior, it's possible to hit the paywall instead of getting the asset
$.publish('/paywall/hit', data);
// paywall.js: In paywall behavior we subscribe/handle the topic, call displayPaywall
function handleTopics() {
$.subscribe('/paywall/hit', function(e, data) {
displayPaywall(data);
});
}
Animations
- Tested animations using jQuery, GSAP, CSS
- jQuery worst frames per second
- GSAP and CSS comparable
- Settled on CSS with no fallback
- Already using CSS transitions throughout the site
- Less JS overhead
- Not without problems (Chrome sub-pixel bugs)
Further information
- Platform templates repository: https://zonecode.codebasehq.com/projects/colony/repositories/colony-templates-platform/tree/master
- Includes (very detailed) readme.md
Fin
Building the interface for wearecolony.com
By Sam Loomes
Building the interface for wearecolony.com
- 1,244