Blog

How I’d Learn Front End Web Development Now

When I started out with doing web stuff in 1999, things were very different, much simpler in some ways but much harder in others. So, the way I gradually learnt was quite different from how somebody would learn now.

Back in my day…

Don’t yawn, there is a point to this. In 1999 when I started learning this stuff, there was only HTML, CSS and JavaScript. No TypeScript, no Sass, no real frameworks to speak of, no packages, no build tools. You get the picture.

So, there was a lot less to learn but learning was harder. There wasn’t great documentation online, or, at least, not easy to find, so I used books. Cross browser compatibility was hard.

In short, it’s a completely different landscape now. So, I thought it would be interesting to think about how I would learn or advise others to learn if starting out now.

The basics

The basics are still the basics. HTML, CSS and JavaScript are the technologies used by web browsers. That hasn’t changed in all this time and it’s not likely to change any time soon. While trends will come and go a good understanding of these three areas will always be time well spent.

Accessibility

This is a critical area that is often overlooked. The web is a universal platform that should be for everyone, not just for those with good eyesight, expensive devices and fast networks. We need to consider how we deliver content that works for all.

It’s definitely worth learning this from the beginning so things are done in the right way as it’s harder to correct bad habits later. Being able to demonstrate an understanding of accessibility will put you ahead of other candidates who have skipped over it when it comes to job hunting.

Go deep

Going further, I’d say it’s worth exploring these HTML, CSS and JavaScript in some depth before moving on. I think it’s worth skimming through everything on them at pace without worrying about retaining too much. This could be either a course or just working through documentation. Just becoming familiar with what features there are and some terminology will help you understand more conversations and documentation, as well as know what to search for when the time comes to use them. Nobody can remember it all and even experienced developers have to look up syntax. That’s not generally what an employer would expect, it’s more about the broad understanding of how you can use features to solve problems.

Responsive design

It’s rare these days that we can create a web page that will be for a single screen size, so we need to know how to make a user interface that looks good on a big desktop screen and a phone. This is a whole area that is again worth tackling fairly early on. It’s a bit of an art, a collection of techniques and tricks that are not easy to discover. This is an area that would probably benefit from a course.

Source control and package management

Once you’ve got enough of the basics to make something amazing, you’ll naturally want to share it with the world, and then you’ll want to make use of your amazing thing or other people’s in your future projects.

Source control is about publishing code but also collaboration – reviewing each other’s code, branching out and merging it back together. The most commonly used system for this is probably git. Worth reading up on.

Package management is about bundling up your project into a package that can be easily exported and then imported into other projects. The most common platform for front end code is npm.

These two areas usually involve using the command line, a terminal where you type commands to make things happen. It’s not as scary as it looks and makes you look like a proper hacker to those not in the know.

Frameworks

Probably later than some would expect, but I genuinely feel the other things are more important to get good longer term. If you learn a framework too early their way of doing things becomes your normal and then if you change framework you have to start again. If you understand the core technologies then you can see what the framework is giving you and can adjust more easily.

CSS frameworks can be very useful for providing ready-made styling, bringing consistency and the CSS is well structured. It’s a good way of learning how to structure your own CSS for larger projects.

JavaScript frameworks like React, Vue or Angular take some investment to learn but it is paid off in terms of faster development down the line.

There are also UI frameworks and design systems which provide complete components ready to use.

With all of these frameworks, there’s lots of time saving and knowledge to be gained but it’s important to remember that these are just someone’s opinion and one way of doing things. There is no single right way or best way.

Extending the basics with pre-compilation

I’d say that’s probably everything you need but there are a couple of other bits that are cheap to learn so worth throwing in there – more skills to boast about can’t hurt.

Sass is a superset of CSS – it’s CSS with added bells and whistles. You write in .scss files, making use of the fancy additional features and then it gets compiled to normal CSS. The great part is that it’s additional features, not a different language so CSS is valid Sass. You can start out with a .scss file, just write normal CSS and it gets compiled to CSS. It’s a bit pointless but means you can start off with nothing and then gradually learn and use Sass one feature at a time. It’s a nice easy learning curve.

It’s the same idea with TypeScript. This is enhanced JavaScript so you can write in .ts files and get JavaScript, learning the new features as you go.

With both of these, once you get into the new features you’ll never go back.

Then, anything goes

Once you’ve got these skills, it’s really an open playing field. You can learn whatever takes your interest, or maybe whatever your job needs.

Let me know if you’d do things differently.

Progress Indicators

I’ve been working on a questionnaire with a requirement to show progress through the questions. It has thrown up some interesting challenges which I felt were worth sharing.

When I first saw the requirement I thought it would be simple – progress is just number of questions divided by number of answers, easy maths, right? Well, it could be in a very simple questionnaire but ours threw up a few more curved balls. Here are some additional considerations:

Some questions are mandatory, others are optional, so are we counting all questions or only the mandatory ones?

There is some conditional logic so a question may be shown or hidden depending on how you answer another question. How do we handle that?

Some questions can have multiple answers, like a checkbox list, so how many do we count?

Some answers may automatically answer other questions. I know this sounds odd but it’s a big old questionnaire and sometimes it was useful to repeat some questions and answers in a different context in case it changed the answer.

Our architecture has questions and answers as 2 separate API calls, which each bring back object arrays. Questions and answers are linked by a common data point, which is just an identifier so that we can match them up. So, time to work through our extra considerations…

We only want to count mandatory questions. These are denoted by an isRequired property on each question so we can filter to that like this:

const filteredQuestions = questions.filter(q => q.isRequired);

We also only want to count questions that are shown. We can’t reasonably expect a user to answer a question they haven’t seen. This is similar to the isRequired property but using isVisible, so to filter on both of these (instead of just the one property above) we can do this:

const filteredQuestions = questions.filter(q => q.isRequired && q.isVisible);

If questions have multiple answers, it doesn’t matter, we’re just interested in whether or not they have an answer.

Next we need to deal with duplicated questions and/or answers. We can convert our filtered questions and our answers into arrays of unique data points. First we simplify the array to only hold the data point string, then we dedupe it by converting the array to a set and back again.

const questionDataPoints = questions.map(q => q.dataPoint);
const uniqueQuestionDataPoints = [...new Set(questionDataPoints)];

const answerDataPoints = answers.map(a => a.dataPoint);
const uniqueAnswerDataPoints = [...new Set(answerDataPoints)];

Now that we’ve got a list of unique question data points and a list of unique answer data points we only need to see which of our questions have answers, which we can do like this:

const numberOfQuestions = uniqueQuestionDataPoints.length;
const questionsAnswered = uniqueQuestionDataPoints.filter(q => uniqueAnswerDataPoints.includes(q));
const numberOfAnswers = questionsAnswered.length;

These figures can now be used as our value and max attributes or numerator and denominator in a fraction. To give a percentage we can do this:

const percentage = Math.round((numberOfAnswers/numberOfQuestions) * 100);

If we want a normalised figure, a decimal in the range between 0 and 1, we can stick with the simpler fraction calculation like this:

const normalized = numberOfAnswers/numberOfQuestions;

The <progress> HTML element can take max and value attributes or if we don’t specify a max we can simply pass a normalised value.

Learning to Write Code that is Good Enough

When you go through school you’re always taught to do your best, to try to make the thing you’re working on the best it can possibly be. When it comes to software we naturally want the same – we dream of something that’s fast, accessible, responsive and free from any bugs. It’s just not realistic.

Need for Speed

In the real world of web or software development, speed of development is key. We have to deliver functionality by deadlines. This might be because users need it for a fixed date, or maybe you need to move quickly to make the most of a gap in the market, or you need to beat your competitors or keep pace with them – there are many reasons.

Let’s say we’re adding a new feature to search and filter product data. We’ve estimated that the full feature will take 4 weeks. However, we can deliver a very basic search box that just matches all product text within a week. We can actually deliver about three quarters of the value to the end user in one quarter of the time.

The need for speed means that we can’t take our time and build the perfect solution. We need to be fast and that inevitably means compromising and cutting corners. It’s OK to release something that isn’t perfect. It’s even OK to release something with known bugs.

Release Early

By getting the code into production and letting users try it out earlier we can use their feedback to steer the rest of the feature. Maybe after the first release we realise that this is all they need and we don’t need to build the rest? Maybe it’s too slow in the real world and we need to go back and improve this before adding more complexity? Maybe the known bugs are not quite what we thought they were?

This is general agile development, starting simple and building in iterations, and is largely about good planning and communication. We can apply the same kind of thinking to the coding.

Coding Shortcuts

Can we get away with a hard-coded list or a static JSON file for now instead of creating a new database table or API?

Can we select defaults on dropdown lists or radio button groups so we don’t have to add required validation?

Can we use browser storage rather than writing to the database?

Can a form just post key-value pairs to an email address to begin with while we’re working on the database?

We don’t need polished design or animations until we know the solution is right.

I’m sure you get the idea. Not perfect, just good enough. Go fast, hit the deadline, listen to feedback and improve it when the pressure’s off. If you’re releasing something that you feel is risky do it under a ‘BETA’ or ‘Experimental’ flag so users know what to expect and it doesn’t damage your reputation.

Reasons for Developers to Have a Blog

One thing I’d definitely recommend to any new developers is to have your own blog. It’s also a view I’ve seen shared by a lot of experienced developers. But why?

How I Started

I’ve had this WordPress blog up and running since summer 2008. I know. A long time. I had a small static website for about 5 years before that. For me it came out of necessity. I was doing freelance web design so needed somewhere to promote my services and showcase what I could do. I started writing articles as a way of creating fresh content in order to climb the search engine results listings. This certainly did not have an instant impact but over a long time I think it did make a difference.

When I started writing articles I knew that nobody would be reading them. I’m a realist and accepted that from day one. I was writing for myself. I still see it this way. It’s for me and if it helps someone else, that’s a bonus.

Knowledge Base

When I learn something interesting that I think is worth holding onto I write about it. It’s a good way of helping to commit it to memory as well as creating an easy to find reference point to come back to.

With anything of a technical nature, putting it into your own words and using your own mental models really helps you to fully understand it. It’s a bit like the idea of learning by teaching. If you’ve ever done a presentation you’ll know that the preparation you do really helps strengthen your own knowledge of the subject.

Your Journey

A bit like keeping a diary having your own blog will let you see where you were a year ago, 5 years ago, ten years ago, or more. It’s like a record of your own journey within the technology and the industry.

Show and Tell

However, in my opinion, these are not the best reasons for having a blog. I think that the best reason is having something to show for your time. By putting in some time to write, little and often, over time you build up a nice collection of your thoughts, ideas and opinions. You have evidence of what you’re into and what you spend time thinking about.

Put yourself in an interview situation, going for your dream developer job. You can show your blog and right there you have strong evidence that you are passionate about the subject and that you willingly invest time and effort in it. That has to count for a lot. It shows more commitment and serious intent than social media activity.

Writing Tips

You don’t have to be good at writing. Even the best writers improve over time. Keep going and you’ll find your way.

Don’t beat yourself up if you haven’t written for a while. Just do it as and when you want to. Don’t force it and write about something you’re not that bothered about just to get content.

Similarly, don’t feel it has to be long form and 1000 words every time. It’s fine to just share an idea in a few sentences.

Self Hosting

Another recommendation with writing a blog is to host your own site so that you retain 100% ownership of your content. There are numerous tech blogging platforms (e.g. medium, dev.to) but owning your own content and having any traffic surges benefiting you rather than the platform is definitely worth it long term.

If you do use a third party platform check out the export options. Can you get all your content out and move it elsewhere? It’s good to be free to do what you want with your work.

WordPress

There are lots of blogging platforms and software options out there. Personally I’ve always found WordPress is the best fit for my needs. The fact that it has native apps means that if I’m out and about and suddenly have a great idea for a post I can capture a quick draft there and then.

It’s also very easy to export and import your data, meaning you can shift content from an old blog to a new one, combine or separate blogs, and move between hosted (.com) and self-hosted (.org) versions.

The control over the design and ability to switch themes easily means you can keep your site fresh without having to worry about rewriting the content – there’s a perfect separation between content and presentation.

The Dangers of Logic in CSS

We can do a lot of logic in CSS. I’m thinking specifically of scenarios which take the form “if this, then that”.

There are media queries which will let us control the appearance of elements based on a variety of factors. Probably the most common is screen width, so we get things like “if the width is 1024px or higher, then show an extra element”.

There are pseudo selectors like :empty, :checked, :valid, :disabled which let us control appearance based on state, giving us, for example, “if the parent element has no children (:empty), then change its opacity”.

We can also do logic based on combinations of elements or selectors, like li + li, for example, “if the list item follows another list item, then give it a top border.”

I’m sure there are plenty more ways of applying logic but you get the idea. Each of these is equivalent to writing a conditional statement in a programming language – if this, then that.

The big question is, should we be doing this in CSS, and is there a point at which it becomes too difficult to manage in CSS and we need to defer to another technology, like JavaScript?

My Experience

I started thinking about this when I was designing a UI with a lot of logic going on. We had a busy table where we show some additional columns at wider screen resolutions. At smaller widths the user would be able to toggle between different groups of columns and save a preference. But then these additional columns are only offered if they contain data. So, we had logic around the screen width, user preference and presence of data, which, multiplied out, meant 8 permutations.

I initially tried to do it all with CSS. I set up media queries for the narrower and wider screen widths. Within each of these I then read a class for the user preference and then I used :empty to see if table cells contained any data. I managed it and it worked. Just.

However, I realised that it was really not scalable. Every time I added a new condition it doubled the amount of CSS I was having to write. If we wanted to add more logic in future it would create more and more work and be harder and harder to maintain.

By moving all the logic into JavaScript we can set simpler classes, one for each type of display we need rather than every permutation of logic. So now we just have 3 classes: 1) show the first set of columns, 2) show the second set or 3) show all columns.

We still have lots of branches in our JavaScript but the big difference is that it’s easy to read and follow. It’s also easy to edit or extend if we ever need to.

I think doing some logic with CSS is fine but as soon as you’re starting to layer it on and find yourself multiplying out the selectors you’re writing it’s probably time to move it over to JavaScript.