2.2 The Essential CSS
In the second part of this course, we’re going to write the essential CSS: the styles that will power the dropdown menu. Let’s begin.
2.2 The Essential CSS
Let's jump back to our Visual Studio code. We don't need the notes here anymore. Instead, I'm going to open my styles.css file. And in here, I'm going to start with a reset. So on the reset, it's always a good idea to start with such styles, because they allow you to begin working with a clean slate. We're first going to start by setting the box sizing of all the elements to border-box. Okay, and what this will allow us to do is basically be able to set paddings and margins. Or actually paddings on an element, and not effect the overall width and height of those elements. Next, we're going to set a body. Okay, so what is this all about? Basically setting margin and padding, 0, will remove all the margins and the paddings that you see on the body. So if I do a refresh now, you can see that removed the small gap from the edges of my body. Also, I'm loading the Roboto font, which is from Google, I went ahead and loaded that right here. So I'm just setting a simple style font, 16 pixels, this is the font size, and the way I used font here is basically a short hand. All right, so 16 pixels is the font size, 1.5 is the line height, and then it's followed by the font stack or the font family. And here I'm using Roboto as the main font with a fall back to Arial. And if Arial is not available, we do a fall back to Sans-Serif. Now, let's move on to the actual navbar. So the navbar refers to our actual header here. And before we move on, I want to do a quick note regarding how you would position such elements. There are multiple ways you can achieve a layout, like you saw in the beginning of the video. So, the first way is to use elements with display in line block. That will allow you basically to position elements so they are on the same row. Basically, they will behave like columns, and they will be displayed on the same row. Another approach is to use the floating method. Now the floating method will basically allow you to float elements left and right. And you have a little bit more control over how this is, over the result. A third way is to use flex box. Now flex box is actually a, let's say, a relatively new technology. So not every browser is going to support it, at least older browsers, like IE, with versions smaller than 10. So IE 7, 8, 9, do not support flex box. So, if you want to support older browsers, the best way you can do that is to use the floating method. So you would float the logo to the left, and you would float the actual menu to the right. So for the navbar, we're going to start by adding a little bit of padding. So we're going to say padding 1rem, to the top, 4rem, to the right, and I'm gonna end there. This basically adds one rem to the top and bottom, four rems to the left and right, and the result is this, right? So I added a little bit of padding on the sides and a little bit of padding on the top. Next, I'm going to set the background color to white. And I'm doing that for later on when we might have, or we will have, content on the page. So I don't want the contents on my header to overlap with the contents on my page. Next, let's target the logo here. And let's float it to the left, and let's target the menu, and we'll float it to the right. Okay, and this is what we have so far, looks pretty good. But the problem is, if I'm gonna add a different background color here to the navbar, let's say red. As you can see, it's going to show up like this, and this is not what we want. The reason it's showing up like this is because we have floated elements inside. And once we do that, those floated elements are basically taken out of context. So they will not be able to set a height for their parent elements. In order for their parent element to have a height, and to be displayed properly, we need to clear those floats. Now, a very simple approach is just that oveflow to hidden, all right? And that will basically clear those floats and display the parent properly. The thing with overflow, though, is whatever is kind of flowing outside of that container will be cut off, will be hidden. That's why the value of the overflow property is set to hidden. So for a drop down menu, that's not good, because our menus will not be shown when we hover on their apparent links. So we need to find another way. Well, the other way comes in a form of a clearfix hack. Before that, we're going to set navbar, after, so we're gonna create a pseudo-element. And we'll just set the content to nothing, display to table, and clear both. All right, and that acheives exactly the same thing, the floats are cleared and now the parent element is displayed properly. Now we can go back to a white background here, and. We'll move on, and we're gonna style the anchor tags. So we're gonna say navbar a, first thing we'll do is we're gonna set the text decoration to none. And that's gonna remove the underline. Okay, next we're gonna give these a color. And just to keep things simple, I'm gonna use black with various degrees of opacity. So I'm gonna use rgba(0,0,0 and .60), which is black, 60%. And finally, let's give them a color on hover. So .navbar a:hover. I can just copy this color from here, and I'm gonna give it an 85% opacity. Let's try it out. Okay, looks good. Now let's see about the actual menus. So in here, I'm gonna say .menu ul. So the menu is this nav. So in order to style these properly, we have to start targeting the contained ul's and list items. And what I wanna do with it is basically set list-style to none. That will basically remove all of the bullets. Next we're gonna set padding: 0; and margin: 0;. A little bit of a reset on the menu. So do a refresh. And now everything is on the same line. Next let's target the first-level menu items. Now the first-level menu items, I'm just gonna say here 1st level, those need to be displayed on the same line. So, We're gonna say .menu. And I'm gonna do this. Greater than, it's actually not called like that but I just wanna describe it. So .menu > ul > li with this operator basically means select only the direct descendents of ul and of menu. So we only want to select, The direct descendants from the direct, or the direct list item descendents from the direct ul descendents of menu. And I'm gonna set display to inline-block. Let's do a refresh. So we're starting to get somewhere. Next let's target the anchor tags inside those items. So .menu > ul, we're going to use the same direct descendant selector. Okay, we're gonna set display to inline-block and that will basically, Well, it should align, The items here on the same line, let's see. Let's add a little bit of padding to them. Let's do 1, rem on the sides, 1.5 rems on top and bottom. So let's do a refresh. Yeah, we're getting there. You might not see it yet, but we're actually targeting the correct items. Let's add a font-weight of bold so you can see them, all right? So here are the first-level items we're displaying. Currently, they're not on the same line, because they have these submenus which are still visible. So to get rid of those, let's work on the second level. So the second level can be targeted very easily with .menu li ul. So, why is that? Well, Here's how [COUGH] the second level looks like, all right? So, how do we get to it? Well, we target a list item and then the ul. So in here, we're going to set display to none. And that will essentially remove all of the submenus, all right? And now we only have the top-level items showing. And then the trick to getting these submenus to display properly is to position them absolutely. But in order for that work, we need to target, The parent list items and set their position to relative. Because an element that's positioned absolutely will position itself in relation to its parent if it has a position: relative. Otherwise, it's gonna search for the next parent that has a position: relative. So in here we're gonna say position: absolute. And then let's stop here for now. And let's display those menus, all right? So currently, If I'm refreshing, nothing happens if I hover over these items. But when I hover over an item, I want to show its submenu. So we can do that very easily by saying .menu li:hover and then we'll select the direct descendant ul. And all I'm going to do is set display to block. Let's do a refresh. And here it is. And this also works for [COUGH] excuse me, for the third-level submenus. But we still need to add a little bit of styling to those. But whenever I'm hovering over a list item, we can choose to show its direct descendent ul, pretty cool. Now we're gonna set the top to 100% for these absolutely positioned elements. And I'm doing that because if we set the top to 0, Those will be displayed at the very top of the list item. But by setting them to 100%, we make sure they are displayed at the very bottom. So that top 100%, I will set left to 0, Okay, and let's give them a width. Let's say width, let's say about 15 rems. Okay, and what else? Let's add a padding, so I'm gonna say 1.5 rms top and bottom, 0 on the sides. And I'm doing that just to space out these elements a little bit. Next, lets add a background color, And the background color I chose sounds like this, F3F5F6, this is a very light grey. And also, lets add a border radius of 5 px, that will allow us to create rounded corners. All right so, this is how they currently look like all right, now let's target the anchor tags inside these sub menus and set a little bit of padding on their side and a little bit of padding in between each one. So, in here I'm gonna say .menu li ul a so I'm targeting the anchor tags inside the nested sub menus, we're gonna set display to block. And we’re gonna set padding, let’s say 0.5 rems top, 1.5 rems on the sides already much, much better. Now let’s see what we can do with this third level. Well the third level, will actually be displayed on the right side of my second level menu. So when I hover on this link it's corresponding sub-menu will be shown on the right side. So let's say here, third level, And for the third level, we're gonna do this, .menu, li ul, and then again li ul, all right? Let's take a look at this HTML structure to see where this is coming from. So menu, li ul selects the first submenu or the level two submenu. And then again li ul selects the next level which is the level three. So this is how we can reach these submenus. Now in here what I'm gonna do is set left to 100%, and I'm gonna set a top of 0, oops 100% here. And that'll basically move it from here, To the side. But notice we have a little bit of a gap here on the top. And that's caused by the padding top that we applied to the submenu. Easy way to fix that, set the top to -1.5 rems. Okay. That looks pretty good. Now, there's also a small problem, because in a nav bar we want the logo, [COUGH] Well most of the time we want it to be vertically aligned with the menu. So, [COUGH] To show you this really quick let me just change the background color here really quick just demo color. So as you can see, this is our menu, And this is our logo obviously, if not aligned vertically, with our menu. Now you can vertically align this very easily if you were using something like Flexbox. But that's obviously not the case here or, if you were displaying these elements as in-line blocks, you could then apply vertical align. So that would have aligned them just fine, but here we're using floats. So how do we achieve the vertical alignment? Well, instead of floating the logo, we're actually going to position it absolutely, because by positioning it absolutely, we're able later on to vertically align it in any way we want. So, quickly we'll go back to our code, and on the logo instead of floating into the left, we're gonna set position absolute and we're gonna set top to 50%, right. So that aligns it, that 50% of the immediate parent that has position relative, which is the body. So to prevent that, we need to go back to our nav bar and set position: relative here. Okay, now this positions the top left corner of the logo at 50%, but we don't want that. We want the logo itself, or the image itself, to be positioned Right in the middle. Well, that's really easy to do we just, Set a transform on the logo, translate y- 50%, and that will nudge it up half of its height. So it's now positioned properly in the middle of our nav bar, okay. Now, let's see what else we can do here to this menu. Let's actually revert back to our white color. So we can have a better look. All right, we could use some arrows in here, right? An arrow down for the first level menus, or the first level menu items, and arrow right for these submenus. We could also use a different transition so instead of just the submenus appearing like this, we can use a nice opacity transition, right? But I think we'll leave that to the third section, the finishing touches. Functionally, we got pretty much everything done right now. So I think we're gonna take some questions, so let's see if we have any questions. Okay, the first question, why did you choose to use rem for the padding? Can you use pixels or percentages? I chose to use rem because I just got into habit of doing to rem relates to the base font size of your document. So if your base font size is 16 px, 2 rems is gonna be 16 times 2. If you're using pixels, you have It's a bit more strict, right? You don't have too much control. If you want your pace to scale accordingly using ems or rems, is a good choice. If you're gonna use ems, then those ems will be relative to the font size of your parent. But rems will be relative to the font size of your body. And by using that, I wanted to get a little bit more control. I hope that answers your question. Okay, here's another question. When should you use the direct descendant operator? And when is it better to just use something like L-I-U-L L-I-U-L? Well, here's the thing with the Direct Descendant Operator. You have more control, when you're using the Direct Descendant Operator. If you just say L-I-U-L, that's gonna select all of the ULs that are under that LI, and I don't just mean immediately at the next level. I mean, as many levels down as possible. By using the direct descendant, you make sure you only select those immediate children of your parents. So if you say LI, direct descendant UL, you select the immediate children, the immediate UL children, of that LI. And not the ones that are nested deeper. I hope that answers your question. [COUGH] Let's see another question. Can you explain why top 100% works? Well, top 100% basically tells the browser to position that element at 100% the height of that element. So if you are to say top 50%, it's the top portion or the top edge of the element that you want to position will be placed at 50% the height of the parent element. The same thing with any other value. Zero places it right at the top of the element. 100% places it right below the element or right at the height of that element. Let's see other questions. Is there a better way to do it in 2017? Are clear and float hacks. I wouldn't necessarily say they're hacks, [COUGH] excuse me. [COUGH] I would say they are just ways of doing things that have a lot more browser support. A better way to do it in 2017, sure. Flexbox, or grit. But as I had mentioned in the beginning, those come with a cost because they are not supported by older browsers. Personally I would use Flexbox [LAUGH] because it's just so much easier to position everything and it's supported in IE 10+. Currently, IE 10+, or IE 10 excuse me, I believe holds about 0.2 market share in the browsers. So in order to explore, overall holds about 3, 4%. So personally I don't think it's such a big deal. You should be using Flexbox if you don't have specific requirements that ask you to use or ask you to create your websites compatible with older browsers and here I mean IE seven, eight, nine, ten, even. So definitely go for Flexbox if you can do that. Let's see another question. For the clear fix, white table and not block. Well, that's a very good question, honestly I do not know. This clear fix, this is actually a hack [LAUGH] if we're gonna talk about the question that I answered previously. With these hacks, you don't really start to question why that's the way it is. It just works. You use it. You then move on. You hope for a better solution. I haven't actually tried it with block. It might work. Let me actually see if it works. You made me curious. So [COUGH] I'm gonna set display block here. And let's set it a different color. It still works. So I guess you can use a block, as well. Not necessarily a table. This probably has to do with some older browsers, not recognizing display block properly. So if you wanna use the clear fix hack in older browsers, you might need to use display table. That's just a thought though, I do not know that for sure. Okay, let's see other questions. Is CSS Grid okay to use in production? I wouldn't say that. CSS grid is still relatively new so you might be in a great or in a risky position if you're gonna use that in production. I would say go for a safer version like Flexbox, which as far as I know still has a bit better browser support than CSS Grid. All right, it seems that's about it for questions for this section. Now, please excuse me like ten seconds while I get a sip of water and we will continue.