Saturday, 29 October 2016

Web development and pressures

This is a post about the pressure that we put on ourselves as web professionals and what we can do to reduce it.

I have had a few jobs as a web developer since graduating in 2006. I spent nearly 6 years at Pearson Education, where I gained extremely valuable experience in front-end development, along with learning the ropes in gathering requirements, wireframing, SEO, testing and lots more. In June 2013 I joined the Digital department of a large global consultancy. I was very excited as I knew it would be a fast-paced and steep learning curve, but I was ready to take the next step in my career. In my first few months there, I quickly learned to use Git, SCSS, responsive design, Grunt, to name a few and I was working on exciting projects for big clients.

I remember a particular 1-2-1 I had in early 2014 with my line manager at the time. We talked about my interests, my possible career path and what I can do to continue my progress within the team and company. I mentioned that I was developing an interest in topics such as CSS architecture, SMACSS, BEM etc. He told me I shouldn't just be interested in them, I should know them off by heart by now. I also mentioned that I was constantly reading and researching other topics to broaden my knowledge and he pointed out that I "should be the person other people are reading about" rather than just regularly reading about web development.
At first, I felt I bit of confusion. I had always tried my best in everything I did, yet I felt that maybe I wasn't doing enough. I needed to be better, know more, do more, be that person that people read about. On the one hand, I was inspired and on the other, I was unsure as to what I should do next to quickly meet this goal. I had already signed up to a few email newsletters such as Responsive Design Weekly, CSS Weekly and HTML5 Weekly (now Front End Focus), but I decided to sign up for dozens more - Angular, JavaScript, Node, Web Design Weekly, and loads of others to boot. I was literally reading emails and articles in every spare minute to try and keep on top of the entire world of the web. Plus I had a Net magazine subscription so I was also reading that most days of every month. I was bookmarking everything using the Pocket app (highly recommended, by the way) and I was trying to read everything as soon as I saw it because if I didn't, I would fall even further behind.

But then, something dawned on me. There were too many frameworks, too many libraries, too many tools. And I was trying to be an expert in everything when, quite frankly, I didn't need to be and, quite frankly, I needed to take a little step back because I had a life outside of the office! I wasn't enjoying my web dev life any more - in fact I think I lost a bit of confidence in my abilities - and something needed to change.

I decided to continue bookmarking the articles and videos, but if I didn't read them immediately it didn't matter. They would still be there a few days or weeks later and I could still try them out in due course. I also decided to reduce the number of email newsletters I was subscribed to, because there were some I was reading just for the sake of it. I also noticed I was coming across more and more articles by other web professionals regarding the pressures of keeping up with the industry. So, it turned out I wasn't alone in how I felt.

The reason why I have written about my experiences is because, 2 years on, I am still regularly reading articles about fellow industry professionals feeling the same pressures. I read something the other day that stated that as a web developer, if you don't have side projects or make contributions in every opportunity of your spare time, you are not a good developer. Well, no wonder we are feeling so stressed about it all!
I'm not saying at all that you shouldn't have side projects etc but whether you do or don't shouldn't label you as a good or bad developer. And likewise, you shouldn't have to know everything about everything in web development to feel like you are up to date with the industry and doing your best in your job. Everyone has their own style, their own pace and their own personal situations outside of the office - but as long as you feel you are pushing yourself and developing yourself and your career, that is all that matters.

I think the way to reduce all this pressure is to make sure that we take a step back every once in a while. Sometimes I feel like reading dozens of articles in one go, playing around with libraries and tools etc. Sometimes I don't feel like it at all and I do something else to relax. And that's ok, because the web will still be here tomorrow and we can all still help to move it forward in our own way and our own time and we can still make a huge impact on the world we live in.

I hope you enjoyed this post - perhaps you agree with some/all of what I have written, or perhaps you disagree - I'd love to hear your thoughts! Tweet me at @theonico85 and don't forget to use #webdevgeekout!

Thursday, 1 January 2015

Refactoring My Website - Part 3

Happy new year! I hope you have enjoyed all your celebrations in the last couple of weeks.

I have recently been writing about my website refactor (see Part 1 here and Part 2 here) and now I have come to the end of the exercise I am just tidying up my build process - and I'm going to tell you about it in this post.

When we last looked at my Grunt file, it wasn't looking too shabby - it was compiling my SCSS files and watching for changes, and I had a nice OS X notification appearing whenever the tasks were successful or failing (take a look here). Today, I wanted to improve my build process further by implementing the following changes:
  • Automatically load any Grunt tasks to remove the need for "grunt.loadNpmTasks('');"
  • Concatenate the CSS files in the CSS folder
  • Minify the final CSS file used on the site
First I wanted to make sure I could concatenate my CSS files. I was quite surprised at how much trouble I had with this. I thought I could just use grunt-contrib-concat (spoiler: I did in the end) but whenever I ran my Grunt task, it just wasn't concatenating my files. I was running the Sass and Watch tasks as well so I removed them and just ran the "concat" task, which worked. So after a lot of cutting, pasting, searching on Google, trouble-shooting and starting again, I decided to try a test "concat" task alongside all of my other tasks:

concat: {
  css: {
    src: ['css/1.css', 'css/2.css', 'css/3.css'],
    dest: 'css/123.css'
  }
},

This would concatenate 1.css, 2.css and 3.css (three makeshift files I created) into a file called 123.css. Again, it didn't work. So I removed the Sass task and kept the rest and tried again - but still no luck. Then I put back the Sass task and removed the Watch task. Bingo! My files were concatenating! So for some reason the Watch task was stopping the concatenation. I then added a minification configuration using grunt-contrib-cssmin which was pretty simple, and added a "clean" task so that my final "tn.css" or "tn.min.css" would be deleted and recompiled accordingly. At this point I created two Grunt tasks; one for developing (which included the Watch task) and one for building (which did not, and  included concatenation and minification):

grunt.registerTask('develop', ['clean', 'sass', 'watch', 'notify_hooks']);
grunt.registerTask('build', ['clean', 'sass', 'concat:css', 'cssmin', 'notify_hooks']);

In hindsight it made more sense to do this anyway as I don't need to watch my files when I have deployed my final files. I also don't need to concatenate and minify my files during development.
Finally, I modified my Grunt file slightly so that all Grunt tasks are loaded in automatically (using load-grunt-tasks).

I have created a repository for my Grunt file, called basic-grunt-toolkit. I will be improving it over time and I am also planning an advanced Grunt file as well which will utilise Bower along with some other useful Grunt plugins. I hope you find these resources useful - please feel free to fork and use them for your own projects!

Wednesday, 24 December 2014

Refactoring My Website - Part 2

In Part 1 of my website refactoring process, I looked at the overall state of the code in my website and considered some changes and improvements that I could implement without a huge amount of time and effort. I set up a Grunt file and started the process by changing my CSS files into SCSS files so that they can be generated by running the "grunt" task.

In this post, I will talk about how I continued the CSS/SCSS refactor and improved my Grunt file as I worked.

So, my to-do list was as follows:
  • Turn CSS into SCSS (done)
  • Split CSS into SCSS partials
  • Consolidate duplicate CSS properties
  • Change element selectors into classes
  • Nest selectors
  • Use variables
  • Use mixins for projectlistitem selectors? e.g. projectlistitem-UKC
  • Remove /*/mediaquery*/ hack from mediaqueries file (not sure what this is, perhaps it was to support IE7?)
  • Adjust breakpoints (905px and 1105px??)
  • Try to write code mobile-first i.e. no need for small-screen media queries
  • Move media queries into classes or within partials
Split CSS into SCSS partials
Before I even opened up my favourite text editor (for this I am using Coda but I do like Sublime Text 2 as well), I opened my website in a browser, viewed the source and printed the CSS files (tn.css and tn-mediaqueries.css). I then spent around an hour scribbling notes on the printouts, looking for duplicate properties, thinking about the use of element selectors and specificity and how they can be amended/removed, highlighting potential variables and mixins/placeholders. I also concentrated on grouping the CSS as per Jonathan Snook's SMACSS guidelines which I am a huge fan of. It is suitable for small sites as well as large ones so I wanted to give it a go and see how it works for me.
 

I really liked the method of printing out the code and looking at it away from the computer. I found it easy to flick through the pages and check the different CSS, and it helped to make everything clear in my mind as I hadn't really looked at the CSS for quite a few years. I also felt it was a good warm-up to the main event of re-writing my code.
From my notes and scribbles I could see my files and folders within the "scss" folder would look something like this:


/base
> normalise.scss
> base.scss
> helpers.scss
> variables.scss
> mixins.scss (perhaps)
> placeholders.scss (perhaps)

/layout
> layout.scss

/modules
> header.scss
> navigation.scss
> breadcrumb.scss
> projectlistitem.scss
> footer.scss
...

/theme
> fontawesome.scss (might move this into modules)

I started to cut and paste the CSS from my tn.scss file into partials, and imported them using "@import" in "tn.scss". At this point I wasn't bothered about what would happen to my mediaqueries file as this would be dealt with in due course. I also took the opportunity to update my Gruntfile so that it watched for any changes in the "scss" folder, using the Grunt Watch plugin:

watch: {
        css: {
          files: ['scss/*/*.scss'],
          tasks: ['sass'],
        },
    },


and I set up my Grunt OS X notifications to save having to toggle to my Terminal window all the time:

notify_hooks: {
   options: {
     enabled: true,
     title: "Grunt tasks completed",
     success: true,
     duration: 5

    }
}


At times, I noticed that the Grunt notifications weren't displaying and when I checked the Terminal, it hadn't picked up changes to my new partials. I'm not sure why this was happening, but to check that the new tn.css file was being generated correctly I added a comment at the top of every partial:

/**** filename.scss ****/

This allowed me to quickly check the new changes were in the CSS file. I also found that quitting out of Terminal every now and then helped too. Again, no idea why...you can see the updated Gruntfile here. For now, I was happy with this; I could concentrate much more on the SCSS itself with the knowledge that some of my workflow was being dealt with separately.

Next, I moved on to changing the colours into variables. This was quite a good exercise as I had colours scattered throughout my partials, so I was able to briefly review the existing CSS code whilst swapping the hex's for variables. At this point it became apparent that I was using very similar colours throughout the site; #CCC, #DDD, #E2E2E2 - so I quickly compared them in Photoshop and where possible I tried to consolidate my colours.

Then came the fun part: improving the CSS proper, and making the changes to the markup. I made some placeholders for the common properties (e.g. used for h1, h2 headings), I changed all ID's to classes and I made sure I was no longer targeting element selectors i.e. I changed them into classes as well. I also changed any long CSS properties to short-hand to minimise the amount of lines in the CSS. Finally, I removed the now-deprecated <hgroup> element (in the Portfolio main page) and replaced it with <section class="...">.
Afterwards, I moved on to the media queries - I moved them inline within the partials files (therefore the link to the tn-mediaqueries.css file in every page would not be required) and I modified them so that the CSS is written from a mobile-first perspective. You can see a (mostly final) version of my SCSS files and Gruntfile here.

My next task will be to beef up my Gruntfile a bit more - but I'll leave that for another day (it is Christmas Eve after all!)

I hope you found my post useful and hope to see you for the next one!

Tuesday, 16 December 2014

Refactoring My Website - Part 1

It has been a while since I built my personal website, theo-nicolaou.co.uk. My main aim at the time was to keep it simple - updates had to be quick and easy, and I felt the design could be relatively simple too. I just wanted to be able to showcase my work and use the site as a mini-playground for experimenting and learning things like HTML5 and responsive design.

A few years down the line and the requirements haven't really changed. I'm happy with the design overall (although I might tweak it slightly in due course) and it is still pretty easy to update considering it is built by hand - adding a new item of work to the site, including preparing the images in Photoshop, takes no more than 30 minutes. However, the code behind the scenes is a little outdated so I thought I would take the opportunity to spruce it up a little and continue with the experimentation and learning. I have also been planning to create a basic Grunt file to eventually use in future projects - I thought I could get started on this by writing it in the context of my website.

This blog post is one in a series detailing how I went about my website refactor.

For reference, my website currently links to two CSS files - tn.css and tn-mediaqueries.css and a few JS files such as respond.js and HTML5 Shiv. My main focus to begin with will be the CSS files. As you can see, there are quite a few changes which I could make. Overall they wouldn't take a huge amount of effort but they would help improve the scalability and maintenance of the code:
  • Turn CSS into SCSS
  • Split CSS into SCSS partials
  • Consolidate duplicate CSS properties
  • Change element selectors into classes
  • Nest selectors
  • Use variables
  • Use mixins for projectlistitem selectors? e.g. projectlistitem-UKC
  • Remove /*/mediaquery*/ hack from mediaqueries file (not sure what this is, perhaps it was to support IE7?)
  • Adjust breakpoints (905px and 1105px??)
  • Try to write code mobile-first i.e. no need for small-screen media queries
  • Move media queries into classes or within partials
I could probably review the names of the classes themselves, but I'll see how it goes after I finish everything else.
The Grunt file could include the following plugins:
  • SCSS compilation
  • Watch
  • LiveReload
  • Image Optimisation 
  • OS X Notifications
And then if I wanted to extend it further, perhaps I could add these:
  • Concat
  • Minify
  • Lint
First, I wanted to set everything up and make sure everything was working. I had to install Node.js on my Mac (and NPM, but Node.js includes this anyway), and then install Grunt. After that, my first milestone would be to convert my CSS into SCSS files, and then set up the Grunt file to compile back into CSS.

So, let's get started!
  1. To install Node, go to http://nodejs.org and click "Install".
  2. Then, run the following command to make sure you have the latest version of NPM:

    sudo npm install npm -g
After I installed Node and NPM, I moved on to setting up Grunt and the package.json file that goes with it. More details can be found all over the internet, mainly on the Grunt website but also I do like this tutorial alot.
I set up my package.json file by running the following command in Terminal:
npm init
This presents a series of basic questions to help set up your package.json file.

Then, I ran the following command to install the Grunt Command Line Interface (Grunt CLI). This will allow you to use Grunt wherever you like your machine:
sudo npm install -g grunt-cli

Finally, I created an empty Gruntfile.js in the root of my project. With the very basic foundations in place, I moved on to installing the Grunt plugins which would enable me to compile SCSS into CSS. All the plugins are installed using the command "npm install <plugin>". Top of the list was Grunt itself. I know, a bit odd that you need to install a Grunt plugin to use Grunt, when you have already installed the Grunt CLI. But, whatever...
npm install grunt --save-dev

When the first Grunt plugin is installed, a "node_modules" folder is created in the project root. Inside this folder are the relevant files for the Grunt plugins themselves.

Next I installed the Grunt Sass plugin (to compile SCSS into CSS). In addition to this, I installed the Watch plugin (to trigger compilation when any specified file types are modified), an image optimisation plugin to compress all my images, and the OS X Notifications plugin (because it is cool). I wanted to use the LiveReload plugin (because manually refreshing your browser is *so* last year) but I found out that it has been deprecated and the functionality moved into the Grunt Watch plugin.
npm install grunt-contrib-sass --save-dev
npm install grunt-contrib-watch --save-dev
npm install grunt-image --save-dev
npm install grunt-notify --save-dev
Wow. I know what you're thinking: all this and still not anywhere near the CSS yet! Never fear, we're not far off the first milestone. I copied my two CSS files, saved them in a folder called "SCSS" and renamed them to "tn.scss" and "tn-mediaqueries.scss". Then, in my Gruntfile.js I added the configuration so that it would look at the specific SCSS files and compile them into the CSS files (with names that I specify). The Grunt file can be found here.

You'll notice that the file does not include any configuration for the other plugins - I will configure these and explain how I did this in a future post. For now, that's it - the ball is rolling on my website refactor project. I hope you enjoyed reading this post and I hope you will come back to read the next in this series, where I will continue with the code cleanup and the Grunt config.

Monday, 27 October 2014

Lists, pseudo-elements, Chrome and jQuery

I recently worked on a project where I needed to find a way of displaying an ordered list with customised numbers. When clicked, each list item would display a different image on the page and any other images would then be hidden. The list item would also then have an "active" state i.e. the text would display in a different colour and the list number would also display with a different colour. I didn't want to use background images with numbers for the ordered list items as we didn't know how many would be displayed at any one time, so this would not be a scalable solution.

I used this tutorial by Treehouse as a basis for how to display my customised ordered list - I won't go into detail about how to do this here. However I will point out that instead of using the ::before pseudo-element, I used :before to allow support for IE8.

I am writing this post to explain how I got around some of the issues I encountered. Note some elements in the code (such as class and variable names) are ficticious.

My markup looked something like this:
<ol class="list-container">
  <li>Lorem ipsum 1</li>
  <p>Paragraph ipsum 1</p> 
  <li>Lorem ipsum 2</li>
  <p>Paragraph ipsum 2</p> 
  <li>Lorem ipsum 3</li>
  <p>Paragraph ipsum 3</p>
  <li>Lorem ipsum 4</li>
  <p>Paragraph ipsum 4</p> 
</ol>
<div class="image-container">
  <ul>
    <li><img src="images/image1.png" alt=""/></li>
    <li><img src="images/image2.png" alt=""/></li>
    <li><img src="images/image3.png" alt=""/></li>
    <li><img src="images/image4.png" alt=""/></li> 
  </ul>
</div>

and my SCSS looked something like this:
.list-container {
    list-style-type: none;
    list-style-position: outside;
    counter-reset: li;

    li {
     ...
      &:before {
          position: absolute;
          top: -5px;
          left: -2em;
          width: 2em;
          display: block;
          margin: 0 10px 0 0;
          font-size: 110%;
          line-height: 44px;
          color: white; //set colour of ordered list number to white
          text-align: center;
          content: counter(li);
          counter-increment: li;
          @extend .sprites-list-bg-yellow; //use compass to generate sprites
      }
      &.active {
        &:before {
          @extend .sprites-list-bg-blue; //use compass to generate sprites
        }
       ... 
     }
Using a small amount of jQuery, I added some slide transitions for when the list items were clicked.
My jQuery looked something like this:
(function($) {
  $(document).ready(function() { 
var $myList = $('.list-container li');
var $myImage = $('.image-container li'); 
// Show first list item and first paragraph as active on page load.
    $myList.first().addClass('active').next('p').show();
    // When any list item is clicked...
    $myList.click(function() {
      var $thisPos = $(this).parent().children('li').index($(this));
      if (!$(this).hasClass('active')) {
        // ...hide any list item with class "active".
        $myList.removeClass('active').next('p').slideUp('fast');
        // ...and slide down the paragraph under the clicked list item.
        $(this).addClass('active').next('p').slideDown('fast');
        // Show the corresponding image.
        $myImage.hide().eq($thisPos).show();
      }
    });  
})(jQuery);
This pretty much met the design. However, when I tested (in IE8, IE9, Chrome, Firefox and Safari), I found that a couple of browsers weren't playing ball.

Chrome and IE8 both had trouble displaying the list once any of the items had been clicked on. In IE8 the list items seemed to slide on top of each other (almost like they needed a clear: both or something like that) and in Chrome the numbers in the :before looked like they were being sliced in two. Safari and Firefox were fine (of course).
I searched online and immediately found myself reading post-upon-post about jQuery and Chrome and artifacts on the screen.


After quite a bit of head-scratching I decided to refactor my SCSS in the :before pseudo-element. I commented out all of the properties and added them back one by one, to see what would happen. I started with the "position" attribute - when I changed its value to "relative" the list items moved out of alignment relative to their :before elements BUT when I clicked on them, I could see straight away in Chrome that the slicing bug was no longer happening. So I continued refactoring and debugging, and found that setting position to "absolute" indeed was the root of the problem. Switching it to "relative" also solved the IE8 issue where the list items were sliding on top of each other.

My finished SCSS for the :before element turned out to be something like:
&:before {
  position: relative;
  top: 1.3em;
  left: -2.4em;
  width: 2em;
  display: block;
  margin: 0 10px 0 0;
  font-size: 110%;
  line-height: 44px;
  color: white; //set colour of ordered list number to white
  text-align: center;
  content: counter(li);
  counter-increment: li;
  @extend .sprites-list-bg-yellow; //use compass to generate sprites
}
So the lesson here is, as always, test whatever you build. Even modern browsers such as Chrome could possibly have issues displaying simple functions performed by a modern library such as jQuery.

Tweet me (@theonico85) with your thoughts - don't forget to use #webdevgeekout!

Wednesday, 1 October 2014

Learning JavaScript, localStorage, JSON, etc...

At the beginning of this year I decided to focus on improving my JavaScript knowledge. I used a combination of online resources (www.codecademy.com) and books (Professional Javascript for Web Developers by Nicholas C. Zakas) to help get a good grounding of the fundamental concepts and then I built a mini-JS Quiz application (https://github.com/theonicolaou/jsQuiz) with my new-found skills.

As you can see in the README, I have a roadmap for the JS Quiz - my learning experience is far from over! I recently started to look at two of the items in the roadmap at a very basic level - add login functionality using localStorage, and store the quiz questions in a JSON file - to get a better understanding of what might be involved when I eventually get round to continuing the project. This is a short blog post about my experiences of prototyping with JavaScript, JSON and localStorage.

I know the internet is a big place and I know you have to persevere when searching for information/resources/tutorials etc, but I was quite frustrated at how few basic (working) tutorials I found for using localStorage and using JSON with JavaScript. Maybe I wasn't looking in the right places, but I was looking for a long time; I'm sure I spent a good couple of hours trying to find a simple, clear tutorial of how to hook up a JSON file into a JavaScript file and a similar amount of time looking for a tutorial on how to use localStorage. In the end, I found the very basic information I needed (combined with Nicholas Zakas' book) and I created two Plunkr's which I converted into GitHub repos:

Basic HTML5 localStorage example
Type a username and password into the fields and click "Log in" to display the data in an alert. The data is stored at this point. Then you can retrieve it by clicking "Show Data".
To test that localStorage is working, remove the localStorage.setItem lines in the script.js code, then fill in the fields and click "Log in". The alert will display the inputted values but clicking the "Show Data" button will display "null" because by removing localStorage.setItem the values are not being stored. Therefore the "Show Data" button will not have anything to show.

Basic JS with JSON example

A basic example of how to use an external JSON file in JavaScript, by calling it with AJAX. The AJAX looks for a JSON file to parse as long as the onreadystatechange event detects a readyState of 4 (request finished and response is ready) and a status of 200 ("OK"). The JSON file itself is just a collection of name/value pairs, and an array with name/value pairs. The JavaScript then looks for specific values in the JSON file and writes it out into the document.

Both examples are very basic and raw; I know there are elements of the code which can be improved but my main goal was to gain an understanding of how JSON and localStorage works. I think I have achieved my goal and I plan to use my prototypes as a starting point for improving my JS Quiz.

I hope my examples are helpful! Feel free to fork the repos and submit pull requests with improvements!




Sunday, 28 September 2014

"Agile is for life, not just for...projects...?"

Okay, it doesn't have quite the same ring to it, but stay with me here - it actually works! I'm using Agile/Kan-ban in my day-to-day life and it definately works. I wanted to write a short post about it so you can see how it is having a positive impact on my life - and perhaps it will for you too.

In March this year I finally got onto the property ladder when I bought my own place. The decorating/moving-in process was fun and exhausting, but the key was...Agile.

I made a huge spreadsheet of everything that I needed to do in the run-up to my move date in mid-May, which I divided into tasks per week, and I used the Clear app to keep track of everything for a specific week. I also found myself adding unrelated tasks into a separate "To Be Assigned" list in Clear, which I then revisited and added to the weekly lists as I saw fit. Once the week was over, I would move any other tasks back into the "To Be Assigned" list, or into the weekly list for the new week.

This, combined with the advice in David Allen's book "Getting Things Done", really helped me to keep on top of everything. It sounds so simple but it really did work.

Now that I have moved in to my new place I am using Clear pretty much every day. But, more to the point, I am using Agile pretty much every day. If I have something on my mind I make the effort to define everything I can think of which needs to be done, so that I can free my mind and get on with my day. Then, I look at my list (scrum board, or whatever) and prioritise the tasks I need to complete. It might sound geeky, or silly, but just try it and you will never look back!