1 00:00:00,000 --> 00:00:04,450 [CSS Best Practices with Guil Hernandez] 2 00:00:04,450 --> 00:00:06,700 [Guil Hernandez] Hi everyone, I'm Guil, one of the front end 3 00:00:06,700 --> 00:00:08,700 design teachers here at Treehouse. 4 00:00:09,040 --> 00:00:12,700 In this workshop we'll be covering CSS best practices. 5 00:00:13,270 --> 00:00:15,900 These are methods we can use to make our CSS 6 00:00:15,900 --> 00:00:19,000 more efficient, maintainable, and scaleable. 7 00:00:19,490 --> 00:00:23,740 As we will soon find out, there is a lot more to writing good CSS 8 00:00:23,890 --> 00:00:27,950 than simply knowing all the latest and greatest features and techniques. 9 00:00:28,560 --> 00:00:31,660 Today's web sites and applications are larger than ever 10 00:00:31,910 --> 00:00:34,510 and a lot hinges on the CSS architecture, 11 00:00:34,810 --> 00:00:40,880 so CSS that is poorly thought out can be a strain on development in the long run. 12 00:00:42,130 --> 00:00:45,900 In this workshop we will be covering topics such as 13 00:00:45,900 --> 00:00:49,940 CSS architecture, classes versus IDs. 14 00:00:50,250 --> 00:00:53,630 We'll also get into specificity in selectors, 15 00:00:54,250 --> 00:00:57,700 and we'll then cover some CSS reset methods 16 00:00:58,440 --> 00:01:03,660 along with ways to format our CSS and using vendor prefix. 17 00:01:04,190 --> 00:01:07,190 Finally, we will get into some helpful tools 18 00:01:07,420 --> 00:01:11,860 to help us write CSS with these best practices in mind. 19 00:01:12,950 --> 00:01:18,920 When writing CSS our main goal should be that our CSS is 20 00:01:18,920 --> 00:01:24,190 predictable, reuseable, maintainable, and scaleable. 21 00:01:24,630 --> 00:01:27,170 So let's review these in detail. 22 00:01:28,550 --> 00:01:33,970 CSS rules that are predictable should behave as we expect them to. 23 00:01:34,460 --> 00:01:38,040 If we need to update or add any new CSS rules 24 00:01:38,190 --> 00:01:40,890 they shouldn't affect other parts of our site. 25 00:01:41,210 --> 00:01:45,680 Reuseable CSS should be decoupled from the html. 26 00:01:46,120 --> 00:01:49,490 So if we need to add any new components or features 27 00:01:49,680 --> 00:01:54,260 we shouldn't need to recode any patterns or solve any problems 28 00:01:54,650 --> 00:01:57,480 that we've already solved with existing CSS. 29 00:01:58,250 --> 00:02:02,510 Now one of the most important ones is making our CSS maintainable. 30 00:02:03,100 --> 00:02:07,580 This means that we should not have to refactor any of the CSS 31 00:02:07,580 --> 00:02:12,010 if we need to add updates or new features and components. 32 00:02:12,550 --> 00:02:16,200 The added features or updates we make should not break 33 00:02:16,200 --> 00:02:18,960 any of those other components in the site. 34 00:02:19,710 --> 00:02:26,300 Now at some point our site or application will need to scale, which will then require 35 00:02:26,300 --> 00:02:30,990 more developers working on and maintaining our site and our code, 36 00:02:31,500 --> 00:02:35,950 so we need to write our CSS so that it can be easily managed 37 00:02:36,420 --> 00:02:41,240 by other developers who are looking at our code for the very first time, 38 00:02:41,550 --> 00:02:44,140 and there should not be a learning curve for them. 39 00:02:44,800 --> 00:02:50,830 This is when a lot of these best practices come in to help us with a lot of these goals. 40 00:02:51,660 --> 00:02:54,770 For example, keeping our CSS "DRY." 41 00:02:55,800 --> 00:03:01,120 DRY, or "Do Not Repeat Yourself," is a common best practice 42 00:03:01,600 --> 00:03:05,850 in web development where the main idea is to avoid 43 00:03:06,210 --> 00:03:09,980 repeating these same chunks of code or patterns. 44 00:03:10,340 --> 00:03:14,870 If we have bits of code that are repeated multiple times throughout the site 45 00:03:15,310 --> 00:03:18,200 it's a good idea to refactor the CSS set 46 00:03:18,200 --> 00:03:23,820 so that there's only one instance of that code—or one occurrence of that code. 47 00:03:23,820 --> 00:03:28,430 This way each property and value pair is only defined once in our style sheet. 48 00:03:29,320 --> 00:03:35,330 The idea with DRY is to group these repeated CSS properties together 49 00:03:35,330 --> 00:03:42,240 into one rule then add selectors to those groups if they share the same property. 50 00:03:42,240 --> 00:03:45,940 That way our CSS is more maintainable and we would only have to change 51 00:03:45,940 --> 00:03:50,810 one line of CSS, which results into a cleaner html file, 52 00:03:51,320 --> 00:03:56,550 and we only rely on those specific selector groups in the CSS. 53 00:03:57,270 --> 00:04:02,010 For example, we might have a CSS file with 3 rules. 54 00:04:02,610 --> 00:04:07,720 Each of these share the same padding and border radius properties. 55 00:04:08,190 --> 00:04:13,130 The button and field rules share the same display property, 56 00:04:13,470 --> 00:04:18,180 and the float property is only declared in this common rule here. 57 00:04:19,120 --> 00:04:24,790 To make this CSS a bit dryer we can simply separate those shared properties 58 00:04:25,330 --> 00:04:29,510 into 1 rule that groups the selectors using those properties. 59 00:04:29,910 --> 00:04:33,390 So now the button field and column selectors 60 00:04:33,950 --> 00:04:36,120 share the padding and border radius declarations, 61 00:04:36,810 --> 00:04:40,560 and below that the button and field selectors share the display property, 62 00:04:40,880 --> 00:04:45,290 and the column rule now only has that float property declared. 63 00:04:45,390 --> 00:04:49,750 Now this was a very simple example of grouping selectors together 64 00:04:49,750 --> 00:04:54,690 that share the same properties, but what if we have to deal with hundreds of lines 65 00:04:54,690 --> 00:05:00,350 of CSS or large scale sites that have tens or hundreds of pages? 66 00:05:01,180 --> 00:05:08,160 Well, object-oriented CSS, or OOCSS, can be really useful for this. 67 00:05:09,220 --> 00:05:15,760 OOCSS was introduced by Nicole Sullivan in 2009, 68 00:05:16,270 --> 00:05:20,910 and the base principles are a lot like our previous example with DRY. 69 00:05:21,530 --> 00:05:26,770 The object in OOCSS is a repeating visual pattern. 70 00:05:27,560 --> 00:05:31,460 That visual pattern then gets abstracted into 71 00:05:31,550 --> 00:05:34,820 these independent blocks of CSS or modules. 72 00:05:35,580 --> 00:05:39,050 Those modules can then be reused anywhere in our site. 73 00:05:39,690 --> 00:05:44,020 So with OOCSS we will need to think more in terms of style patterns 74 00:05:44,540 --> 00:05:47,250 instead of just styling these individual elements. 75 00:05:47,880 --> 00:05:52,330 We'll also need to think of our web site or app as these code-independent 76 00:05:52,330 --> 00:05:57,270 components that can be rearranged without affecting surrounding components. 77 00:05:58,180 --> 00:06:01,440 OOCSS has 2 main concepts. 78 00:06:02,300 --> 00:06:06,330 The first one is the separation of structure from appearance 79 00:06:07,120 --> 00:06:10,400 and the separation of containers and content. 80 00:06:11,740 --> 00:06:15,900 When we separate the structure from appearance it means that 81 00:06:15,900 --> 00:06:20,850 once we spot these repeating patterns in our CSS we'll need to abstract them 82 00:06:21,250 --> 00:06:24,310 into these separate skins that are reuseable. 83 00:06:24,810 --> 00:06:27,910 We'll then need to name those skins logically, 84 00:06:28,450 --> 00:06:34,910 and, finally, we'll add those skin classes to our html elements that require those styles. 85 00:06:35,790 --> 00:06:39,810 For example, here in our CSS we again have 3 separate rules. 86 00:06:40,210 --> 00:06:42,860 Now they all share the border, border radius, 87 00:06:43,470 --> 00:06:47,250 padding, and box shadow values as we can see here. 88 00:06:48,150 --> 00:06:54,410 Using OOCSS we can actually abstract those into a separate rule or object 89 00:06:54,820 --> 00:07:00,190 and make that our base skin style, which can be reused anywhere in our project. 90 00:07:01,260 --> 00:07:06,030 Then the html can still have those classes for container, box, and button, 91 00:07:06,440 --> 00:07:09,820 but we can then append those skin classes 92 00:07:09,820 --> 00:07:13,130 in the class attribute to bring in those space styles. 93 00:07:13,250 --> 00:07:17,780 Now if skin needs to be changed we only need to change it once in the CSS. 94 00:07:19,450 --> 00:07:22,330 When we separate containers and content 95 00:07:22,900 --> 00:07:27,780 the style components we create should be code or location independent. 96 00:07:28,250 --> 00:07:33,140 So the elements should be reuseable no matter where they are on the page, 97 00:07:33,910 --> 00:07:41,330 and the CSS should not be specifically tied to the html or a location in the document. 98 00:07:41,830 --> 00:07:43,910 The module should actually be able to adapt 99 00:07:44,670 --> 00:07:47,260 to different containers and be easily themed. 100 00:07:48,140 --> 00:07:53,100 When we separate containers and content all elements with those given classes 101 00:07:53,100 --> 00:07:56,580 will also look the same on the page no matter what. 102 00:07:58,000 --> 00:08:02,770 For example, we might have a page with a header and footer 103 00:08:02,900 --> 00:08:08,590 that span the full width of our browser, but then we would probably like to have 104 00:08:08,590 --> 00:08:13,830 these inner containers that need to be centered on the page, as we can see here. 105 00:08:14,420 --> 00:08:17,140 So our html might look something like this 106 00:08:17,140 --> 00:08:21,490 where we have the main header, main content, and main footer elements 107 00:08:22,060 --> 00:08:26,960 with these header inner and footer inner divs nested inside. 108 00:08:28,040 --> 00:08:34,760 These will need to share the same structural styles like width, margin, and padding. 109 00:08:36,030 --> 00:08:39,630 Our CSS could look something like this with these 3 selectors 110 00:08:40,220 --> 00:08:43,200 grouped into 1 rule that shares those properties. 111 00:08:44,150 --> 00:08:49,520 With the separate containers and content principle in mind, we can abstract 112 00:08:49,520 --> 00:08:55,910 those structural styles into their own reuseable class called global width. 113 00:08:56,340 --> 00:09:03,800 Then in our html we'll just need to add that global width class to the class attribute. 114 00:09:04,680 --> 00:09:11,860 Some of the benefits to using OOCSS is that it results in smaller style sheets 115 00:09:11,860 --> 00:09:14,780 that are easier to maintain and scale. 116 00:09:15,430 --> 00:09:20,750 It also makes our CSS predictable, which is one of our main goals when writing CSS, 117 00:09:21,220 --> 00:09:24,550 and we could very well build an entirely new html page 118 00:09:24,770 --> 00:09:27,430 without having to touch the CSS at all. 119 00:09:27,770 --> 00:09:30,690 Once we've defined all these modules in the style sheet 120 00:09:31,030 --> 00:09:33,400 we can sort of plug them in where needed. 121 00:09:34,000 --> 00:09:42,410 For more info on OOCSS you can check out github.com/stubbornella/oocss 122 00:09:42,680 --> 00:09:45,550 or check out the link I added to the workshop notes. 123 00:09:46,550 --> 00:09:51,390 A similar method called Scaleable and Modular Architecture for CSS 124 00:09:52,040 --> 00:09:58,360 was created by Jonathan Snook as a style guide that helps organize our CSS. 125 00:09:58,920 --> 00:10:03,160 SMACSS is very similar to object oriented CSS 126 00:10:03,160 --> 00:10:08,340 in that it helps structure our code for projects on any scale. 127 00:10:09,300 --> 00:10:14,040 It also combines repeating CSS patterns into these reuseable components 128 00:10:14,040 --> 00:10:16,080 we can use anywhere in our sites. 129 00:10:16,780 --> 00:10:20,450 The difference is that SMACSS separates our components 130 00:10:20,740 --> 00:10:25,350 into 5 general categories and those categories are 131 00:10:25,710 --> 00:10:30,350 the base rules, the layout rules, the module rules, 132 00:10:30,900 --> 00:10:33,290 the state rules, and the theme rules. 133 00:10:34,550 --> 00:10:39,410 Our base rules in SMACSS define all the default styles 134 00:10:39,820 --> 00:10:43,110 and how they should look no matter where they are on the page. 135 00:10:43,860 --> 00:10:50,130 Base rules are directly applied to element selectors, not classes or IDs. 136 00:10:51,900 --> 00:10:56,510 Base rules can be used as a CSS reset. It's very good for that. 137 00:10:57,000 --> 00:11:02,110 For example, here we have base rules with our box sizing for all elements, 138 00:11:02,740 --> 00:11:05,170 one that removes margins and padding from the body, 139 00:11:05,900 --> 00:11:08,650 sets the body font styles and so forth. 140 00:11:10,670 --> 00:11:16,730 The SMACSS layout rules are what divide the page into the major components. 141 00:11:17,100 --> 00:11:20,700 For example, the main header, the sidebar, the footer, 142 00:11:21,050 --> 00:11:25,260 and these components can then contain 1 or more modules. 143 00:11:26,580 --> 00:11:30,880 For example, here we have some layout rules for our main wrap container, 144 00:11:30,880 --> 00:11:36,840 the main headers and footers, and some of the layout columns of the page. 145 00:11:37,860 --> 00:11:44,100 Our module rules are the reuseable modular components or the minor components. 146 00:11:44,730 --> 00:11:49,730 Each module we create should exist as a stand-alone component 147 00:11:49,990 --> 00:11:54,100 so it can be easily moved throughout the layout without breaking anything. 148 00:11:54,860 --> 00:11:59,500 When we write module rules we should avoid using IDs and element selectors. 149 00:11:59,950 --> 00:12:03,240 We should stick with those class names since they're reuseable. 150 00:12:04,000 --> 00:12:08,470 For example, here we have examples of the main nav component, 151 00:12:09,220 --> 00:12:13,340 callout module, along with maybe a login or search-box component, 152 00:12:13,930 --> 00:12:17,060 and these should all be reuseable throughout our project. 153 00:12:17,060 --> 00:12:19,060 We should just be able to plug them in wherever 154 00:12:19,060 --> 00:12:21,230 we need to without affecting anything else. 155 00:12:21,810 --> 00:12:27,520 Now we can also subclass these module rules if we need to change the look 156 00:12:28,310 --> 00:12:30,900 because we want to place it in other parts of our site. 157 00:12:31,580 --> 00:12:34,250 To do that it's best to use a subclass 158 00:12:34,770 --> 00:12:39,800 instead of creating a new conditional style based on the new location. 159 00:12:40,560 --> 00:12:43,480 Here are some examples of the subclassed module. 160 00:12:43,900 --> 00:12:47,070 We might have these mod and searchbox components 161 00:12:47,320 --> 00:12:52,750 that maybe need to be modified to use in the footer or the sidebar sections. 162 00:12:53,320 --> 00:12:56,990 Instead of creating descendant selectors for mod and searchbox 163 00:12:57,220 --> 00:13:01,730 we can create those subclasses that contain those modified styles. 164 00:13:02,390 --> 00:13:09,630 Then in our html we can, for example, keep those searchbox and mod classes and, to 165 00:13:09,630 --> 00:13:15,960 bring in the modified styles, we simply append those subclasses in the class attribute. 166 00:13:17,330 --> 00:13:21,440 In SMACSS the state rules are what define 167 00:13:21,440 --> 00:13:24,570 how the modules look when in a particular state. 168 00:13:25,630 --> 00:13:28,450 These are the collapsed or expanded states, 169 00:13:28,950 --> 00:13:33,850 maybe a success or error state, or a hover inactive state in a link. 170 00:13:34,630 --> 00:13:38,120 State rules augment or override other styles, 171 00:13:38,380 --> 00:13:42,610 and we can apply them to layout and module styles. 172 00:13:43,250 --> 00:13:48,290 State rules can also be used with pseudo-classes, media queries, or JavaScript. 173 00:13:49,820 --> 00:13:52,440 Examples of state rules are, as we can see here, 174 00:13:52,440 --> 00:13:58,110 the hover rule for mod, maybe an active state or a transparent state. 175 00:13:58,560 --> 00:14:03,900 We also have these hidden states and maybe a JavaScript specific state 176 00:14:03,900 --> 00:14:06,660 for expanding or collapsing elements. 177 00:14:07,500 --> 00:14:12,990 Finally, the theme rules are what define the color scheme or the typography. 178 00:14:13,750 --> 00:14:19,030 Theme rules are similar to state rules in that they define how the layout might look. 179 00:14:19,640 --> 00:14:23,810 So they are what separate the themes into their own set of styles, 180 00:14:24,150 --> 00:14:26,150 so that they are easier to modifry. 181 00:14:26,610 --> 00:14:32,010 Theme rules are optional because we may not have a need for themes in our project. 182 00:14:33,360 --> 00:14:37,910 So, as Jonathan Snook states, "We'll need to think about our interface 183 00:14:37,910 --> 00:14:43,080 as not only modularly, but as a representation of those modules 184 00:14:43,080 --> 00:14:48,110 in various states because it will make it easier to separate styles appropriately 185 00:14:48,370 --> 00:14:51,170 and build sites that are easier to maintain." 186 00:14:53,660 --> 00:14:59,210 There has been a lot of discussion lately about using classes versus IDs. 187 00:14:59,710 --> 00:15:04,150 So let's talk a little bit about when it's best to use a class or an ID in a selector. 188 00:15:04,840 --> 00:15:12,620 It's best to use IDs as JavaScript hooks or as fragment identifiers in our page. 189 00:15:13,090 --> 00:15:18,270 For example, here we have 3 anchor elements that target sections of the page 190 00:15:18,270 --> 00:15:24,640 if their IDs match the # in our URL or in the href attribute. 191 00:15:25,210 --> 00:15:29,320 Here we have IDs being used as fragment identifiers, 192 00:15:29,620 --> 00:15:32,380 but we can then bring those in as JavaScript hooks, 193 00:15:32,380 --> 00:15:37,690 for example in our search field and the submit button functionalities. 194 00:15:38,900 --> 00:15:44,060 IDs are very heavy on specificity and they cannot be reused. 195 00:15:44,320 --> 00:15:49,300 That is why it's best to use classes because they are more flexible for styling, 196 00:15:49,700 --> 00:15:51,700 and they can always be reused. 197 00:15:52,220 --> 00:15:58,390 So then back in our html file we can add those to the elements for the presentation. 198 00:15:59,230 --> 00:16:01,900 Now there are a few more things to consider, for example, 199 00:16:01,900 --> 00:16:09,160 we should avoid using the same class or ID for styling and JavaScript. 200 00:16:09,670 --> 00:16:13,150 Doing that will make our architecture a lot more fragile 201 00:16:13,400 --> 00:16:15,500 because we're setting up a lot of dependencies 202 00:16:15,720 --> 00:16:19,310 between the CSS, JavaScript, and the fragment identifier. 203 00:16:20,000 --> 00:16:23,490 If we need to create JavaScript specific classes 204 00:16:23,870 --> 00:16:27,170 it's best to prefix them with something like JS. 205 00:16:27,680 --> 00:16:31,610 This way they're easily identifiable as JavaScript hooks 206 00:16:31,860 --> 00:16:36,360 and it decouples the presentational classes from the functional classes 207 00:16:36,880 --> 00:16:41,920 and, most importantly, it reduces the chances of affecting JavaScript behavior 208 00:16:42,360 --> 00:16:47,120 when we need to make those thematic or structural changes in the CSS. 209 00:16:48,440 --> 00:16:51,690 For example, here we have some JavaScript specific classes 210 00:16:51,880 --> 00:16:56,270 for maybe collapsing an element, hiding it, fading it, 211 00:16:56,660 --> 00:16:58,730 or sliding it on the page. 212 00:17:00,160 --> 00:17:05,210 This leads usa into how specificity is calculated in a selector. 213 00:17:05,750 --> 00:17:11,240 Specificity is what determines which CSS styles are applied by the browser. 214 00:17:11,940 --> 00:17:17,390 Selectors with the most specificity always take precedence over others. 215 00:17:17,950 --> 00:17:21,930 Let's talk a little bit about the calculations a browser will make 216 00:17:22,130 --> 00:17:25,210 in order to determine that specificity in a selector. 217 00:17:26,200 --> 00:17:30,950 It's important to understand this conceptbecause knowing how the browser 218 00:17:31,690 --> 00:17:36,280 will interpret your code can come in really handy when debugging CSS, 219 00:17:36,570 --> 00:17:38,730 and it will also save you a lot of time. 220 00:17:39,590 --> 00:17:45,030 The browser uses 4 categories to define the specificity in a selector. 221 00:17:45,240 --> 00:17:50,750 One of those is inline styles, which use that style attribute and elements. 222 00:17:51,150 --> 00:17:54,250 The others are IDs, next. 223 00:17:54,690 --> 00:17:59,990 It uses classes, attributes, selectors, and pseudo-classes, and, finally, elements. 224 00:18:00,550 --> 00:18:05,950 The browser then assigns a specificity value to each one of these categories, 225 00:18:06,200 --> 00:18:08,210 and we can sort of think of them as points. 226 00:18:09,690 --> 00:18:14,730 Each zero here represents each of the categories, respectively. 227 00:18:14,730 --> 00:18:18,170 So no selectors are zero points across the board, 228 00:18:18,630 --> 00:18:23,260 and if the selector consists of any of these four categories 229 00:18:23,710 --> 00:18:27,520 one point is added to its respective category. 230 00:18:28,450 --> 00:18:31,840 For example, 1 point will be added for every inline element, 231 00:18:32,100 --> 00:18:37,730 1 point for every ID, 1 for every class, and 1 for every element selector. 232 00:18:38,130 --> 00:18:41,840 Let's take a look at an example of a selector here. 233 00:18:42,110 --> 00:18:45,030 Here we have a selector that has 1 class. 234 00:18:45,590 --> 00:18:52,860 The browser then adds 1 class point, which gives us a specificity value of 1,0 or 10. 235 00:18:54,440 --> 00:18:59,780 Next, if the selector has 1 ID and a class in the selector 236 00:19:00,260 --> 00:19:04,430 the browser will then add 1 class point and 1 ID point 237 00:19:04,900 --> 00:19:10,010 which then gives us a specifricity value of 1, 1, 0 or 110. 238 00:19:11,150 --> 00:19:17,200 In another example, if we qualify that class by adding the list item element selector 239 00:19:17,430 --> 00:19:25,820 the browser will then add 1 point for the element and our specificity value is 1, 1, 1. 240 00:19:27,600 --> 00:19:32,220 If we then add an unordered list element selector to that nav ID 241 00:19:32,540 --> 00:19:38,610 the browser will then add 1 more element point, which gives us that value of 1, 1, 2, 242 00:19:39,130 --> 00:19:44,130 and, finally, inline styles are very heavy on specificity. 243 00:19:44,880 --> 00:19:52,230 As we can see, it gives inline the value of 1, which results in a specificity value of 1000. 244 00:19:52,690 --> 00:19:55,720 So other things to keep in mind with specificity 245 00:19:55,720 --> 00:20:00,970 is that we should not rely on parent or descendant selectors 246 00:20:01,390 --> 00:20:04,540 because they lower the specificity of child elements. 247 00:20:05,050 --> 00:20:09,580 A better approach is using name spaces as modifiers. 248 00:20:10,000 --> 00:20:13,230 That way they are self-contained and modular. 249 00:20:13,500 --> 00:20:16,260 The modifiers can then be used anywhere and they're 250 00:20:16,260 --> 00:20:18,460 not entirely location based. 251 00:20:19,500 --> 00:20:24,910 For example, we can prefix moidified selectors with the base class name. 252 00:20:25,500 --> 00:20:29,640 So here we have an element with the class title in the second rule 253 00:20:29,800 --> 00:20:32,880 that we might want a modifier for the sidebar. 254 00:20:33,280 --> 00:20:37,650 Well, instead of relying on that sidebar descendant selector, 255 00:20:37,870 --> 00:20:43,740 we can extend it by creating a new modifier class named sidebar title. 256 00:20:45,560 --> 00:20:49,870 Here's another example where we might want to adjust something for the sidebar 257 00:20:50,260 --> 00:20:52,720 when it's inside the main footer. 258 00:20:53,360 --> 00:20:57,550 For that we can create the modifier class using the main footer 259 00:20:57,550 --> 00:21:00,120 name space right in front of sidebar. 260 00:21:00,410 --> 00:21:04,400 It's very similar to subclassing module rules 261 00:21:04,400 --> 00:21:07,170 with that SMACSS approach we covered earlier. 262 00:21:07,560 --> 00:21:11,980 It's also important that we do not rely on tag selectors 263 00:21:12,160 --> 00:21:17,460 because tag selectors are not reuseable and they can be easily overridden, 264 00:21:17,820 --> 00:21:21,330 which then makes our CSS architecture more fragile. 265 00:21:22,330 --> 00:21:29,460 Finally, we'll need to avoid those important declarations in our CSS values. 266 00:21:30,970 --> 00:21:34,310 We should not use important unless absolutely necessary 267 00:21:34,430 --> 00:21:38,930 because it breaks the natural order of the CSS cascade. 268 00:21:39,240 --> 00:21:43,910 It overrides all specificity, even ones in inline style. 269 00:21:44,690 --> 00:21:48,130 It has also been referred to as the "Jedi mind trick" of CSS. 270 00:21:48,390 --> 00:21:52,800 So, as you can see, it's a very powerful declaration that we need to be careful with. 271 00:21:48,590 --> 00:21:52,800 So, as you can see, it's a very powerful declaration that we need to be careful with. 272 00:21:53,660 --> 00:21:59,300 To sum up CSS specificity, inline styles will win over external style sheets, 273 00:21:59,850 --> 00:22:04,700 IDs win over classes, and important wins over all. 274 00:22:06,700 --> 00:22:12,780 Next up, it's always good to use some form of CSS reset in our architecture. 275 00:22:13,980 --> 00:22:19,420 Most CSS resets provide a baseline for styling our pages. 276 00:22:20,050 --> 00:22:23,890 By completely removing certain browser style inconsistencies 277 00:22:24,280 --> 00:22:28,860 like margins, padding, line height, and some of the heading font sizes 278 00:22:29,890 --> 00:22:34,440 we're making sure that our page looks pretty consistent on all browsers 279 00:22:34,500 --> 00:22:39,320 before we begin writing our main styles, but it's also okay 280 00:22:39,620 --> 00:22:44,170 to leave in some of those browser default styles as we'll find out shortly. 281 00:22:45,510 --> 00:22:51,140 The method we should avoid for CSS resets is using the universal selector. 282 00:22:52,010 --> 00:22:55,660 When using that universal selector we have no control 283 00:22:56,680 --> 00:23:02,490 because we lose inheritance in CSS values from parent to child elements. 284 00:23:02,860 --> 00:23:06,190 It trumps any form of inherited style. 285 00:23:06,560 --> 00:23:12,410 Because of that we'll need to write a lot of extra CSS to define a property 286 00:23:12,410 --> 00:23:15,370 for both the parent and the child element. 287 00:23:15,760 --> 00:23:20,560 It also affects the browser—the page load time—because the browser 288 00:23:20,560 --> 00:23:25,590 has to run througth every page element to apply the reset properties. 289 00:23:26,850 --> 00:23:32,510 A common CSS reset method is Eric Meyer's reset CSS. 290 00:23:33,100 --> 00:23:35,800 Reset CSS provides a really good starting point. 291 00:23:36,170 --> 00:23:39,190 We can then edit or extend as we need. 292 00:23:39,560 --> 00:23:44,110 It also includes all the necessary and new html5 tags 293 00:23:44,110 --> 00:23:47,930 like header, footer, aside, section, and so forth. 294 00:23:48,140 --> 00:23:52,900 The good thing with this method is that we shouldn't need to include the entire reset, 295 00:23:53,380 --> 00:23:56,930 just those attributes that we're using and restyling. 296 00:23:58,000 --> 00:24:02,480 One of the most common methods these days is normalize.css. 297 00:24:03,270 --> 00:24:07,970 Some advantages to using Normalize over other CSS reset methods 298 00:24:08,650 --> 00:24:12,840 is that Normalize preserves those useful default styles, 299 00:24:13,050 --> 00:24:18,240 so we don't need to redeclare styles for some of those common typographioc elements 300 00:24:18,240 --> 00:24:24,430 like headers, paragraphs—they all preserve those consistently across the browsers. 301 00:24:24,980 --> 00:24:28,570 Also, the form elements are cross-browser consistent. 302 00:24:29,200 --> 00:24:32,460 Different browsers do have different styles for form elements 303 00:24:32,460 --> 00:24:34,840 so Normalize keeps those consistent right from the start. 304 00:24:35,760 --> 00:24:40,160 We can then remove entire sections of the normalize.css file 305 00:24:40,160 --> 00:24:46,320 because the file size is very small and modular with detailed documentation 306 00:24:47,310 --> 00:24:50,950 and, most importantly, it has great browser support. 307 00:24:51,440 --> 00:24:53,820 Now it's important to keep in mind that we should not 308 00:24:53,820 --> 00:24:58,540 have to write new CSS to reset previous styles. 309 00:24:59,050 --> 00:25:01,100 If you find yourself doing that often, 310 00:25:01,600 --> 00:25:05,310 you'll need to stop, reassess, then refactor your CSS. 311 00:25:06,040 --> 00:25:11,020 Next we'll talk about the best order for formatting CSS rules. 312 00:25:12,250 --> 00:25:15,610 One of those methods is the single line method, 313 00:25:16,240 --> 00:25:19,320 which is the most space and size efficient, 314 00:25:20,060 --> 00:25:24,250 and it requires the least vertical and horizontal scrolling in your style sheet 315 00:25:24,640 --> 00:25:26,640 for writing and editing CSS, 316 00:25:27,050 --> 00:25:30,390 but it is difficult to browse through and immediately target 317 00:25:31,060 --> 00:25:34,510 the specific parts of the CSS as we can see here. 318 00:25:35,850 --> 00:25:40,250 CSS rules can get complex so because of that most developers like 319 00:25:40,250 --> 00:25:44,030 to use that multi-line method, where each property 320 00:25:44,030 --> 00:25:47,780 and value declaration is on a separate line. 321 00:25:49,880 --> 00:25:52,740 We can take the multi-line method one step further 322 00:25:53,000 --> 00:25:57,890 with the multi-line indent format where indented blocks indicate 323 00:25:57,890 --> 00:26:02,210 that we're targeting child elements of the selector above. 324 00:26:03,000 --> 00:26:06,340 For example, here we have main-nav indented beneath main-header, 325 00:26:06,950 --> 00:26:11,620 the column rule is indented beneath the main-content rule and so forth. 326 00:26:12,100 --> 00:26:16,580 We should be minifying and compressing our CSS files in production anyways, 327 00:26:17,180 --> 00:26:22,060 so we should use a method that allows us to navigate CSS quickly 328 00:26:22,730 --> 00:26:24,820 so it will need to maximize readability 329 00:26:24,820 --> 00:26:28,380 even if it means writing each property on a separate line. 330 00:26:29,030 --> 00:26:33,550 Next, what about the property and value declarations? 331 00:26:34,740 --> 00:26:37,750 The best way is to arrange them functionally in our CSS 332 00:26:38,210 --> 00:26:41,380 where the properties are divided into these groups 333 00:26:41,380 --> 00:26:44,590 and aranged in the most logical order. 334 00:26:44,900 --> 00:26:48,160 Doing that improves maintenance and readability. 335 00:26:49,090 --> 00:26:53,360 As we can see here, this rule has the positioning properties; width, height, 336 00:26:53,960 --> 00:26:58,940 border styles, and the background colors all defined in separate groups, 337 00:27:00,400 --> 00:27:03,960 which then improves maintenance efficiency, as we just learned, 338 00:27:04,160 --> 00:27:09,450 and there are a lot of tools that can actually help us with the declaration order, 339 00:27:10,180 --> 00:27:14,430 one of them being CSS Comb, which is a free tool 340 00:27:14,830 --> 00:27:18,030 for sorting CSS properties into specific orders. 341 00:27:18,380 --> 00:27:23,690 It helps us sort and categorize our CSS to improve maintenance 342 00:27:24,190 --> 00:27:30,630 It actually has an algorithm that sorts CSS in the order that is as close as possible 343 00:27:30,630 --> 00:27:35,020 to the decisions web developers would make when writing CSS. 344 00:27:35,570 --> 00:27:38,090 If we were to do something like this manually it would involve 345 00:27:38,420 --> 00:27:41,090 copying and pasting a lot of lines of CSS, 346 00:27:41,480 --> 00:27:44,880 and CSS Comb will do it with just one click. 347 00:27:45,440 --> 00:27:49,530 A tool like CSS Comb will come in handy when working with a team of developers 348 00:27:50,000 --> 00:27:53,550 because it helps maintain our coding style across the team, 349 00:27:53,900 --> 00:27:56,230 which then helps us understand the CSS better 350 00:27:56,380 --> 00:28:02,050 and it helps us find properties much faster, which prevents errors in the CSS. 351 00:28:02,220 --> 00:28:05,360 The cool thing is that code editors like Sublime Text 2 and Coda 352 00:28:05,640 --> 00:28:10,550 all have these CSS Comb plugins we can use right in the text editor. 353 00:28:11,650 --> 00:28:14,660 Next, what about vendor prefix? 354 00:28:15,050 --> 00:28:22,080 It's important to follow up on browser support for many of the latest CSS3 features 355 00:28:22,080 --> 00:28:26,060 so we'll know which vendor prefixes we need to include in our style sheet. 356 00:28:26,640 --> 00:28:29,770 A good resource for that is caniuse.com, 357 00:28:30,210 --> 00:28:33,790 which gives us a comprehensive compatability table 358 00:28:33,790 --> 00:28:37,970 for browser support of all the latest CSS3 features. 359 00:28:38,580 --> 00:28:41,250 Another one is the Mozilla Developer Network, 360 00:28:41,550 --> 00:28:44,180 which is a valuable reference that describes 361 00:28:44,180 --> 00:28:48,250 pretty much every CSS property and the latest browser support. 362 00:28:49,220 --> 00:28:52,830 When writing vendor prefixes it's important to always include 363 00:28:53,090 --> 00:28:57,820 the unprefixed properties last in the rule, 364 00:29:00,230 --> 00:29:04,680 as we can see here with the transition and the linear gradient properties. 365 00:29:06,090 --> 00:29:10,110 There are tools that can help us write these vendor specific properties. 366 00:29:10,420 --> 00:29:14,360 My favorite is Prefixr at prefixr.com, 367 00:29:14,980 --> 00:29:18,090 because we only need to write the properties once. 368 00:29:18,580 --> 00:29:23,270 It then converts our CSS to cross-browser compatible CSS, 369 00:29:23,880 --> 00:29:27,120 and it does that by filtering through CSS3 properties 370 00:29:27,500 --> 00:29:31,220 then dynamically updating them with the necessary prefixes. 371 00:29:31,820 --> 00:29:34,600 Code editors like Sublime Text and Coda 372 00:29:34,600 --> 00:29:39,070 also have prefixer plugins you can use right in the code editor. 373 00:29:42,000 --> 00:29:46,260 Next, if it's necessary, we'll need to provide a fallback method 374 00:29:46,470 --> 00:29:49,200 for some of these CSS3 features, 375 00:29:49,900 --> 00:29:55,780 because first we'll need to always develop with progressive enhancement in mind. 376 00:29:56,380 --> 00:30:01,700 With progressive enhancement we start from a basic working example as our 377 00:30:01,700 --> 00:30:07,820 foundation so it's an experience that all browsers will be able to provide to our users. 378 00:30:08,220 --> 00:30:11,850 We then add those enhancement layers one by one. 379 00:30:12,330 --> 00:30:15,810 With progressive enhancement it's important that we start with 380 00:30:15,810 --> 00:30:20,040 semantic, well-strutured markup, then add that CSS layer 381 00:30:20,040 --> 00:30:22,180 followed by the JavaScript layer. 382 00:30:23,620 --> 00:30:27,840 This minimizes dependencies on a lot of CSS3 features 383 00:30:28,170 --> 00:30:32,410 because we don't sacrifice the accessability for convenience. 384 00:30:33,530 --> 00:30:37,580 We can also use feature detection as a last resort. 385 00:30:38,590 --> 00:30:42,980 Now a really useful tool for feature detection is Modernizr. 386 00:30:43,560 --> 00:30:47,650 Modernizr is a powerful JavaScript-based library 387 00:30:48,120 --> 00:30:52,090 that detects support for html5 and CSS3 features. 388 00:30:52,490 --> 00:30:55,820 It then allows us to provide a fallback 389 00:30:55,820 --> 00:30:59,440 for those browsers that do not support certain features. 390 00:31:00,150 --> 00:31:06,420 Modernizr tests for over 40 features in a matter of milliseconds, so it's really fast, 391 00:31:06,790 --> 00:31:10,410 but we shouldn't need to include the entire library. 392 00:31:10,800 --> 00:31:14,740 We can actually create a custom build only for those features we need. 393 00:31:16,460 --> 00:31:23,210 Finally, there are tools that can help us write CSS using a lot of these best practices. 394 00:31:24,010 --> 00:31:27,350 One of those tools is CSS frameworks. 395 00:31:28,200 --> 00:31:33,330 With CSS Frameworks all these best practices are already baked in. 396 00:31:34,200 --> 00:31:37,400 A good one to use is Foundation by ZURB. 397 00:31:37,870 --> 00:31:41,070 There's also Twitter Bootstrap and others. 398 00:31:42,250 --> 00:31:45,890 It's important that we do not use a framework just because 399 00:31:46,460 --> 00:31:49,500 you don't understand CSS best practices. 400 00:31:50,000 --> 00:31:53,070 We should use a framework to speed up our work flow, 401 00:31:53,360 --> 00:31:56,990 so to make us faster, not necessarily better at CSS. 402 00:31:58,060 --> 00:32:02,350 Next, another helpful tool is CSS preprocessors. 403 00:32:02,930 --> 00:32:06,240 Preprocessors save us a lot of time writing CSS, 404 00:32:06,700 --> 00:32:11,030 and they make our CSS modular and easily scaleable. 405 00:32:11,640 --> 00:32:15,300 A lot of the useful features in CSS preprocessors are 406 00:32:15,740 --> 00:32:18,300 being able to create variables, nest selectors, 407 00:32:19,110 --> 00:32:23,160 create mix ins, and do math functions, along with a lot more features. 408 00:32:24,390 --> 00:32:29,720 Some of the most popular CSS preprocessors are Sass, Less, and Stylus. 409 00:32:30,550 --> 00:32:34,150 Preprocessors do require a bit of a learning curve, 410 00:32:34,680 --> 00:32:37,650 but just remember that it's CSS after all, 411 00:32:38,050 --> 00:32:41,160 and they're not a new language, just a new syntax. 412 00:32:41,800 --> 00:32:46,160 Okay, so that will do it for our workshop on CSS best practices. 413 00:32:46,450 --> 00:32:48,880 As we've learned, it's important we continue using 414 00:32:49,000 --> 00:32:52,350 those best practices throughout our development process. 415 00:32:52,750 --> 00:32:55,480 To learn more about CSS check out our learning adventure 416 00:32:55,480 --> 00:33:01,230 on becoming a web designer or developer and our Deep Dives on html and CSS. 417 00:33:01,540 --> 00:33:03,500 I'm Guil Hernandez, thanks everyone.