Modern CSS: Writing Better, Cleaner, More Scalable Code | Harry Roberts | Skillshare

Modern CSS: Writing Better, Cleaner, More Scalable Code

Harry Roberts, Front-End Architect, Writer & Speaker

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
7 Lessons (40m)
    • 1. Introduction

    • 2. The Problems with CSS

    • 3. CSS without ITCSS

    • 4. Specificity Wars

    • 5. The Three Sides of ITCSS

    • 6. ITCSS in Practice

    • 7. Final Thoughts

34 students are watching this class

About This Class

Looking to write clean, sustainable, and scalable CSS? Learn a new methodology for easier, more flexible code!

Join award-winning front-end architect and speaker Harry Roberts for a groundbreaking class that will transform your approach to CSS. Harry walks through his personal method for embracing its features, avoiding overrides and workarounds, and creating code that scales as you grow. You'll learn how to:

  • Use Harry's innovative "bottom up" approach
  • Be more specific to create code that lasts
  • Segment your project into clear, concise layers
  • Understand how CSS works to level up your code

You've never seen CSS like this before. No matter your experience, you'll walk away with new tactics and techniques for crafting sustainable, scalable code with ease. After taking this class, you'll never write CSS the same way again.


1. Introduction: Like many people, I got into the web completely by accident. I thought I was going to be a bad ass graphic designer for many years, and I felt way more in love with development than I never did with design. Hey, I'm Harry, I'm a consultant web developer and performance engineer from the UK. For the last six years now, I've been speaking at a lot of events. A big part of that is IT CSS or Inverted Triangle CSS, and that's what we're going to be learning about today. IT CSS is a methodology, a way of thinking about CSS. It will help you to grow and scale projects over a very long period of time. The Inverted Triangle is a very diagrammatic overview of an entire CSS project. Reason we have a triangle is because each of the three sides represent one of the core tenants of Inverted Triangle CSS. Regardless of whether you are using SaaS, or laaS, or Vanilla CSS, or Host CSS or even a CSS in JS solution, IT CSS will train you exactly where you should put every different component from line zero to line 15,000 of your project. So the first few lessons in this course, maybe quite theoretical, lots of diagrams, lots of drawing things, and really getting our head around how IT CSS works, theoretically. Once we've covered all that stuff, we'll dive right into a codebase and look examples of how IT CSS comes together on the file system as a line of code. The good news is that you don't need to be an expert in CSS already in order to start using IT CSS. If you've got a simple understanding of the fundamentals of CSS, you can start using IT CSS in projects immediately. I'm Incredibly excited to start teaching you all about IT CSS. So let's get started. 2. The Problems with CSS: In order to fully understand ITCSS, it's important that we look at the issues we are trying to solve. CSS is a language developed over 20 years ago. We're still using to build bad applications today. That isn't a problem in and of itself, but some of the issues that prevent at scale, are things we need to tackle. For example, the fact it all operates globally, means that any rule could potentially inherit from a different one or pass its styles on to something else. This needs managing very carefully. CSS is also incredibly dependent on source order. By large whatever is written last is what will get applied. This means we need to be to keep a very close eye on the order in which we structure and build our code base. However, add to that the fact we have specificity. We can completely invert that logic anyway and selectors with a higher specificity than others, can override things in somewhat unexpected ways. We can all these potential pitfalls. We need to design a system of managing CSS, that can actually formalize and sort of structure these features in a way that works for us rather than against us. However, it would be completely improper and unfair to blame everything on CSS. The fact that CSS has stood the test of time for over two decades, shows that potentially there is something that we as developers are getting wrong as well. Developers have many different coding styles. One developer might write code that works the exact same as somebody else, but looks very different. Perhaps, we to manage this. So, we've got a unified way of working across a team. Developers are also famously bad at writing documentation. I don't think I've ever worked on a project that had just the right amount. What if we could make our code documentation? If we can begin working to a shared methodology, perhaps we can build project without needing reams and reams of documentation. Huge issue that teams rather than individuals present, is that CSS is probably the only language that every single member of a development team will write. I've never written a line of Node.js. I don't write any MySQL. But every single person I've ever worked with has written at least some CSS. This diversity and skills all contributing to one language means that, we can't guarantee that everybody knows as much as the next person. If we could design a methodology that takes the stress and the pain away from that, we could get non-experts contributing CSS in a non-detrimental manner. Taking all of that into consideration and being sympathetic to how teams work and being mindful of the way CSS works, what we need is a framework and a way of working that will help solve these problems. That framework is ITCSS. Lets dive in. 3. CSS without ITCSS: So, what will start off with is visualizing it in a very diagrammatic way, what an existing legacy or non ITCSS project might look like, and where the problems occur in style sheets that aren't using a formalized methodology such as ITCSS. So, imagine if you will, that this rectangle right here represents an entire existing CSS project. This is a CSS file. Now this could be an actual CSS file of a single monolithic file, or it could be the result of compiling lots of different SaaS files into one big file. How we get to this point isn't really important right now. Just imagine that this is your entire CSS project, and to make things a little easier to understand, let's say we've got line zero, down to line 3,000. Let's say it's a nice small project. Now traditionally, the way we would normally write CSS, is we would look at the design that we're about to build and we'd identify the first features. We might look at the design and see well, we need to use a CSS reset. So, I put my CSS reset somewhere near the beginning because that feels to make sense. So, we start by putting some scaffolding, maybe some kind of framework filling CSS toward the beginning, and then look further into the design and decide that well, the first thing in a photoshop file or the sketched file is a header. So, I put my header CSS here. Now, we're building style sheets around a visual language here. The structure of a design. This is a very common way of writing CSS, and for the most part, especially on small projects, this will usually work. As a project starts to grow, we will start to hit problems. What we're doing here is we're writing CSS in a very, very human order. This is the way a human looks at CSS. However, the problem we've got is that a browser doesn't care whether the header is the first thing in a photoshop file or not. All a browser cares about is what specificity a selector might have, how far reaching that selector might be, what might inherit from that selector. So, if we begin writing our CSS in a very human structured way, we'll soon run into problems, where perhaps the first bit of CSS works fine, and we write another bit of CSS and this works just fine. We write a third bit of CSS again, not encountering any problems. All of a sudden, we might write a fourth bit of CSS but for some reason gets overridden by this CSS here. This could be caused by the specificity walls, this could be caused by selectors fighting each other up a prominence, it could be caused by any number of things, but without fully considering our CSS architecture by writing CSS in what I would consider a very human way. Well, not really very sympathetic to help CSS actually works or how the browser would appreciate receiving that CSS. So now we've got a problem. We've got a problem here where we wanted to fix something. We could refactor this bit of CSS tidy it up and remove the problem but that's not typically what a developer would do. We might have time constraints, we've got deadlines, but what we were most likely to do is to just hack something around to fix it. So, we might end up sticking an important down here, doing something pretty nasty. Once we've solved that problem, we move on. Next bit of CSS happens to work just fine. Next bit of CSS works just fine. Next bit of CSS gets overrun by this, and then this bit here overrides this bit here. So, we've got a problem further up the stack. On a large project, I can almost guarantee that every developer has run into a situation like this and this frustration cuts productivity massively. A lot of the time is spent painting yourself into a corner, and then trying to fight it back out of it, and usually the problem only ever gets worse. Unless you dedicate a large amount of time to refactoring the CSS, you're going to continue down this path, and over a period of weeks, months, maybe even years, the problem will get so bad that you will need to completely start again. Let's continue. Write some more CSS. This is fine, this is fine that overrides this, that's a fine, fine, that gets overridden, gets overridden here. This consistently or constantly erratic nature, this kind of inefficiency is very prevalent among large project, and this is how CSS projects begin to spiral out of control. So, after a long enough time in this project has matured, we find that we've got all of these inefficiencies happening quite frequently. Usually, you'll identified this frustrations first hand, as you're working on a project, you will notice that we're getting these problems. You will notice that perhaps a six month old feature, is overriding a feature that you actually write right now today. Another good way, an easy way of identifying these in the browser, is in chromes inspector. When you do right click and inspect element, if you see a lot of CSS with lines there, a lot of strikethroughs, this represents tremendous inefficiency. This represents CSS that was written at some point, saved to disk, compiled into a styler-sheet, sent to a web server, ultimately sent to a user, sent to their browser, and it was never used. It's in efficiencies where we're constantly overriding CSS that was written many months previously. Now, if this diagram right here represents Phase one of a CSS project, perhaps it's the initial build of a project, the initial series of features for a project. Problems get even worse when we begin to add new distinct features or new distinct phases. So, if this represents Phase one, typically, the place where we would put Phase two of a CSS project is unfortunately, we tend to bolt on the end. This is how CSS generally tends to work. We just bolt things on the end. Phase three, stick on end of that still. So the problem gets compounded where not only is the code inside each phase fighting against itself, we could end up with entire phases of the project fighting each other as well. Now if you look, we've ended up with this odd phenomenon where our CSS is kind of laid to phase one on top, Phase two, Phase three, and this reminds me of looking at the fossil record. Right? You've got some cretaceous CSS here, some jurassic CSS here. There is absolutely no reason I should be able to slice down your CSS and read it chronologically. There is no reason why your CSS project should mirror your product roadmap. But most of the time, if we don't have a structured way of working, that's exactly what happens. I shouldn't be able to work out that on this date you released this feature purely from looking at a styler-sheet. By using IT CSS, we can take all these problems and re-imagine a structure in which this disappears. These problems we're witnessing here, this could have striped through this very erratic jumpier around nature we get inside the CSS project, can be caused by a number of things. Mismanaged specificity. So, use of selectors that are too heavy duty, it could be caused by drawing things in an inefficient order or an impractical order, or it could be caused by designing things or writing code that takes too much and opinionated stands too early on. Inverted triangle CSS aims to take all of those three core tenants and formalize them forming each side of the triangle. 4. Specificity Wars: So, let's take a look at what the Triangle actually comprises. We mentioned briefly specificity. Specificity is a selector's inherent weighting, its prominent, its ability to override other dissimilar selectors. Specificity is one of the hardest things to manage on a CSS project at scale. One of the first key rules when writing CSS for large project is, always avoid the use of the id selector. If you want to know more about why we've banned the id selector in CSS, refer to the resources. So, specificity is a huge, huge problem when writing CSS at scale. In order to help development teams visualize the specificity of their entire project, I came up with a concept of a Specificity Graph. What the Specificity Graph will do is, take the previous diagram, [inaudible] the entire stylesheet, and plot the specificity of its selectors. It's a simple line graph. We plot the specificity of a selector. On the X-axis, we plot the line number at which that selector appears. Now, starting with an existing project, perhaps we begin with the star selector. The star selector carries a specificity value of zero. So, at line one to line 3,000, we might start with a selector with specificity value of zero. In an existing or legacy project, the chances are very high that we haven't actually managed our specificity properly. This could lead to a Specificity Graph that looks something like this. Perhaps we start with a star selector, maybe some element selectors, somebody used an ID, maybe some classes among here, and nested class. What we will see as we go through is, we plot the different types of selector and their relative specificities on a graph that could end up looking something like this. It's important to note at this point that this is a purely theoretical model. This isn't an actual Specificity Graph of an actual project. If you'd like to see a true Specificity Graph, again, refer to the resources. There are tools available that will take an input stylesheet and build you an accurate graph. For now, however, just see this as a mental model to help visualize the problem of mismanaged specificity. An existing or legacy project, without it's specificity properly managed, may have a graph that looks like this. As you can see, there is very little consistency. Now, the problem isn't necessarily here, with high specificities. The problem exists when we want to contribute code in an area of low specificity. If we want to do some edits or some additions or add a new feature to this particular part of the codebase, we have the worry that perhaps this selector here could inadvertently override us. If that's the case, we may have to introduce something here like an important or a nested selector or some other kind of hack to artificially increase the specificity of this selector to override that one. This in turn brings us another problem because what if this part of the codebase here needs to now override this one? We get stuck in this one-way street, where we can't just bail out at any point, we can't just opt out of this model. We're in what are known as the Specificity Wars, where we have to keep fighting down the exact same path, making the rest of the project progressively worse. This is what we typically call a bad Specificity Graph. So, on a real life project, the kind of graph shape we are looking for is constantly trending upwards. That is to say, we want specificity across the entire project to gradually increase as we go from line one to the end of the project, in our case, a relatively small project of just 3,000 lines. If we're to visualize that, it would look a little like this. A Specificity Graph that constantly trends upwards has the immediate benefit of the fact that anything defined later in the project will automatically override anything defined previously, just by virtue of its location. The practical upshot of this is that a feature defined, for example, right here, should automatically override anything defined previously by virtue of where it lives. The same can be said of a feature added, for example, here. This immediately begins to remove the problem of older or existing or even legacy features overriding new work. Now that we've arrived at the shape of the theoretical, healthy, good Specificity Graph, we can begin to retrofit this into something more tangible and something more workable. We can begin to take slices from this theoretical codebase and begin to create directories on the file system that will house our different types of CSS. The first slice or layer in our Inverted Triangle is dedicated to fairly generic reset-type of styles, things like normalize.css or your CSS reset, any kind of global box-sizing, anything that is very widely available to the project but has a very, very low specificity. This directory will house this kind of code and is named generic. Typically, we would find that the generic layer would be identical across almost any project you work on. You probably used the exact same normalize.css across different projects. You probably used the exact same reset.css across different projects. This means that this layer is very copy and pasteable and can be deployed across many different projects or product. After the generic layer, we begin to increase our specificity. We step in to what is known as the elements layer. The elements layer, predictably, contains any CSS dedicated to styling HTML elements. For example, what does an a element look like without a class on it? What would an h1 element look like without a class on it? We've increased specificity slightly, and we've start to change the function of the CSS to begin adding some design styles. But it's still a very low specificity and quite broad layer. A good rule of thumb when thinking about the elements layer is to imagine what your site would look like if it had no classes or IDs anywhere in HTML whatsoever. How would the CSS make a simple h1 and paragraph look? How does CSS make a simple link an unordered list look? Beyond the elements layer, we step into what is known as the objects layer. The objects layer is the first layer in which we are allowed to introduce class level specificity. So, whereas the generic layer starts with something as low specificity as the star selector, the elements layer deals only with HTML element selectors. The objects layer is allowed to begin dealing with class level specificity. In CSS, an object is a structural design pattern. It comes from a school of thought named Object-Oriented CSS, which was developed by Nicole Sullivan. Object-Oriented CSS could be a Skillshare course in itself, so please refer to the resources for extra learning. But for now, all you need to know is the objects layer is the first layer which introduces class level specificity, and it deals with structural design patterns. These are things like grid systems. The next layer that we encounter in Inverted Triangle is known as the components layer. For me, the components layer is by far the most important. The components layer is the thing that contains the majority of what we would know as the website. Components are things like buttons or navigational elements or carousels. The components layer contains the thing that the user would see and interact with. You should think of the preceding layers as very architectural. These are the things the user is very unlikely to be aware of. The user doesn't really care if you use normalize.css, the user doesn't care which grid system you use. The previous three layers are where we handle most of the architectural problems, and the components layer is where we begin to achieve encapsulation. The components layer would be made of single files that would control perhaps a carousel or a drop-down or a button. Proportionally, the components layer makes up the biggest part of the project because most of your website would be components. This stands to reason that you would make most of the changes and additions to your project in this part of the codebase. Very important, therefore, we encapsulate the code in here very well. The final of the default ITCSS layers is known as the utilities layer. Now, what you'll notice here is this enormous spike toward the end. That's because the utilities layer is reserved for all the nasty CSS you don't really want to talk about. The utilities layer is where you might drop things like hacks or your IE7 stylesheets. Here, you can also get away with using important. Now, if we step back and look at this completed graph, we can begin to see a more tangible and meaningful output. We can see that as we progress from line one towards line 3,000 of our project, the specificity of our CSS only ever increases. As we step through that increase in specificity, we begin to take vertical slices out of the project and categorize our CSS around certain functions. 5. The Three Sides of ITCSS: Now, you're probably beginning to wonder how we've managed to get this far and not even seen a triangle yet. Well, we're going to look at exactly where this fits in. We just learned about specificity graphs and quite a lot of detail, the inverter triangle work on three core principles and the most important one of those is specificity. Now, this diagram once again represents the entirety of your CSS project whether that is a single CSS file or whether that was the result of many SAS files compiled into one resulting stylesheet, this triangle represents all of that put together. So, again, we start line zero and we progress down to a line 3,000. Each edge of the triangle represents one of the three core principles. The first being specificity. Specificity will always increase as we progressed through the project from line zero towards line 3,000. Our specificity should only ever increase. The second core principle underpinning ITCSS is a principle called explicitness. Explicitness looks at the idea of how opinionated a piece of design might be. For example, if only one button on the entire website needs to have a red background, you wouldn't apply that red background to every single A element, you would wait until later in the project to identify that one button and apply it there. A lot of the reasons CSS project starts to go awry and start to fall apart, it's because people have a tendency to design too much too early on and then have to spend the rest of their project undoing that. Explicitness forces some restraint and makes developers only opt into additional design changes as they are required. The third and final core guiding principle behind ITCSS forms the last side of the triangle and indeed brings everything together, that principle is known as the reach. Now, whereas specificity and explicitness both increase as we go through the project, reach will actually decrease. Reach deals with how much of the page or the component or indeed the entire website a specific selector is able to affect. A very far reach selector, it's like the star selector can affect the entire DOM. It also has a very low specificity. Conversely, a single class can only affect a single DOM node at a time, the DOM node to which is attached, and classes also happens to have a much higher specificity. The reach decreases as we go down the triangle and is what makes a triangle at all. Without reach, it would be the inverted square, which I guess is just a square and squares don't sell workshops. Reach brings the entire triangle together and decreases the amount of the page or component of a DOM we can touch at any given time. So, as is my intention, this is all very high level. What I'm going to do is quickly scribble an example selectors beside the triangle to show you what kind of code you could expect to find where. I mentioned already is the star selector, which carries a specificity value of exactly zero. The star selector can affect every single DOM node on a page, cow is very low specificity, and therefore should also be very explicit. You wouldn't want to apply font weight ball to the star selector. Progressing further, we may find perhaps an A element selector. The A element has a higher specificity than a star selector and therefore can only affect a little bit less of the DOM, only every anchor element can be styled. Progressing further, we got a more explicit design style, perhaps we wont style a button. So, a button is an increasing explicitness. An increase in explicitness carries a natural increase in specificity because we would have to use a selector like.button. What you tend to find is that specificity and explicitness are relatively equally matched. Anything with a specificity of this would have a corresponding explicitness. You wouldn't want to apply a button's design style explicitness against the star selector specificity, which would be very detrimental. Let's imagine for a second that we have a specific type of button, perhaps a button that cannot be clicked on by a user because they haven't input a correct email address. We'd have to get another selector for that. Now, our design style has got more explicit because it's not just a button, it's a kind of button that can't be used. This increase in explicitness may need to bring an increase in specificity. So, we might have a selector like. disabled, which denotes an element that can't be used. Taking our specificity and explicitness, we naturally arrive at the reach of that selector. The disable class would only be applied to the one button is disabled at any given time, therefore it's reach is very small. If we're to look at the A element, that could be upwards of 100 links on a page, this means it's using A selector, which has relatively low specificity, also means that because there could be 100 links on a page, we can't give them an overly opinionated design style and because there could be upwards of 100 links on a page, the reach of that button is actually very high. These are how the three key metrics, the three core principles all play into one another. Normally, what you will find is if you obey two of the three principles, you get the third one worked out for free. Whenever you need to add code to a project, ask yourself, "How explicit or opinionated is the design style?" If it's a fairly opinionated design style, you would need an equivalently opinionated selector that will therefore bring an in specificity. By virtue of having quite an explicit design style and a high specificity, you are easily going to get the rich worked out for you. To briefly expand on the reach and what that means for the shape of our project, let's quickly reimagine the triangle as actual cone shape rather than a flat triangle. This funnel shape now represent how the selectors as you progressed from line zero to line 3,000 of your project affect less and less of the DOM at a time. So now, what your find is each layer is responsible for styling less and less of the page as you progress. The first layer targets almost everything, and progressively less, and less, and less before you reach the bottom of the triangle or now, I guess the inverted cone, and your affecting with pinpoint precision single DOM nodes at a time. A useful analogy for this entire workflow is if you were to imagine a sculptor making a statue. A sculptor may approach a quarry and ask for a large block of marble. Now, what the quarry would do is perhaps blast that piece of marble out the side of the rock face, and take it down to the stone mill, and stone mill will take that big chunk of rock, and make it into a nice workable cube. Then, the scope to take that bit of rock to the studio, and would get a big hammer and a big chisel, and roughly made the shape of a person. After they've done that, they'll get a smaller hammer and a smaller chisel, and start to put details like fingers. What would be a very unusual way of working is if that sculpt just took a big block of marble roughly can I've just blast off my rockface and fashion just the perfect finger sticking out of the top of it. What I try to do here is the exact same with CSS, cut broad strokes early on in a project to cover maybe 50 percent of the heavy lifting. Then, the next bit covers the next 10 percent and then five percent until we get these smaller and smaller bits of work targeting fewer and fewer DOM nodes at a time. Working in this way allows us to keep targeted, and keep things well managed as we progress further and further into the project. So, we just looked a lot of diagrams just there, we don't look at a single line of code. Let's now move over to the computer. See how this stuff comes together in a project, on the actual file system using real CSS. 6. ITCSS in Practice: So, we just spent a bunch of time there looking at very conceptual diagrams. We didn't look at a single line of code. So, what I want to do now is dive into an example project that I've built. The example project is called Discover. It's a mock kind of travel website and it's got a great repository that you've got complete access to, so make sure you check the resources for that. It's also hosted on LINE URL, so you can see exactly what we're building. But let's take a look, this is a small kind of made up project that is built using ITCSS. The first thing I want to show you is what this looks like on the file system, what does this actually look like in Finder. Now, it's a very small project because it was invented purely for example sake, so you're not going to see anything complex like any sort of task or one has any build pipelines, anything like that. Here, we can start to see the makings of the inverted triangle. The first thing you'll notice is we've got one main.scss file, this is our single entry point. So, this one file is responsible for importing all of the other aspects of the CSS project into their respective order as per the inverted triangle. Next, you will see that every single layer of the triangle has a corresponding directory. Now, this is completely optional. One of the key things of ITCSS is it does leave a lot of these decisions down to the developer. I used to have a set up where I didn't have a directory for each type of CSS file. I just had a flat directory structure but I realized that after a while that gets really hard to manage, so I move towards a structure more like this, in which we can see that every type of CSS selector, every type of layer in a triangle does have its own corresponding directory. I've grouped all of the files for each layer into that directory that is named after me but what I also do is I named each of my files layer.file.scss. So, here, you'll see elements.headings.css. Here, we might see objects.layout.scss. Having the layer name inside of the file name makes it very easy to understand which part the project I'm working on at any given time. But again, this is completely down to developer preference. As well as grouping each type of file into its corresponding directory, I also like to name each file after the layer it pertains to. So, what you can see here is components.avatar.scss or in this file or it's folder right here, we've got objects.layout.scss. The reason I like do this, is it's nice to see just from the file name alone, which part of the project I'm working on. If I have objects.layout.scss open in my text editor, I know exactly which part of the project I'm contributing to. Now, let's take a look at our main.scss. This is the main entry point. This is the single source file that zips up all of the rest of the project and it is this source file that produces main.scss later. Looking up main.scss in my text editor, the first thing you'll notice is this table of contents. Again, this is completely optional, this is developer preference. But I like to maintain a fairly manual table of contents at the top of my main entry point. What this allows me to do is write down in human terms exactly what is contained in the project. What you often find is as projects get larger and get older, a lot of people become unfamiliar with what kind of CSS exists inside this CSS directory. They don't know which features already exist, what's already been built and so on. While maintaining this rather manual but very human readable table of contents, developers are always made aware of what is available to them. Moving on from a table of contents, we will begin to see my @import directives. So, what you will see here is my import for the settings and tools layers. These are purely pre-process of layers. This contains global settings for my project such as typographical scales or color palettes. The tools layer contains things to do with any mixings or functions the project might require. Let me move on to the layers that we saw previously. These are things we drew down in our diagrams. If you noticed the relative size of each layer, you can start to understand where the bulk of the project comes from. For example here, the generic layer is rather small. We don't really have much in here, we've got our global box sizing, some normalize and reset kind of styles and some shared styles also. But let's look into the elements layer. We can see we've got a few more files here, starting to get a little larger. This is where we're signing things like headings, links and lists. These are the html elements that make up our page. Beyond this, we move to our objects layer. The objects layer is the first layer in which we're allowed to introduce classes. This again is slightly larger than the elements layer but when we progress to the components layer, we see that things are by far much, much larger. The components layer makes up the bulk of any given project. The majority of your website will be component based, ITCSS supports this by creating an entire part of the project for all of these things live. What you will see is consistent names, components.logo, components.masthead. It is in these files that we find the majority of our UI. Finally, we move towards our utilities layer and it's at this point we import any kind of debugging files or any utilities and sort of helper classes. It's at this point that we may bring in specific IE 7 fixers or different fixers for different browsers. Utilities layer is reserved for CSS that isn't quite perfect. Its reserved for CSS that is quite high specificity, often even containing importance. We'll look at this in more detail shortly. By looking over this file, we should hopefully see that even quite a large project can be distilled into very manageable chunks. We can quickly see exactly what lives where and why. This means that looking for existing CSS becomes trivial and it means adding new CSS should become fairly simple and straightforward. By looking at the patterns that have been left by a previous developer, we can pick up where they left off and create a much more consistent code base. As you can see from the current file we're looking at, it has all of the standard ITCSS related at present. But certain projects might require different layers or the removal of certain layers. ITCSS leaves this completely up to us. So, that was a real quick look at how the triangle can come together in one imported SAS bundle. Of course, depending on your project, your circumstance, your build process, your build pipeline, the specifics may well differ and the beauty of ITCSS is it's entirely up to you how you modify this workflow. What I want to show you next, however, is the resulting SCC file. All the diagrams we drew previously were from line 0-3,000, is what we used, they were represented complete compile stylesheets. Let's look at how that turns out. Now, let's look at how this all comes together once it's been compiled into one big stylesheet. Immediately here, we will that we've got a familiar table of contents, that carried over from our main entry point, our main.scss file. If we whisk past that, we're going to start to see some natural SCSS. Now, remember, the three core principles of the triangle, low specificity toward high specificity, inexplicitly towards explicit and wide reaching down to narrow reaching. So, right away we can see here very low specificity. You've got a star selector, we've got the html element selector, these are very low specificity selectors that cast a very wide net. The star selector captures literally everything in the DOM. So, as we progressed through this, and I'm going to do this relatively quickly, what you should see is the specificity graph forming before your eyes. As we whiz through low specificity element selectors, next up we should start to see some class selectors appearing when we get towards objects. Here, we've got 0-layout, so we've got that immediate specificity bump into our objects layer, the first layer in which we're allowed to see classes. What you'll notice here is these classes are proceeded with an o-. Now, this is an optional naming convention that comes with ITCSS. Progressing from here, we find more classes, so we don't get an increase in specificity but we do get a change in purpose. Here we've got to c- which denotes our component classes. Components are the bits that make up the majority of the UI and here we see it's using a bamm like naming convention. As we progress beyond the component classes, we're going to start finding very, very high specificity classes. This is where we get to our utilities layer. Utilities layer is a special case. It's reserved for any kinds of CSS we're not particularly thrilled about. On large projects, it's guaranteed it's going to happen, that you will have to contribute some CSS that isn't quite as you would like. Now, that's not ideal. Of course, it's not ideal but it is probably going to happen, it's happened on every project I've ever worked on. So, what's quite important is having a dedicated place for these bits of CSS that live our utilities layer becomes a catchall, a miscellaneous drawer that captures all of the CSS that doesn't quite fit anywhere else. Leaving it toward the end means that it doesn't risk setting the tone for the rest of the project. You don't want to call your hacky CSS at the beginning of your stylesheet because doing so would mean that the rest of the stylesheet has to fight around it. We draw all this stuff right at the very end, so it can immediately override anything that came previously with very minimal overhead. As we progressed right to the very end of the stylesheet, we will find that that's where things finish. We end on a very high specificity with some very, very targeted single use case classes. These are utility classes that are designed to overwrite anything that came previously with minimal effort. Now, I would urge you to absolutely go and dig around this repository because as you start to pick it apart, you'll soon find all of the things we've discussed sit immediately into place, you'll find that things make much more sense. You'll find yourself able to navigate the code base very very quickly based on the conceptual stuff we learned earlier. Now, of course, that was just a demonstration, for demonstration sake. It was a very small, very self-contained demo. It's not necessarily that realistic of a large sort of beast of a project. So, what you'll find is that as you implement ITCSS in the real world, the benefits will become way more apparent, even in this trimmed down example hopefully we learn that by following the three core principles of ITCSS, we can begin to give things dedicated places to live and dedicated places to be found. What this means is, if any developer parachuting into a project can easily locate themselves and easily navigate around the code base they potentially never even seen before. 7. Final Thoughts: So, there we have it, an introduction to the Inverted Triangle CSS architecture. We learned how CSS, when left to its own devices, can quickly become unruly and hard to manage. But then we also learned that with a lot of diligence and some formality, we can easily write those things back in and help them work to our advantage. Above all else, what I really want people to take away from this is the fact that ITCSS isn't a complex system, it doesn't require drastic changes in process or form. As well as that, it's a very very light-touch. So, you can modify ITCSS to suit your technology stack, skills on your team, the size of your project, even the type of project you're working. On more technical level, I think my key takeaway for you would be, i'ts really really really important to manage things like specificity very very well, because this is usually the technical way in which projects start to spiral the quickest. So, what next? Well, the first thing you could do is join the discussion. If you've got any questions, any concerns, any examples, or downloads you would like to discuss or go out in the open, absolutely you go and do that. I'll keep an eye on there and answer any questions you may have. Of course, keep an eye on the resources sections, a bunch of links to the different reading materials and keep an eye on that. There's plenty of stuff to look at. So, that was it. Thank you so much for hanging out. I'm really looking forward to seeing how you take ITCSS, mold into your own project and your own work, and I guess I'll see you next time.