CodeIgniter Class Level Variables

Class Level Variables in CodeIgniter was a big stepping stone to moving Gittr towards a better flow.

As the CTO of Gittr, I’m always looking for ways to improve the way we write our software, from utilizing different features and techniques to simplifying or compacting our logic. We’ve got a pretty good flow going, but there was one thing I saw that was tripping me up: constantly defining and redefining variables.

The big thing we’re working on right now is the ‘administrator’ section of our app, which allows privileged users access to methods to change settings, view stats, add, remove, and edit partnered merchants and generally manage the application. We’ve gone through a few different generic methods of rendering views, which always looks a little something like this:

public function view($page) {
    //if the admin is logged in
    if ($this->UserModel->adminLoggedIn()) {
        //assemble the $data
        $data['user'] = $this->UserModel->getUserData();
        $data['company'] = $this->CompanyModel->getCompanyData();
        //load the view
        $this->load->view('admin/'.$page.'.php', $data);
    } else {
        //if the user isn't logged in, redirect to the login page

We pass the $data['user'] and $data['company'] to each view to display the appropriate data and link to the right things. Things like the Company’s and User’s IDs are very important to keeping track of who did what, especially when dealing with multiple users. So these pieces of information are very important.

With these (and other variables) constantly being defined in every method, I wanted a way to not only make sure we’re keeping it consistent, but also cut down on file size. After removing every instance of the call to getUserData() and getCompanyData(), I counted just over 100 lines of code, or about 5,000 characters, saved altogether. The solution I found was variables defined on the class level.

The idea is this: each time the controller is constructed, the three variables ($user, $company, $loggedIn) are set. Then, they can be accessed within the methods to pass the data to the views. Here’s what that looks like:

class Demo extends CI_Controller {
    //declare the variables
    protected $someVar;
    protected $otherVar;

    public function __construct() {
        /* Load in libraries, helpers, models, etc */
        //set the variables 
        $this->someVar = $this->SomeModel->someFunction();
        $this->otherVar = $this->OtherModel->otherFunction();

    public function index() {
        //use the variables
        $data['var'] = $this->someVar;
        $data['other'] = $this->otherVar;
        $this->load->view('view.php', $data);

I think this accomplishes two things: it keeps your code DRY (Don’t Repeat Yourself) and it cuts down on the possibility of breaking things when you change how you call a function (ex. changing the parameters passed and accepted). I think this is a pretty basic use of utilizing class-level variables in the controller and I’m really excited to find other ways to implement this idea. If you have other ideas on using this, leave a comment!

CSS Counting: What, How, and When


I recently read This awesome article on CSS-Tricks about a bunch of interesting CSS properties. While some of the properties were already well known to me, there were a few that stood out and. The one that stood out the most, though, was CSS Counting.

What CSS Counting Is

CSS Counting relies on a (sort-of) variable which, of course, is maintained by CSS. The counter can be manipulated by CSS rules to track their usage. The whole list of properties and values are listed below:

body {
    counter-reset sets the value and names the counter 
    counter-reset: el; 
.el {
    counter-increment adds to the value with every 
    next instance of an element with the 'el' class
    counter-increment: el;

    counter() prints the value 
    &:before {
        content: "Count: " counter(el);

How To Use It

Well, the code above kind of goes into how to use it, but it doesn’t explain the logic. Basically, counters should be reset on a basic level. So if you have a counter for headings in an article, and your article is a single page, it would make sense to reset the counter on the <body> tag.
But if your articles come in a stream, say on an ‘endless scroll’ website, it would make sense to reset the counter on every <section> or <article> tag (or <div> tag, depending on how you built your site).
You can also have multiple counters, so using it to list article numbers with another counter for subheadings is possible. Or subsubheadings. Or subsubsubheadings. Or….
Here’s a demo!

See the Pen CSS Counting by Nate Northway (@the_Northway) on CodePen.

When to Use Counters

A few years ago, I built a site for a neighborhood association. I could have used this technique to label the bylaws efficiently.
Other areas where this could be used can be in list-type articles, or anywhere that uses labels to reference sections.


The problem with this method is that the :before CSS pseudo-element is not selectable, meaning that if somebody needed to copy/paste the bylaws in the previously mentioned neighborhood association site, the section/subsection count wouldn’t have been copied over.
One way to circumvent this issue is by building the counter functionality in JavaScript. But that would totally invalidate the use of the CSS counter. Unfortunately, there is no way to access the CSS counter in JavaScript (even when using a library). Hopefully, a method can be developed to make the counter accessible to JS.

Although CSS Counters are cool (and could arguably be useful), they aren’t accessible because to show them requires the use of a pseudo-element. They aren’t selectable, won’t be seen by a screen-reader, and won’t show up in ‘reader’ views (like on Safari). Because of the lack of accessibility, I’d suggest against using this method (for now). As an alternative, consider using a JavaScript alternative.

Net Neutrality: What it Is, Why it Matters, and How it Concerns You

Ajit Pai being sworn in as FCC Commissioner. He will be a major player in the decisions on Net Neutrality.

Net Neutrality has been a hotly debated topic for a few years now. But after the 2015 ruling upholding the FCC’s classification of the internet as a utility (thus applying Common Carrier laws to the ISPs), it hasn’t been discussed as much. With the US’s recent election, however, the freedom of the internet is in question again.

What Is Net Neutrality?

Wikipedia has a really good article that on Net Neutrality. To summarize, it’s the principle that ISPs (Internet Service Providers – ATT, Time Warner, Comcast, etc) and governments regulating the internet should treat all data the same, without discrimination (throttling or price changing) against type, source, or destination of data. Additionally, practicing Net Neutrality ensures that discrimination doesn’t occur based on the type of hardware attached to access the network or the mode of communication.

The principles of Net Neutrality cover quite a few bases: it ensures that dissenting ideas are not silenced, ensuring a freedom of speech. It also ensures that users can use common hardware to access networks, which makes it accessible to all classes. Additionally, the principle ensures that those using different modes of communication are able to access the network, too, further ensuring the Net’s accessibility.

Accessibility and the free flow of information are ingrained in the DNA of the internet. Since the internet’s inception, data exchange has been at it’s heart. Since then, partly thanks to Net Neutrality, accessibility has become a cornerstone of the internet. Governments have requirements outlining the ways in which their websites need to be accessible so that users with disabilities can access them. Most websites are built with accessibility features, like the WAI-ARIA initiative headed by the W3C.
In fact, accessibility is a part of most technology. Hardware and software implementations of accessibility features have been present in most technology for a long time, and has been reported on since at least 1980. With accessibility being such a pillar of technological design, it’s logical to ensure accessibility for a part of technology that is (probably the most) public part of modern and future technology.

The Role Of Data

Though hardware plays an important role in making the internet neutral, it’s meaningless without data. The other facet of Net Neutrality is non-discrimination of data. Since ISPs have the ability (and arguably the responsibility) to monitor data, it’s origins, destinations, and type, it is their duty under the principle of Net Neutrality to ensure the equal handling of data.

If that’s a little difficult to understand, let’s use an example: without net neutrality laws, ISPs like Comcast could charge consumers extra for data that comes from sources that criticize them, their supporters, the political or social leaders they support. Additionally, they could throttle, corrupt, and/or edit the data that is sent to the end user to ensure that their agenda and goals are met.

Why it Matters

Net Neutrality matters because it ensures the equal distribution of data and access thereof. Without net neutrality, it’s possible that the public could live in a sort of corporate dystopia – one in which the ISPs are the lawmakers. With lobbying being such a huge part of politics in the United States, lack of net neutrality could lead to a lot of problems. Not only could giants such as Comcast and ATT use lobbyists to get politicians to make laws in their favor, they could also control the information being distributed to the public, so it’s possible that they could be making deals in their favor and nobody would know about it.

How it Concerns You

Recently, there has been a lot of talk of a phenomenon known as “fake news“. Fake news exists to encourage complacency in a population which does a good job of just skimming the surface – meaning that facts and research aren’t looked into often. Often, fake news confirms beliefs that certain parts of the populous already have, without any evidence to support those beliefs. This is confirmation bias and has lead to numerous misunderstandings, misconceptions, and a disregard for facts on a number of social issues.

Even with net neutrality in place, fake news is a huge part of social media and has had an effect on politics in America. Without net neutrality, verifiability of sources would be next to impossible, meaning that the spread of fake news would be rampant. It’s truly Orwellian.

So, to the end user, a lack of net neutrality means the loss of journalistic integrity and a return to old ways of obtaining news and verifying it: newspapers and trips to the libraries, finding sources still under common carrier laws (like television and radio), and putting a heavy dose of skepticism on everything.

What You Can do to Ensure the Net Stays Neutral

The best things to do include figuring out who your representative is and writing, calling, and emailing them in support of net neutrality. Sharing articles about net neutrality on social media to tell your friends about it is important, too (and encouraging them to contact their representatives is good practice). You can also donate to the Freepress, which is dedicated to fighting anti-Net Neutrality.

If you don’t donate or write your representatives, at least tell your friends about net neutrality and it’s importance to freedom in the United States and the world. Here are some good articles on Net Neutrality:

Again, if you don’t donate to Free Press or contact your representatives, at least tell your friend about Net Neutrality and it’s importance to freedom. Start by sharing the articles above and discussing the topics with your friends.

Error Handling and HTTP Redirects

Default Apache Error Page

There are few things I dislike more than seeing a website handle basic errors with a default error page. There are a few UI/X considerations to think about when handling redirects to tell the user they’ve encountered an error. The case I think about most often includes a user being linked to a page that no longer exists. A default page will tell them only that the page doesn’t exist. It won’t tell the user if (a) the site also no longer exists, (b) if the page exists elsewhere, or (c) how to find what they’re looking for. Additionally, the default error page gives no easy way to navigate to the rest of the site. It doesn’t include a search form to look for the content they tried to access, nor does it provide a way to find out if the link they were given just had a typo.

How I Fix This

There are a lot of ways to deal with HTTP redirects. The way I do it is with Apache – your server’s configuration may be a little different if you’re on a different platform.(*) Basically, I tell my server that if there is an HTTP error, to redirect to a certain page, called error.php, in the root directory of my site.

ErrorDocument 400 /error.php
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
ErrorDocument 405 /error.php
ErrorDocument 408 /error.php
ErrorDocument 500 /error.php
ErrorDocument 502 /error.php
ErrorDocument 504 /error.php

This custom page has two main components: a variable to store the redirect type (from $_SERVER['REDIRECT_STATUS']) and a keyed array with the codes set as the key and values being an array with one value for the name of the code and another value with the description.

$codes = array(
  400 => array('400 Bad Request', 'The request cannot be fulfilled due to bad syntax.'),
  403 => array('403 Forbidden', 'The server has refused to fulfill your request.'),
  404 => array('404 Not Found', 'The page you requested was not found on this server'),
  405 => array('405 Method Not Allowed', 'The method specified in the request is not allowed for the specified resource.'),
  408 => array('408 Request Timeout', 'Your browser failed to send a request in the time allowed by the server.'),
  500 => array('500 Internal Server Error', 'The request was unsuccessful due to an unexpected condition encountered by the server.'),
  502 => array('502 Bad Gateway', 'The server received an invalid response while trying to carry out the request.'),
  504 => array('504 Gateway Timeout', 'The upstream server failed to send a request in the time allowed by the server.'),

I use the template of my site’s index.html file to import the necessary styles and code, then hit the user with a full page message, explaining, in detail, the code and nature of the error. I add in a few actions they can take, too: go back to where they came from or search for what they were looking for. I use jQuery to get the last URL (if there is one), and set the link on the page to it. I also change the link text depending on if it was a referred link or not.

  if (document.referrer && $("#btn").length) {
    $("#btn").attr("href", document.referrer);
    $("#btn").text("Go Back");
  } else {
    $("#btn").attr("href", "index.html");
    $("#btn").text("Go Home");

The HTML is really simple. I’ll omit the <head> and just leave you with the main section

<div class='error' id='redirect'>
    <h1>Error: <?php echo $codes[$status][0]; ?></h1>
    <p class='lead'>
      <?php echo $codes[$status][1]; ?>
    <a class='dg-close' href='' id='btn'></a>
    <div class='row center-align'>
        <form role='search' method='get' id='searchform' class='searchform' action='searchform.php'>
            <h3>Try A Search</h3>
            <div class='input-field'>
                <label class='screen-reader-test' for='s'>Search For:</label>
                <input type='text' name='s' id='s' />
                <input type='submit' name='submit' value='Search' class='dg-close' />

There are different (and arguably better) ways to do this, but this is how I handle HTTP redirects to provide a consistent UI and give the user more information than just “There was an error”. This solution solves 2/3 problems presented: it tells the user the site exists (just by being a non-default page), and it shows the user how to find what they’re looking for. (The functionality to suggest pages will be in another post.)
A little extra thing that can be done: in ‘error.php’, a short bit can be added to email yourself a an error report, including the URL that triggered it, the redirect status and code, and any other relevant information.

Want to see this in action? Click here to throw an error.

* If you’d like to provide different language samples, I’d love to include them! Just shoot me an email!

Development Software and Tools


I’ve been building websites for the better part of 3 years now. In that time, I’ve switched operating systems three times, I’ve used dozens of text-editors, hundreds of tools, and many, many browsers and devices. I don’t think I’ve ever written down what I’ve used, aside from the brief mention on Twitter every once in awhile. So, I’m gonna start doing just that.
I’m gonna break down my development tools and software here, then when something changes, whether I add to or remove something from the pile, I’ll update this article (without removing what was replaced, if anything was). So, let’s go!

Text Editor

I think the text editor is the heart of every developer’s tool kit. It’s where in most of the work of development is done, and can lend a huge hand in speeding up (or slowing down) your website development game. When I first started looking for editors, I wanted something that was free, good looking, open-source, and had good documentation. I still want all those things, but I want more than just that short list. I also want something I can customize, with a nice set of default features but can also be built on, and a good community behind it.
For those reasons, I hang with, ‘the hackable text editor’.
I like Atom because of all the things I mentioned above: it’s free, good looking, open-source, has good documentation, it’s customizable (read: hackable), has nice default features, is expandable, and has a pretty good community behind it.
I run Atom with a few (non-default) packages:

  • Remote-sync by yongkangchen: FTP in the editor. Works from a single JSON config file. The only thing I don’t like about this is that there isn’t a default keybinding.
  • Atom-minify by armin-pfaeffle: Minification of CSS and JS files, with an option to minify on save. Minify in file or directly to another file
  • Autoprefixer by sindresorhus: Adds browser prefixes to CSS properties/attributes. No need to find and manually update prefixes. Comes with lots of options
  • HTML-Head-Snippets by joshbuchea: Josh Buchea’s HEAD is a really good resource for solid SEO and general <head> content. This package lets the developer add snippets into their file right from Atom, eliminating a Copy/Paste step.
  • Linter by atom-community: A base linter. You do need to install specific packages for your language, but it does really well and all of the packages are robust and work like a charm.

The other thing I like about Atom is that it just looks really damn good. The dark theme is what I went to right away and the syntax highlighting and colors, oh man, everything just feels like the exact thing I want to look at when coding.


Among other important tools in a web developer’s kit lie the browsers they use. I’m not going to break down everything, but I will break down what browsers I use and for what purposes:

  • Chrome: Chrome is my daily driver. I use it for all my normal browsing, in addition to some testing. I do most of my layout testing in Chrome and a lot of the initial design in Chrome as well. I always disable plug-ins while first testing, but once I’ve got things going how I like, I re-enable plug-ins that are known to disrupt UI (post coming about that soon, I swear!).
  • Safari: I rarely use desktop Safari for normal browsing, but I use it daily for testing. I usually open up Safari when I’m done with initial layout/design elements in Chrome. I’m constantly testing on my iPhone for mobile Safari, from first layout to final touches.
  • Firefox: I don’t use Firefox for anything other than testing. I don’t like it. That being said, it can bring up a lot of issues that aren’t found in other browsers, so it’s important to test in. I usually don’t open it until I’ve gotten to putting on final touches.
  • Mobile Chrome: I really dislike Android, not for the design or UI, but because of the inconsistencies across hardware platforms. For that reason, I’ve never intentionally bought an Android device. Until I realized I needed to, about a month ago. So I started using mobile Chrome and the Android browser to test alongside the rest of my flow. The tablet I have is always sitting on my desk, ready to look at whatever. It also serves a double purpose as my media device, so music is always streaming from it. Helps with the mood.
  • Anything else: Unless there is a real use case, I don’t test in other browsers. I use a Mac so testing in IE and Edge are annoying, at the least, and difficult, at the worst. But I do run a Windows VM and once I’ve started staging the site I do a quality check in IE (back to 12) and Edge. I do, also, quality check on Firefox and Chrome on Windows.

Virtual Server

For all of my local testing (pre-staging), I use MAMP (Mac Apache MySQL PHP). It’s really easy to set up, requires VERY little maintenance, and comes with everything that I need: Apache, MySQL, and PHP. It also comes with the ability to connect different devices on my local network, and when I have it set up correctly, I can remote into my network from a client’s office (or the coffee shop) to see what’s being worked on at home. This makes pre-staging testing a breeze and makes local development kinda fun!
I don’t know what else is out there, to be honest. As far as virtual server software goes, my understanding is that MAMP is the cream of the crop, baby. If there is anything else and you’d like to see me try it, shoot me a message at


I use the Sass preprocessor to make writing CSS a lot easier and a bit more programmatic. Atom plays nicely with it and it’s really easy to learn how to use.

I think that just about wraps up everything that is worthy of a breakdown. I use a lot more tools, but not all of them are worthy of a full breakdown. I’m happy to list them, but why I use them should be evident if you visit the link I’ll provide


Most of this software is free, but if it’s not, it’s really cheap or worth the price


Most of these services are free to some extent, but most of it has a paid option that is vastly superior to the free option. I really suggest that with the free stuff you strongly consider their paid alternatives. Google Suite, CodePen, and Browser Stack are the services I’m happy to pay for because the functionality they provide is unmatched. Look into what’s right for you, though.


I was motivated to list my hardware. I think it’s important to note that hardware is pretty interchangeable. What I have is not the best setup. It’s the best setup for me. Some software is very necessary. Like, a text editor, a virtual server, and an FTP client, I would say are necessary parts. Which ones you use may not be so much. The same goes for hardware. A computer is absolutely necessary, but multiple testing devices probably aren’t, though they’re nice to have. That being said, here’s what I’ve got.

MacBook Pro (Retina, 13 inch, Early 2015)

I’ve got a 13″ 2015 rMBP with 128gb flash storage, 8GB RAM, and the 2.7GHz Intel Core i5. I run El Capitan. I love this computer. It’s powerful enough for what I do, the battery lasts all day through meetings, it looks great, the keyboard and trackpad feel great, and it’s pretty durable, too.
I don’t like two things about it. First off, it doesn’t like to read my hard drive. I’ve been told this is an OS level issue, but I’m hesitant to upgrade to Sierra. Secondly, when I stress it, it tells me. I’ve never had a laptop that heats up or gets as loud as this one. But those two compromises are much smaller than the compromises I’ve had to make with most of the previous laptops I’ve owned.


  • Acer 23.5″ Monitor
  • WD 1TB MyPassport for Mac (entertainment, backups)
  • Logitech Wireless Mouse
  • Kingston 16GB Flash Drive (jump drive?)
  • PS3 Controller for gaming

Other Hardware

There is other hardware I use nearly daily, mostly for research, communication, or testing purposes.

  • iPhone 7
  • NeuTab N7 Pro (cheap Android Powered tablet for testing, reading/comms on-the-go)
  • Samsung 19″ Monitor (more testing)

In addition to all that crap, I also always carry a notebook and a couple nice pens. Nothing beats jotting down ideas. Don’t throw that paper away. On slow days, I look through these notebooks (I have 7 on my bookshelf now) for inspiration and add lost ideas to my Trello ‘ideas’ board (after deliberation).
I also use these notebooks for initial meetings with clients. Unless absolutely necessary, when meeting clients, I keep my laptop in my bag and engage with the client, writing down specifics in the notebook and translating that to a Google Document later.

This list is incomplete. I use more software and services, but I don’t use them every single day. As I come across pieces that I’ve missed, I’ll add more to this article.


Accessibility is absolutely necessary in today’s day and age. It provides a chance for everyone, without bias, to interact with a website and obtain the information they need or want in that moment. Lack of accessibility can lead to higher bounce rates, users being unable to obtain information, and a negative effect on your bottom line. There are many cases to be made in support of accessible design.
Recently, I had to field a call from my mother, a 50 year old with almost total vision loss, who needed help filling out an online form, which was necessary for her to complete a task related to money management. The form wasn’t compatible with her screen reader, so she needed my help to finish it. Though I have no problem navigating screens with my mom, people with disabilities (or other needs for accessible information) who don’t have a person to assist them face some problems. The need for accessibility is higher than ever, with more than 2 billion internet ready devices existing as of 2013[1]; a number that only grows.

Case 1: Everybody Uses Smartphones

Nearly 2/3 of adult americans use smartphones[2]. That number is higher in youth, meaning that as the years go on, more and more adults are using smartphones. If literally every person were to try to use a non-accessible website, imagine how quickly that website will die when 2/3 of them can’t access it. The fact that so much of the population’s access to the internet is through their cellphone should speak enough to the reason implement accessibility in web design.

Case 2: Disabled Users

Much like my mother, disabled people need to use the internet to complete necessary tasks that they otherwise may not be able to complete. Some things like banking forms, job applications, applications for assistance, communicating with other people, and aligning transportation can not be completed without the internet. The nature of the internet provides a unique opportunity to remove certain dependencies for people. For example, a person who has a speech impediment can now clearly communicate with a health care provider through a web chat session to clearly state symptoms they are experiencing. These advantages do not come without responsibility, though.

Case 3: Limited Access To Technology

Take into consideration the fact that some people have limited access to technology. Folks in impoverished communities, people with limited access to decent education, and people dependent on public facilities to access the internet may be using older technologies to accomplish what they need to do. It’s important to keep these people in mind when designing your site, not only because it’s necessary to your business, but also because these users are just as important as any other user. Designing your website to work on these devices/in these softwares is necessary to the continuation of your product/service.

Case 4: Money

Yep. There, I said it. Making your thing accessible brings you more money than not. Consider this: Nearly 1 in 5 people have a disability in the US[3]. 20% of the population. That means that 1 in 5 people accessing any given website have a disability (on average). If it costs $1 to join your site, 100 people access your site, and it isn’t accessible, you’ll soon be refunding $19, and be preparing to either refund more in the future and to not get that money from your users who require your website be accessible.

But it’s not all about money

If money is your only motivator, web design probably isn’t for you. However, I’m not here to judge. If you’re reading this, you care enough, I guess. Either way, money shouldn’t be your only motivator to creating accessible sites. Keep in mind that real people are on the internet. The fact that bits represent people on a computer screen may obscure personal interactions on the internet, but I promise you, real people are having real problems created by a lack of accessible websites. I want the whole world to be happy with the internet because my experience with the internet has been mostly positive and I want everybody to benefit from it’s existence. My way of giving back is through accessible design. I hope you take these things into consideration and feel the same way, or at least see the need for accessible design.

The Differences Between IDs and Classes

To style HTML with CSS, there are a myriad of selectors that can be used. The
first, and most basic, of these selectors is the element selector, which
selects all elements of that type. To be more specific with selectors, IDs and
classes can be used, and are probably the most commonly used CSS selectors.
Though you can achieve similar things with both, Classes and IDs are way

Starting Simply

The first course or tutorial you read about CSS probably introduced the element
selector. This selector targets all elements of that type. So, when you plug this
into your CSS:

p {
  font-size: 16px;

All the <p></p> elements on your page will have a font-size of 16px. The
element selector has a low level of specificity. That is, usually, there are
multiple elements of a type on every page. Element selectors are useful when
there are only a few elements on a page, or in tools like resets or (in some
cases) layout tools. When more specificity is needed, classes and IDs help
target specific elements or types of elements.


Say, for example, you want some <p></p> elements to have differently colored
text. You might add a class attribute to the HTML with the value blue-text,
which would be targeted in CSS with the class selector, like so:

.blue-text {
  color: blue;

That targets all elements with the class attribute of blue-text. Classes are
useful for reusable code. Utility classes, like align-left or button, are
good candidates for class names. They are also useful for grid systems. Class
selectors have a higher degree of specificity than element selectors.


IDs are used in more than just CSS. They can be targeted in URLs, for example.
Appending an element’s ID to the end of the URL will bring that element to the
top of the browsing context. You can give that a shot now by clicking this
link, which appends #bottom to the URL. There is a <div></div> at the bottom
of this post with the ID of bottom. That should now be at (or near) the top of
your window.

IDs are also used in JavaScript and jQuery (and a lot of other front end
technologies). They are used to watch specific elements for events, provide an
easy way to target an element, and make it easier to know what you’re doing as a
developer. Take the following HTML into consideration:

<button id='btn-1' class='btn'>Action 1</button>
<button id='btn-2' class='btn'>Action 2</button>
<button id='btn-3' class='btn'>Action 3</button>

In CSS, these buttons could all be targeted with the same class selector. However,
since they each serve their own purpose, in jQuery, we’ll be targeting each
individually. There are a few ways to go about this, though. The first is a
roundabout way:

$("body:nth-child(1)").on('click', function() {
  alert("Action 1");

$("body:nth-child(2)").on('click', function() {
  alert("Action 2");

$("body:nth-child(3)").on('click', function() {
  alert("Action 3");

This is all well and good, but it requires (a little) thinking, creates (a little)
bloat, and could be done easier with IDs:

$("#btn-1").on('click', function() {
  alert("Action 1");

$("#btn-2").on('click', function() {
  alert("Action 2");

$("#btn-3").on('click', function() {
  alert("Action 3");

This makes our code much leaner and cleaner and easier to understand. We could
whittle it down more (even to just 3 lines of code), but that’s for another time.
In CSS, IDs are the most specific selector that is not a pseudo-class (like
:nth-child or :not(selector)). They are meant to target non-generic elements,
so you should never have two elements on your page with the same ID.

The Differences

The differences between classes and IDs are similar to vehicle Make and Model.
Every vehicle Ford makes has a few of the same attributes: they all have the
‘Ford’ badge on the front, they all have the same rims, they all have the same
FOB, and they all have the same airbags inside. The make is just like a class:
it defines a set of attributes for a number of different items/elements.

IDs are like models, each model of Ford cars have different attributes, like the
Mustang may have a monster V8 engine, but the Focus has a 4-banger with an
electric motor. The Focus also has 4 doors, but the Mustang has two (and it’s a

The Similarities

Whether an element is targeted by it’s class or ID name in CSS doesn’t change
how the element is styled. Both IDs and Classes can be used to style your page.

The Takeaway

IDs and Classes are extremely useful. Element selectors are the most vague selectors,
and class and ID selectors help target elements more specifically. IDs are the most
specific type of selector. IDs are used in other contexts, too, like linking to
specific elements in a page and being used in jQuery, JavaScript, and other
front-end technologies.

Bottom div!