The basic idea behind putting round indicators on the side of a web page, is to give a hint to the user about the number of sections she/he can go through. We think of each dot as a content chapter, with its own title. Usually, users have to hover over a dot to access the title.

In an attempt to simplify this pattern, we decided to transform the dots when the user interacts with them, by scaling them up and showing an icon + label. Users don't need to select a specific dot/item, but just move to the side, thus showing their willingness to access the navigation.

Here is a quick preview of the final result (created using After Effects):

Vertical Fixed Navigation #2

Adding style

On small devices (viewport width smaller than 800px), we set a position: fixed for the .cd-nav-trigger and nav elements and placed them at the bottom-right corner of the page; we then scale down the navigation, using the bottom-right corner as transform origin.

When user clicks on the .cd-nav-trigger element, we give the .open class to the navigation to change its scale value from 0 to 1, with a CSS3 transition to achieve a smooth animation.

On bigger devices, we use Modernizr to detect touch and no-touch devices (using .touch and .no-touch classes).

On touch devices, the lateral navigation items (labels and icons) are visible by default, while on no-touch devices they are shown when the user hovers over the lateral navigation.

We set a fixed height and width for the nav element, and place it on the right side of the viewport. We use its ::before pseudo-element to create the navigation background; on no-touch devices only, the ::before element is, by default, translated to the right (outside the viewport) and is moved back to its original position when the user hovers over the navigation. The same happens for the span.label elements.

To create the navigation item icons and dots, we use, respectively, the ::after and ::before pseudo-elements of the navigation anchor elements (a). On no-touch devices only, the ::after and ::before are scaled down by default and then scaled back up when the user hovers over the navigation.

Now the tricky part: when the navigation dots are scaled down, they are too distant one from the other. We can reduce this distance translating them along the Y axis.

Let's start from the central dots (in our case, the second and the third); we want to translate down the second one (so we have to use a positive translate value), while we want to translate up the third one (so we have to use a negative translate value). In our case we have:

If you have a different number of navigation items, you have to change these translate values accordingly. For example, if you have six items, starting again from the central dots (in this case, the third and the fourth), you can assign them a translateY value of 1.5 em/-1.5em; then to the second and the fifth a translateY value of 4.5em/-4.5em (3*1.5), and finally to the first and sixth a translateY value of 7.5em/-7.5em (5*1.5).

If you have an odd number of items, let's say 5, you do not translate the central one (in this case the third one). You then assign a translateY value of 3em/-3em(2*1.5) to the second and the fourth dots, and finally a translateY value of 6em/-6em(4*1.5) to the first and fifth dots.

Events handling

When user scrolls through the sections, the updateSections() function evaluates which section is currently being viewed and assigns the .activebutton.cd-nav-trigger to open/close the navigation on small devices.

Tuesday, January 05, 2016

If you are not using Gulp or any task runner, believe me when I say that you are missing out on all the front-end fun stuff. Today, I intend to share my advanced Gulp based automatted workflow for building WordPress themes, with the community.

I remember the time when I had to minify CSS and JS files, compress the images and the fuss of testing my designs across different browsers let alone devices — oh my. If my recollection of lost isn't misleading me then I used to spend like 30% of my productive hours on this stuff.

Thankfully, someone wrote a piece about DRY (Don't Repeat Yourself) and it got me thinking about the flaws in my workflow. I believe a tweet from Chris Coyer led me to start using Grunt in 2012 or a little later. I used it for over a year and boy it was a fun ride.

Why Gulp?

While Grunt took care of optimizing images, compressing scripts, and compiling Sass, I never really enjoyed writing Grunt files. Then in Dec 2013, I heard about this new task runner called Gulp. On a Sunday morning, I thought to create a dummy project and try Gulp, to say that I was hooked would be an understatement.

Why Do I Like Gulp?

At that time, there was hardly any documentation available for using Gulp with WordPress, but thanks to the awesome helping community at Stack Exchange, I was able to make it work. I found Gulp to be a lot better than Grunt. Here is why:

Gulp is faster than Grunt (One of my theme's compile time went from 12secs to 300ms)

Gulp is intuitive and gets 20K-25k downloads a day, which is equal to or great than Grunt downloads

Gulp's code-over-configuration makes it not only easy to write tasks for, but also much easier to read and maintain

That said, let's leave the story for now and see what it is like to be using Gulp with WordPress.

Do I Need to Use Gulp?

Are you a web developer? Do you program in HTML/CSS sometimes?

— Yes!

Did you ever use a task-runner? Feel like you belong to the stone age while all the crazy kids in town are using awesome advanced workflows?

— Yes! :(.

OK! let's get you started then.

Since this article is about an advanced Gulp based workflow, explaining how to do basic Gulp related stuff is out of the scope. But instead of leaving you (beginners) in the middle of nowhere, I'd like to suggest a few articles to help you get started.

If having a basic Gulp workflow is nothing new for you, then maybe you'll enjoy reading my advanced gulp workflow.

Advanced Gulp WordPress Workflow

While building premium themes for WordPress, I end up with a lot of grunt work which includes:

Minifying & optimizing CSS with stylesheets and Sass

Custom JavaScripts and 3rd Party Scripts via Bower

Synced cross-browser design testing on different devices

Tunneling my localhost dev branch to a random public URL for public access

Building an installable zip theme file without any node modules, cache files or .Dot files data in it

Let's explore how I get all this stuff done with Gulp.

I have set up a Github repository called Advanced Gulp WordPress. You can check out the structure of files inside it for better understanding.

A Look at gulpfile.js

Now let's take a look at gulpfile.js which is present in the root folder of our theme. I will explain each task one by one to make it easier for you to understand. You'll find completed gulpfile.js at the end of this post.

Since I assume you already know how Gulp works, I will not be explaining how to put all the plugins/packages in package.json file and other basic setup related steps.

Step #1: Setting Up the Variables

First of all I am going to set up certain variables so that I don't have to change everything for every other theme I create. Let's review the code:

I used to have LiveReload in my workflow, which would reload the web page whenever a file gets edited and saved. But when Browsersync was introduced, it helped me cut down half of the shitty things I had to do in order to automate syncing between different browsers. Browsersync helps me with the following stuff;

Injecting CSS changes without any web page getting reloaded

Change the port and set up a tunnel through a random public URL, which means my teammates can access the dev branch live at my localhost in a matter of minutes

Synced testing across different browsers, where I open the given URL at my Desktop, Laptop, Tab, and mobile to test same features in a single go with synced scroll, clicks, form inputs, etc. Watch the video at Browsersync.

Step #4: Gulp Style Task

Let's take a look at the styles task I built. In this task, there is a lot going on. We are compiling Sass, creating minified CSS and optimizing media queries.

L#9: Here I provided the source of Sass file, which is a style.scss file present at ./assets/css/style.scss

L#10: Initiated plumber to avoid pipe breaking due to minor CSS errors when I save a file

L#11: Sourcemaps got initiated. A source map provides a way of mapping code within a compressed file back to its original position in a source file. This means that – with the help of a bit of software – you can easily debug your applications even after your assets have been optimized. The Chrome and Firefox developer tools both ship with built-in support for source maps.

L#12 – L#20: Sass is being compiled in compact format, you can read about Sass formats here

L#23: I am prefixing CSS with autoprefixer. The legacy browsers which should be supported are mentioned inside the arguments array

L#26: Here I have saved the final compiled CSS file for our WordPress theme in the root directory. Since style.scss was being compiled, the output will be style.css file. Now all you need to do is make sure you use a "!" in the comments at the top of the style.scss file so that, even when the compiling/compressing happens, the comment remains: i.e. /*! Theme Name: Your Theme etc... */

L#27: I filtered all the .css files in the root directory, which at the moment is one style.css file

Step #7: Building a Clean Installable Theme Zip File

This is a group of tasks which are responsible for creating a clean copy of installable theme zip file. Take a quick look at the code. There is nothing much to it, it is all basic copy pasting and deleting or ignoring of files/folders.

buildImages: Task to build and copy the final set of images to the buildTheme folder

buildZip: Task to create an installable Zip file of the buildTheme folder

build: Main task which runs styles task to compile CSS then cleans up everything with a cleanup task. After that, it runs all the scripts related and build related tasks and a final cleanup task at the end to produce a theme zip file via buildTheme folder.

Step #8: Watch Task

Finally, there is a watch task which helps in automatically running the styles, scripts, images and browser-sync related tasks in case of any change that occurs in the below-mentioned folder.

Tuesday, October 27, 2015

Lately I've spent more time than usual using the Chrome Developer Tools. Along the way I found a couple of nice features that I had previously missed (or at least hadn't needed enough to look for; e.g. blackboxing and asynchronous stacktraces). Because of this, I wanted to summarized a few of the features that I really like about devtools.

1) The little magnifier glass icon that shows you which CSS class/selector in what CSS file that ultimately decides the styling for a specific element and CSS property. For example, select "inspect" on any DOM element and then switch to the "Computed" sub-tab to the right. Find the CSS property you're interested in and clicking the magnifier icon takes you straight to the correct CSS class/selector in the right .css file (very useful when you start out working on a new large web app):

2) To see what XHRs the web app sends while you're using it, check the "Log XMLHttpRequests" checkbox under "Settings" and keep an eye on the console tab. Before I knew about this, I would set up my browser to go through an HTTP intercept proxy like Burp suite but this more convenient if you just want an quick overview. Of course, with an intercept proxy you also get the opportunity to modify the XHRs before they reach the server, which is really nice for security testing. A lightweight alternative to that is to look under "Sources :: XHR Breakpoints" and activate the "Any XHR" breakpoint.

3) Now, suppose that the web app you're working on is making some XHR at a regular interval (for example, keeping the current view up to date) and you would like to know where this timer is setup (i.e. where the call to setTimeout() or possibly setInterval() is made). To figure this out, you switch to the "Sources" tab, and check the "Async" checkbox. This will make all your stacktraces continue beyond setTimeout() and friends, even multiple levels deep. It does the same thing for requestAnimationFrame() and addEventListener() and a few others too. You'll find the checkbox here:

4) To quickly find the code that runs when you click a particular button or link is clicked, activate an "Event listener breakpoint" for Mouse :: Click just before you click the particular button (another killer feature when starting out work on an existing large web app):

5) When you use "Event listener breakpoint :: Mouse :: Click" you might end up in a third-party library like jQuery at first, and so you'd have to step a few times in the debugger to arrive at the "real" event handler. A great way to avoid this is to "blackbox" the third-party script. The debugger will never stop inside a blackboxed script, instead it continues to run until it reaches a line that isn't in a blackboxed file. You can blackbox a script by right clicking the filename of the third-party library in the callstack and the selecting "Blackbox Script" from the context menu:

6) You can jump to a specific file, by name, using ctrl-p (just like in atom):

7) You can jump to a function, by name (but only in the currently open file), using ctrl-shift-p:

8) You can search through all files using ctrl-shift-f:

9) You can edit using multiple simultaneous cursors by selecting some word and then pressing ctrl-d a few times to select more instances of that word (again, just like in atom). Very nice for renaming variables:

10) When working on a website stored locally it's possible to edit files in devtools and save the changes directly to disk. To do this, switch to the Sources tab, right click on the Sources sub-tab and select "Add Folder to Workspace" and then finally select the local folder where your project is located. After that, right click the local copy of some file in your site and select "Map to Network Resource..." and then select the corresponding "network" file:

Other handy tips include:

$0 in console is the element you selected in the elements view.

You can evaluate XPath expressions using $x("//p") (very useful if you're writing selenium testcases and CSS selectors doesn't get you all the way).

I also recommend that you install two Chrome extensions:

JSONView will indent and syntax highlight JSON blobs for you (and even allow you to expand/collapse blocks). It also makes URLs inside JSON clickable which often makes it possible to explore a JSON-based API via the browser. For example, try navigating to http://omahaproxy.appspot.com/all.json before and after you install it (better formatting) and also https://api.github.com/ (clickable URLs make it easier to explore the API).

JS Error Notifier (non-"spyware" version) creates a popup each time a Javascript error is printed to the console. Unfortunately, the main version of this extension submits private “usage data” to a third-party service (see discussion in issue #28). But at any rate, this extension has helped me notice and fix several bugs.

All in all I really like devtools, the only annoying thing that I can think of is that you cannot customize keybindings:

Thursday, October 22, 2015

Monday, October 19, 2015

Since I started my career on the web, I've been building websites that follow standard grid layouts. It got to a point where I was telling an intern at my company that developers think in rectangles. I mean, there's nothing wrong with rectangular layouts. They're like your mom's Volvo, steady and reliable. But sometimes, it's fun to try something different. I'm lucky enough to work with some awesome designers, and for a new project, they came up with a diamond-based grid layout. Well then, challenge accepted. (•̀o•́)ง

Tuesday, October 13, 2015

Writing asynchronous code is hard. When it comes to JavaScript we rely heavily on callback functions to accomplish asynchronous tasks which can be unintuitive. This cognitive overhead creates a barrier to entry for newcomers to programming and the language and even causes frequent heartburn for those of us who have been using the language a while.