[MUSIC PLAYING] BRIAN YU: Welcome back, everyone, to Web Programming with Python and JavaScript. Today we're going to continue where we left off from last week. So last week, if you recall, we talked about Git, a version control tool that lets us manage different versions of our project, and keep track whenever we make new changes to our project, and let us look back at the history of changes that we made to our project. And then we also took a look at HTML, which let us lay out a website how we wanted to, as well as CSS, or Cascading Style Sheets, which allowed us to take a web page, and style it in different ways, and change the aesthetics of the page in order to make it look the way that we want it to look. So this week we'll dive more in-depth into all three of those, focusing especially on HTML and CSS, and taking a look at how we can leverage these tools and some other tools to help make our websites even more dynamic to help them be designed the way that we want them to be designed. So the first thing that we'll take a look at is go back to Git. So if you remember from last week, Git was a tool that we were using in order to keep track of different versions of our project. And in particular, as we work on a project and continue to make changes, the term we used in Git was to make commits to our project. So we might start with a first commit that just contains initial files that we had when we started the project. And as we continue to work on the project and add new features, it's a good idea, when working with a version control system like Git, to frequently make commits when we make a new change, save those changes such that, later, we can refer back to them via a commit message that describes what changed in this particular version so that later on, we have a history of all of the changes that were made to the project at any given time. So we might continue to making changes. And what you might imagine is that this chain of different commits might start to get pretty long. So maybe we have a working project at this stage in the program, and we want to add a new feature to our web application, for example. So at this point, we might start working on a new feature here by adding another commit. We might make more progress on that new feature, keep working on that feature. But what if, at this point, while we're midway through working on some new feature to our existing web application, we realized that there was some sort of bug, some bug in our web application that occurred way back here that we want to quickly fix, so that we can ship out a new fix so that people aren't sitting with that bug for a long time? Well, this linear structure where, every time we make changes, we just save those changes one after another, that makes it pretty challenging to say, I want to fix a bug back here. We could, of course, reset, and go back to this stage, and fix the bug, and then keep working on the new feature. But we've already made these new changes to the new feature. So it sort of starts to get a little bit messy at this point. So Git has this in mind when it was first designed. And so that's why Git has a tool called branching. And what branching effectively allows us to do is, rather than just have a single linear progression of the entire project where each change always follows on the change immediately before it, and that's the only path that we have to follow, branching lets us take our project in multiple different directions. It lets us maintain one branch that will be our "master" branch, the original version of our code that's supposedly the version that's always usable, and then lets us have other branches that allow us to work on different features that are still in progress, and later, take those branches and work them into the original code. So to take an example, we might start with that same first commit and still continue to make changes. But when we're in a stable place and we want to try to add a new feature and start working on that new feature, rather than just add that feature immediately after it, what we can do is we can branch off, begin a new branch, and say, OK, let's start working on this new feature in a separate branch from the original project, and keep working on that new feature on that other separate branch. Then, at this point, if we come to that same realization, the realization that, oh, way back here, there was some bug in the code, some bug that we would want to fix, rather than try and reset, and go back here, and figure out how to get back to where we were before, we can just switch back over to this branch, fix the bug there. And that way, we're in a position where we now have these two separate branches, this one original branch that has that fixed bug, and then this other branch whereby we started working on a new feature, and we kept working on a new feature. And this is especially helpful if it's not just you that's working on the web application. If you and multiple other teammates are also working on the same application, you might imagine this as saying, you are working on one branch going off in one direction working on the project. And some other person, some collaborator you're working with, is sort of going off in a different direction, working on some different feature, but also on the same project. And later, when you're ready, you can do what Git calls "merging"-- in other words, taking two separate branches and then combining them together. So we might label these branches. This is what we would generally call the master branch, which is the default branch, the original branch that we started out with. And then these other branches, you can have as many as you want. You can name them whatever you want. In this case, I've just called this branch "feature" to represent the fact that this is a branch that's representing a new feature that we would want to potentially add to this existing web application. Git also has a bit of additional terminology that's useful to know. Git uses the capital phrase "HEAD" to refer to where we currently are in the repository. So if you're working on the project and you're currently working on the master branch, then HEAD points to master. In other words, where you are in the repository right now is the master branch. That's the code you're working with. But Git makes it very easy to change where HEAD is. If you wanted to go to the feature branch, or "check out" the feature branch, as Git would use with its terminology, you could very easily check out the feature branch moving the HEAD to the feature branch. And now you can continue working on that feature. And so only when you feel comfortable with the feature, when you feel comfortable with the bug fixes can you then merge the two together by having another commit that combines two previous branches and merges them back together into one. And so this concept of Git branching is very helpful whether you are working on different parts of your own web application and have different features that are happening at once that you want to develop separately but then combine together later, or if you and collaborators are working together on a project where it's very easy for you to work without having to worry about what someone else is doing. And only when you're both ready with your separate features do you then want to merge them together and figure out how to resolve any conflicts that might come about where you and another collaborator have potentially edited the same line of the same file, for example, that you can then deal with by resolving those merge conflicts like we saw last week. So we'll take a look at an example of that just to give you a sense for how this would actually work on the command line and how we would actually do branching. So I have, here, a Lecture 1 repository. And right now, inside of Lecture 1 is just a file called index.html. So index.html is, right now, just a test website that has title as "Test." And inside the body is just the word "test." This is just a sample website that we're going to use to demonstrate the idea of branching. So maybe I'm going to make a commit to this file. Instead of saying "test" in the body, let's say something a little bit nicer. Let's say "Hello, world!" So I've changed the message in the body. And now, on the command line, I'm going to git add index.html. I've made changes to index.html. These are changes that I want to track the next time that I make a commit. And now I can say git commit -m. I want to leave a message when I make this commit. And in this case, I want to say I changed the body message. So that's the change that I just made. Again, Git counts that as one insertion, one deletion. And so that commit is now made to this repository. But now say I want to test something a little bit different. I want to try something different, and I don't want to mess up my original master branch. Well, if I type "git branch" right now and press Return, what you'll see is a listing of all of the branches that are currently on my repository. And right now it's just this one branch, master. So that's the only branch that I have. But if I want to create a new branch, it's as simple as saying "git branch" followed by the name of some new branch that I want to add. So I want to add a new feature to my website. I might call that branch the feature branch, for example. So I press Return. And nothing seems to happen. But if I type "git branch" again to say, OK, let's take a look at the branches that I currently have in this repository, what are they, I'll see that we have a master branch, and we also have this feature branch. And the fact that the master branch is highlighted in green and has the star next to it tells me that this is the current branch that I'm currently on, and this feature branch is some other branch. So let's say I now want to move to the feature branch and start working on that. So I might say "git checkout," where "checkout" is the term that Git uses for saying, I want to move where I currently am in the repository to somewhere else. Right now I'm on the master branch. I want to move to the feature branch, for example. And so if I press Return here, it says "Switched to branch 'feature.'" And if I type "git branch" again here, you'll see that, now, feature branch is the one that's highlighted in green. It's the one with the star next to it. That is now the branch that I'm currently on. If I go back to the index.html file, nothing really seems to have changed. But now I can start to say, OK, let's add in a new feature. So here is a new feature, just another line to the website in this case. But I can go ahead and add and commit that. And a quick trick that we talked about briefly last week is that you can say "git commit -am" to combine the git add step and the git commit step into one step. git commit -am just says, add all of the files that I've changed that I've already been tracking, and commit them at the same time. Just combines those two steps into one in case you want to be a little more efficient. And now I added another line. So that's the change that I just made there. And that's now on my feature branch, right, where I have "Hello, world!" and "Here is a new feature." If I were to-- now, if my current branches are feature and master, if I were to check out the master branch again, go back to the master branch before, what you'll notice is that, now that I'm back on branch master and I go back to index.html, this file now shows me the version of the file that is on the master branch that only has this "Hello, world!" line and doesn't have that second line that I added, which means that that other change isn't on the master branch. It's only on the feature branch. And as a result, it's not going to be represented here. I can see that even more clearly using a command that we learned last week, git log, which shows me the history of all of the commits that I've made on a particular branch. If I, here, now, on the master branch, type in "git log" for example, you'll see, here was my first file. And here I changed the body message. But those are the only two changes that I made on this particular branch. If I checkout the feature branch instead, switch to that branch, and type "git log" again, you'll see that now there are three commits on this branch. There was the first file, the change to the body message, and the fact that I added another line there as well. And so this goes to show that different branches can have different commits working on them, so to touch that you can be working on different features separately without needing to worry about what's happening on a different branch. So now we've been working on these separately. Now we want to combine them back together. So let me go ahead and switch back to the masker branch. And remember now, in the master branch, it just says "Hello, world!" just the simple message. If I now want to take what was previously on the feature branch and merge it into the master branch, while on the master branch, I'm going to type "git merge" followed by the name of the branch that I want to merge in. In this case, that's the feature branch. And that's saying, take those commits that are on the feature branch, and let's merge them into the master branch. So git merge feature-- one file changed. There was one insertion. That makes sense. And now, even though I'm on my master branch, if I check the file, I see that second additional line that was added there. And so different branches can work separately. But when I'm ready, I can merge those changes together. In this case, it was a very simple change. But sometimes those changes could be more complicated and might require resolving those merge conflicts. But that allows you to assist yourself in the development process whether you're working alone or with collaborators, just to make that process a little bit easier. Questions about branching or merging? Yeah. AUDIENCE: [INAUDIBLE] BRIAN YU: Correct. Great question. So the question is, if I create a branch on my computer, what happens to the GitHub repository where I originally cloned the code from? So the answer to that question is, when I create a branch locally on my own computer, it only exists on my computer. It doesn't yet exist on GitHub until I push it to GitHub in order to tell GitHub that that new branch exists. And in fact, we can show you that. I'll show you that right now actually. So if I-- I'm going to go ahead and reset what I did before. I'm just going to remove the lecture1 repository. And we'll just restart it, just to give you a demonstration. If I go to github.com/student50/lecture1, this is the GitHub page for this repository. And I want to clone this repository. I'm just starting from scratch here. I'll go to the Clone or Download button. I'll take this link, copy it, and then say "git clone" followed by that link. That's going to clone the lecture1 repository. And if I go into the lecture1 repository, I only have a master branch. But now let's say I want to add a new branch. Let's add a feature branch. And on this feature branch, I'm going to first checkout the feature branch so that I'm on the feature branch. And now I'm going to say-- let's go ahead and open up index.html. Right now it just says "Test." This was the original contents of that repository. I'm going to change that to say "Here is the new branch contents." So this is the new version that I want to add to this feature branch. And I'll go ahead and git add index.html and commit that change-- so "New branch contents." And now if I try to git push-- remember, before, that git push is the command that I use to take the changes that I made on my computer and make them reflect on GitHub-- you'll notice that what I get is this strange message that says "The current branch feature has no upstream branch." And what that means is that I've created a new branch, feature, on my computer. But there is no corresponding branch on GitHub that I can push to yet, right? GitHub only has a master branch. And on my computer, I have both a master branch and a feature branch. So if I want to push to GitHub and say, all right, push to GitHub, but push to a new branch on GitHub called feature, then I'll run this command here, git push --set-upstream. So when I push up to GitHub, what branch do I want to push it to? And I want to push it to the feature branch. So that's just copying this command right here. And so when I do that, I have now pushed that new branch up to GitHub. And if I refresh this page-- or even if I don't refresh-- it tells me that I've pushed a new branch, feature. And I can click on that feature branch to see that, on the feature branch, I have the new branch contents. But if I switch from the feature branch back to the master branch, this just has the original test contents. So you can take your existing branches and push them to GitHub as well such that GitHub can help manage all of those branches too. Other questions about Git, branching, or merging? AUDIENCE: [INAUDIBLE] BRIAN YU: Yeah. So if you look at the URL here in GitHub, it tells you the name of the person who owns the repository, the name of the repository itself. And then, here is master, which is just the name of the branch that I'm currently on. And so when you navigate through GitHub's user interface, you will see the different names of the branches show up in the URL as you go to different pages. AUDIENCE: On the front page. BRIAN YU: Oh, so the question is, what happens on the front page? On the front page, by default, there's a default branch that GitHub uses. And usually that's the master branch. You have the ability to change what that default original branch is. But generally speaking, it will be the master branch. AUDIENCE: [INAUDIBLE] BRIAN YU: Oh, OK. So the question is, in project 0, we're working with GitHub Pages, which lets us take websites and deploy them to the internet just by pushing them to a GitHub repository. The way that GitHub Pages works is that it's only deploying to the internet from a particular branch. So when you set up GitHub Pages in the Settings page of your repository, you had to tell GitHub, I want to upload files to the internet based on the contents of the master branch, for example. Or you could specify which branch you wanted. And so as a result, anything that's on any other branch isn't going to be reflected on the internet if you just go to the GitHub Pages website. What you'll need to do is test the changes on your own on your own computer. And when you feel comfortable with them, when those are the changes that you want to deploy to the internet, then you can merge them into the master branch. And that will be what ultimately gets deployed to the internet. Other questions about Git, or GitHub, or branches? OK. A couple other topics just to talk about briefly-- so these were sort of the key commands that we were using when regarding to branching in Git. git branch, If we don't have anything after it, just shows us all of the branches that we currently have. If we have git branch followed by the name of a branch, that creates a new branch. git checkout lets us change where we currently are in the repository. We can change from one branch to another branch, or even one commit to another commit. And then, git merge allows us to take two separate branches and combine them back together. OK, so a couple other things to talk about-- next is the concept of remotes. This is something we've already been using. But we haven't really looked at how exactly it's working. The concept of Git remotes is just the idea that we can have a version of the repository that's stored somewhere else on the computer, in particular-- or stored somewhere else on the internet, in particular-- on GitHub, for instance, if we're cloning the repository from GitHub. And so if you've been working with GitHub in project 0, for example, and you keep seeing the word "origin" show up-- it showed up just a moment ago when I was trying to push to a new branch, for example-- that origin is just the name of a remote, a version of the repository that lives somewhere else. I have one version of the repository on my computer, and the remote is some version of the repository that exists on GitHub, for example. And so how does that work? Well, I have some version of the repository that, maybe, has four commits on it. And this is the remote version, the version on GitHub, that might be a little bit later. And both my version of the repository and the remote both have their own branches. We saw before that I might have two branches even though GitHub might only have one branch going on. And this branch might be further along in terms of the commit history than my current branch is. And so if I wanted to work with this remote version of the repository, what I might do is run a command called git fetch, which just means, go to the remote, this online version of the repository, and download all of the latest commits. And so when I run git fetch, it's going to take those commits from the origin, this version of the repository stored on GitHub, and download them locally so that, now, I have this origin/master branch, the master branch from my origin remote. And I have my current master branch, which is still here. So master is where I am in my repository. And so if, now, I want my master branch to be updated to reflect the latest changes, the command to do that is to sort of say I want to merge where I am with where origin master is. And so if you do git merge origin/master, that causes your master branch to be updated to reflect the latest version of the origin. But this process is so frequent-- the process of, download the latest commits and move myself to the latest commit based on the master branch of the origin-- that these two commands can be simplified into just the command git pull. But if you're ever wondering what git pull is actually doing, this is what's happening. It's downloading, or fetching, the latest commits from the origin. And then it's sort of fast-forwarding yourself on the master branch to match up with the latest commit on the origin master branch. But that's what git pull is doing. And that's what allows you to manage that remote repository and move yourself to the latest version. OK, couple other concepts that are sort of specific to GitHub that may prove useful to you as you start to work on the projects-- one is the concept of forks. So a fork of a repository is just an entirely separate version of that repository that gets copied based off an original. So what you saw in project 0, if you started-- or if you haven't started, you'll take a look at it this week-- is that we create a new repository for you that's going to store the contents of project 0. And the first thing that you'll want to do is create a fork of that repository where we have a version of the repository that belongs to us, and you are going to fork it-- in other words, create an entirely separate version of that repository that belongs to you. And so on that fork that you own, you can do whatever you want to it. You can add new branches, you can push to it, you can pull from it, and you can manage it entirely. And all of that won't affect the original version of the repository. So if you ever look at open source projects, projects that many people on the internet are contributing to, very frequently there will be one version of the repository that's the version of the repository. And different people that want to contribute to that project will each independently fork that repository-- take their own version of the repository, make their necessary changes to it. And when they like their changes, when they'd like for those changes to be merged back into the original version of the code, they'll submit what's called a pull request. And a pull request is just a fancy way of saying that you would like for your changes to be brought in from one branch of some repository to some other branch of the same repository, or even a different repository. So when you submit project 0 for instance, you'll do that via submitting a pull request to the original version of the repository. And you'll often see pull requests as a good way of getting feedback or comments from other people that you're collaborating with on projects. They're an easy way of saying, I've made these changes. I would like someone to review those changes before we merge them into the master branch of a repository, for example. They're are a good sanity check, in a way, to take a step back and take a look at the code that you're about to merge before you actually perform that merge. So I'll show you an example of that now. So over here, we set up a-- we had, on the lecture1 repository, a master branch and a feature branch where, on the feature branch, I had added some new changes and added some new code. And now if I want to submit a pull request-- in other words, say, I like this new feature branch. I would like for it to be merged into the master branch-- I'll just click the Compare & Pull Request button on the right side of the feature branch. And I'll just go ahead and click the Create Pull Request button. And so this is a GitHub-specific feature that lets whoever owns this repository see that I am proposing to make these changes to the code. You can see what changes I'm proposing to make-- remove this line, add that line. And what this allows us to do is to have a conversation about the changes that I'm proposing to make. It allows for people to request that new changes get made. And this is a common paradigm, if you see projects on GitHub, where people will use the pull request feature as a way of getting feedback and working together collaboratively on projects. And so you'll get an opportunity to play around with forks and pull requests over the course of project 0. And you'll find more information about that in the instructions. But just wanted to give you a look at it so that you can get a sense for what the interface looks like, and ultimately, how that works. But now let's take a step away from Git and start going back to actually designing web pages, and structuring our web pages, and organizing them, in particular, by taking another look at HTML. So last week we took a look at the basics of HTML, how we might structure a website using nested tags. If you remember, those tags took the form of an open angled bracket, then the name of the tag that we wanted, and then a closing angle bracket. And using just that simple syntax, we were able to create lists, we were able to add images into the content of our web page. But thus far, we've only been interacting with a single page. We had one something.html document where we put in a bunch of tags. And that rendered a web page that displayed some contents. But modern websites and modern web pages nowadays don't just display content, and that's it, on one page. They'll very often need to interact with other pages, in particular, by linking to other pages such that you click on a button, or click on a link, and that takes you somewhere else. So let's take a look at how we might actually do that if we wanted to write HTML code to connect multiple different websites together. So what we'll take a look now is we will look at links0.html. And so what we see in links0.html is just a standard HTML web page. As we remember from before, !DOCTYPE html just means this is an HTML5 document, a document written in the latest version of HTML. This html says this is the beginning of the HTML content of the website. Here is the header of the website, the Information that's sort of metadata to the page-- not stuff that's going to be displayed in the main contents of the web page, but information that's helpful for the web browser. In particular here, we specified a title. The title of this page is "My Web Page!" And then, inside the body of the web page, we have this contents, which is how we're going to be creating a link. So here we have a, or anchor, and then href. And href just stands for, what is the hyperlink that we want to link to when someone clicks on the contents of whatever is inside that tag. So right now it says, "Click here!" And href="hello.html" means, when someone clicks on Click here! we should take the user to hello.html. And so if we open up hello.html and see what's in there, that's just a web page that says "Hello, world!" for example. So now if I open up links0.html, what you'll see is, right now, just has a big, blue link that says "Click here!" And if I click on that link, where I'm taken to is-- if you look in the URL, the URL changes to hello.html. And the contents of that page is "Hello, world!" And so by using that tag, we were able to link to a different page that was located in the same folder. I had a links0.html file, and also, a hello.html file. And a href was my way of saying, when I click here, I want to link and go to that other page instead. And this hello.html file doesn't just have to be a file that's located on my computer in the same folder. It could be an external URL if I want to link to an entirely different website, for instance. So if I want to link to https://google.com for example, and say click here, and take that to Google, now, if I refresh my links0.html page and I click here, now I'm taken to Google's home page. And so I can link not only to a file located on my system, but I can also link to elsewhere on the internet as well. And in addition to linking to a different file or to an entirely different web page, you can even use these a href tags to link to different places on the same web page. And this is becoming increasingly popular as more and more content gets put on the same page. And oftentimes when you click on links, they're not taking you to different pages, they're just taking you to different places on the same page. So we'll take a look at an example of that as well. Here is links1.html. So what you'll see is, in links1.html, I have a whole bunch of sections. So each section starts with a heading, h2, for a reasonably large heading. And each one has an ID. And recall from last week that the ID attribute of an HTML element is just an easy way to give an HTML element a name. So I want to give this header the name "section1" such that, later, as we'll soon see, I can refer to this h2 tag as section1, the thing whose name is section1. I have a paragraph that has some text. I have a second section that's called section2, another paragraph, and then section3, with a heading, and then contents underneath that as well. So how do I now link to different parts of this document? Well, if we notice up here, I have what-- I just called it a table of contents, and then ul for unordered list. And remember, li are the elements contained within an unordered list or an ordered list, li standing for "list element." And each one of these list elements is, itself, a link. We have that same a ref syntax in that tag. But the link, instead of being a .html file, starts with this pound symbol where the pound symbol just means, rather than link to an individual page, link to something with a specific ID. In particular, here, by clicking on the section1 link, this means, link to whatever has ID section1. And this means, link to whatever has ID section2. And this means, link to whatever has ID section 3 such that now, if I open links1.html, you'll see a table of contents and individual sections. And if I make the window small enough such that I can't see all of the sections all at once, you'll see that if I go to the table of contents and click on Section 1, for instance, it'll automatically jump down to Section 1. The page didn't change. I'm still on that same page. But it jumps me down to that first section. And if I instead click on Section 2 by clicking on that link, that'll jump me down to Section 2 on the web page. And likewise, clicking on Section 3 jumps me down to Section 3. And the reason that this page knows about all these relationships is via that ID attribute, the fact that every place I want to link to has that ID identifying it as section1, section2, section3. And then my individual links can then use those ID names to say, here is where I want the page to link to when I click on that individual link. Questions about linking between pages? Yeah. AUDIENCE: Is it possible more than one [INAUDIBLE]?? BRIAN YU: Good question. So the question is, can the same ID show up in more than one place? And the answer is no. In HTML, there is sort of a rule, which is that an individual ID can only appear once on any given page. So you should never reuse the same ID in two different spots on the same page. IDs are meant to be unique. So when I refer to something by ID, there should only ever be one of those things. If we want to refer to a group of things by the same name, there's a different attribute for that called "class." And if you give multiple different things the same class name, then it's possible to refer to a group of things all at once by referring to that class. Great question though. AUDIENCE: [INAUDIBLE] You won't be able to-- so the question is, can we link to something based on its class? And the answer is that's not quite going to work, because you imagine we might have three things that all have the same class name. And so if I link to it, the web page isn't going to know, which thing do I actually want to link to. So generally speaking, when we link to things, we'll want to link to the same page based on their individual IDs. Couple other notes about HTML-- so those were links. HTML has undergone a number of different revisions. So the latest version is HTML5. Back in HTML4, if we wanted to organize our website into different parts, you might imagine that a more complicated website might have a header at the top of the website. It might have a navigation bar, whether on the left side of the website or a banner across the top, for instance. It has some main content, and maybe a footer at the bottom that has copyright notices, or other links, or whatnot. In HTML4, you might have seen syntax that looks something like this in order to organize your website, where a div, if you recall from last week, is just a vertical section of the web page. It's just a generic section of the web page that has some name associated with it. And we might have added class names to this where we said, div class="header" such that later, I could use CSS and say, take anything that's a header, and give it a dark green background, and make the font size 36 points or whatnot. And we might have had a separate div whose class was "nav" for the navigation bar, a separate div for individual sections of the web page, and a separate div for the footer. And this is still a reasonably common paradigm. But in HTML5, since this process is so frequent in web pages, there are actually new tags that are added to HTML5 that are increasingly being used in more modern web pages that simplify this process. Rather than just have divs that have class names that are specific parts of the web page, some parts of the web page now, in HTML5, have their own tags such that if you want to better organize the header of your website into one section, or the navigation bar of your website into one section, you can use the header tag to say, this is the header of the website, nav for, this is the navigation part of the website. And the reason you might do this is because, then, in your CSS, for instance, you could say, take anything inside of the nav bar of my website, and give it these particular stylistic properties in order to make the navigation bar render in a particular way, for instance. And so this can be a nice, simpler way of helping to organize your website in a way that's easy to read and is easily understandable. These aren't the only new tags that are introduced in HTML5. There are a whole bunch. I won't talk about them all. But a couple that are particularly of note are audio and video tags, which make it really easy to embed audio content into your web page or embed a video into your web page, and then also, this one called datalist, which is increasingly popular now as autocomplete on-- when we're typing on a phone or on a computer, becoming increasingly prevalent. And I'll show you an example of one of these datalists just now, because it is quite a nice feature. So one thing we looked at last week was creating a simple form where, inside of a form, we might want people to enter in their name, and their email address, and other information that they would want to submit. We haven't gotten, yet, to how we can process information from that form and do something meaningful with it. But we talked about how to create a web page that just displays a form that people can enter information into. So let's go ahead and take a look at form.html now. And what we saw before is this part looks very similar to the form that we saw from last time where we have a form tag that just says, this is going to be an HTML form. And here on line 10, we have an input field. An input tag just says, this is going to be a place where someone can input information. We named that input field, which doesn't do anything for us just yet. But you can imagine that we've seen the value of naming things in the past. When we name particular HTML elements, that makes them easy to refer to. And in the same way, naming particular elements of our form is going to make it easy to refer to later such that, when someone submits the form, we're going to be able to write code that says, get the name from the form that will get at this specific input field. Or get the user's password from the form, which will get at that specific input field. The type attribute of this input field is set to "text." This is just text that we want the user to input. And the placeholder is "Name." And likewise, for the password, the type is "password," which is a slightly different type. And we'll see what's different about it in a moment. And the placeholder there is just going to be "Password." Here we see a different type of input. Here we're asking for a favorite color. And the options are going to be red, green, blue, or other. And rather than just have them type in something, this type of input is a radio input-- so a radio box where there is sort of a bunch of circles, and you can click on one of them to select which one you want. This is a slightly different form of form input that might prove useful to you depending on the type of form that you're trying to create. And here we just have four different inputs, one for each of those different radio options. And then finally, down here, we have an input that is going to represent what country the person is from. And so we named it "country." And we associated it with a particular list. And so this is the new feature of HTML5. I associate it with the list "countries." And immediately below that, I have a datalist, which is just going to be a list of possible options that will populate this form. And we'll see what that looks like in just a moment. It's name is "countries" so that our input field knows how to reference it. And now we just have a whole bunch of options, one option for all of the countries. We just got a list of countries, and put them all into individual options, and put them into form.html. So now if I open up form.html, here's what that ultimately looks like. I have a place where I can type in a name. I have a place where I can type in a password. And recall that that password field had a slightly different type. The name field's type had type="text," just normal text that I'm typing in. The password had type="password." Browsers know how to interpret type="password" to mean something special, to mean this is secure, sensitive information that they're typing in. So when I start typing into this field, it's just going to show up as dots. It doesn't actually show the actual text. And that I got just by saying type="password." And the browser knew to interpret that as secure password information, stuff that shouldn't just be displayed as text on the screen. The favorite color radio button, I had these for radio input options. And that shows up this way, where I can select among these potential favorite colors. And then for country, because I had this datalist, if I start typing in "United," for example, it's going to automatically fill in with any matching elements from that datalist, because I provided the list of all the countries. And now all I have to do is click on the country that matches-- in this case, United States. And that fills in the category appropriately. I could also click on that arrow to see any of the matches that showed up there as well. And so datalist is one of several new features in HTML5. There are a whole bunch of new tags, audio, and video, and datalist among them. We won't have time to look at all of them. But just wanted to give you a taste for what's new in the latest version of HTML. And HTML continues to add new tags and new features. But one of the problems is that browsers need to support the latest versions of HTML. So it isn't always the case that as soon as there is a new feature to HTML, that every web browser in the world will suddenly support it. Oftentimes, older browsers might take longer to support newer features of HTML. But HTML5 is starting to become widespread. All the major browsers now support the most important features of HTML5. So you can start to use things like audio and video embeds and datalists in the websites you design with reasonably high confidence that whoever is looking at the web page will be able to understand it. Question? AUDIENCE: [INAUDIBLE] BRIAN YU: Good question. So the question was, is it important that, in all the projects in the class, that it works on every single different browser? Generally speaking, the languages that we're teaching, HTML5 and the latest version of CSS, you should feel free to use even if much older web browsers might not support those features. We'll talk a little bit later in the course about how you might go about making sure that some of the features will work even on older browsers as well. But for the sake of project 0, I wouldn't worry too much about it. OK, so that's HTML. And now what I wanted to do was move on to talk a little bit more about CSS. So CSS, which stands for Cascading Style Sheets, was the tool that we used last week to style up our website. In the form we just saw, everything was sort of black text. It was all in the same font. And it wasn't particularly aesthetically pleasing. And what CSS allows us to do is have a lot of control over how the website actually looks, over the colors, and the fonts, and the layout, and ways that things are organized. And we're going to spend, basically, the rest of the lecture today talking about how to make that website look good. Because there's a lot that goes into organizing the website and styling the website in such a way that it's going to be visually appealing, and that things are organized the way that we want it to look. And in particular, in the modern day and age, where people are looking at websites on a bunch of different platforms-- looking at them on their laptops, and on their tablets, and on their phones-- it's important to think about and consider how different websites might look on different platforms and to make appropriate adjustments in order to make sure that if you look at the website on a computer, it looks good, but it will still look good even if you look at the website on a phone, for example. And so we'll explore some of the tools and technologies that we might use in order to do that. But let's start by looking at some of the more advanced features of CSS to have even more control over how it is that we want to style our website in order to have a lot of control over that individual style. So let's take a look at this example. So this is an example that is similar to something we saw last week just to give you a refresher on what CSS looks like in terms of code. We see that inside the body, we have two headings. Here's one big headline, and here's a smaller headline. Recall that h1 is the biggest headline, h2 is the next biggest, all the way down to h6. And up here in the style section of the page, we've included some CSS content. And so here, what I said is h1, comma, h2, where the comma just means I want to apply styling to multiple different things. I want to apply styling to the h1s and the h2s. I could have equivalently said, h1s I want colored red, and h2s I want colored red. But oftentimes, if you find yourself repeating yourself, it's a good idea to look for ways to simplify. And this is a paradigm that we're going to be returning to later on in this lecture. But to make this simpler for now, we can just say h1, comma, h2 to mean, I want this styling to apply both to h1 tags, the big headlines, and h2 tags, which are the slightly smaller headlines such that if I open up multiple.html now, what I see is the big headline, which is red, and the smaller headline, which is red as well. But in addition to the comma that just lets us select multiple different things, there are a bunch of other CSS selectors that let us be very precise about selecting particular parts of our website that we want to style and styling them in particular ways. On these simple websites that I'm about to show you, they might seem a little bit trivial. But as your websites start to get more complex and start to have a bunch of different moving parts to them, it can be very helpful to be able to be very precise in selecting particular parts of your website that you want to style in particular ways and making sure that only those elements get styled in a particular way as opposed to all of the elements on the web page, for instance. And so no need to worry about memorizing all of this. All the CSS selectors are very well-documented. And it's easy to look them up in order to find a particular selector that works for you. But I'll show you these now just to get you a sense for what you can do with CSS and the amount of control and precision that you can have over CSS selectors such that they may serve as inspiration as you go ahead working on project 0 or other websites that you want to be styling, potentially, in the future. So let's go ahead and open up descendant.html. And so what's happening here inside the body of this website is that we have a couple things going on. So inside the body of the website, we have an ol, where ol stands for ordered list, which is just a list where things, instead of being bulleted like and an unordered list, are numbered-- thing number 1, 2, 3. And the web browser will automatically number those things for us. And we have a bunch of list items, so list item one, list item two. And inside of this ordered list, we have a list inside of the list. So if you've sometimes seen websites that have nested lists, or lists that have a left side and then an indented part that's a list within the list, this is all this is, another list inside of the ordered list that is a sublist-- sublist item one, sublist item two-- and then another list item that's part of this original ordered list. So if you think back last week to where we talked about the DOM, that tree that shows how different HTML elements are nested within other HTML elements, you can think of this as the ol, the ordered list, containing four different pieces, one list element, another list element, an ordered list, which, itself, contains two list elements, and then a final list element in the ordered list. And so what styling do we want to apply to this? Well, here we're saying that we want to apply styling to ol li. So there's no comma here. It's just ol li. ol stands for ordered list, and li stands for list item. And what styling the ol, space, li is going to say is, I want to style all of the list items, the li's, that are contained within an ordered list, or all of the list items that are descendants of the ordered list, equivalently. And so all of those list items I want to color red, for example. And so now, if I open up descendant.html, we see that all of the list items, including the sublist items, are all styled as red. And so why did the sublist items get styled as well? Well, it's because the only rule that this CSS is following is that if there is a list item, an li, that is a descendant of or is contained within an ol, an ordered list, then it's going to be colored red. And this list item here, even though it's inside of an unordered list, is still inside of this broader outer ordered list. And so it's going to be styled as red additionally. If I add another list that's entirely outside of the ordered list and say ul for unordered list-- and I might say, here is a second list here, and here's another item. So this is an unordered list that's outside of the ordered list. If I refresh the page now, this second list is not styled in that same way. Because these are, yes, list elements, or list items, li's, but they're not contained within an ol. And so as a result, they don't get styled in the same way as all of these individualist list items do. Questions about how that space operator works to select just the descend-- any descendants of a particular HTML element and specify those, specifically, as the ones to be styled? AUDIENCE: [INAUDIBLE] So the question is, if, in this case, we were to omit the li entirely and just say ol, that I want it to be styled red, would that do the same thing? In this case, yeah. Because if we style the ordered list, everything within it is ultimately a list item. And so it's going to be styled red as well. But you can imagine more complicated cases where the outside tag might have a bunch of different types of tags within it. And if we only want to specify certain elements within the outer element to be styled, that's when having a second thing after it can often be helpful. And we might take a look at couple examples of that later. So that worked for selecting any descendants. And the way to think about how this is working is that we have these list items, which are-- you can think of as children of the ordered list, and these list items down here, which you can think of as grandchildren of the ordered list, where we have the ordered list, and then the unordered list, and within it are the individual list elements. What if I only wanted to select the immediate children, but not the grandchildren, the ones inside of it? And so for that case, what we want isn't the defendant selector that selects all of the descendants, but rather a selector that is just going to select, for us, the immediate children. And so let's take a look at child.html now, which is going to be the same body contents. We still have an ordered list with individual list items and a sublist contained within it. But here's the difference in the style tag, just a minor syntactic difference. Rather than ol, space, li, we have ol, greater than sign, li. And not greater than sign is CSS's syntax for specifying an immediate child. So ol greater than li is going to only select list items that are immediate children, directly descended from any ordered list. And it's going to color those as red and ignore anything else. So if we open up that website and take a look at what that looks like by opening up child.html, this is the result, right? The immediate children of the ordered list, the numbered items, all show up as red. But the sublist items, the things that are contained within the unordered list inside of the ordered list, those aren't styled. Those are still colored black, because they're not immediate children of the ordered list. They're grandchildren of the ordered list. And so I'll show you that code again just so you can take a look at it to get a sense for what's going on there. Questions about the distinction, though, between the defendant selector and the immediate child selector? OK. There are a couple other selectors that are useful to just see so that you get a sense for what you can do with which HTML and CSS styling. One is going to be in attribute.html. So in attribute.html here-- and all this source code is going to be made available after the lecture if you want to take a look at it-- we have, here, a form where that form is very similar to the types of things we've already seen where we have a input field for the first name, an input field for the last name, and an input where the person looking at the web page can type in their age, for example. And what you notice is slightly different about these is that first name and last name have a particular type. Their type is text, their text that we want the user to input. And their age, on the other hand, is going to be a number. The type is number. And what some web browsers will do is-- when the type of a input field is a number, is-- they will try to help you restrict the valid inputs that you can type it. Have you ever seen a HTML input form, for example, where they're expecting a number, and if you type the letter, nothing happens? That's because the web browser might know that the type of this input field is a number. And so I better not allow anyone to type text into that input field. Because it should only ever be a number. And so that's what that's doing there. But what that allows us to do is style things in particular ways. And so CSS also allows for styling things based on individual attributes. And so before, we saw how we could style any generic tag. But here what we're looking at is I want to add styling to input fields, but only the input fields where the type of that input is text. And I can use any attribute name and value here. It doesn't just need to be input types. It can be any time where we've seen attributes added to HTML elements. So we saw, like, src for images, or href for links. These are all attributes that we can use the attribute selector for in order to style them in particular ways. So here we said the input type is text. And if it's text, I want the background color to be red. And if the input type is number, then I want the background color to be yellow. So I'm delineating between different input fields based on their individual attributes to say, here is the way I expect certain attributes to behave. So if I open up attribute.html now, here's what I see, where these are all input fields. The only difference between them is particular attributes that they have. And first name and last name are now places where I can type in text, and their background color is red. And age, because it has a type of number, is going to display a background color of yellow. I have allowed myself to be more precise about the way that I select elements in order to style things exactly the way that I want them to be styled. And ultimately, that's what CSS selectors are designed to help you do. They are designed to help you be more specific about the way that you work with CSS and the way that you select individual elements to help make the process of designing a web page that looks the way you want it to look all the easier. So couple other things to look at-- let's take a look at different types of selectors that operate in different situations. In particular, CSS has the notion of what's called a pseudo-class. And a pseudo-class is just a special state of an HTML element. Because a web page is not just something that gets displayed, and the user sees it, and that's it. The user is often interacting with that web page. They're hovering over things. Their cursor is moving around the page. And so we might want our web page to respond to user interactivity-- that when a user hovers over something, for example, we might want that behavior of the web page to change in some meaningful way. So let's take a look at exactly that example by taking a look at hover.html. And inside the body of hover.html, it's actually a very simple body. There is very little happening here. I have a button tag, and it says "Click me!" And that's it. But now let's take a look at the styling. This is where things get interesting. So inside the style of this web page I have a couple things going on. I've said, take the button. And here are the things that I want you to know about how we should be styling this button. It should have a width of 200 pixels, a height of 50 pixels. The font size will be 24 pixels. Those are just arbitrary numbers that I chose to make the button look a little nice. And the background color of the button is going to be green. But here, this colon syntax is what I call a pseudo-class representing a specific state of the HTML element. In particular, this is what happens when the button is hovered on, when the cursor moves over that button. And in particular, what I'm saying here is that, now, I want the background color to be orange instead. So I went to change the styling of the website based on a particular state that an element might be in. So if I now open up hover.html and take a look at it, right now it just says "Click me!" It's a green button. But as soon as my cursor moves over the green button, it changes to orange, right? I have that hover pseudo-class attached to this button such that it knows that when something hovers over it, the styling of it should change. So this allows the styling of a website to vary depending on how the user's interacting with it. And so you may have seen this type of thing happen where, when you hover over something that's important, it changes color, or it grows, or it does something different with its styling. And oftentimes this is how it's working, just pseudo-classes that are placed on CSS elements to make them behave in certain ways. In addition to pseudo-classes, CSS also has what's called pseudo-elements, which are ways of affecting particular parts of an HTML element. And so I'll show you a couple examples of that now. These are a little bit less common, but are still things that may come up. So I'll show you before.html right now. And so in before.html, what I have here is an unordered list of links. Here's one link. Here's another link. Here's a third link. And right now they all just link to #-- in other words, don't really do anything. We're not linking to any external website. But for each of these links, these a tags, I have this pseudo-element before. And what this is saying is I want to apply some styling that happens before the contents of the actual link. And in this case, the content is slash 21d2, which is a special hex value for a Unicode symbol. So these are symbols that you can't just normally type on the keyboard. But special symbols like emojis and other symbols have particular codes. This code, you'll see in a moment. And then it says "Click here." And the font weight of this contents is before. And so it might not be immediately clear what exactly is going on here, but I'll show it to you. And then we'll come back to the code so you can take a look at what's really happening. Let's open up before.html. And what you see is three links-- one link, another link, a third link. But all of them are prepended with this arrow sign that says "Click here." And so how did that happen where all three of the links have that additional information at the beginning of it? Well, these individual links only said "one link," "another link," and "third link." But all the magic is happening inside the style tag where I'm saying, for every link, before the contents of that link, I want you to add this particular content-- in particular, this symbol, and then the words "click here." And I want the font weight of that before element to be bold. And the result of that is this, where each one of those individual links is prefaced with arrow sign, click here. And so if you have a bunch of different elements that you all want to begin with certain text or a certain symbol for example, you might use colon, colon, before, as we used here, or colon, colon, after, which does the same thing, but at end of the element, in order to make those modifications as well. One other potentially useful one-- and then we'll take a short break-- is selection.html. So inside selection.html, the body of it is just one long paragraph. But inside the styling, I say p::selection. In other words, when something is selected, I want that selection to behave in a particular way or have a particular styling. In particular, I want its color to be red, and I want its background color to be yellow. So if I open up selection.html, what I get is just some text. But if I highlight that text, it highlights in a very particular way. It highlights where the text I'm highlighting is red, and the background is yellow. Because I'm specifically saying, I want, when I highlight the contents of this paragraph, for the styling to appear in a particular way. And so that's something that you can do as well. And so a bunch of those CSS selectors are summarized here. We have the multiple element selector where a comma separates two things to say, I want styling to apply to both of these things, the descendant selector for when I want to select everything contained within something else, immediate child for immediate children but not grandchildren or great grandchildren of an element. We didn't see this one, but the adjacent sibling selector lets you select something that comes immediately after something else-- so two elements that are sisters to each other in the tree rather than one being the parent or containing the other. We saw the attribute selector that let us say that inputs that are numbers should be treated as different from text inputs, and then pseudo-class for things like when I'm hovering over an element, and then pseudo-elements for saying before the contents of a page or after a contents of the page. Again, no need to memorize all of that. But these are just a sample of the CSS selectors that you can use in order to have a lot more control over the contents of your HTML page. When we come back, we'll dive even more into CSS, not looking at CSS selectors specifically, but looking at how we might take a web page and make it more mobile-responsive for example, and use some more advanced CSS features. But for now, we'll take a short break. And we'll be back in a couple minutes. OK, welcome back. So now what we're going to do is take a look at how we can go about making our web pages mobile-responsive. In particular, responsive design is generally the idea of trying to make sure that our web page is going to look good regardless of what platform we look at it on. Whether that's a desktop machine, or a laptop, or a phone, or a tablet, or any other device, we want the website to look good across all of that variety of platforms. And so when we start to think about responsive design and how to go about making the website look good no matter what, what are some things we would need to think about? What might be important to keep track of when thinking about how things look on a computer versus a phone? Yeah? AUDIENCE: [INAUDIBLE] BRIAN YU: Making sure the text responds right-- yeah, different screen sizes might adjust for-- might require differently-sized text in order to make the text look good. Sometimes if you look at older websites that aren't really designed for phones, and you try and look at it on a phone, all the text feels, like, squished into the center of what's called the viewport, the area of the phone that you see web content on. We'll talk about ways that we can go about fixing that. Good point. What other things might be relevant to consider when we think about going from bigger screens to smaller screens or different platforms that websites need do exist on? AUDIENCE: [INAUDIBLE] BRIAN YU: Yeah, things need to move around a bit. You might need to-- it might not just be a matter of making everything smaller in order to fit on the mobile screen. But if you've got a desktop website that has a bunch of different columns worth of stuff, maybe three columns of information, and you want to shrink that down to a mobile screen, now, suddenly, you can't just squeeze all three columns into the same narrow window on the screen. You might want to stack the three instead rather than have all three separate. And so we'll talk about ways that we can go about making those considerations and making sure that our web pages are able to adapt to those sorts of different types of platforms and different screen sizes. And so the first strategy that we're going to be using here-- will be a number of different strategies. But one strategy that will use are what are called media queries. And so a media query is a specific way of assigning CSS not to a particular HTML element, but to a particular HTML element on a particular type of media. So that type of media might be particularly-sized computers, or particularly-sized phones, or even the difference between how you want a website to look when you are writing the code for it to appear on a screen versus how you want the website to look if someone prints it out, for example, on a printer. Because maybe when someone prints your website out on a printer, you want the content of the page to look different than if you were just writing websites that were going to appear on computer screens. And you might want those to be different. And so let's take that as a first example and take a look at our first media query. And so what we'll take a look at is print.html. And so what we have here is, in the body of our web page, three paragraphs. So this is a paragraph. This is another paragraph. And then I have a third paragraph, and I've added a class to it. And that class is going to be called screen-only. That's just a name I made up, but it's useful for me to know that this is going to be a paragraph that is only going to show up on computer screens. When I print it out, it's not going to show up. So this paragraph won't appear when you print this page. And you might want this if you have particular instructions for, like, click on this button or click on that button that are relevant when someone's looking at your web page on a screen but aren't very relevant if someone wants to print out the contents of your web page, for instance. And so how do I go about styling that? Well, this is what the style header looks like here. I have this @media, which means, create a media query. I want to apply CSS styling, but only in particular situations, only in particular cases. What case do I want to apply the styling in? Well, in this case, I said @media print. In other words, this styling, I only want to apply when the media, or the medium by which my web page is being viewed, is it's being printed. And then .screen-only-- remember that dot is a way of specifying, select everything with a particular class name. Down below we had a paragraph whose class name was screen-only. And here I'm saying, take anything whose class is screen-only, and said its display property to none. And if you haven't seen this before, display property being set to none means, make it not visible. In other words, it's not being displayed. And we'll see other examples of the display property later. But what's the result of that going to be? Well, again, I have three paragraphs. Here's a paragraph. Here's another paragraph. And here's a paragraph that won't appear when you print the page. And if I open print.html, what I see is those three paragraphs. And on my screen, they look totally normal. There'd be no way to tell that this paragraph is any different from the other two paragraphs. But if I go to the File menu, and I try and print this-- if I were going to print this web page out-- then the result that I see in this preview is that I see, this is a paragraph. I see this is another paragraph. But that third paragraph isn't there, right? That paragraph is now being printed. And in my CSS, I said, when the media that I'm trying to use when viewing this page is a screen, I want that paragraph to have a display property of none. I don't want that paragraph to be visible. And by doing that, I'm able to control how that web page appears on particular mediums. So that allows me to make sure that this paragraph doesn't appear when I print the page. But of course, printing is just one example of a different medium on which I might be looking at content. The more frequent case nowadays is probably that I have content being viewed on differently-sized devices, that I have a computer with a very wide screen, a tablet with a slightly narrower screen, a phone with a screen even narrower than that. And I want to make sure that my website responds to those changes as well. So how might I go about doing that? Let's take a look at responsive0.html. And in the body of this website, it's very simple. All it says is a headline that says "Welcome to My Web Page!" And that's the only content of the web page in the body. But now let's look at the styling. What's going on here, I have more @media queries. But this time, instead of specifying @media screen for, here's the media for what style it should look like when something is being displayed on screen, or @media print for when I'm printing something out, I have @media min-width-- 500 pixels. And what that means is that the styling that follows is CSS styling that apply whenever this page is being viewed in a window that's at least 500 pixels wide. And in particular, when the window is at least 500 pixels wide, I want the entire body of my web page to have a background color of red. Meanwhile, for @media max-width-- 499 pixels, that's saying the exact opposite, that if I'm on a smaller window where the maximum width of the web window is 499 pixels or anything smaller than that, then I want the body's background color to be blue. And so this allows me to change the styling depending upon how wide or how narrow a particular web page is. So if I open up responsive0.html, what I see is "Welcome to My Web Page!" And the web page background is red. And so that tells me that, based on the contents of my code here, the background color of red should only apply when the width of my viewport, the width of my window, is at least 500 pixels. So what happens now, if I try to shrink that website and make it less than 500-- I can grab the end and just shrink down this website. And watch what happens. It's still red. But as soon as it shrinks below 500 pixels, it changes to blue, right? Above 500 pixels, it's red. Below that, it's blue. And that's a first example of how we might change the styling of our website depending on how big or small the screen that we're looking at it happens to be at that time. So what are some other examples of that? What's a more practical use case? So in reality, we probably don't care all that much about, we want the wider screen to have a red background and the smaller screen to have a blue background. But we might care about something like this, which is a little more involved. But I have a body. And right now my headline is empty. It's just an h1, sort of a empty headline. But we're going to fill it in with content. But that content is going to differ based on the size of the screen. So here I've said @media min-width -- 500, same as before. When the width of my screen is at least 500 pixels, then before the h1 tag, the first thing that should show up in my heading should be the content "Welcome to My Web Page!" But on the other hand, if the size of my web page is 499 pixels or smaller, then I want the content of my h1 tag to just be the word "Welcome!" maybe because, on a smaller screen, I don't want a longer headline that might wrap onto two lines, for example. I just want a shorter headline that's going to look a little bit better on a smaller screen. And so what would that ultimately look like? Well, it's going to be the same thing as the background color, but just instead of changing the background color, we're changing the contents of what's actually displayed on the screen. So I open up responsive1.html. And right now it just says "Welcome to My Web Page!" as if I had just had h1, welcome to my web page, end h1. But if I shrink the window now, when it would have normally needed to potentially wrap onto another page and I go beyond 500 pixels, the headline changes. Now it's just "Welcome!" There's no "to My Web Page," because, on the smaller screen, I want the smaller headline to appear. If I go beyond 500 again, go larger, then the full headline comes back. And so again, that's all because of these media queries that let me specify the min width or the max width of the screen that I want things to render on and decide how I want the CSS styling to appear depending upon that screen size. One other thing you'll notice up here on line 5 is this sort of strange line, meta name equals "viewport" content equals "width=device-width, initial-scale=1.0"-- so sort of complicated line. All this line is saying-- and you'll see this line in a lot of websites nowadays-- is the viewport of my web page is just the visible area on the computer screen, or the phone screen, or whatever screen is being used to view the contents of the web page. And oftentimes in older websites, if you tried to view a website on a phone, it would just pretend that you were rendering the website on a computer, and render it as a wide display, and then shrink it down onto the phone such that all the text on the phone was really, really small. If you've looked at websites on your phone, you may have seen this before. All this is doing is a line that's telling the browser to adjust the viewport to make sure that we're scaling it to the width of the actual device, that the width of the viewport should be whatever the width of the device is. And as a result, that will help to prevent text from appearing really, really small when you render it on a phone as opposed to on a desktop. This line is often just a good first step to throw into your web page when you want to make it mobile responsive, because that will help to make sure that the sizing of things appears appropriately. But the key of what we're doing here in order to make this responsive is these media queries that are allowing us to specify what CSS gets applied under which circumstances. And so this is just some of the basics of how we can use CSS in order to help allow us to style websites in particular ways depending on different devices. We can also use particular CSS layouts. And I'll show you a couple of these now. Again, no need to memorize exactly what's happening here, but just to give you a sense for what's available in CSS. But before I move on, question? AUDIENCE: [INAUDIBLE] BRIAN YU: If you had both-- so the question-- AUDIENCE: [INAUDIBLE] BRIAN YU: Oh, if you wanted to specify both a minimum and maximum, I think there is a CSS keyword that allows you to combine two different media queries-- so like, min-width-- 300 and max-width-- 500. And I think you can look to the-- I'd refer you to the CSS documentation just to look at how you would go about structuring that media query. What we're looking at here is a tool built into CSS called flexbox. And what flexbox is going to allow us to do is create a web page that looks something like this. So we have a whole bunch of elements here, and each one is labeled A, B, C, D, E, F, G, all the way through L. And there's 12 of them. And what might we expect to happen if we were to shrink this web page down and view it on a smaller device? Well, what we probably want to happen is we still want to see these squares, but we don't want to have to scroll too much to the left and right in order to see all four. We'd rather have these individual cells rearrange themselves as we shrink down the page. And so watch what happens when I shrink this page. It originally shows me four in any given row, and I have three rows. But after I shrink it down a little more, it's going to just show three on each row. And now I've got four rows. And if I shrink it down more, it's got two on every row, and now I've got six rows. And if I shrink down even more, now we've only got one, where each thing is just stacked on top of each other. So this is what we were alluding to a little bit before, where if we have items appearing in multiple columns of content across the screen, we might want those things to move around as we begin to resize the window in order to make it more adaptable to different platforms and different devices. So what does that ultimately look like? Here's an example of flexbox in action. I have a container that's just going to contain all of these individual divs. Each one is just a letter followed by some random text. And here's the styling that makes that all happen. Inside my container, I'm setting its display property to flex. In other words, I want this to be a flexbox that allows the content to, in this case, wrap around it when it reaches the end of a line. So you might imagine that it's like if I had all 12 in one straight line. But as I shrink down the screen, I want the individual cells to wrap onto the next line and the line after that in order to make room for everything to show up within the width of my window. And now I have this .container, greater than sign, div. Remember, that greater than sign means immediate child. So for any div that is immediately the child of the container, here's how I want it to display. And this is just arbitrary. I wanted the background to be green. I gave it a font size. I gave it some margin and padding in order to make it look the way I want it to. And I specified how wide it should be. But really, the key was this, this display, colon, flex, flex-wrap, colon, wrap. This is what allows me to get that flexbox to wrap around just like that. One other style that I'll show you that's useful when we're laying things out is having a grid. We might want a grid sort of like a table that displays information in a grid format. And so that might look something like this, where I have a grid of individual cells-- 1, 2, 3, 4, 5, 6, all the way up to 12. And I might have content in each one of those. And you might imagine that this is useful if you want some information in the left side of the page and some information on the right side of the page. And notice, as I shrink this down, the size of that third column automatically adjusts in order to fit the width of the page. If I go beyond it, it starts to get cut off. But if I'm greater than a certain width, that third column will adjust itself. So how does that work? I'll just briefly show you this. And again, this code is all available to you after the lecture if you want to take a look at it to get a better understanding for how it works. But inside the body of my website, I have a div whose class is just grid. And I call it "grid" arbitrarily. And then within that grid are individual grid items. And here is 1 through 12, all just one after the other. So how did I take those 1 through 12 grid items and make it appear in a grid that looks like this? Well, here's the CSS styling that made that happen. For the grid, the background color is green. I used display, colon, flex before when I wanted things to wrap around. Here I'm using display, colon, grid. I gave it a particular padding. Remember, padding is just the spacing on the inside. And I wanted the grid column gap, or the space between individual columns of the grid, to be 20 pixels, and the space between individual rows in the grid to be 10 pixels. And here is grid-template-columns. This is what allows me to specify how wide I want each column to be. And here I've said the first column should be 200 pixels, the second column should be 200 pixels, and the third column should be automatically generated. Just however much space you need to fill space, that is how much space the third column should take up. If I instead change both the second and the third columns to be automatically filled, then what I get is column 1 that will always be 200 pixels, but columns 2 and 3 that will now adjust themselves naturally in response to how I move things. And if I change all of them to auto, for example, now all three of them will just automatically respond to me changing the size of the website. And they will shrink and grow accordingly in order to fit. Question? AUDIENCE: [INAUDIBLE] BRIAN YU: Great question. So the question is, how did I get the spaces to show up between the individual grid cells? Those were two particular CSS properties. Here grid-column-gap was 20 pixels. That's the space between individual columns. And grid-row-gap is the space between rows. If I change the row gap to, like, 50 pixels, for example, now there's more space in between individual rows. And so you can use the column gap in the row gap to control the amount of space that shows up in between the individual cells. But ultimately, this is starting to get a little bit complicated. And realistically, it would be pretty annoying if, every time we wanted something to wrap onto new pages, we needed to remember exactly how the flexbox worked and set up the flexbox for ourselves. But luckily, nowadays there are all these CSS libraries out there, which are ways that are-- CSS written by other people that we can then use them in order to make our lives easier when it comes to making our websites mobile-responsive, for example. And one of the most popular libraries is called Bootstrap. And that's the one I'm going to be introducing you to now. You'll get an opportunity to work with it in project 0. But Bootstrap is just an easy way of giving you access to some CSS that lets you make your websites styled a little more nicely, make them a little more mobile-responsive right off the bat without you needing to do a whole lot of work. And so if I open up nobootstrap.html, this is just a simple website, just like stuff we've seen before, where I have a heading that says "Hello, world!" and then a paragraph of text. And if I open up nobootstrap.html, this is what it looks like, same sort of thing we've seen before. If I want to add Bootstrap to my file, all I need to do is-- in bootstrap.html, this is the exact same website, but I've added one extra line, this link line where I'm linking a stylesheet. I'm linking Bootstrap's CSS file, which is located somewhere on the internet. And if you go to Bootstrap's website, you can find this exact line that you can put into your web page. And now everything else about my website stayed the same. All I did was add Bootstrap's CSS. And now if I open bootstrap.html, the website looks a little bit nicer. You notice that there's some padding along the outside. You notice that the headline is in a slightly different font. This is Bootstrap's default style that you're welcome to change. But that is Bootstrap's way of just making your website look a little bit nicer, look a little bit more modern. But the real power of Bootstrap comes when you start to look at the way that Bootstrap organizes information and lays things out. So Bootstrap's layout system uses a column-based model where the website is divided into-- or each row in the website, you might think, is divided into 12 individual columns. And you can control how many columns different things take up, recognizing that 12 columns is sort of the full width of your entire website. So let's take a look at column0.html. So inside the body of this website, here's what we have going on. I have a div whose class is row. Row is a special class in Bootstrap that just means, this is going to be a row of my page that's ultimately divided into 12 columns. And here are my individual divs within that row where each one has a class of col-3. And col-3, in this case, just stands for, this is a column that's going to take up three columns' worth of space. So if I have a 12-column page, I can have four things that each take up three columns' worth of space. And that's ultimately going to make up my entire row. So this is a section, another section, a third one, and a fourth one. And I've added some styling to it in order to make it look a little bit nicer. I've added some padding on the outside, a background color, and a border. And you'll see what that looks like in just a moment. So if I open up column0.html, you can see that, now, I've got these four sections, these four individual columns that are each taking up three out of the 12 total columns that are on the Bootstrap grid layout. And notice, if I shrink it down, some of the spacing goes away. You'll notice things automatically adjust a little bit. So it's designed to be very mobile-responsive out of the bat. I didn't write any of the code or the CSS to help things resize and rearrange when the screen size changes. Bootstrap's doing that all for me. So that's four columns. But really, what I would like is for these columns to move around depending on the size of the screen, that I don't just want it to be four columns. Because once it gets to a really narrow device, these four columns, if there's a lot of content in them, this is going to look really squeezed together so to speak. So what might I do about that? Well, in this case, let's take a look at columns1.html. This is very, very similar, almost the same, with a couple of changes inside the row. Before every class inside these divs inside my row, we had a class of col-3 for, we want this column to take up three out of the 12 possible columns that are present inside of the Bootstrap grid layout. In this case, I've done something a little more sophisticated. I said, "col-lg-3" and "col-sm-6." In other words, on a large screen where Bootstrap has defined for me what counts as a large screen by taking a look at what typical computer displays look like, what mobile displays look like, what tablet displays look like-- but on a large screen, I want this div to take up three columns out of the 12 on my screen-- in other words, a quarter of the total width. But on a small device, I would rather it take up six out of the 12, or half of the total width of the screen. And likewise, I did the same thing for each one of these individual columns within this row. And so on a large screen, we have col-lg-3, large 3, large 3, large 3, where each column will take up three out of the 12 possible columns in the Bootstrap grid model, whereas on a small screen, each one will take up half of the total width of my Bootstrap grid. So what does that look like? What's the impact of this when I try and render this website and look at it? If I open up columns1.html, on a large screen, it looks exactly the same. I've got one column, two, three, and four, where each column is taking up three out of the 12 available column spaces that Bootstrap provides to me. But as I make this smaller, what you'll notice is that once it gets to a certain point-- in this case, here-- it changes from four columns all in a row to two columns on each row where, before, here, on a large screen, each column was taking up three out of the 12 possible columns that were available in Bootstrap. But on a smaller screen, each one's taking up half of that width. And the result of that is that the latter two columns, which don't fit within the 12, get moved onto another line entirely of their own. So I could have done this using flexbox like I showed you a moment before, where things start wrapping onto other lines as I start to reduce it. But Bootstrap, which is actually written using flexbox, sort of abstracts that away and lets us just take advantage of defining how wide we want our columns to be on different size devices. And Bootstrap takes care of the rest of making sure that things get rendered the way that we want them to. Question? AUDIENCE: [INAUDIBLE] BRIAN YU: Question-- yeah, so Bootstrap does define classes within it. AUDIENCE: What happens if I [INAUDIBLE]? BRIAN YU: Great question. So the question is, Bootstrap defines a whole bunch of these classes. It defines row, and col-lg-3, and col-sm-6, and so on and so forth. What happens if I, in my CSS files, am also using col-lg-3 or row as CSS? And generally speaking, your web browser is able to take multiple CSS files and try and reconcile them somehow by applying all of the styling together. But if the styling conflicts, if Bootstrap says this row should have this width, but you say the row should have some other width, then one of them ultimately needs to take precedence. And generally speaking, the one that takes precedence is the one that is more specific. So if you had said that, I want the styling to apply to any row that is a child of some other thing, then that will take precedence over just a generic, I want rows to be styled in a particular way. But generally speaking, it's a good idea to be mindful. And if you were defining classes of your own, oftentimes it's a good idea to give them different names from the ones that Bootstrap does just to avoid having that conflict at all. AUDIENCE: [INAUDIBLE] class in Bootstrap. BRIAN YU: Correct, container is a class in Bootstrap. AUDIENCE: [INAUDIBLE] BRIAN YU: Yeah, Bootstrap-- AUDIENCE: [INAUDIBLE] BRIAN YU: So if you want to take the Bootstrap classes and add your own styling to them, you can sort of override Bootstrap, so to speak, by adding CSS code that refers to Bootstrap's classes. But you can add additional styling of your own to them to make them display the way that you want them to display. And you can experiment around with that to see how that ends up actually working. But Bootstrap, in addition to providing this grid layout, also has a host of other features. And we're not going have time to go through all of them. But I'll show you a couple of interesting ones here. For instance, Bootstrap makes it very easy to create alert messages. So these are some sample messages, just generic news, good news, and bad news. And in order to create those alert messages, all I needed to do was apply particular classes. So the class alert and alert-primary will automatically style something as a blue alert message. An alert alert-success will automatically style it is a green one. And alert, dash, alert-danger automatically styles it as a red message. And so this makes it very easy to add these alerts to my code, because Bootstrap has already written the styling for how to make them display in a way that looks nice. | if you're curious and you want to use more of Bootstrap's elements, you can go to Bootstrap's website, which, I believe, is getbootstrap.com. And if you go to their documentation on Bootstrap's website, you can look at all of their components. So here, what we just saw were Bootstrap's alerts. You can see all of Bootstrap's alerts. And here is the code that you can just copy and paste in order to create alerts that look in a particular way. Bootstrap also has special styling for buttons, buttons that appear in different colors and different sizes. And they tell you what classes to add to your buttons in order to make your buttons styled in a particular way to make them look a little bit nicer. And there's a whole lot of other features and styling that Bootstrap adds. You can just scroll through this list and get a sense for some of the features that Bootstrap gives to you. And by using some of these features, you can start to make your website look a lot nicer much more quickly by taking advantage of the work that Bootstrap's already done. So one last topic that I wanted to talk about today with regards to CSS and how we might go about styling our website is what happens when our stylesheets start to get a little more complicated and get a little more sophisticated. So I want to take a look at variables.html here. And you'll see why it's called "variables" in a moment. But right now I have, inside of variables.html, an unordered list, a ul, and an ordered list, an ol. And let's take a look at a sample CSS file that I might use in order to style this variables.html file. I have ul, which is set to font-size-- 14 pixels, and color is red, and ol, which is font-size-- 18 pixels, and color is also red. So these two lists are going to be displayed in different-sized fonts, but I want their color, ultimately, to be the same. I want their color to render as red either way. What if-- and maybe that's because the generic style of my website is that I like the color red, and I want my web page to render things as red. But what if, later on down the line, I decide, well, wait a minute, I'd really rather that by list be blue instead, instead of red. In this case, I would need to go back to two different places, to the unordered list, and change the color to blue, and the ordered list, and change that color to blue as well. And you can imagine, in a more complicated website, if I had dozens of different examples of CSS styling in particular colors, I might need to go through all of them and change those individual colors. And it might not be as drastic of a change as red to blue. It might be just a slight shade of red that you want to change, and you want to change it in many, many different places. And having to change it independently on each separate line is ultimately going to start getting tedious. And remember, we talked about before, if you ever find yourself repeating the same thing over, and over, and over, you should always think about, is there a better way to do it. Is there something else we can be doing instead? And if you're familiar with programming and programming languages like C, or Python, or any other language, then you might be familiar with the concept of variables, where we assign a variable of value once, and then we can reuse it multiple times. And if we change that variable's value, then that variable's value is changed everywhere, so to speak. And so what we're going to do now is introduce an entirely new language which is built on top of CSS called Sass. And what Sass is is it's an extension to CSS that gives us a little more power and a little more flexibility when it comes to designing CSS stylesheets that lets us programmatically generate stylesheets in a more advanced and more powerful way. But ultimately you'll see that the concepts here are just to make it easier to generate the stylesheets that we want to generate. So instead of variables.css, I'm going to look at variables.scss, where .scss is the typical extension for a Sass file, which is going to be some specific extension to CSS that we're going to explore in a moment. So what's going on in variables.scss? Well, the first thing I do on line 1 is define a variable. We haven't previously had any variables in CSS, because CSS, out of the box, doesn't really support the idea of a variable. But Sass, this extension to CSS, does. And so how does it work? On line 1, I said $color-- all variables in Sass begin with a dollar sign-- $color, colon, red. So I'm defining a new variable. It's called color. And its value is going to be red. And then, here's what's happening. I have my unordered list, whose font size is 14 pixels. And the color-- instead of saying red is the color, I'm saying $color, meaning $color was this variable that I defined to be red before. Whatever color that is, that's the color I want my unordered list to be. What about my ordered list? Well, the font size is going to be 18 pixels, and the color is also going to be whatever the value of this color variable is. And so by doing this, I get the same effect-- an unordered list that's 14 pixels in font size and red. And same is true for the ordered list-- 18 pixels in size, and the color is also going to be red-- no different. But I faced a problem. Can anyone guess what the problem might be if I tried to just use this code and render it in the web browser? Do we think it will work? Yeah? AUDIENCE: [INAUDIBLE] BRIAN YU: Oh, is there, like, a particular CSS property called color? That's not going to be a big deal for us, but that's a good point, that we want to be careful about naming things. But ultimately our web browsers are trained to understand CSS, and they know how CSS works. But web browsers don't, out of the box, understand Sass, this extension to CSS, where we have variables in there. So our web browsers are going to start to complain if we just put this inside of a CSS file and say we want this to render as the styling for the website. So what we need to do is take this SCSS file, this Sass file, and convert it into a CSS file. And that's why there's a program called Sass, which does just that. And I'll show you how it works. If I go into my variables directory, what I have here is a variables.scss file. And if I run sass variables.scss variables.css, what that is going to do is it's going to take my variables.scss file, and it's going to compile it-- turn it into-- a CSS file that my web browser is going to be able to understand. So I press Return. That compiled it. And now if I take a look at it, I see I now have a variables.css file, which I didn't have before. And I also have this additional map file. You don't need to worry too much about that. But if you're curious, that's just a way for your browser to understand the relationship between the CSS and the SCSS file in case it wants to figure out-- it's useful for debugging or figuring out what line something came from in the original file. But let's look at this variables.css file, which I didn't create. It was generated for me by Sass. What does it look like? So it looks, ultimately, like this. And it's exactly what my previous CSS file looked like. But it substituted that color variable with the name, or whatever value that color variable was actually assigned to. So color is now red. Color is now red in both the unordered list and the ordered list. The fact that the curly brace is on the same line instead of on a new line like we've been doing before is just that stylistic choice. It doesn't actually make a difference on the way that the page renders. But what I've done is I've used the variable from the SCSS file and compiled that file into a CSS file. And now this is something that my web browser can ultimately understand. So now if I go back to variables.html and open up variables.html, what I get is an ordered list where the unordered list items are smaller than the ordered list items. But all of the list items are red. And now, if I wanted to change this-- if I wanted to change the color from red to blue, for instance, rather than change it in two different places-- or, and you imagine, in a larger-scale program, potentially dozens or hundreds of places across your web application-- all I need to do is change this $color variable. I change it from red to blue, for example. And if I open variables.html, now it's still red. I changed it to blue, but the styling of the list items is still red. Why is that the case? Why did that happen? AUDIENCE: [INAUDIBLE] BRIAN YU: I need to recompile it, right. Because this HTML website is only looking for variables.css. It doesn't know anything about variables.scss, which is the file I've actually been working with. So I need to run sass variables.scss variables.css. That's going to recompile my CSS file such that when I now refresh the page, now everything is blue. Now, as you're developing with SCSS, you might imagine that it's going to start to get annoying fast, where every time you make a change to a SCSS file, you're going to need to recompile it back into CSS. So Sass has some built-in features to help make this a little bit easier. One is that Sass can watch a file-- in other words, keep track of the file, or even a directory full of files-- and any time any of them changes, automatically recompile the CSS file. So if I said sass --watch variables.scss, and any time a change is made to variables.scss, compile it to variables.css, now Sass is watching for changes. So now if I go back here and change the color to green, for example, and I save that, if I check back here, Sass has automatically detected that I've made a change to variables.scss. And it's written me a new version of variables.css. So without me needing to manually go in and recompile that SCSS file, I can refresh the page. And now all of the list items are green. So that's marginally better, that instead of needing to recompile the Sass file every time I make a change, I can just tell Sass, watch all of my SCSS files. And whenever any of them change, automatically compile it to CSS for me. And an additional feature is that many website deployment systems, GitHub Pages included, have built-in support for Sass such that if you push an SCSS file to GitHub Pages in project 0, for instance, GitHub will automatically take care of the process of compiling that Sass file from a .scss file to a .css file such that when someone goes to your website, they will see the resulting CSS style applied to your website. And so many system nowadays have built-in support for SCSS. They make it easy for you to use Sass in order to have a little bit more control over your styling in order to make websites really look the way that you want them to look. Questions about Sass so far and what we've seen? Yeah? AUDIENCE: [INAUDIBLE] BRIAN YU: Great question. Do you need to install anything in order to run the sass command? Yeah, you'll need to install Sass in order to make any of that-- the command line sass command work that does the compilation from SCSS files to CSS. If you never want to do the compilation yourself-- if you want to just rely on GitHub to do that compilation for you-- then you don't need to install anything. You can just push an SCSS file to GitHub Pages. And GitHub Pages will, on its own, convert it into CSS. But if you want to test that compilation locally to see what the resulting CSS looks like, then you'll want to install Sass. It's a freely available, pretty small piece of software that you can just install onto your computer the same way you installed Git or other software in order to make that easier. Other questions? Yeah. AUDIENCE: What if I had multiple CSS files, like if we downloaded the Bootstrap CSS file and I [INAUDIBLE] from that? BRIAN YU: Great question. So the question is, how does Sass work when we're dealing with multiple different files? Sass has a built-in command that actually lets you import existing CSS from a different file into a Sass file. So there's built-in support for multi-file stylesheets built into Sass. We won't see any examples of that in this lecture. But if you go to the Sass website, you'll find examples of how they're able to incorporate different files into the same file in order to use variables that are defined in a different file in a separate stylesheet. Great question though. One more question? Yeah? AUDIENCE: [INAUDIBLE] BRIAN YU: Great question. So the question is, when you're linking the file, do we want to link the CSS file or the SCSS file? We always want to link the CSS file, because the CSS file is the only one that the browser actually understands. Google Chrome, out of the box, doesn't know how to take a Sass file and understand what the variables mean. It only understands the CSS file. So what we need to do is say, reference the CSS file, and then just make sure that somehow, either us doing it ourselves or letting GitHub Pages do it for us, get that Sass file compiled down to CSS such that we can then use it for our own purposes. Excellent question though. So those are variables in Sass. But what other features does Sass give us? How else can we make this a little more powerful? Well, one other feature that's very helpful is nesting different CSS selectors within each other. And I'll show you an example of that now. So here is nesting.html. So inside the body of nesting.html, I have a big div, inside of which is a paragraph inside the div, and also a list inside the div, an unordered list with three list items that are all inside of this div. And outside of that division of the site, I have a paragraph that's outside of the div and a list that's also outside of the div-- so sort of a trivial, contrived example, but just going to show you a bunch of different hierarchies via which we might organize different HTML elements. And I want to style them in a particular way. So let's take a look at nesting.scss. And so here's the contents of nesting.scss. I have div font-size-- 18 pixels. And then within the div's curly braces, I have an additional p. And what that p is standing for is that I want this styling to apply to any paragraphs that are inside of a div. Now, notice that this isn't anything we couldn't have done before with just regular CSS. We could have said, on a different line, div, space, p and then color equals blue to say paragraphs inside of a div should be colored blue. But nesting things within each other just helps to organize things a little more. Especially as our stylesheets start to get longer and more complicated, we might find it easier to organize our code into something like this where we can say, all right, how are we styling the div. Well, the font's going to be 18. Any paragraphs within it should be blue. And any unordered lists within it should be green. And that just helps to organize our styles a little more such that, as they get longer, it gets easier to look at and easier to maintain. So when I compile that using Sass, which I've already done, I'll show you with the resulting nesting.css file-- or actually, I'll do it now. I'll go into my nesting directory where I have a nesting.scss fild. I'll go ahead and compile nesting.scss to nesting.css. And we'll take a look at what that file looks like. And what it's ultimately done, it's done exactly what we would have done before if we didn't have Sass at our disposal. It said div's font size is going to be 18. And then where, before, we just had p inside of the div, it's changed that to div, space, p. In other words, all paragraphs contained within a div are going to be blue, and all unordered lists within the div are going to be green. But instead of needing to specify this div every time, we were just able to enter scss, have a slightly simpler, slightly easier to look at interface that tells us how things are going to be styled inside the div. So if I open up nesting.html, what the result is is that the paragraphs get styled as blue, the list items get styled as green, but only the ones that are inside of this part, which was that original div. And anything outside of it doesn't get styled in that particular way at all. So that nesting feature is just another nice to have that Sass offers. Sass offers a number of different other features. But the last one that we'll take a look at today is the concept of inheritance. And inheritance is something you may be familiar with if you've done programming before in object-oriented programming languages like Java or Python. But inheritance in the context of Sass is used to refer to when you have some general styling that you might want to apply to a whole bunch of different things, but each of those different things you might want to be styled in a slightly different way. So if you think back to Bootstrap for example, where we saw those alert messages in Bootstrap where we had-- I'll open it up-- where we had a blue alert, a green alert, and a red alert, what if we wanted to create this sort of interface for ourselves without using Bootstrap where we wanted different alert messages that were different colors? Well, you might imagine there's a lot of styling that goes into this. There is a particular font that they're using. There's a particular font size that they're using for all of these alert messages. But also, all of these alert messages are different. This one's blue, this one's green, this one's red. And as a result, they need slightly different CSS styling. But they're fundamentally very similar. So there's a lot they share in common. If we were to write out the CSS by hand, we might have a lot of repetitive styling where we have the styling for the first alert message that got a lot of the same stuff, then a blue information, same thing for green and red. But with SCSS, we can use the concept of inheritance to factor out all of those commonalities in order to make it easier and more efficient to generate CSS that lets us have styling that inherits from some overarching property. And so let's take a look at what that looks like by opening up inheritance.html. So what I have here is, without using Bootstrap, I have three different divs. This is a success message. This is a warning message. This is an error message. One's classes is success. One's class is warning. One's class is error. So those are my three classes that I have to deal with. And I want to style them in a particular way so they show up sort of like the Bootstrap alerts that we were looking at just a moment ago. So let's look up at inheritance.scss and see what's going on here. So what I have here is this %message. And percent isn't something we've seen before. It's something specific to Sass. And it lets us define, effectively, a template, something that other things are going to inherit from. And this is just going to be a generic message-- whether it's a success, of a failure, or an info message, just a generic message. And that message has a particular font family. It's going to be a sans-serif font. It has a particular font size, 18 points, and it's going to be bold. That message is going to have a border around it, a 1-pixel solid black border around that message. And it will have certain spacing, 20 pixels worth of padding, and then 20-pixel margin. And that styling, I want it to apply to all three of my different categories of messages. Success messages, and error messages, and info messages alike all should have that same styling. And so how do I do that? Well, this is the code that I need, now, in Sass, in order to define those three classes. My success class, I just say, extend message. Take all the styling from the message before, and use it. But let's additionally add that the background color is going to be green. Likewise, for the warning message, let's extend the message. It's going to have the same style properties as the message. But the background color is orange. And same with error, except now, the background color is red. If I now compile that down to CSS, the result is that I get CSS code that applies this generic styling to all successes, warnings, and errors, and this specific background color to success, and a specific background color to warnings, and a specific background color to red-- to errors. And again, none of this is stuff that we needed Sass to do, but using Sass makes it a little bit easier. It's a little bit of a nicer semantic to say, here's a generic message, here's the styling for that message, and here are specific success, warning, and error messages that are going to extend or inherit from that message in order to add additional information, the result of which is a CSS file that we could have written ourselves but that gets generated from the SCSS file. So if we now open up inheritance.html, this is what we get, a success message, a warning message, an error message. We see the spacing around each. We see the font size and the font style that we wanted it to be. But the difference comes in the different classes. One is a success message, one is a warning message, one is an error message. And so those different types of messages have different CSS styling applied to them. And as a result, they appear a little bit differently. So questions about any of the Sass tools that we've seen so far, whether it was variables, or nesting elements within each other, or using inheritance to allow a generic style to be applied to multiple different types of classes, or IDs, or elements? OK, if questions do come up, feel free to reach out. And feel free to post in the Slack and ask questions as you begin to dive into project 0. In project 0, you'll have more of an opportunity to experiment with some of this, to use Bootstrap, to make your web page mobile-responsive, and to begin to use Sass in order to create more advanced, more sophisticated stylesheets. Next week we'll dive into a look at Python, and how we actually create web applications by writing in Python, and using some of the HTML and CSS we've looked at in the last two weeks in order to do so. But for now, that's it for Web Programming with Python and JavaScript. Thank you all, and we'll see you next week.