Using BEM in our Project8:22 with Guil Hernandez
We'll start by using the BEM naming convention to build a navigation component.
An important thing we need to keep in mind when using the BEM methodology is that it 0:00 can be a pretty subjective way of thinking. 0:04 Your definition of a module may be different than mine or someone else's. 0:06 The main thing is that we need to think in terms of abstraction layers for 0:10 blocks, elements, and modifiers. 0:14 Block being the highest level. 0:16 And, any block we define can be used freely within a page, or 0:18 even between projects, without extra dependencies. 0:21 So not everything needs to be defined with the BEM naming convention. 0:25 So for instance, in our index.html file, the site-logo 0:29 class here is inside the header, but it's simply named site-logo. 0:34 Since the logo can go anywhere in the layout and 0:41 it doesn't depend on any context, we'll call it site-logo and leave it at that. 0:44 Now, here's a different example of high level abstraction with BEM. 0:49 So we have a navbar. 0:54 And inside navbar, there's a navigation marked up with an unordered list. 0:57 But just because the navigation is inside of navbar 1:03 doesn't mean that it needs to be entirely dependent on its context. 1:08 Besides the nav block, the nav bar may also have a search field component, or 1:13 maybe the logo could go here instead, this icon toggle element, and so forth. 1:18 The key is to break something into a module or 1:23 block only if it would be useful in another context. 1:26 Everything else can remain an element of the module. 1:30 So, what we'll do next is use the BEM naming convention To build and 1:33 style a nav component. 1:38 So first we'll define the block class by giving the ul element the class nav. 1:40 [BLANK_AUDIO] 1:48 Then the child elements of nav will have the class nav__item. 1:49 So I'll give the first list item the class nav__item. 1:54 Then I'll just go ahead and copy it and paste it in the list items below. 2:00 [BLANK_AUDIO] 2:04 And we'll also want a modifier class that indicates the current nav link. 2:09 So we'll also give our last nav item the class nav__item--current. 2:15 So at this point, you might be worried about the longer than usual class names in 2:23 the markup or the redundancy of some of these classes in the HTML. 2:27 Well, that may be the only downside of BEM. 2:32 But I think the benefits of using this convention outweigh those concerns and 2:35 make it worthwhile, because it makes our class notation expressive, 2:39 which helps us and other developers figure out what the selectors mean. 2:44 So when we see a class in our stylesheet for nav, nav__item, or nav__item--current, 2:48 we immediately know that we're in the nav block targeting the item elements and 2:54 specifying styles for the current variation of the item element. 2:59 And what this does is, it keeps our CSS very manageable. 3:04 So next we'll see how Sass lets us split up our styles into 3:07 modular rules based on the block. 3:10 So for this lesson, I've created a separate partial for the nav component. 3:13 So in our nav.css file, let's first target the nav block class. 3:19 And we're going to add top and bottom margins to our nav module. 3:26 So we'll say margin-top, and then we'll once again use the em() 3:30 function to define a top margin that's equivalent to 20 pixels in ems. 3:35 [BLANK_AUDIO] 3:40 Then we'll say, margin-bottom, and this time we'll set it equivalent to 30 pixels. 3:41 Okay. So, before we move on, 3:47 we'll go down to the console, and write the command sass 3:48 --watch scss to css, and now Sass is watching for changes in our project. 3:52 Now, one thing that's important to point out is that when writing modular Sass 3:58 rules, we should avoid nesting descendant selectors, because as I pointed out 4:02 earlier, we want to minimize contextual CSS that's dependent on a parent. 4:07 When styles are tightly coupled to the DOM like that, there's a good chance that if 4:12 we modify anything in the HTML, it can break our layout. 4:16 So even though child elements inside blocks are context dependent, 4:20 we can write them in a way that they only make sense in 4:26 the context of the block that they belong to. 4:29 And I'll show you what I mean by that. 4:31 So, in Sass, 4:33 we're now able to use a parent selector to append a suffix to the selector. 4:34 And this works really great when using the BEM conventions. 4:40 So let's keep going by styling our nav__item elements. 4:43 So right inside the nav block, we'll target the nav item class 4:47 with an ampersand selector followed by a double underscore and item. 4:52 And we'll give our nav items a display of inline-block. 4:58 [BLANK_AUDIO] 5:03 And we'll set the top and right margins to 0 and the right and 5:05 left margins equivalent to 12 pixels. 5:09 So now when we save and compile our nav partial and bring up our CSS output, 5:12 notice how the ampersand suffix selector sort of undoes the nesting in the Sass and 5:18 outputs the nav__item rule without making it a descendant of nav. 5:24 Even though we sort of wrote it that way in our partial file. 5:29 So now we'll go back and style the nav links inside of the nav items. 5:33 So earlier, I said that it's best to avoid nesting. 5:38 But I think one of the exceptions to that is when 5:41 styling anchor elements for navigations. 5:44 A lot of the times, they do rely on the context. 5:47 So inside the ampersand item rule, we will add a new rule for the anchor elements. 5:50 And let's set a few properties for that, so 5:58 we'll say font-size equivalent to 18 pixels in ems. 6:01 [BLANK_AUDIO] 6:05 Then we will use a font-weight property, and 6:09 let's make the font weight the variable $font-weight--light. 6:12 [BLANK_AUDIO] 6:16 And for the color, let's once again use our handy palette function. 6:18 And we will call the base shade of grey. 6:25 [BLANK_AUDIO] 6:28 Let's also display them block. 6:30 And we'll want to add a little bit of padding, so we'll say padding. 6:33 And we'll once again use the em function to give them a padding equivalent to 6:37 8 pixels for that new 18 pixel font size context. 6:41 Remember, we set the new font size to 18 pixels. 6:46 And finally, let's give it a border-bottom. 6:49 [BLANK_AUDIO] 6:52 So now, to target that nav item current modifier class, 7:00 we'll again use Sass's ampersand suffix selector. 7:04 This time using two dashes to indicate the modifier suffix, so we'll say current. 7:09 And let's target the anchor element inside of current. 7:15 And let's change the color to black, so 7:20 we'll use the palette function and call the base color black. 7:23 [BLANK_AUDIO] 7:28 And let's change the border color to the $color-primary variable, so 7:30 that fountain blue color we defined earlier. 7:35 [BLANK_AUDIO] 7:38 All right, so 7:41 we'll save our nav.scss file, and let's take a look at our output CSS. 7:42 When we take a look at our nav rules, we can see that even though this current 7:47 modifier selector is nested two levels deep inside the nav and 7:51 nav__item rules, it still outputs the selector at the highest level, and 7:57 not as a child of nav__item and nav. 8:03 All right? 8:06 So now, when we take a look at our nav component in the preview, 8:06 we can see that everything is nicely styled. 8:11 And because it isn't location dependent, 8:14 we can use this nav component anywhere in our layout without breaking anything. 8:17
You need to sign up for Treehouse in order to download course files.Sign up