Blog Posts
If you've managed to mingle with defunkt's the push state ajax, you've already seen the amazing performance enhancement that comes with it. I use it almost religiously in my apps now, and it's fantastic. But there are a few things I had to roll up on my own to make an even greater quality user experience. Hence, in this quick blog post, I will spit out a few of my code snippets I've used to make GitHub-like pjax transitions.
By the way, I've been using Coffeescript for so long that I will force it on my readers mainly because of laziness and because you really ought to be coding in Coffescript. Its never too early to start. ;)
The StatesPjax is great, kudos to Chris Wanstrath. It is so great, that these transitions only took me a second to figure out thanks to his implementation of pjax custom events:
pjax_view.on 'pjax:beforeSend', () -> pjax_view.on 'pjax:start', () -> pjax_view.on 'pjax:success', () -> pjax_view.on 'pjax:complete', () -> pjax_view.on 'pjax:end', () ->These states are basically ajax setting functions and can be used to trigger certain events at different points of the pjax requests. Keep reading...
The CodeSo the first thing I did was to prepare my DOM elements on the beforeSend event and slide them as needed.
$(document).on 'pjax:beforeSend', (event) -> prep_transition ( $( event.relatedTarget ).data('animation') ) sec = $('.js-section').clone() display_spinner()I basically slide the section out of the page (or view) and display a loading .gif spinner while I wait for the animation to be over ( I also set the animation type ('forward' or 'backward') in the link's data attribute).
This is how my prep_transition function looks like. My default transition is just a fadeOut/fadeIn.
prep_transition = (anim) -> switch anim when 'forward' $('.js-section').animate( { 'right' : '100%', 'opacity' : '.5' }, '350') when 'backward' $('.js-section').animate( { 'right' : '-100%', 'opacity' : '.5' }, '350') else $('.js-section').fadeOut 'fast'This is my display_spinner function.
display_spinner = () -> t = setTimeout ( -> $(' <div class="ajax-loader" style="display: none;">').appendTo('.js-content').fadeIn 'fast' ), 250Next, I perform the animation when the request completes. Clear timeout, handles the spinner timeout. Remember to set your t var as global.
$(document).on 'pjax:success', (event) -> clearTimeout(t) display_spinner() choose_animation( $(event.relatedTarget).data('animation') )Choose_animation function looks like this. Again, default animation will be a fadeIn/fadeOut.
choose_animation = (anim) -> switch anim when 'forward' transition_forward() when 'backward' transition_backward() else default_transition()Now the real animations actually need to be defined. A default transition (like mentioned before) will fade in and fade out the section:
default_transition = () -> $('.js-section').fadeIn 'fast', () -> clearTimeout(t) $('.ajax-loader').fadeOut 'fast'The Forward and Backward animation are (as expected) very similar, except that they move the DOM elements in different directions. The animation basically sets the opacity of the js-section div to 0 and animates it it out of view on the beforeSend event. After this, js-section's css is set to be on the opposite side of the page (still out of view) and the opacity is set back to 1 as we reset the spinner timeout and slide it in from the new position back into view.
transition_forward = () -> $('.js-section').css { opacity: 0, right: '-100%' } $('.js-section').animate right: '0px' opacity: 1 , duration: 350 easing: 'easeOutCirc' complete: () -> $('.ajax-loader').fadeOut 'fast' clearTimeout(t)Like I mentioned, the backward transition is similar:
transition_backward = () -> $('.js-section').css { opacity: 0, right: '100%' } $('.js-section').animate right: '0px' opacity: 1 , duration: 450 easing: 'easeOutCirc' complete: () -> $('.ajax-loader').fadeOut 'fast' clearTimeout(t)Notice I am using jQuery easing to give the effect a more organic look.
And that is it! You have now a github-like pjax transition. Just remember that wherever your js-section class is contained the wrapper is set to overflow hidden.
Today I ran into the need of making an iOS-like checkbox like those seen on the iPhone settings panels, and realized that no one really made a simple (free) plugin for it.
What I found is plugins such as Thomas Reynolds'. He made a plugin much more intricate than what I really needed and it is not free for commercial use.
So I made a public repo of my plugin which I called iCheckBox.js with a sample page and some simple styling for anyone to have at it. Enjoy. ;)
Here is the hosted sample page to see the results and documentation.
Edit: After writing this, I came across Compass. It is exactly what I started doing on my own with SASS but more complete. I suggest taking a look at it, very impressive and clean.
If there is one thing that makes CSS more bearable to program with and easier to modify is SASS or SCSS. This stuff is great: Nested classes, Variables, Extensions and my favorite feature: mixins make front end development less painful and a whole lot more efficient. How? I will list a few of my preset tools I use everyday for any project.
VariablesWhen I first heard of SASS/SCSS, I was reading an article bashing on the concept of having variables in CSS. The argument was that if you are using variables, you are not writing a well structured cascade. Classes should be as generic as possible and each sub-class should be able to inherit and override any re-applied attributes, thus limiting the repetitiveness.
But variables in CSS are so much more than simply re-use of values. They can be easily stored in a vars.css.scss file (if you have more than one CSS file per module) and can be accessed easily if any changes need to be made to the entire site. I even go as far as making preset values and commenting the different variations of values set to specific elements. This way I can easily switch from one theme to another by simply removing comments out of one block and commenting the others. For example:
// Daylight $text_color: #FFF; $oreground: #000; // Nightlight /* Uncomment block to apply $text_color: #FFF; $foreground: #000; */ body { background: $foreground; color: $text_color; } Nesting and ExtensionsOnce I realized how much more effective and easier to comprehend CSS gets when you code in nested classes that follow along your HTML (or even better: HAML!!), I established that I will never code plain old CSS again. Nested classes are just what they sound like, and extensions are just what you would expect if you have programmed in C++ or a similar language before. Seriously, we should all be saying f$@k CSS!!
Extending and nesting classes example:
.simple-box { // Apply a simple border and styling border: 2px solid #CCC; color: #ECECEC; background: #353535; // Nest in an h1 style only for this box .h1 { font-size: 2em; color: #FAFAFA; } } .round-box { @extend .simple-box; // we have inherited the class 'simple-box' // apply styling specific to round-box border-radius: 5px; } Mixins: Saved the best for lastMixins are the answer to my prayers. How freaking awesome would it be to call a function that applies certain styles to your CSS element? Better yet, with that once simple line of code, make it so the styling is as browser compatible as possible. This is where mixins come in. Below I will list out a few of my home-cooked mixins that I put to use quite often.
Note: once you have a mixin defined, just call it inside a class with:
@include mixin-name( parameters );Ellipsis:
@mixin ellipsis { overflow: hidden; text-overflow: ellipsis; }Cross-browser CSS3 animation:
/* include to element for CSS3 animations */ @mixin transition($sec) { -webkit-transition: all $sec ease-in-out; -moz-transition: all $sec ease-in-out; -o-transition: all $sec ease-in-out; transition: all $sec ease-in-out; }Cross-browser border radius:
@mixin border-radius($rad) { -webkit-background-clip: padding-box; /* fix WebKit background bleed on border-radius */ -webkit-border-radius: $rad; -moz-border-radius: $rad; -ms-border-radius: $rad; border-radius: $rad; }Cross-browser box-shadow:
/* Example: @include box-shadow(1px, 2px, 0px, 3px, #CCC); */ @mixin box-shadow($x, $y, $blur, $spread, $col) { -webkit-box-shadow: $x $y $blur $spread $col; -moz-box-shadow: $x $y $blur $spread $col; box-shadow: $x $y $blur $spread $col; }Cross-browser inset box-shadow:
@mixin inset-shadow($x, $y, $blur, $spread, $col) { -webkit-box-shadow: inset $x $y $blur $spread $col; -moz-box-shadow: inset $x $y $blur $spread $col; box-shadow: inset $x $y $blur $spread $col; }Cross-browser top-down linear gradient interpolation:
@mixin linear-gradient($gradnt1, $gradnt2) { background-image: -moz-linear-gradient(top, $gradnt1, $gradnt2); /* Firefox */ background-image: -webkit-linear-gradient(top, $gradnt1, $gradnt2); /* Safari */ background-image: -o-linear-gradient(top, $gradnt1, $gradnt2); /* Opera */ background-image: -ms-linear-gradient(top, $gradnt1, $gradnt2); /* IE */ background-image: -webkit-gradient(linear, left top, left bottom, from($gradnt1), to($gradnt2)); /* Chrome */ background-image: linear-gradient(to bottom, $gradnt1, $gradnt2); /* current standard, but unimplemented */ }Of course, the options are endless..
Viola! Easy, peasy non-cluttering cross-browser CSS calls of your favorite attributes. I hope this helps someone as much as me.
Because a simple Hello, World! seems monotonous and uninformative, I've decided to make use of my first blog post and spit out a few things about myself and what drives and motivates me to be, what I like to call, a creative developer.
Ever since my first years at the University of Florida studying Software Engineering, I love to tinker with Linux distros. I used to install and re-install Operating Systems like it was my job, trying on different settings and playing around with open source software. Since then, my passion for the culture grew, and I could not help but admire hackers such as Richard Stallman.
My curiosity and eagerness to learn, as well as my appreciation for the arts and easthetic computing, lead me to change routes mid-way through college, and I finnaly found my nitch under the Digital Arts and Science (DAS) programme at UF's College of Engineering. This programme stuck through the most rigorous core computer science courses that UF has to offer, and also allowed me to explore the digital arts realm. My knowledge of multi-media design, human-centered computing, and interaction and communication through computing grew as I enrolled in higher level courses.
I now like to partake in the challenge of making today and tommorow's ever-changing technology more reliable, responsive and beautiful for all of us to use. I am currently exploring the world of front-end development, which I find very intriguing and rewarding. With the plethora of new gadgets spitting out into the market each year, this industry keeps me at my toes and forever learning and fabricating solutions to new (and old) problems.

