├── .gitattributes ├── README.md ├── 02 - Premium Course ├── 07 - Deployment │ └── 01 - Deployment.md ├── 03 - Hero │ └── 01 - Prep and setup.md └── 05 - Testimonial │ ├── 01 - Prep and markup.md │ ├── 04 - Troubleshooting.md │ └── 03 - Second quotation mark.md ├── 01 - Basic Course ├── 02 - Intro to Sass and Responsive Design │ ├── 15 - Nesting and BEM.md │ ├── 12 - Sass functions.md │ ├── 14 - Why I use em units in media queries.md │ ├── 08 - Using max-width media queries.md │ ├── 03 - Responsive design.md │ ├── 04 - Sass and BEM.md │ ├── 16 - Default browser styles.md │ ├── 09 - Order of media queries.md │ ├── 10 - Responsive typography.md │ └── 18 - Helper and utility classes.md ├── 05 - Top Navigation │ ├── 06 - Adding gap with flexbox.md │ ├── 01 - Design and exporting logo.md │ ├── 08 - Hover states.md │ └── 02 - Creating a skip link.md ├── 04 - Global Styles │ ├── 02 - My VS Code setup for screencasting.md │ ├── 01 - Study the design.md │ ├── 05 - H-tags.md │ └── 07 - Responsive typography and media queries.md ├── 10 - Full-width CTA │ ├── 03 - Sharing styles.md │ ├── 07 - Helper and utility classes.md │ ├── 08 - Button styles.md │ ├── 01 - Prep and HTML markup.md │ ├── 09 - Checking the styles.md │ ├── 04 - Sass extend at-rule.md │ └── 06 - Sass mixins.md ├── 09 - Testimonial │ ├── 04 - Quotation mark styles.md │ ├── 03 - Adding styles.md │ └── 05 - Quote and author styles.md ├── 03 - BASIC Website Setup │ ├── 03 - Adding the favicon.md │ └── 02 - GitHub commits.md ├── 06 - Hero │ ├── 15 - Optional Grid mobile layout.md │ └── 16 - Optional Grid desktop layout.md ├── 01 - Getting Started │ ├── 01 - Welcome.md │ ├── 04 - Setting up project files.md │ └── 05 - What is Sass.md ├── 08 - Full-width Feature │ ├── 01 - HTML markup.md │ └── 03 - Paragraph and image styles.md ├── 11 - Footer │ ├── 04 - Footer column markup.md │ ├── 05 - SVG styles.md │ └── 06 - Sizing and aligning the SVG.md └── 12 - Deployment │ └── 01 - Deployment.md └── 03 - Ultimate Course ├── 01 - TopNav and Hamburger Menu ├── 01 - Prep and markup.md └── 11 - Locking scroll.md ├── 03 - Blog Posts ├── 07 - Gradient variations.md └── 06 - Layout styles.md └── 02 - Testimonial └── 01 - Setup.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rdb-transcripts 2 | 3 | Transcripts for Responsive Design for Beginners course 4 | -------------------------------------------------------------------------------- /02 - Premium Course/07 - Deployment/01 - Deployment.md: -------------------------------------------------------------------------------- 1 | ## Deployment and Congrats! 2 | 3 | Alright, congrats on finishing the Premium course! 4 | 5 | So, if we want to see all the changes that we made in this course, we already set up the Netlify deployment in the last course. And since it's synced to the GitHub repository, every time you push it will trigger a new deployment on your Netlify site. 6 | 7 | So, let's check and make sure the deployment is working, and that the website looks good. 8 | 9 | Let's go to Netlify.com, and log in to your account, and we used "Log in with GitHub" last time, so we'll click that button. And, if you're logged into your GitHub account, it should be able to log you into Netlify. 10 | 11 | Here's the dashboard-- yours probably looks different from mine since I have some other random sites here. But in the "Sites" list you should be able to see the Responsive Design Website, and its randomized name. 12 | 13 | If you click on it, it will load the dashboard for that specific site. And you can click the link to load the actual website. 14 | 15 | Alright, here's the website, and it does seem to have the changes that we made in this course-- the Top Navigation has the gradient underlines, the Hero section has the wave image, we have the new Alternating Features section, the updated Testimonial section with the 2 quotation mark symbols, and the Full-width CTA has the simple form that we added. 16 | 17 | And let's also check the mobile version. In Responsive Design Mode I'll select iPhone, and scroll down the site. And everything looks pretty good! 18 | 19 | So, we've finished and deployed the Premium website. Now what? Well, if you've bought the last course, the Ultimate course, then you can continue on with that one. And if you aren't sure how to get there, I have the link to it down below. 20 | 21 | Now, if you haven't bought the Ultimate course because you've been buying the courses individually, and you need an upgrade, you can buy the Ultimate course by itself by going to the same link below. 22 | 23 | Alright, see you in the Ultimate course! 24 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/15 - Nesting and BEM.md: -------------------------------------------------------------------------------- 1 | # Nesting and BEM 2 | 3 | So far, we've used BEM to create the classes for `grid` which is the block, then `grid__main` and `grid__sidebar` where `main` and `sidebar` are elements of the `grid` block. Now I'm going to add some more elements to the sidebar, specifically we'll add some sidebar widgets, which will be blocks of content within the sidebar itself. 4 | 5 | First I'll start by adding to the markup in the index.html file. I'm going to move the content that we have in the sidebar currently into a new div. Let's create the new div that will have a class of `grid__widget`. Then I'll move the h2 tag and the paragraph tag into it. 6 | 7 | And let's have multiple widgets in the sidebar. If I select the first widget and then hit Ctrl-D it will duplicate it. And I'll make the headline in the second widget say something a little different, like "Check out this cool thing!" And also, in order to make it look different from the first widget let's delete some of the text so the paragraph here will be shorter. 8 | 9 | We have two widgets-- now let's make one more by duplicating the second widget and changing the headline and paragraph text. 10 | 11 | When you're working from a design a lot of times the designer will put in placeholder copy, since the final copy is usually not ready until later on in the development process. So one thing I try to do is stress test what happens when there are different lengths of copy in the different elements. For example if you're building a series of cards, you need to know how it's going to behave if one title takes up 2 or 3 lines instead of just 1, and if the text in one card is a lot longer or shorter. So that's why I'm trying to make these cards look different, because we never know exactly what the final copy will be. 12 | 13 | If we look at the website now, we can see each of the widgets in the sidebar! What I want to do is add some themes to the sidebar widget, and each of those themes will have a different background color. Let's start writing our styles in the `_grid.scss` file. After the `&__sidebar` block selector, I'm going to add a new block selector, `&__widget`. And, I'm going to move the background-color property from the `&__sidebar` selector into the `&__widget` selector. So now when we look at the website we can see each individual widget. 14 | -------------------------------------------------------------------------------- /01 - Basic Course/05 - Top Navigation/06 - Adding gap with flexbox.md: -------------------------------------------------------------------------------- 1 | # Adding gap with flexbox 2 | 3 | The other issue we need to fix is in the links themselves. We need to add space between the items, because right now they're right next to each other. In the past, we had to use either margin or padding to add space, but fortunately with both flexbox and grid we can take advantage of the `gap` property. 4 | 5 | Going back to the Flexbox Guide, if we scroll down more, the `gap` property is set on the flex parent, and it controls the space between flex items. And it will only add space between flex items-- so if an item is first or last, it won't add space on the edges, which is really nice. Let's check out the design to see how much space between items we want. 6 | 7 | In Figma, if I click into the design to select an individual text link, then hold down the Alt key and hover my mouse over a link next to it, Figma tells me that there is 40px of space between items. 8 | 9 | Back in VS Code, if we go to the `topnav__links` selector, we can add the gap property there. And in terms of whether to use pixels or rems for gap, I think either is ok-- I might use pixels for this, because if we change the browser base font size to something significantly larger, we don't necessarily want the space to get really huge too. 10 | 11 | What we can do is try `40px` first, and then change the base font size to see if the links are still reasonably readable if the space between them doesn't change. Let's try that. 12 | 13 | We'll set gap to `40px`, and then open our browser settings and set the base font size to 32 so it's double the size. Then if we go back to the website and manually reload, we can see the text is much larger. The `40px` of space is still `40px`, it hasn't doubled since pixels are an absolute unit which won't get affected if you change the base font size. 14 | 15 | Now, just for comparison's sake, let's also see what it would look like if we used rems instead of pixels. Back in our styles, I'll change the `40px` to `u.rem(40)` to use rems. And if we go back to the website the space between the links is now double to `80px` between them. 16 | 17 | I think in this case either rems or pixels is fine. I might change it back to `40px` just because it was still readable, and it gives more space on the website to the text itself. So let's change that back to `40px` and then in our settings change the base font size back to the default 16. 18 | -------------------------------------------------------------------------------- /01 - Basic Course/04 - Global Styles/02 - My VS Code setup for screencasting.md: -------------------------------------------------------------------------------- 1 | # VS Code settings 2 | 3 | Before we start with the Global Styles, I wanted to show you a couple of things that I'm doing with my VS Code setup for screencasting purposes. 4 | 5 | So as you can see here, we have VS Code on the left, and the website on the right, because I wanted you to be able to see both the code and the website at the same time. However, things are looking pretty cramped. 6 | 7 | So in order to save some space and make it easier for you all to view, I'm going to hide the left sidebar, called the primary sidebar. You can do that by going up at the top and click the first layout looking icon, "Toggle Primary Side Bar". Or you can use the shortcut Ctrl-B on Windows, or Command-B on Macs.. 8 | 9 | And I'm also going to hide the far left Activity Bar, since we don't use it that often. If you right-click in the bar, you can select "Hide Activity Bar". And I actually bound that to a new keyboard shortcut, Ctrl-Alt-B. 10 | 11 | You can create custom shortcuts in VS Code if you go to File, Preferences, Keyboard Shortcuts. Or on Macs, it's at Code, Preferences, Keyboard Shortcuts. 12 | 13 | In the search bar type "Activity", and we want to look for "Toggle Activity Bar". Click the pencil "Edit" icon and type in Ctrl-Alt-B or Command-Alt-B for Macs, or another combination that you'd prefer. I've already bound that shortcut to toggling the Activity Bar. 14 | 15 | So now, if I press Ctrl-Alt-B, I can hide the Activity Bar, and Ctrl-B will let us hide and show the Primary Sidebar. 16 | 17 | And I've also bound another keyboard shortcut. If you search for "Copy line down", by default it's "Shift + Alt + DownArrow" but I'm clicking that Edit pencil and then binding it to "Ctrl + D", or for Macs you could use "Command + D". I use this command a lot, so I wanted it to be something easy to press. 18 | 19 | In addition, in Firefox, I've set the Developer Tools, to be in its own separate window instead of on the left or right side. You can select this if you click on the three dots on the top right. 20 | 21 | So now, all the code, whether it's in the Firefox Dev Tools, or VS Code, will be on the left, and the website will be on the right. 22 | 23 | And, in VS Code, I'm going to be running the "Live Sass" and "Live Server" extensions down in the Terminal panel, but keeping it small so we have more real estate for the code. 24 | 25 | Alright, now let's get into the real stuff. 26 | -------------------------------------------------------------------------------- /01 - Basic Course/10 - Full-width CTA/03 - Sharing styles.md: -------------------------------------------------------------------------------- 1 | # Sharing styles 2 | 3 | I mentioned earlier that this Full-width style has some similarities to the Full-width Feature section earlier in the website. So let's go up and take a look at that to see if there's any shared styles that we could use here. 4 | 5 | The Full-width Feature section is similar in that everything is centered, and the text color is white due to the magenta background. I'm going to inspect the styles to see where we set them. In the `fw-feature` section tag, we set the background-color, the text color, and set `text-align: center` which, if we uncheck that box, is controlling the headline and paragraph text alignment. 6 | 7 | The wrapper div doesn't seem to have anything section-specific, and neither does the h2 tag. The paragraph tag has a `margin-inline: auto` rule to center it within the section tag, because we set a `max-width` of 70 ch or characters. If I uncheck the `margin-inline` rule, you can see the paragraph tag is limited to that 70ch width and is aligned to the left. And we want the `max-width` so that it doesn't go all the way across the section, for better readability. 8 | 9 | We don't have an image tag in the Full-width CTA section, so I don't think we need to worry about that too much. But the other style rules for centering, text color, and the paragraph styles are ones that we would also need for the Full-width CTA section. 10 | 11 | And while we could simply write the same style rules, it would be more efficient if we could figure out a way to share styles. Fortunately, there are multiple ways that we can share styles. 12 | 13 | One option is to use a Sass at-rule called `@extend`, which lets you use the rules from a different selector in your current one. And related to that, we can use a Sass feature called `placeholders` that work with the `@extend` at-rule so that you can use the placeholder styles in multiple places. 14 | 15 | Another approach is to use Sass mixins to generate a set of style rules anywhere that the mixin is included. And lastly, we can create a helper or utility class for these shared styles, and then add the class to both the Full-width Feature and Full-width CTA sections. 16 | 17 | As is often the case, I don't think there's 1 single approach that's the best. A lot of it depends on your own preferences when writing styles, or your company's existing approach. But I do think that it's useful to know all of these approaches, in case you encounter them in the future. And then you can compare and decide which one you like the best. 18 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/12 - Sass functions.md: -------------------------------------------------------------------------------- 1 | # Sass functions 2 | 3 | We've established that it's best to use a relative font size like rem or em units. But, as you saw, I had to pull out the calculator to divide by 16 in order to go from pixels to rems. This gets old really quick, as you might imagine. There is one workaround that you may have heard of, where you set the font-size in your html element to 62.5%. This makes 1rem equal to 10px since 62.5% of 16px is 10px. Then you simply divide your desired pixel size by 10 to get to rems, for example 3rem will equal 30px. 4 | 5 | I don't see any actual issues with this, but I personally prefer to try to keep to that default 16px size. And with Sass, we can create a Sass function to do all our conversions for us. 6 | 7 | In our project files, I'm going to create a new Sass file in the util folder, called `_functions.scss` and I'll forward it in the `_index.scss` file. 8 | 9 | In our functions file, I want to create a function that will divide a pixel amount by 16 in order to get to rems. 10 | 11 | To create a function, we'll write `@function` and give it a name. I'm going to name this `rem`. This function will take one parameter, which I will call `$pixel`. Then in the function we need to do some math to divide `$pixel` by 16. In the old version of Sass we used to be able to use a forward slash to divide with math. But with Sass modules needing that slash for loading the file path, we can't do that anymore. But there is a built-in Sass module that comes with some math functions, so we can use that! If we search for `Sass math` we'll find the documentation on the Sass website that can help us get this working. 12 | 13 | First off, let's go to the Overview of the Built-In Modules to see how to use them. If we look at the code example, it tells us we can use the `@use` at-rule to import the module, the same way that we're importing our Sass modules from our actual files. Up at the top of the functions Sass file, we can write `@use 'sass:math'` to import it with a default namespace of `math.` 14 | 15 | Now let's look at how to divide with sass:math. I'm going to do a quick search for the word `div` for `divide` and there's a section at the bottom about "Other Functions." There is a `math.div` function that takes two parameters and divides the first number by the second number. 16 | 17 | Back in our functions Sass file, in the rem() function let's use the `@return` at-rule to return the result of `math.div` with the parameters of $pixel divided by 16. And we'll need to add the `rem` unit at the end. That should be all we need. Now let's use our rem() function! 18 | -------------------------------------------------------------------------------- /01 - Basic Course/09 - Testimonial/04 - Quotation mark styles.md: -------------------------------------------------------------------------------- 1 | # Quotation Mark Styles 2 | 3 | I'm just going to start from the top with the quotation mark image, and we can work our way down the section. Looking in the design, the quotation mark image is a little bigger on desktop than it is on mobile. On desktop it is 78 pixels wide, and on mobile it is 52 pixels. 4 | 5 | There are a couple of ways we can handle the size. One way would be to set the width to 52px for mobile, add a media query, and then change the width to 78px. 6 | 7 | We could also use the Fluid Typography Calculator and instead of font-size we'd input the width numbers for mobile and desktop, and then copy the output and set the width to that. 8 | 9 | And one other way that I can think of that might be a little simpler is to use a relative unit, percentage, as the width. If we go to the design, we have the 52 pixel width for mobile. And as a refresher, the percentage unit is based on the parent's width. So for mobile, the parent will be wrapper div, which has 24 pixels of space on either side. And for the mobile viewport width of 375px, we can use our calculator and divide 52 by 375 to get around 0.16 or 16%. 10 | 11 | So we can set the width to 16%, and let's see how that looks. 12 | 13 | And let's save, and on the website we can see our new style rule, and let's monitor the width in the "Layout" tab, and see how it changes between desktop and mobile. On mobile it is [XXX], and if we increase the viewport width it grows and on desktop widths it's definitely bigger than the 78px from the design. 14 | 15 | So we can control that if we go back into our styles and set a max-width of `u.rem(78)`. And now if we save and go back to the website, it is 78px on desktop, and as we decrease the viewport width the image shrinks until on mobile widths we're back to [XXX]. 16 | 17 | And we didn't need any media queries which is kinda nice. I do want to mention that I wouldn't do this for font sizing, because percentage won't be affected by the browser base font size. But since this is an icon image and it's fairly big so I think it should be recognizable and I think we can get away with using percentage for it. 18 | 19 | If you do want to make the size get bigger if the browser base font size goes up, you can use the Fluid Typography Calculator to get the width sizes, or use media queries and set the width in rems for mobile and desktop. 20 | 21 | Alright! Next, we need to add space under the quotation mark image. Going back to the design, on desktop we have 40px of space under the image, and on mobile it's 20px. 22 | 23 | Again, you can use media queries to change the width and margin instead of what we did here with `clamp()`. It's really just a matter of your own preference and if you like the fluid change instead of the sudden change when you hit that breakpoint. 24 | 25 | Ok, so that should be it for now for the quotation mark styles. 26 | -------------------------------------------------------------------------------- /01 - Basic Course/03 - BASIC Website Setup/03 - Adding the favicon.md: -------------------------------------------------------------------------------- 1 | # Adding the favicon 2 | 3 | In this video, I'll show you how to set up a favicon for your website. Favicons are those little icons for a website that you see in your browser tab, or if you save a website to your mobile phone home page. In order to get a favicon to load for your website, you need to save the image file in your website root, and also add some code in your index.html head to link to it. 4 | 5 | Favicons can be kinda tricky. The problem is that you can't just have one favicon image and call it a day. All the different browsers and devices available have different preferred image formats and sizes. And trying to keep up with all the different versions you need can be very time-consuming. 6 | 7 | Fortunately, there is a pretty good solution that will provide you with all the different images and the code for your index.html file that you will need. I did some research on favicons, and it seemed like a lot of people recommend using a website called RealFaviconGenerator.net. So that's what I'll be showing you how to use. 8 | 9 | If you go to the site, it will prompt you to upload an image file. This image needs be a square image and be at least 260 pixels wide and tall. I've included the favicon for our website in the Figma design. So if you go into Figma, there is a frame on the far right called "Favicon." And we want to export that favicon image. So select the image, then in the right sidebar go down to the "Exports" panel and click to export it as a PNG and at 1x size. 10 | 11 | Then, on the Real Favicon Generator site click that "Select your Favicon image" button and select that PNG. After a few seconds, it will show you what the favicon will look like on different browsers and devices. You can leave the image as is, or you can slightly customize how the image looks, so feel free to play around with some of these options. Once you're done with any customizations, scroll down to the bottom and click the "Generate your Favicons and HTML code" button. 12 | 13 | It might take several seconds to finish, but when it's complete you can click to download the "Favicon package" to get all the image files, and there's a code snippet that you can copy and paste in your HTML head. 14 | 15 | First let's get the files. The Real Favicon Generator site will have given you a ZIP file. Unzip the file and copy all the image files from the zip and paste it directly into your project folder in the root directory. 16 | 17 | Then let's go back to the Favicon Generator site and copy that code snippet. Then in your VS Code, open up the index.html file and paste the code in the of your HTML. I don't think it matters a ton where in the head you put the favicon code, but I'm going to paste it right after the title tag, before the Google Fonts tags. 18 | 19 | Now, when you load your local website, you should be able to see that favicon load in your browser tab! 20 | 21 | Up next, we'll be starting to write our global styles for the website in our Sass files. 22 | -------------------------------------------------------------------------------- /01 - Basic Course/09 - Testimonial/03 - Adding styles.md: -------------------------------------------------------------------------------- 1 | # Adding Styles 2 | 3 | First up in our styles, let's create our Sass partial for the Testimonial styles. Since we're using `testimonial` as our BEM block name, we'll want to create a Sass file with that file name. In our scss folder, this should go in the `components` subfolder since the Testimonial section will include styles that we only want to use in that section. 4 | 5 | In the scss/components folder I'll create a new file and call it `_testimonial.scss`. And since we're creating a new partial, we need to open the components index.scss file and @forward the `testimonial` partial. 6 | 7 | And let's go back to the testimonial.scss file, and up at the top, we want to load our utilities by writing `@use` and then the path to the util folder, `../util` and we're loading it as the namespace `u`. 8 | 9 | Next up, I want to add selectors in our Sass file that correspond with all the classes that we have in our index.html file. I'm going to right-click the testimonial.scss file, select `Split down`, and then in the top half go to index.html. So now we can see the HTML and the classes in the top half, and our styles in the bottom half. 10 | 11 | The first selector will be our block name class, `testimonial`. And then we'll add curly brackets, and in them we'll add the next element, `testimonial__wrapper` with the ampersand, double underscore and `wrapper`. After that will be `testimonial__icon`, and then `quote`, then `author dash wrapper`, `author dash image`, and `author dash description`. 12 | 13 | And that should be it for the Sass selectors. I'm going to close that bottom testimonial.scss file, and let's see what we should work on first in the website. 14 | 15 | In our website we have all the content there. I do want to inspect the different semantic tags that we added, like `figure`, `blockquote`, and `figcaption`, just to check what default browser styles they have that we might need to cancel out. 16 | 17 | If I inspect and hover over the `figure` tag, it looks like we have some margins added-- margins are highlighted in yellow. Then the `blockquote` tag also has some default margins. And the `figcaption` looks like it doesn't have any default styles added. 18 | 19 | I do want to zero out the margins for the figure and blockquote. I think I'll add those styles in our boilerplate styles as opposed to the testimonial styles. This is because if I need to use any of those tags again in the future, I'd like to only have to zero out the margins once instead of having to do it in each section. 20 | 21 | In VS Code, let's go to `scss/globals/boilerplate.scss`. And I'll put this rule after the image tag. For our selector we'll do a compound one with `figure, blockquote` separated by commas. And then in the curly brackets I'll set `margin` to zero. 22 | 23 | Now, going back to the website, and when I inspect the figure and blockquote tags, they no longer have the default browser margins. So we should be good to start adding our Testimonial styles. I'm going to start with colors, text styles, and spacing. And then once we get all those set we'll work on the layout styles. 24 | -------------------------------------------------------------------------------- /01 - Basic Course/06 - Hero/15 - Optional Grid mobile layout.md: -------------------------------------------------------------------------------- 1 | # Optional: Grid mobile layout 2 | 3 | To start off with our grid layout, let's go into our hero.scss file, and I'm going to go through our styles and comment out the flexbox style rules, so that can start from scratch with our grid styles, but we still have them for future reference. 4 | 5 | In the `hero__wrapper` I'll comment out `display: flex`, `flex-direction`, I'll leave `gap` since it does the same thing in both flexbox and grid; and then comment out `align-items` and keep the `padding-block`. Then in the large breakpoint I'll comment out `flex-direction` and keep `gap` and `padding-block`. Just for organization's sake, I'm going to group the commented styles up at the top together. 6 | 7 | In the `hero__image` selector, I'll comment out the `flex: 5` rule in the breakpoint. And the same in `hero__text`, I'll comment out `flex: 6`. 8 | 9 | Looking at our website, and sliding from desktop to mobile viewport widths, we can see that all the basic styles are there, and the unicorn image is still scaling. We just don't have the 1 to 2 column layout and centering the unicorn image. 10 | 11 | Let's start adding our grid styles for mobile. The grid parent will be the `hero__wrapper` div just like it was the flexbox parent, and then also the grid children will be the `hero__image` and `hero__text` elements, again like they were for flexbox. 12 | 13 | In the `hero__wrapper` selector, we first want to turn on grid by adding `display: grid`. Then we'll have to create our grid template, since unlike flexbox nothing will happen by just adding `display: grid`. For mobile, we want a 1 column layout, so I'm going to add `grid-template-columns: 1fr` to create 1 column that will take the full width of the grid container. 14 | 15 | And now let's save and see how that looks. And now we have our mobile layout, with the gap of 40px between the two rows, since we kept that from our flexbox styles. The hero text looks pretty good, but we still need to center the unicorn in the top row. 16 | 17 | With flexbox, we could center along a row by setting `justify-content: center`. However, grid is a little different. Let's check out the CSS Tricks grid guide-- you can search for `css tricks grid` and it should be the first result. Once you're on the page, do a Ctrl-F to search the page for `justify-content`. 18 | 19 | And you can see in the little diagram that `justify-content` controls the alignment along the inline, or row axis of the entire grid, if there is space available within its container. If you want to control the alignment of grid child items within their individual cells, you'll want to use `justify-items`. Let's do another Ctrl-F and search for `justify-items`, to see a visual depiction of what that looks like. 20 | 21 | `Justify-items: center` is what we're looking for, so let's go back to our styles, and in the grid parent `hero__wrapper` I'll set `justify-items: center`. And when we save and check out the website, the unicorn is now centered! 22 | 23 | And let's do a quick check to compare the website with our mobile design. I'm going to use Responsive Design Mode to emulate the iPhone. And if we flip back and forth between the design and the website, it looks good to me-- the size of the image and text look good, and the spacing between elements seems the same between both. 24 | 25 | Let's now set up the desktop layout. 26 | -------------------------------------------------------------------------------- /01 - Basic Course/01 - Getting Started/01 - Welcome.md: -------------------------------------------------------------------------------- 1 | # Welcome! 2 | 3 | Hey everyone, welcome to Responsive Design for Beginners. Thank you so much for joining, and I 4 | sincerely hope that this course will help you on your web developer journey. 5 | 6 | So to start off, what's in this course, and what's the best way for you to go through it? 7 | 8 | Well, Responsive Design for Beginners is actually made up of three courses, Basic, Premium, and Ultimate. 9 | 10 | You're currently in the Basic course. I'll start by showing you how to get set up with the tools that you'll need, like VS Code and the GitHub Desktop app. 11 | 12 | And then I'll take you through a crash course in Sass and Responsive Design, where we build a demo website using Sass. 13 | 14 | After that, we'll be using those same project files to start building the basic website from a custom Figma design. Now, even though this course is geared for beginners, and I do explain every step, I do recommend learning at least the basics of HTML and CSS before taking this. 15 | 16 | Now, if you're not sure where your skill level is in comparison with a course, you can try to just start going through it. And then if you find yourself being really lost, you may want to pause the course and then learn the basics before trying again. 17 | 18 | I have some free resources linked down below this video, where you can learn HTML and CSS, or just get a refresher. 19 | 20 | All right, so when you're going through the course, I highly recommend not just passively watching the videos, but trying to follow along in your own code editor. 21 | 22 | At some points in the course, I'll give you the opportunity to pause the video and then try things for yourself first. And then when you wanna see my solution, you can resume the video to see how I did it, and you can even pause the course at any point if you wanna try figuring something out yourself first. 23 | 24 | Another tip that'll help you learn is that if I mention a term or a property that you're not familiar with, I would encourage you to write it down so that you can research it later on. And if you have any questions or you get stuck on anything as you're going through this course, you can always post a message in the Discord community. The invite link should be right above this video. 25 | 26 | And lastly, a note on Figma. Unfortunately, halfway through recording the course, Figma changed their UI so that the Inspect tab, which used to be in the right sidebar, was moved into what they're calling Figma Dev Mode. 27 | 28 | Right now, Dev Mode is free and in open beta test, but from what I've heard, Adobe, which acquired Figma, is going to eventually make Dev Mode a paid product. Since I want you to be able to use Figma for free, I'm not gonna be using Dev Mode in this course. 29 | 30 | But only the regular free design mode. So because of this, there are a few instances in the course where I did use the old Inspect tab to copy some CSS style rules. Fortunately, I didn't do it that often, and where I did, I've now added some text notes above the video player telling you how to work around that. 31 | 32 | I also re-recorded some parts of videos to use the new Figma UI. So there are a few places where you may still see the old Inspect tab in the videos, but if you do, please ignore it. And I hope it doesn't cause any confusion. 33 | 34 | All right, that's it for the intro, let's get into the course. 35 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/14 - Why I use em units in media queries.md: -------------------------------------------------------------------------------- 1 | # Why I use em units in media queries 2 | 3 | Now that we have our font-size and other sizing properties updated to use rems, I'm going to show you why I use em units in my media queries instead of pixels. I mention this just because I've seen that pixels in media queries seem to be the most common unit used by websites and even front-end frameworks that otherwise follow accessible practices. 4 | 5 | For this demo, we'll go back into our "util/\_breakpoints.scss" file and I'm going to duplicate each of the Sass maps that we created earlier and comment them out, just to keep the final code that we want. Then I'll set all the breakpoint values to pixels without the function. 6 | 7 | So we'll save that, and then load the website. 8 | 9 | So far things look totally fine. If we inspect the "grid" class element we can see that 700px breakpoint kicks in at the right time and the website content goes from 1 column on mobile to 2 columns for tablet and desktop. 10 | 11 | The problem happens if we change the browser's base font size in our settings. I'm going to double the font size to be 32 instead of 16, and reload the website. Now everything like the text has been scaled up since we're using rem units in our font sizes, which is good! But if we make the viewport narrower, the 2 columns get really narrow, and with the larger text it makes things look cramped. And this is not a great user experience. 12 | 13 | The reason this is happening is because the media queries are set to pixels. If we inspect the grid class element, we see that it's still changing to 2 columns at 700px wide. And since pixels are an absolute unit, they are not affected by changing the base font size. So essentially you have the layout going from 1 to 2 columns at a narrower viewport than we really want, in order to keep the design. 14 | 15 | We doubled the font size from 16 to 32, so ideally we'd want that breakpoint of 700px to also double to 1400px, so that the layout won't change to 2 columns until the viewport is much wider. 16 | 17 | Let's fix this problem by going back into our `_breakpoints.scss` file and deleting the pixel Sass maps and uncommenting the em Sass maps. Once we do that, if we go back to our website to look at the iPad view, the layout is in one column now. And if we slide over the inspector panel, it will go to 2 columns at around 1400px and wider. And the columns have more breathing room now, which makes for a better user experience. 18 | 19 | I hope that helps explain why it's best to use em units in media queries. You can use rem units, as they are also a relative unit. But unfortunately at the time of this recording there's a weird bug in Safari if you zoom in on your browser that makes the breakpoint hit at a different viewport. It doesn't have the cramped content issue that using pixels does, but I would stick with em units for now. 20 | 21 | So now, we have all the building blocks that we need in order to build a responsive website. We have our media query breakpoints set up with Sass maps and mixins, we have our font sizes scaling up nicely using the CSS clamp function, and we're keeping things accessible by using our rem() and em() functions to convert from pixels. 22 | 23 | The last part of this section is going to be building out this demo website a little bit more and delving a bit deeper into BEM. 24 | -------------------------------------------------------------------------------- /01 - Basic Course/04 - Global Styles/01 - Study the design.md: -------------------------------------------------------------------------------- 1 | # Study the design 2 | 3 | In this video we're going to start adding some global styles to the website. By global styles, I mean things that will be reused throughout the website, not just limited to one section of the site. For example, font styles, colors, and layout styles like spacing and containing the content to 1200px wide. 4 | 5 | When I start building a website from a design, what I'll usually do is look at the design and see how things are set up design-wise. So let's go to Figma and do that now, and take a look starting from the top and working our way to the bottom. 6 | 7 | So up at the top we have our navigation bar, with the logo on the left and links on the right. Then under the navigation, we have our hero section. 8 | 9 | The term "hero" is an advertising term that refers to the top section of a website that displays the most important content, either explaining what the company is all about or promoting a current marketing campaign. 10 | 11 | In this website we have a two-column hero on desktop with text and buttons on the left, and an image on the right. And on mobile this two-column layout gets stacked to 1 column with the image first, then the text below it. 12 | 13 | Under the hero is a features section that's 3 columns on desktop and 1 column on mobile. And there are some icon images for each feature block. 14 | 15 | Under that, we have a Full-width Feature section with text and an image. Using these solid color images seems to be a trend nowadays. 16 | 17 | One benefit of this style of illustration is that they are less complex than a photographed image and can be exported as PNGs or SVGs which will have a smaller file size than if you exported them as a JPG. This will help your website to load faster, and it's one reason why I think these illustrations are popular right now. 18 | 19 | Under the Full-width Feature section is a quote or testimonial section, with a quotation mark image, the quote text, and author picture and information. On mobile the content is stacked to 1 column, with the author photo and author information centered. 20 | 21 | Then, we have a Full width CTA or "call to action" section. This is part of a website marketing strategy, where your entire website is promoting the company and trying to get you to purchase something from them. 22 | 23 | Most of the website content is telling you about the product, and at the bottom of the website, they are trying to get you to take some kind of action based on what you've seen. In our case here we are trying to get the user to click the "Free Trial" button and sign up for that. 24 | 25 | The layout is basically the same between desktop and mobile, with both versions having the content in 1 column and everything centered. The trickiest part about this section is the background, which is a linear gradient. It looks slightly different between desktop and mobile, where on mobile the right side doesn't go as light as the right side on desktop. 26 | 27 | Then under the CTA section is the footer, which contains the logo again, and then 4 columns of links on the desktop design. On mobile, the content is split in 2 columns. 28 | 29 | So that's just a first look at the design. I like doing this before I start to code so I can get a quick overview of what I have to do, and also identifying what areas of the website might be more challenging or time-consuming to build. 30 | -------------------------------------------------------------------------------- /01 - Basic Course/05 - Top Navigation/01 - Design and exporting logo.md: -------------------------------------------------------------------------------- 1 | # Design and exporting logo 2 | 3 | In this section we're going to start building out the top navigation of the website! To start off, let's take a look at the design. 4 | 5 | For desktop, the navigation has the Mythos logo on the left, and three navigation links on the right. If I think about how I might need to build that, I could use either flexbox or grid to layout the header. And on mobile, the design is pretty much the same, just with the logo smaller and links closer together. 6 | 7 | Since the logo is an image, we'll need to export that from Figma first. So in Figma, let's double-click to select the logo. Then in the right sidebar down at the bottom, click the "Export" panel. And in the dropdown, make sure it has "SVG" selected as the file type. 8 | 9 | We want an SVG because the image is made up of shapes with a solid color, which is good to export as a vector image like SVG that can scale up infinitely. 10 | 11 | Click the "Export" button and Figma should download the image file into wherever your downloads get stored. 12 | 13 | We could also export it as a PNG with a transparent background, since the image is a flat illustration style which PNGs are good for. Just keep in mind that PNGs are raster images so they can't be scaled up without becoming pixelated. 14 | 15 | JPGs are another type of raster image, but they can't have transparent backgrounds. So I definitely wouldn't use JPGs in this case. 16 | 17 | When working with images, one important thing to think about is file size, and seeing which file type gives you a smaller file size. Let's try also exporting the logo as a PNG, and then compare the file sizes of both SVG and PNG to see which one is smaller. 18 | 19 | In the "Export" panel, I'll change the option to export as a PNG. And for PNGs and also JPGs, you generally want to export them at at least 2x, which will create larger images that won't look pixelated on retina or other high pixel density displays. I'll get into this concept in more detail later in the course, but for now just make sure to set this to 2x. 20 | 21 | Let's go to our file explorer to compare the image files. And it looks like the PNG is half the size of the SVG. And another thing to keep in mind is that with PNGs and JPGs, you can run them through an image compressor tool. I use TinyPNG.com all the time, and it's pretty surprising how much it can compress your files. 22 | 23 | Let's go there and then compress the PNG file just to see how small we can get it. And it looks like the compressed version has been reduced by half, just over 1 kilobyte. Both are really small because the logo image is a small image and is pretty simple, with just the white letters and transparent background. 24 | 25 | The difference between 1 kilobyte and 5 kilobytes is very minor, so in this case I'm still going to use the SVG because if the design ever changes or we need a larger logo somewhere else, we can use this same file. 26 | 27 | If the image files were a lot larger, then it might be better to consider the PNG, since the difference would be bigger. 28 | 29 | I'm going to copy the SVG file, and then go into my project folder. I'm going to make a new folder in the root called "img" to store all our images from Figma. And then I'll paste in the file there. 30 | 31 | Let's go back to Figma to see if we need to export any other images. And it looks like there aren't any others, so we're all set for images in the top nav. 32 | -------------------------------------------------------------------------------- /01 - Basic Course/04 - Global Styles/05 - H-tags.md: -------------------------------------------------------------------------------- 1 | # Add styles for h-tags 2 | 3 | **Note: since recording this video, the Google Font "Source Sans Pro" has been renamed to "Source Sans 3".** 4 | 5 | Let's also take a look at the typography styles. I'm going to inspect the top h1 tag, and click into the "Computed" tab. Then in our browser I'm going to switch the device to iPhone. And as we increase the viewport in our browser the h1 font-size also increases. 6 | 7 | If we go to the "Rules" tab, we can see that the font-size is being set using the CSS clamp() function, which was from our demo website styles. 8 | 9 | However, we need to make sure that the font sizes are matching what we have in the design, since I just kinda used a random font-family and font-size numbers for the demo website. 10 | 11 | Back in Figma, I'm going to select the "Desktop" frame and hide both layout grids so we can just focus on the website content. Let's check the font-family first. If I select the main heading, in the right sidebar it says the font-family is "Source Sans Pro" and the font-weight is "Bold." 12 | 13 | And if I select the subheading it's the same font family, with the font-weight set to "Regular." The top nav font is also "Source Sans Pro" bold. 14 | 15 | When you have a design it's generally a good idea to check the text styles to see what font-families and font-weights are being used throughout the design, since that's what you need to know when getting the font from Google Fonts. 16 | 17 | First we'll need to go to Google Fonts, so I'll open a new tab and search for "Google Fonts" and then go to the site. In Google Fonts, we can search for "Source Sans Pro" and then select it. And in the different styles we need Regular 400, and Bold 700. And we're not using any Italic styles. 18 | 19 | With fonts, you do want to be careful about not using too many different font families and font weights, because each one needs its own separate font file, and whether you're loading them via Google Fonts or with local font files, the more you have the more users will need to download when loading the website. 20 | 21 | I've tried to keep it very minimal with just the one font family and two weights, but if your design has a ton of different weights across multiple font families you might need to check with the designer to see if there's a way to reduce the amount of variations on the website. 22 | 23 | Back to our fonts, to load them we will need to copy the code snippet under "Use on the web" and then go to VS Code in the index.html file. We have some existing Google Fonts code from our demo website, so let's delete those-- it's the 3 link tags that load "googleapis" or "fonts.gstatic.com" things. And then paste in the new code, checking that it's loading "Source Sans Pro", with 400 and 700 font-weights. 24 | 25 | Once we have our HTML code for Google Fonts, we'll want to update our CSS styles with the "Source Sans Pro" font-family. To make sure we have it right, we can go back to the Google Fonts page and in the right it will say "CSS rules to specify families" and I'm going to copy the style rule. 26 | 27 | Then back in VS Code, we need to check where we set the font-family-- it should be in `globals/boilerplate.scss`, and set on the body tag. And it is set to the "u.$font" variable, so to find where we set that, we know it's in the util folder since we have that "u" namespace, and in the util folder is a fonts.scss file. 28 | 29 | So here we can paste in the new font-family, and just make sure to delete the `font-family:` part since we only want the font family name. And it should say `'Source Sans Pro', sans-serif`. 30 | 31 | And that should be it for our font family styles, for now! 32 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/08 - Using max-width media queries.md: -------------------------------------------------------------------------------- 1 | # Using max-width media queries 2 | 3 | So our breakpoint is going to create the min-width media queries that we need. But there are some instances where I do want to use a max-width media query, if there are more mobile style rules than for desktop. 4 | 5 | One example of this in our demo website could be if we wanted to have the sidebar text centered on mobile only, and not on desktop or tablet. We'd want a style rule saying `text-align: center;` for mobile, and we wouldn't want any text-align rule for tablet or desktop since they would use the default left-align. 6 | 7 | If we used a min-width media query for this, we'd have to set `text-align: center` for our default styles, then add a media query to cancel it out with a `text-align: left` for tablet and desktop widths. So you'd be saving having to write that extra `text-align` rule with a max-width media query. This might seen very minor since it's only one line of code, but there could be cases where you'd have multiple style rules that you only want on mobile. So in those cases a max-width media query would save you time.k 8 | 9 | Let's create a new mixin for that. Going back to VS Code in our `_breakpoints.scss` file, we need to create a new Sass map for the breakpoints. We need a slightly different set of widths so that there won't be any overlap in breakpoints which can cause weird behavior on websites. 10 | 11 | Our breakpoints-up map used 700px, 900px, and 1440px. We'll make a new one called `$breakpoints-down` and in that we want to use the names `small` for 699.98px, `medium` for 899.98px, and `large` for 1439.98px. There's a 0.02 pixel difference between the values in `$breakpoints-up` and `$breakpoints-down` to avoid that overlap. And I got that 0.02px number from researching Bootstrap-- they use that difference as well. 12 | 13 | Then we'll create a new mixin called `breakpoint-down` that will also have that `$size` parameter, and it will write a media query using `max-width`, and use `map-get` with the parameters `$breakpoints-down` and `$size`. And in the media query it will load `@content` to add in whatever style rules the mixin contains. 14 | 15 | Now we can use our mixin in our styles for the sidebar, to make the text center aligned. In the `_grid.scss` file in the `.grid__sidebar` selector, I'll load the mixin with `@include` and the name of the mixin we just made, `u.breakpoint-down` with that `u` namespace for util. And we will set the parameter to `small` so that it will take effect for devices that are 699.98px and smaller. 16 | 17 | Let's see if that works in the website. In our browser, if we slide the inspector panel over to make it a mobile width, we can see that the sidebar text is indeed center aligned. And if we test using the device emulator, it is center aligned for iPhone, and if we select iPad it will be back to the 2-column and left aligned style. And one thing to note is that in the inspector, the breakpoint width has been rounded a bit by the browser. We originally wrote `56.24875em` but Firefox has rounded it up to 56.2488em. 18 | 19 | And, just to illustrate why we have that 0.02px difference in our `$breakpoints-down` map, let me change the `medium` value to `56.25em` to match the `$breakpoints-up` map. When we save and go back to the browser, if we slowly slide over the panel, you can see that there is a tiny viewport width where the layout is in 2-columns but the sidebar text is center aligned. 20 | 21 | This is an edge case since it only exists at basically one pixel specific width, but you never know how large a user might be loading your website, so ideally you want it to look consistent at every single viewport width. Also, I used to do a 1px difference, but noticed that it caused the media query to trigger 1px too `late` when you're narrowing the viewport, which is a similar issue. It's not the biggest deal in the world, but having that 0.02px difference seems to be the best solution. 22 | -------------------------------------------------------------------------------- /02 - Premium Course/03 - Hero/01 - Prep and setup.md: -------------------------------------------------------------------------------- 1 | ## Prep & setup 2 | 3 | [ have 2 File Explorer windows open, one for Downloads and one for the project ] 4 | 5 | Alright, in this video, we're going to be modifying the Hero section to make it a little more fancy. Let's first take a look at our existing, Basic website, and then compare it with the Premium design to see what we'll be changing. 6 | 7 | On our website, on desktop, we have the text content first on the left, and the unicorn image on the right. 8 | 9 | [ highlight "hero__wrapper" ] 10 | 11 | And it looks like they are vertically centered. Right now the unicorn is taller than the text, and the text is centered vertically so there's equal space above and below it. 12 | 13 | Then if we turn on Responsive Design Mode and load the iPhone view, the image is first, and it's centered. Then below it is the text. 14 | 15 | So that's our current website, let's now check out the design in Figma. 16 | 17 | In Figma, the biggest change I can see is that we have this curved wave shape at the bottom of the hero instead of just the flat bottom that we had before. 18 | 19 | On desktop, the unicorn image looks like it's slightly overlapping that curve. Also the alignment of the text and image is a bit different. Instead of being vertically centered, it looks like the text is aligned to the top, and the unicorn is a bit below the top of the text. 20 | 21 | Then, if we look at the wave shape, it is 80px below the text. And it looks like it's aligned with the bottom of the unicorn. This is a pretty common design pattern I've seen, where you have a curved shape for the bottom of a section, with some image slightly overlapping it. Which is why I wanted to put this in the course. 22 | 23 | Let's check out the mobile design. It looks very similar to the previous version in terms of alignment. The only new addition is the wave shape at the bottom. 24 | 25 | Since that wave image is new, we will need to export it and add it to our project files. Since it's a shape like the unicorn, we'll want to export it as an SVG, so that we can scale it without making it look pixelated. 26 | 27 | And, I am using the same SVG image for both desktop and mobile versions. The mobile version looks a bit more bumpy, I guess you could say, because we're squashing the image to fit the smaller viewport. And I think that's totally okay because it is just a shape so it doesn't matter if it looks slightly different as the viewport changes. 28 | 29 | I'm going to export the desktop version. If I hold down Control or Command for Macs, then I can click right into the hero-wave layer without having to double-click through the groups. 30 | 31 | With hero-wave selected, I'm going to go to the right sidebar and down in the "Export" panel, make sure "SVG" is selected and click "Export hero-wave". 32 | 33 | And it's downloaded, so let's go to our File Explorer, and I'm going to copy the image from the Downloads folder, then go to the other window where I have the project files, and I'm going to paste it in the "img" folder. 34 | 35 | Let's now go to VS Code and open our Hero styles. I'm going to press Ctrl+P for the Quick Open menu, type in "hero" and select "hero.scss" to open it. 36 | 37 | Since we're redoing the hero section, I'm going to clear out most of the styles from the scss/components/hero.scss file. In the file, I'm going to delete the layout style rules from the selectors, but keep the selectors. 38 | 39 | So in the main hero class selector, I'll keep the background-color and color rules, since those probably won't be changing. But I'm going to remove everything from "hero**wrapper". Then for "hero**image" I'll delete the styles except for the width: 61%, max-width: u.rem(483), and the width: 100% in the large breakpoint. 40 | 41 | Then in "hero**text" we'll remove everything. And we'll keep the styles in the "hero**button" since that's just adding space between the buttons. 42 | 43 | And when we save and look at the website on desktop, all our layout styles are gone and we have the unicorn image and the text below it. 44 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/03 - Responsive design.md: -------------------------------------------------------------------------------- 1 | # Responsive Design 2 | 3 | To illustrate the other Sass concepts and also get into how responsive design works, we're going to build a demo website. It will be a 2-column layout with a main section and a sidebar. 4 | 5 | Let's go into our index.html and make some changes to the code there. 6 | 7 | I'm going to wrap the h1 tag and paragraph tag that we have in a "main" tag. This will be the main content. Then I'll add a new element using the "aside" tag. 8 | 9 | In the aside element, I'll add an h2 tag and say "More Info" and then add another paragraph with some lorem ipsum text by typing in "p>lorem30" to add 30 words. 10 | 11 | The main and aside tags are what's called semantic HTML tags, where the tags themselves have a meaning separate from any CSS rules that you might apply to it. The h1 tag is another example of a semantic HTML element-- the "H" stands for "headline." And the "p" or paragraph tag is yet another one. 12 | 13 | The "main" tag means this is the main content on the website. And the "aside" tag means that the content in it is secondary. It's generally a good idea to use semantic tags when you can instead of putting everything in a div or span element. Using semantic HTML is good for SEO because it lets search engines more easily parse the information on your website. And it's good for accessibility because screen readers can likewise navigate a webpage more easily if semantic HTML tags are used. 14 | 15 | Now, with this website layout, I'd like it to be two columns for desktop, with the main element on the left and sidebar on the right, and then have them stack to one-column for mobile, with the sidebar below the main content. At a foundational level, this is what responsive design means-- making the website design look different if it's loaded on different devices. 16 | 17 | There are a few components that work together in order for responsive design to work in the browser. The first one is that you need a specific tag in your HTML head. If we go to VS Code and look in the head, it's the tag with the name "viewport." The viewport is the part of the website that you can see in your device. Most websites are longer or taller than your viewport, but you can scroll down the page to read what's further down. So the website content is usually taller than your viewport, but is the same width as your viewport, unless you have to scroll horizontally to see content that's off-screen initially. 18 | 19 | The viewport meta tag is doing two things. First, it's setting the width of the website to the device width that is currently viewing it. So if you're loading the website with a phone that is 375px wide, the website will be 375 pixels wide. If you're loading it from a monitor that's 1920px wide, the website will be 1920 pixels wide also. Then the initial-scale set to 1.0 means that it will set the initial zoom at 100%. 20 | 21 | We can view how a website will look on various devices with an emulator that's built into all browsers. I'm using Firefox. We can change the device by going into the Inspector and clicking on the icon that looks like a phone and tablet. Then we can select the specific device that we want to view the website as. I'll select an iPhone. And we can see that the website viewport is now the size of the iPhone. If we switch to an iPad view, the website will also adjust to that width. 22 | 23 | Let's see what happens if we don't have that meta viewport tag. If I comment it out and then save, and go back to our browser, the text on the website is actually a bit smaller than it was before. If we change to the iPhone view again, this effect is even more obvious. 24 | 25 | What's happening is that the width of the website is not getting set to the device width, so it wants to get a lot wider than 375px. Then in order to fit the whole width on the phone, it's making everything very small. This is not what we want for a user experience on a website, of course. And if you've ever loaded a website on your phone and it looked super zoomed out like this, it's probably because the website hasn't been optimized for responsive design and is missing that meta viewport tag. 26 | -------------------------------------------------------------------------------- /01 - Basic Course/10 - Full-width CTA/07 - Helper and utility classes.md: -------------------------------------------------------------------------------- 1 | # Helper/utility classes 2 | 3 | To set up the helper classes with the shared styles, I think it would make the most sense to put them in the globals folder, since the util folder is for Sass mixins, functions, and other features that then can be loaded in other Sass partials with the `@use` at-rule. 4 | 5 | In VS Code, I'm going to go into the scss/globals folder, and create a new file. And I am going to call this `fullwidth`. Because even though it's a duplicate file name of our mixins Sass file, in real life you would be using one or the other. I'm just going to keep the fullwidth mixin file around for future reference. 6 | 7 | And since we have a new Sass partial, I need to go into the globals index.scss file and `@forward` the `fullwidth` partial. And now, let's go to the fullwidth mixin file, and I'm going to copy the whole thing and paste it in the globals/fullwidth.scss file. And of course, we need to make this a helper class, not a mixin, so I'm going to remove the `@mixin` at-rule and make the `fullwidth` name a class. 8 | 9 | So now, we have a `fullwidth` BEM block, and then a `fullwidth__description`. And to apply these styles, we need to add these classes to the proper elements in our index.html file. 10 | 11 | In the index.html file, I'm going to go up to the Full-width Feature section, and in the section tag I'll add the helper class `fullwidth`. Then for the paragraph tag I'll add the class `fullwidth__description` and in the image tag, I'll add the class `fullwidth__image`. 12 | 13 | And let's do the same in the Full-width CTA section. In the `fw-cta` section tag, I'll add the `fullwidth` class, and in the `fw-cta__description` paragraph I'll add the class `fullwidth__description`. 14 | 15 | And, we need to go into the styles for each section and remove the mixin so it's not doing anything. In the fw-cta.scss file, I'm going to comment out the `@include u.fullwidth` rule, and then do the same in the fw-feature.scss file. I'm commenting them out just for test purposes in this course, for reference and so that it's easier to add the mixin back in. 16 | 17 | Now let's make sure everything is saved, and see if the fullwidth styles are getting loaded on the website. Going first to the Full-width Feature section, I'm going to inspect it, and if I select the `fw-feature` section tag, we can see that it does have that `fullwidth` class, and in the styles below, we can see the `fullwidth` class and the 2 rules. 18 | 19 | Then, if we click into the `fw-feature__description` paragraph, we can see that it does have the helper class `fullwidth__description`, and in the Rules it has the styles centering it with `margin-inline: auto` and setting the max-width to 70ch. Looks good! 20 | 21 | And let's go down to the Full-width CTA section, and do the same thing. It does have the `fullwidth` class and styles in the Rules, and the paragraph also has the helper class and the style rules. So it looks like everything is working! 22 | 23 | Whether you use the mixin or the helper class approach, they are accomplishing the same thing, but in 2 different ways. With the mixin, you need to load the mixin in your styles anywhere you want to use it. So we had to include it in both the fw-cta.scss file and the fw-feature.scss file. But we didn't have to adjust anything on the HTML side-- everything is controlled from the Sass files. 24 | 25 | With helper classes, you don't have to add an extra style rule to the selectors where you want to use the shared styles. But you do have to add the helper class to the HTML. So it really boils down to where you want to add a little extra complexity in your files-- either Sass or HTML. 26 | 27 | The strict BEM approach would not use helper classes, but everything would be handled on the Sass end, and the HTML elements would only have the BEM class name. On the other end of things, if you use all helper classes, like what Tailwind does, your HTML elements would have a lot of class names. 28 | 29 | I think both approaches are fine-- I've been using a combination of BEM styles for most things, but also helper classes for components like the button that would likely get reused if new pages and sections get created. 30 | -------------------------------------------------------------------------------- /01 - Basic Course/03 - BASIC Website Setup/02 - GitHub commits.md: -------------------------------------------------------------------------------- 1 | # GitHub commits 2 | 3 | Before we start building our website, let's take a look at GitHub Desktop, to make sure that we are ready to start committing our code. So go ahead and open up GitHub Desktop and open the repository that you created earlier for the course project. Mine is called "responsive design beginners." 4 | 5 | There are probably going to be a lot of changes in the "Changes" tab. Most of them are going to be the new Sass files and other code changes that we made. 6 | 7 | If you scroll down, you might see some changes to the style.css and CSS map file in the "dist" folder. 8 | 9 | Now, let's go back to GitHub Desktop and talk about making commits. When you're using Git to track your code changes, you need to figure out how often you want to make a commit to save your progress. You don't want to wait until the very end when you've completely finished coding the entire website, and make one giant commit. 10 | 11 | This is because, as we mentioned earlier in this course, using Git is like keeping save points in your code history. The more save points you have the easier it will be to revert back to a previous version. If you only have 1 giant save point, then you can only go back to the very very beginning, which won't help you very much. 12 | 13 | So, you want to make commits regularly while you're coding, but you also don't need to make a commit every time you change a line of code, because that can just be too much. 14 | 15 | I usually try to make commits whenever I have finished what feels like a complete little step in development. Or if I write some code that I'm not completely confident about, which I might need to revert in the future. In this course, I'll be showing you when I make commits as I build this website, so you can see how often I commit. And then you can decide for yourself how often you want to commit your code. 16 | 17 | Let's make a commit to save all the changes we've created so far. In GitHub Desktop, check over the changed files one final time to make sure that there's nothing getting committed that we don't want. And then I think everything looks fine. 18 | 19 | Alright, once you've checked your files and you're good to go, in the bottom left corner, type in a commit message-- you can choose whatever you want. I'm going to say "Project setup and intro" since all the files we've created so far have been in the project setup and intro to Sass and responsive design sections. 20 | 21 | Then click the "commit to main" button and your commit should be created! Now if you click in the "History" tab, you can see the commits that you have made so far. You might see one commit that says "Initial commit," and if you do, it's probably from GitHub Desktop generating the start files when you created the repository-- it will automatically make this commit for you. 22 | 23 | And then we have the commit that we just created. I'm also going to publish the repository on GitHub since we haven't done that yet. Up until now, the repository has only existed on our local computer. Once we publish, it will also exist up as a remote repository on GitHub. And this will make it accessible by other developers and when we deploy the website to a production server. 24 | 25 | Once the repository is published, when you're making future commits, the button will let you "push" your changes to "origin", meaning the remote repository on GitHub. 26 | 27 | You don't always have to push every time you make a commit. For me, I'll push my changes up to the remote repository either at the end of the day at work, or if another developer needs to check out code changes that I've made. 28 | 29 | I'm just gonna uncheck it, so it'll be public, and then I'm going to click Publish Repository. 30 | 31 | Once the repository is published, we can check that everything is there by loading GitHub.com and clicking on repository, and then 32 | loading the repository. 33 | 34 | So you can see here we have all the files and folders. Everything looks pretty good. And it tells us that this commit was made just two minutes ago. So this is the commit that we just pushed up here. 35 | 36 | If everything seems like it's working, then you should be good to go! In the next section we'll be going into our code and adding a favicon to our website. 37 | -------------------------------------------------------------------------------- /01 - Basic Course/10 - Full-width CTA/08 - Button styles.md: -------------------------------------------------------------------------------- 1 | # Button styles 2 | 3 | The last thing we need to do for the Full-width CTA section is style the button. 4 | 5 | On the website, let's inspect it in Firefox. We initially copied the `Free Trial` button markup from the hero section, so it's currently getting all its styles from the `button` class and the `button primary` class. 6 | 7 | But if we go to the design, The `Free Trial` button in the Full-width CTA section is solid white, with the default dark gray text color. Since this is a new button style, we'll have to figure out how we want to set that up. 8 | 9 | Let's go to VS Code and take a look at our button styles. They are stored in the scss/globals/button.scss file. As a quick refresher, the `button` class contains the styles that we want all buttons to have-- mainly size and font-size. 10 | 11 | Then the additional button classes, `primary` and `secondary`, set the background and text color of the buttons, as well as their hover state colors. The primary button on the hero is the solid teal, and the secondary hero button has a transparent background and a white border. 12 | 13 | The Full-width CTA button is similar to the primary button styles-- both have a solid background color and no border, and have the dark gray button text. So what I might do is create another helper class inside the `primary` class and set the white background color on there. 14 | 15 | In the `primary` class under the hover state selector, I'll add a new class, `ampersand dot white`. The ampersand is so the final selector for this button will target an element with both the `primary` and `white` class names, as well as the `button` class. 16 | 17 | Without the ampersand, the selector will be `primary space white` which would target an element with the class `white` that is a child of another element with class `primary`. That wouldn't work since we're putting both class names in the button. 18 | 19 | In the `white` class, we need to set the background-color. For the other button styles, we set the colors as custom properties in the globals/colors.scss file, so we should do the same thing for this one. Let's open that colors.scss file, and create some new custom properties under the `--button-primary` custom props. 20 | 21 | We don't need to worry about the text color, since it can use the `button-primary-text` color, but we will need to set the background and the background hover colors. So I'm going to select the `button-primary-bg` and `button-primary-bg-hover` custom properties and press Ctrl-D to duplicate them. 22 | 23 | Then in the duplicated properties, I'll add `white` to their names so we have `button-primary-white-bg` and `button-primary-white-bg-hover`. 24 | 25 | Then we'll need to set the HSL colors. We can copy the `main-bg` HSL color, which is white, then I'm going to paste it for both the white button color properties. 26 | 27 | The default background color is white, but we also want the hover background color to be different. Let's go back to the colors.scss file and see what we did for the teal primary button. So the default teal background color is in `button-primary-bg` and the hover background color is `button-primary-bg-hover` and it is slightly darker. We can tell because the last number, which is the L in HSL, controls lightness. The default teal has 42% lightness, and the hover color has 37% lightness, so it's 5% darker. 28 | 29 | Let's do this for the `button-primary-white-bg-hover`. I'm going to reduce it by 5% and see how that looks. (see if it looks good, otherwise make darker with 90%) 30 | 31 | Now let's go back to the button.scss file, and in the `white` class, I'm going to copy the background-color rule from the `primary` styles, and paste it in there. And I'll also copy the entire hover state selector, and paste it in as well. Then I'll add `white` to the custom property names to use the new custom props we just created. 32 | 33 | Now, we've set up the white button styles, so we need to add the `white` helper class name to the button in our HTML. So for the `fw-cta__button` I'll add it to the end of the class names. And let's save, and check out the website. 34 | 35 | And now we have a white button! And when we hover over it, the background darkens slightly due to the reduced opacity so that it's semi-transparent. So that looks pretty good. 36 | -------------------------------------------------------------------------------- /02 - Premium Course/05 - Testimonial/01 - Prep and markup.md: -------------------------------------------------------------------------------- 1 | ## Markup and positioning 2 | 3 | Alright, so in this section we're going to be making some tweaks to the existing Testimonial section. If we look at the website, on desktop, what we have is the quotation mark image, then the quote text, and then the author photo and description. And on mobile, it's pretty much the same, except the author info is now centered. 4 | 5 | Going to Figma now, on mobile the design looks the same, so there are no changes for that. Then on desktop, the quote text and author info looks the same, but there are now two quotation marks. The original one at the beginning, and then a new one at the end. 6 | 7 | If I select just the quote text and hold down Alt, the opening quotation mark, instead of being right above the quote text, is now positioned to the left by 40px, and slightly above it, by 30px. 8 | 9 | And the closing quotation mark is positioned 40px to the right and 30px below the quote text block. And the author info is 40px below the quote text-- which, if we go to the website and inspect the quote text and go to the Layout tab, it has a bottom margin of 40px. So nothing about the quote text or author info is changing. We're going to just be working with the quotation marks and positioning them. 10 | 11 | When I look at this design, what's the best way to position the quotation marks? We could try using CSS grid like we did in the Hero section to position that hero wave image at the bottom of the section. 12 | 13 | However if we did, we'd have to create the grid on the parent element, figure out the grid column sizes, and place each individual child-- the quotation marks, quote text, and author info-- in the correct cell. Which is possible, but I think it may be more complicated than it needs to be. 14 | 15 | I think that using position absolute on the quotation marks would be a simpler way of achieving the layout, because we can just write styles to affect the quotation marks, and we won't have to do too much different to the quote text and author info. 16 | 17 | The first thing we need to do is create the second quotation mark in our markup. So in VS Code, let's go to the index.html file, and in the Testimonial section take a look at the markup we have so far. 18 | 19 | Right now, we have a figure tag, and it is containing the first quotation mark image, then the blockquote with the quote text, and then the author info. I'm going to select the quotation mark image tag, copy it, and since the first image is right before the blockquote tag, I'll paste the second one right after the blockquote tag. 20 | 21 | So now on our website, we have the two quotation mark images. If I inspect one of them, let's check out the styles that they have. They both have a class of "testimonial\_\_icon", and then in the styles we're setting the width, with a max-width, and then a margin-block-end adding space between the image and the quote text. 22 | 23 | I think we will keep all these styles for now, and we can tweak later on if need be. Let's start positioning the quotation mark images. In VS Code, let's open the testimonial styles. In the Quick Open menu, I'll type in "testimonial" and select the Sass file. 24 | 25 | Again, the styles for the images are in the "testimonial\_\_icon" selector. Let's add a desktop media query so we don't affect any mobile styles. I'm going to add "@include u.breakpoint(large)" and in it, write "position: absolute". 26 | 27 | Now when I save, you can see the quote text and the rest of the content on the page moved up. This is because making the quotation mark images position absolute took them out of the normal flow of the document, meaning that they are no longer taking up space on the page, and the rest of the normal content moves up to fill the space. 28 | 29 | However, if I inspect one of them, and in the browser I toggle the "position: absolute" rule, you can kinda see that the first quotation mark isn't actually moving-- it stays in the same position that it would have been in originally, but it's just not taking up any space. 30 | 31 | The same thing is happening with the second quotation mark-- it is moving up only because of the first quotation mark getting taken out of the flow, but it's not moving up into the quote text, and the author info is now overlapping it as if it wasn't there. 32 | 33 | This is what happens just by adding "position: absolute" to both images. This is our starting point, and we're going to further position each quotation mark, using some of the CSS positioning properties of "top", "right", "bottom", and "left", starting with the first quotation mark. 34 | -------------------------------------------------------------------------------- /03 - Ultimate Course/01 - TopNav and Hamburger Menu/01 - Prep and markup.md: -------------------------------------------------------------------------------- 1 | ## Prep and markup 2 | 3 | In this section we're going to be adding to our Top Navigation-- we'll be building a hamburger menu for mobile devices with some JavaScript, and we'll also make the top nav sticky so that it's still visible after scrolling down. 4 | 5 | Let's first check the out the design, so we can figure out what we need to do. In Figma, I'm going to zoom in on the mobile part. And we can see that instead of having the 3 text links we have a hamburger icon on the right side. 6 | 7 | Then the frame next to it shows the open hamburger menu with the navigation links. We'll probably animate it coming down from the top, like a drawer opening. And we have a close button in the top right. And the rest of the website is covered in a transparent overlay. 8 | 9 | We do need to export the hamburger and close button images from Figma. So I'm going to select the hamburger button, then on the right sidebar scroll down to the "Export" panel, and let's export it as an SVG. Then I'll select the close button, and do the same thing to export it as an SVG. 10 | 11 | And let's get those files, so I'll go into the File Explorer, and in the Downloads folder I'll select both files and copy them, then go to the project folder which I have here, and we want to paste them in the "img" folder. 12 | 13 | Alright, we have our images, and now let's get our markup set. We'll be adding the hamburger and close buttons, and we'll also have to rework some of the markup for accessibility purposes, which we'll get into later. 14 | 15 | In VS Code, I'm going to go to the index.html file, and look at our current markup for the Top Navigation. That's going to be up at the beginning, and everything is in the header tag. 16 | 17 | We have our hidden header H2 tag, then our wrapper div, and in it we have our homepage logo link, and a nav tag, which contains the list of navigation text links. 18 | 19 | And one thing to note is that we have a new text link that says "Home", which will let you navigate to the homepage if you're on a different hypothetical page. 20 | 21 | Everything we're going to build will be in the nav tag, so that includes the hamburger button to open the menu, the close button, and then of course we have our links. 22 | 23 | Now, if we look back at the design, initially the links and close button are not visible. And when the menu is opened, they are visible, and the rest of the regular website content is not accessible. 24 | 25 | So, going back to VS Code, I'm going to create a new div in the nav tag to contain all the content that's in the menu itself-- just so we can target that div to either be hidden or shown, depending on if the menu is opened or closed. 26 | 27 | In the nav tag, I'll create a div, with a class of "topnav\_\_menu". Then I'll move the unordered list into the div. And let's create that first "Home" link. I'll select the "Features" li-tag, duplicate it and change the first text to say "Home". 28 | 29 | We also need to add our open and close buttons. The open button will not be in the "topnav\_\_menu" but outside it, so that it's visible initially. 30 | 31 | So before the "topnav\_\_menu" div I'll create a button element with a class of "topnav\_\_open", and in the button we want to load the hamburger image, so I'll create an image tag, and set the source to "/img/hamburger.svg". 32 | 33 | I'm leaving the alt attribute blank, because we're going to make the button itself accessible to screen readers, so we don't need to do the same for the image. 34 | 35 | But we do want to add the width and height attributes, so I'm going to open the SVG file with the Quick Open menu, Ctrl+P, and type in "hamburger" and select "hamburger.svg". And let's copy the width and height, and paste it inside. 36 | 37 | And let's create our close button. I'm going to save a little time and select the open button, press "Copy", and then in the "topnav\_\_menu" div, paste it before the links, since it's going to be at the top of the menu. 38 | 39 | Then let's rename the class to "topnav\_\_close", and delete the "hamburger.svg" file name, and start typing "close" and select "close-button.svg". 40 | 41 | Let's get the width and height too, so I'll use the Quick Open menu, type in "close" and open the "close-button.svg" file. And I'll copy the width and height, and then back in our markup paste it in. 42 | 43 | Okay, that's pretty good for the markup for now. Let's save and see how the website looks. And we can see our two buttons-- they have that browser default gray color. But everything is showing up, which is good. 44 | 45 | Next, let's start writing the styles for the hamburger menu. 46 | -------------------------------------------------------------------------------- /03 - Ultimate Course/03 - Blog Posts/07 - Gradient variations.md: -------------------------------------------------------------------------------- 1 | ## Gradient variations 2 | 3 | Let's take a look at the website and see how we can change up the gradients a bit, so we don't have this "striping" effect going down the cards. 4 | 5 | If I inspect the "blog\_\_filter" element, let's see how we can change the gradient. Right now they are all going in the same direction, from left to right. So maybe we can try changing the direction. 6 | 7 | The "to right" value means it's angled at 90 degrees. Zero degrees means it will start from the bottom and go up, like a clock hand pointing at twelve o'clock. 8 | 9 | Just in the browser for now, let's change the direction to "0deg". And now the gradient is more horizontal, and still stripe-y. Let's try 45deg... and now it's a bit more angled. Not too bad, but I think it might be really cool to have different angles of the gradient direction for the different cards. 10 | 11 | Like 0 degrees for the first card, 45 degrees for the second, 90 for the third, and so on. Incrementing by 45 more degrees each time. 12 | 13 | I'm going to try figuring this out in our styles, and then see if we can make it a bit programmatic using some pretty cool Sass features. 14 | 15 | In VS Code, let's first hide the image and the text block, so we can focus just on the gradient direction. So in our styles, I'm going to go to the "blog\_\_image" selector and add "opacity: 0", then copy that line and then in the "blog\_\_text" selector paste it in there too. 16 | 17 | Okay, now we just have the gradient. Next, let's start by targeting the first "blog\_\_item" child, and then in that, set the linear-gradient with the 45 degree direction on the "blog\_\_filter". 18 | 19 | In our styles for the "blog\_\_item" selector, I'm going to nest a new selector, to target the first child. So I'll add an ampersand, and then instead of writing "first-child", I'm going to write "nth-child" and then in parentheses, "1". This is so we can target the other children by increasing the number. 20 | 21 | Now, I want to target the "blog\_\_filter" class in this first child. So we'll add on ".blog\_\_filter" to our selector. And in here, we're going to reuse the "background-image" with linear-gradient() from the initial "blog\_\_filter" styles. 22 | 23 | Let's select the whole style rule, copy it, and then paste it in our first child styles. And we'll replace the "to right" with "45deg". Now let's save and see if this works. 24 | 25 | Alright! It looks like our new styles for the first child "blog\_\_filter" are working! The first gradient is now at an angle, and if we inspect it, we can see our new style rule. 26 | 27 | And it is overriding the original rule because the original one. 28 | 29 | Okay, so we have our new style rule for the first child, how about the other ones? Going back to our styles, I'm going to select the whole rule and duplicate it. 30 | 31 | Then I'll change the nth-child number in the second one to "2". And I want to change the degree to be another 45 degrees greater, which is 90. However, we can use math to calculate this for us. 32 | 33 | I'm going to use the CSS calc() function, and in it write "45deg" and then asterisk to multiply, and then "2". I really like the calc() function because you can combine different units and it just works. And let's also use this for the first child. 34 | 35 | I'll copy the calc() function and then paste it to replace the "45deg" in the first child. And instead of 2 we'll set the multiplier to 1. 36 | 37 | Now let's save and just make sure it works, and on our website it looks like the calc() function is working for the first one, and if we inspect the second one, the "blog\_\_filter" is using the nth-child(2) style rule, which is great. 38 | 39 | Now, let's write styles for the other children. I'm going to select the second style rule and duplicate it for the 3rd, 4th, and 5th children. And I'm going to go to each of them and update the number to be 3 in both places, and then 4... and then 5. 40 | 41 | And when we save, now on the website, we have our rotating gradient! Pretty cool, right? 42 | 43 | But if we look at our styles, there is a ton of duplicated code. The only difference is the number of the nth-child and the multiplier that are increasing each time. 44 | 45 | I just wanted to demonstrate to you how doing this the long way would look. Now let's make this a lot more efficient by putting all this code into a for loop in Sass. 46 | 47 | A for loop is something you can do in programming where you are running the same piece of code a certain number of times, with some changes each time based on the order of the item. 48 | 49 | I know that this may sound confusing if you haven't done programming before, but I'll show you how everything will work, in the next video. 50 | -------------------------------------------------------------------------------- /02 - Premium Course/05 - Testimonial/04 - Troubleshooting.md: -------------------------------------------------------------------------------- 1 | ## Troubleshooting 2 | 3 | Let's check things over and compare to the design. If I go to Figma to eyeball everything, it matches. 4 | 5 | Let's now test the website with decreasing the viewport width from desktop down to mobile, to see if there are any points where this new set of styles looks weird. 6 | 7 | I'm going to use Responsive Design mode, and drag the right edge over to decrease the width. And it looks ok until we hit about over 1000px. And now the quotation marks are going off screen, and we have horizontal overflow. And it's like that until we hit our large breakpoint at 900px and switch to the mobile design without position absolute. 8 | 9 | We also probably want to hide that second quotation mark except for desktop widths. Let's do that since it's one quick thing we can fix. In our styles, I think I'm going to use our breakpoint-down() mixin so we can target widths at and below tablet. 10 | 11 | This is just for the last-child one, so I think before our large breakpoint, I'll nest a selector for "ampersand colon last-child", then in it add "@include u.breakpoint-down(medium)" and in that set "display: none". Now when we save, the second quotation mark isn't there, and if we increase the viewport, it appears at the same time as the design changes. 12 | 13 | That's good. Let's get back to our original problem of how to make this design not break at around 1000 pixels. If I inspect, the code, one thing that we could change is making the "testimonial\_\_wrapper" less wide. So right now it's set to a max-width of 50rem. Just in the browser, let's try reducing that by 10 to 40rem. 14 | 15 | Looks better, let's drag over that viewport to decrease it, and right at 900px when the design is going to change, everything is still onscreen, which is great. I might even tweak it a little more narrow, like 38rem, so there's a bit more breathing space around the quotation marks. 16 | 17 | This does work and it's pretty quick. However, you might not always be able to adjust the width of the content. You might sometimes need to create a new breakpoint-- if we do that here, we can get the Testimonial section to switch to the mobile design sooner than 900px which is our "large" breakpoint. 18 | 19 | If I go to the breakpoints.scss file, looking at our breakpoint Sass map, there is a pretty big difference between 900 and 1440 pixels. I think that I might try this solution in our code, just because it might be good in the future to have another breakpoint between 900 and 1440, so I could see this benefitting future code. 20 | 21 | Let's do that. I'm going to duplicate the "large" breakpoint, and let's set the second one to xlarge and maybe 1100 pixels. Then we will have to rename the original "xlarge" to "xxlarge". 22 | 23 | And since we renamed it let's see if we have used the old "xlarge" breakpoint in our styles, because that will have to be changed too. I'm going to press Ctrl-Shift-F or Cmd-Shift-F for Macs, to open the project search, and I'll type in "xlarge". And the only results are in the breakpoints.scss file, which means we haven't used it yet. So we're good on that. 24 | 25 | And we should also create a corresponding breakpoint for the "breakpoints-down" map. So I'll duplicate the "medium" one, name the second one to "large" and change the number to "1099.98" so it's just under the "1100" size of the "breakpoints-up" size. 26 | 27 | And let's check the project to see where we've used the "breakpoint-down" mixin, to see if we need to change any of those names. I'll press Ctrl-Shift-F again, and search for the mixin name, "breakpoint-down". And it looks like we've only used "medium" and "xsmall". We never used "large" which is the one that is now "xlarge". So we're good. 28 | 29 | Now, with our new breakpoint name all set, let's go back to our Testimonial styles, and change the name of the "large" breakpoint to be one size bigger with "xlarge". And change the "breakpoint-down" name to be also one size bigger, from "medium" to "large". 30 | 31 | Now let's test. I'm going to put the website browser window to be full size. And let's move the right edge down to the mobile design. And then drag it out. So at 900px it is still using the mobile design, and when we hit 1100px, that's when we change to the two absolutely positioned quotation marks. 32 | 33 | That looks good! And I think this was a good solution that is also making how we set up our breakpoints a little better for the future. 34 | 35 | Cool! So that's pretty much it for the Testimonial section. Let's go to GitHub Desktop and commit our code. As usual, let's eyeball the files in the Changes tab, and everything looks like this is what we want to commit. So I'll add a message, "Updated Testimonial". And I'll press "Commit to main" and "Push to origin". 36 | -------------------------------------------------------------------------------- /01 - Basic Course/10 - Full-width CTA/01 - Prep and HTML markup.md: -------------------------------------------------------------------------------- 1 | # Prep and HTML markup 2 | 3 | In this section we'll be building the Full-width CTA section. As always, let's check out the design and figure out what our approach is going to be. 4 | 5 | We're getting close to the end of the website, which is exciting! 6 | 7 | So this section has a lot of similarities with the Full-width Feature section we built previously. They are both centered, with a headline and a paragraph. But instead of the laptop image, we have a CTA button. And the background here has a gradient background instead of a solid color. 8 | 9 | Like before, let's go to VS Code and add the HTML markup for this section. Since we know it's very similar to the Full-width Feature section, I'm going to go up to the section tag with the `fw-feature` class and copy the whole thing, then go under the Testimonial section, and paste it there. 10 | 11 | Since we don't need the image I'll delete that. And we need to use a different BEM block name other than `fw-feature`-- maybe `fw-cta` since this is the Full-width CTA section. I'm going to do a Find & Replace, to change the `fw-feature` name to `fw-cta`. But I don't want to change anything from the original `fw-feature` section, only in this new section. 12 | 13 | We can do that by using a Find & Replace within Selection option. First I'll select the `fw-feature` text, and then press Ctrl-F. Selecting the text you're searching for before opening up the Find menu will automatically search for the text you've selected. Right now it says there are [XXX] total matches, and VS Code also highlights the matches in the document, which you can see if you scroll up a bit. 14 | 15 | Now, we want to only search within the second section tag, so I'm going to select that whole section tag in the file, and then in the Find menu I need to turn on the `Find in Selection` option, which is the three lines icon to the right of the down arrow. Now, there are only [XXX] matches, and if you scroll up the matches in the first section tag are no longer highlighted. 16 | 17 | Then, to the left of the text is a right angle bracket. Click that to expand the `Replace` tool. Then in the text box there type in `fw-cta`. Then you can either replace individual matches with the first `Replace` button. Or if you're feeling confident you can replace ALL matches with the second button to `Replace All.` 18 | 19 | One way to get to the Find and Replace menu quicker is if we first close out of the menu. Then highlight the `fw-feature` text, and instead of Ctrl-F, press Ctrl-H to automatically open the Find AND Replace menu. Then select the section tag and click the `Find in Selection` icon. Then you can replace either one by one, or all at once. 20 | 21 | So now it's saying that there are no results for `fw-feature` within the selection, since we replaced them all. 22 | 23 | Now that we're done with that, let's save, and then copy over the actual text from the design for the header and paragraph for this section. Going over to Figma, I'll select the header text and copy it, then in VS Code paste it in the h2 tag and replace the old text. Next, let's copy the paragraph text and then paste it in the paragraph tag. 24 | 25 | After that we need to add the CTA button. In the design it says `Free Trial` like the button up in the hero section. So I'm going to go back to the index.html file, go up to the Hero section, and copy the markup for the Free Trial button, then go back to the Full-width CTA section and paste it in under the paragraph. And we'll want to replace the `hero` block name with `fw-cta`. And for now let's leave the `primary` class name, but we'll be changing this later to get the solid white button styles. 26 | 27 | Now let's create our new Sass partial. Like the other sections, I'll create it in the scss/components folder, and let's call it `_fw-cta.scss`. And we'll need to add it in the components index.scss file, with `@forward 'fw-cta'`. 28 | 29 | Then, in the `fw-cta.scss` file itself, the first thing we'll want to add is using the utils, with `@use '../util' as u`. And now we can start adding the selectors for the elements we added in the HTML. I'm going to split the code editor in half and put the index.html file on the bottom-- right-click the index.html file tab and select `Split down` and it will duplicate on the bottom half. Then in it, I'm going to scroll down to the Full-width CTA section so we can see the elements. 30 | 31 | In our Sass file, the first selector will be our BEM block class, `fw-cta`. Then nested in it will be the BEM element selectors, starting with `fw-cta__wrapper`, then `&__title`, `&__description`, and then `&__button`. Now let's save, and then close the duplicate index.html tab. 32 | 33 | And that's it for setting up our HTML and Sass partial. Now let's get on with writing our styles. 34 | -------------------------------------------------------------------------------- /01 - Basic Course/08 - Full-width Feature/01 - HTML markup.md: -------------------------------------------------------------------------------- 1 | # HTML markup 2 | 3 | In this section we'll be building the Full-width Feature section. As always, let's first take a look at the design in Figma and figure out what HTML markup to use. 4 | 5 | In our design, this section is almost identical between mobile and desktop versions. All the content is in one column and centered on both. The main difference is that on desktop, the text and image are larger than what they are on mobile. 6 | 7 | So, and this is completely optional, if you want to try to write all the HTML markup for this section yourself, feel free to do that! 8 | 9 | If you're not sure how to do something, look back in the index.html file and the styles to see what we've done previously, and use that to go off of. But if you don't feel comfortable doing so at this point, that's totally fine too! 10 | 11 | Alright, pause, give it a shot, and then whenever you're ready, unpause and I'll show you how I'm setting it up. 12 | 13 | Ok, in our design we just have the one laptop image so let's export that as an SVG. I'm going to select the desktop version, and it's in the layer called `laptop-dashboard`. Then in the right sidebar down at the bottom, in the `Export` panel, I'll make sure `SVG` is selected as the file type and then hit the `Export laptop-dashboard` button. Then I'm going to get the file in my File Explorer and copy and paste it into the image folder. 14 | 15 | Now let's go to VS Code and start writing the HTML markup. In our index.html file, like the other sections, I'm going to create a section tag after the previous section by writing `section` and then a dot for the class name. The last section the block name was `features`, so for this one I might call it `fw-feature` for Full-width feature. 16 | 17 | Ok, we got our section tag, now what's next? One thing I like to do is if I'm not 100% sure, I can always look back at the code I've already written and follow the same pattern. So if I look at the previous Features section, I can see that in the section tag we put a hidden h2 tag, and then the div with the block and element name with the double underscore, and then the `wrapper` class. 18 | 19 | Now, in our new Full-width Feature section, I can follow that. If we look at the design we don't need a hidden h2 tag, since this section does have a title visible. So going back to VS Code, the first element I'll create is the wrapper div. And again, the wrapper will center the content and limit it to 1200px on desktop, and on mobile it will add space on the left and right sides. 20 | 21 | To create the div with the class names that we want, I'm going to type `dot` `fw-feature__wrapper` `dot wrapper` and hit Tab or Enter. And VS Code will create a div with the two classes, `fw-feature__wrapper` and `wrapper`. 22 | 23 | Inside our wrapper div, I'm going to first add the headline with an h2 tag. In the previous section we had h3 tags for each feature with a class name of `features__title`. So I'm going to follow that pattern and create this h2 tag by typing `h2.fw-feature__title` and hitting Tab or Enter. 24 | 25 | The class is in case we need section-specific styles for this h2 tag other than what we have globally. Let's get that headline text from Figma, and paste it in the h2 tag. 26 | 27 | Next up we have the description, so under the h2 tag let's create a paragraph tag by typing `p` then a dot and we'll give it a class of `fw-feature__description` and then hitting Tab or Enter. Going back to Figma, let's copy that description text and paste it in the paragraph tag. 28 | 29 | After the paragraph we need to add the image of the laptop with an image tag. So I'll type `img.fw-feature__image` and hit Tab or Enter. Then in the `source` attribute I'll type forward slash, `img` and then select the image we just exported, `laptop-dashboard.svg`. Then we'll add alt text, and you can be pretty descriptive here, so instead of just typing like `laptop` I'm going to write `open laptop showing a dashboard on the screen`. Just imagining how you would verbally describe what this image looks like. 30 | 31 | Let's see what else we need to add for this image-- I'm going to scroll up and check the image tag from the previous section. And we have the class, source, alt text, and we still need to add the width and height attributes. Let's go to our new image and add `width` and `height` and we need to go to Figma to get the dimensions. 32 | 33 | In Figma the laptop image has a width of 792px, and a height of 467px. So we can go back to our code and I'll add `792` for the width and `467` for the height. 34 | 35 | I think that's all the markup we need for this section. Let's save what we have and even though we haven't written any styles yet, let's just see what it looks like on the website. Alright, that looks pretty good-- we have the text and the image. 36 | -------------------------------------------------------------------------------- /01 - Basic Course/11 - Footer/04 - Footer column markup.md: -------------------------------------------------------------------------------- 1 | # Footer column markup 2 | 3 | Going back to the index.html file, I want to select the `footer__column` section tag. And since we want 4 total columns, I'll duplicate by pressing Ctrl-D 3 times. And we'll want to update the copy for all the other links. I'm going to go back to Figma, and select the second column, `Support` and press Ctrl-C-- this will copy the text of the content here. 4 | 5 | Then in VS Code I'm going to paste inside the second `footer__column` section tag. And now we can copy and replace the existing text with the new one. So first is the h3 tag for `Support`, then the links-- Customer Support, Community Forum, Knowledge Base. And this column only has 3 links so we can delete the last link. Now when we save, Prettier will automatically get rid of all the extra space. 6 | 7 | Now for the third column. In Figma I'll select the `Follow` layer and copy with Ctrl-C, then in VS Code I'll go to the 3rd `footer__column` and paste the text there. The `Follow` column has those social media icons, which we'll add later on. And again we'll replace the old text with the new ones. So first the `Follow` h3 tag, then Twitter, Facebook, Instagram, and YouTube. And then press save to delete the extra spaces. And again, we'll come back to the icons later on. 8 | 9 | Now for the last column. In Figma I'll select the `Resources` links, copy with Ctrl-C, and then in VS Code I'll paste them in the last `footer__column`. And then cut and paste the new text-- Resources, Privacy Policy, then Terms of Use. And delete the last two list items, and save. 10 | 11 | Looks good, let's save and check what this looks like on the website. Ok, so we have our text styles, obviously we need to add more styles for the layout. Before then, let's work on adding those social media icons to the `Follow` links. 12 | 13 | Going back to VS Code, I believe we already exported the icons-- they are in the img/social folder. Previously when we've worked with SVGs like the hero image and other images and icons, we loaded them in an img tag. We could do here too, but I wanted to also show you a case for loading SVGs as inline SVGs, instead of in an image tag. 14 | 15 | Let me show you what I mean with the first icon, for Twitter. In VS Code, let's double-click the `twitter.svg` file to open it. Let's press Alt-Z to wrap the lines so we can see everything. You can see that Font Awesome comment that gives attribution for using this free icon. 16 | 17 | Let's copy the whole SVG tag, and then in the index.html file, I'm going to go up to the `Follow` column, find the Twitter `footer__link` anchor link, make a new line before the text, and paste. And this is what it means to have an inline SVG-- we're literally pasting in the SVG code directly into the index.html file. 18 | 19 | And without doing anything else, let's see what that looks like on the website. Ok, so we have the icon displaying, but it's a lot bigger than its supposed to be. One interesting thing that you might notice is that the Twitter SVG is the exact width of the `Twitter` text. If we click into the `Twitter` text and write another `Twitter`, then press Enter to reflect the change, the Twitter icon grows along with the text length. 20 | 21 | This is because the SVG is taking up as much space as its parent element, the anchor link. And the anchor link, which we've set to `display: inline-block`, is going to size itself based on its content, which in this case is the text inside it. Then the SVG will take the same size. If we set this `footer__link` to be `display: block`, it will take up the full width of the footer wrapper, and the Twitter SVG will then grow with it. 22 | 23 | To control the size of the icon, we'll add some styles later on. You can add `width` and `height` attributes to the SVG tag, kind of like we do with the image tags. But I don't think we need to do it for inline SVGs that already have the `viewBox` element. 24 | 25 | The viewBox is a bit more of an advanced aspect of SVGs which we don't really need to work with here. But briefly, the `viewBox` attribute controls the size and composition of the `viewport`, which is a frame through which you view the different elements inside the SVG tag-- for example in this SVG we have just one element, the path tag which is the Twitter bird shape. 26 | 27 | You can imagine the viewBox a bit like the viewfinder of a camera, where you can control where to position objects in the frame, and how much you want to zoom in or out. The 4 numbers in the viewBox set the x-coordinate, y-coordinate, and width and height of the frame. 28 | 29 | Since it does have width and height information, the browser knows how to size the SVG. 30 | 31 | Again, this is a bit more advanced aspect of SVGs, so you don't need to worry about it for our purposes here, as we will be sizing the SVGs in our styles later on. But it's good to have a general idea of what it is. 32 | -------------------------------------------------------------------------------- /01 - Basic Course/10 - Full-width CTA/09 - Checking the styles.md: -------------------------------------------------------------------------------- 1 | # Checking the styles 2 | 3 | Ok! So the button was the last element to finish for this section, so let's do one last check and compare the design to what we have on the website, to make sure everything matches the design. 4 | 5 | On our website, I'm going to inspect the section tag, and check the padding. In the `Layout` tab it says we have 80 px of padding on the top and bottom. So let's go to Figma and see if it's the same. And if we select the CTA Content and hold down Alt and hover just above the selected content, it tells us that it is also 80px on top and bottom. 6 | 7 | Next up let's check the main header text-- in Figma, it's 48px. And the paragraph text is 28px. So 48 and 28 pixels. On the website I'll inspect the header text, and in the `Computed` tab it is 48px, which is right. And the paragraph tag is 24px. 8 | 9 | Ok, these are different, so we'll need to fix that. In the `Rules` tab for the paragraph styles, let's trace back and see where the font-size is coming from. It's set on the `medium` paragraph class. Since it's using that helper class, that makes me think that we set those styles based on another paragraph in the website. 10 | 11 | Let's go to the typography.scss file, and see if there's a different helper class that we can use that does have the correct styles, or if we'll have to create another set of styles for the Full-width CTA paragraph. In the typography.scss file, we can see the `medium` class and in the clamp() function it has a minimum font-size of 20px, and a maximum font-size of 24px. So that's going to be too small for this paragraph. 12 | 13 | The `large` class has a minimum font-size of 24px, and a maximum size of 1.75rem, which if we take out the calculator and multiply 1.75 by 16, it is 28px. We do need the 28px size, and let's also check what mobile font-size the Full-width CTA paragraph needs in Figma. There, the mobile paragraph is 24px. So, going back to VS Code, it looks like the `large` paragraph styles are what we want for the Full-width CTA section. 14 | 15 | I'm just also going to convert that 1.75rem to `u.rem(28)` to match the other clamp() functions, so it's easier to pinpoint what the size is in pixels. And, let's go to the index.html file and in the `fw-cta__description` paragraph, change the `medium` class name to `large` instead. And let's save, and now on the website the paragraph is the correct 28px size. 16 | 17 | The button styles should be fine, since other than the white background color, they are the same as the other buttons on the website. And for the background gradient, we can just eyeball it and make sure it looks similar enough to the design. And if we flip between website and design I think they look quite similar. 18 | 19 | Last thing to check for desktop is the spacing between the elements. On the website, if I inspect the h2 tag, in the `Computed` tab it tells us that we have a `margin-block-end` of 20px underneath. And then if we select the paragraph tag, it has a `margin-block-end` of 40px. 20 | 21 | Going to Figma, I'm going to select the header and hold down Alt and hover over the paragraph, and there's 20px of space between them, which is correct. And I'll select the paragraph, then hold down Alt and hover over the button, and there's 40px of space under that to the button. So that all matches, which is great. 22 | 23 | Now, let's check out the mobile styles. Since we just checked the spacing on desktop, let's do the same thing on mobile. Under the header text on mobile is 20px of space, and under the paragraph is 40px of space. So the mobile spacing matches the desktop spacing. 24 | 25 | Let's go back to the website and I'll turn on Responsive Design Mode and make sure the iPhone is selected. And if I select the header, it is 20px of `margin-block-end`, and if I select the paragraph, it has 40px of `margin-block-end`. So we're good on the mobile spacing side. 26 | 27 | Now let's check the font-sizes for the headline. If we inspect it it is 36px, and the paragraph is around 24px-- the decimals are probably due to the clamp() function, but this is close enough. So 36px header and 24px paragraph. Going to Figma, the mobile header is 36px and the paragraph is 24px, so we're good! 28 | 29 | And lastly, let's just eyeball the background gradient, and flipping between the design and the website, they look the same. 30 | 31 | Alright, so everything looks good. So I think we can consider this section finished, and we can commit our code. Go to the GitHub Desktop App, and let's scan the files to make sure there aren't any files that we don't want to commit, but that looks good. And for the commit message I'll write `Full-width CTA` and press `Commit to main` to commit, and then press `Push to origin` to push our changes up to GitHub. 32 | 33 | Awesome! Ok, so up next will be the last section of the website, can you believe it! We'll be working on the footer section. 34 | -------------------------------------------------------------------------------- /01 - Basic Course/12 - Deployment/01 - Deployment.md: -------------------------------------------------------------------------------- 1 | # Deploying to Netlify 2 | 3 | Alright, in this video we're going to be deploying our website that we just built to Netlify, so that you can load your website from anywhere on the internet. 4 | 5 | Netlify is a great platform for hosting static sites that are built with HTML, CSS and JavaScript, as opposed to what's called dynamic sites that are built with a traditional server-side language like PHP or C# and often have a database hosted on that server as well. 6 | 7 | I'm choosing Netlify for this because it seems to be the most popular option right now, and it has a free tier for personal projects. Other than Netlify, you can also host a static website on Cloudflare Pages, GitHub Pages, or Vercel-- they all are either free or have free tiers for hobby or personal projects, which is perfect for this course. 8 | 9 | Ok, to get started with Netlify, go to Netlify.com and click the "Sign Up" button. Then you can sign up with either email, or your source control login. I signed up with my GitHub login because it automatically connects your repositories to Netlify to make deploying easier. 10 | 11 | Now, once you're signed up with Netlify and you've logged in, you should see a dashboard here. And here's where we're going to create the website that we want to host. So to do this on your dashboard, there's a sites panel down here, and you want to do the import an existing project. 12 | 13 | So if we click that to import from Git, then we want to select GitHub since that's where we've hosted our repository. And then it should pop up a new window, prompting you to ask if you want to install Netlify and connect it to your GitHub account. 14 | 15 | And you have a couple options here. You can click all repositories. And if you think you're going to be using Netlify a lot for multiple different repositories, then you might want to click all repositories. 16 | 17 | You can also just select one repository or a few repositories. And I might do this just since I'm only going to select one repository for this. You want to select the repository. 18 | 19 | Mine is called Responsive Design Beginners. And then now you can see it has selected the repository. So you can just read over the permissions that you're giving. So it looks pretty good. 20 | 21 | And then I'm going to click the install button. And now we can see we're back in our Netlify dashboard. And we can see under here, we have the name of our repository, Responsive Design Beginners, showing up, which is pretty great. So once you see the repository in your dashboard, let's click on that. 22 | 23 | And then we want to look at the different configurations. We want to check the team, CoderCoder's team. I think that's just a Netlify default. But you do want to make sure you're deploying the correct branch. I just have the one main branch, so I'm going to select that. 24 | 25 | But if you have work on other branches that you want to use for your production deployment, you can select those branches. Then down in build settings, if you are using the Live Sass compiler to compile your SAS files, you basically want to keep everything blank. 26 | 27 | So you don't want any of these. And it's going to install from the base directory, which is what we want. It's just your directory in the project. And you don't need to use any of these build commands, because you've already compiled your SAS files to CSS using the live SAS compiler. 28 | 29 | All right, so once this is all set up, then the last thing for you to do is to click the Deploy Responsive Design Beginners button, and it'll start deploying. And this might take a minute or so to finish deploying. 30 | 31 | All right, so once the deployment is finished, you should see a little pop-up message saying Deploy Success. And then it also has a nicely randomly generated name for your website. So if you want to check out the site deploy, you can click this button here. 32 | 33 | And it'll give you some information about your deployment. 37 new files uploaded, et cetera. Everything looks pretty good. And then you can click the Preview button, and it'll actually load the website. So now you can see up in the URL bar, we have a randomly generated URL as a subdomain, and then a .netlify app. 34 | 35 | So we can tell this is a real website, which is pretty cool. And the other way you can get to the website is, let's say you're back in the, let's see, let's go back to our main dashboard. So the other way you can access your website if you're coming from the main dashboard is you can see the sites here listed. 36 | 37 | You can click on that, and then you can see there's a little card here with the name of the site, and you can click this URL to load the site in your browser. 38 | 39 | All right, so that's it for the deployment to Netlify. Again, you can use whatever static website hosting platform you want. I just use Netlify because it seems to be the most popular right now. 40 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/04 - Sass and BEM.md: -------------------------------------------------------------------------------- 1 | # Sass and BEM 2 | 3 | Let's set up a new Sass partial for this demo website. In the scss folder I'm going to create a new subfolder called layout, and in it I'll create the \_index.scss file and another file called \_grid.scss. Then in the \_index.scss file I'll forward the \_grid.scss partial. And, in the main style.scss file we'll forward the layout partials. 4 | 5 | When you're setting up your Sass files and folders, you can either try to organize and name them in a way that makes sense to you. Or you can try to follow existing architecture patterns like the 7-1 architecture. I'm doing a bit of a hybrid, where I'm using the "layout" name from the 7-1 pattern, but using the other folder names (globals and util) based on what previous jobs have used and just my own preferences. Personally, I think that as long as you keep your styles organized, you don't necessarily have to use a specific architecture. 6 | 7 | Let's go back to our index.html file and take a look at the markup. What I'm going to do is use CSS grid to control the 2-column or 1-column layout. In grid, you have a grid parent element, and then the grid child elements. In our case, the main and aside elements are the grid children. So looking at the markup their parent is the body tag. I don't really want to set CSS grid properties on the body itself, just in case we need to add other elements to the body later on. So I'm going to move both the main and aside elements into a parent div. 8 | 9 | This div will be the grid parent. And I want to create a CSS class in order to have a selector to identify the grid styles. So I'll add a class of `grid` to the div, then to the main element I'll add a class of `grid__main` and to the aside element a class of `grid__sidebar`. These classnames having the double underscore may seem kinda strange, which is totally understandable if you haven't seen them before. 10 | 11 | That double underscore, along with how each class begins with the word `grid` is part of what's called the BEM or block-element-modifier approach to writing Sass styles. Let me show you in the grid.scss file. First, we'll add a selector for the parent, which has the class `grid`. 12 | 13 | Then let's add a selector for the main element, which has the class `grid__main`. Instead of having to write a completely separate selector for this class, we can use the nesting feature of Sass, and inside the grid styles, we can write `&__main`. The ampersand will stand in for the parent selector, which in this case is the `grid` class. Then it will be followed by the underscore underscore and main. And we can do a similar thing for the `grid__sidebar` by writing another selector within the parent `grid` class styles, `&__sidebar`. 14 | 15 | How do these class names fit into the BEM model of writing Sass? The B stands for `block,` and you can think of a block as a standalone component in the design. In our example here, the `grid` is the block. The `E` stands for `element.` Elements are child items contained by the block, and here we have two child items: the `grid__main` and the `grid__sidebar` elements. And in those classnames, we're separating the name of the block from the name of the elements with that double underscore. So if you look at the markup, you can identify that the `grid` class is the block and the `main` and `sidebar` are elements. 16 | 17 | The M in BEM stands for "modifier." Modifiers are alternate versions of either blocks or elements. You denote them with a double hyphen. We're going to use modifiers a little bit later in our demo website. For now we'll just be working with the block and elements. 18 | 19 | I remember when I first saw CSS classes that were really long (in my opinion) and had the double underscore, and to be honest, they looked really weird to me at the time. What's the purpose of writing these long compound class names? Well, one benefit to using BEM is that it helps to keep the class names unique, so that you don't have style conflicts if let's say, you had two different sets of styles for a `main` class selector. Also, if you ever changed the name of the block from `grid` to something else, you only have to change the name in one place in your Sass files, as opposed to having to run a Find and Replace for any instance of the `grid` class name. 20 | 21 | BEM also is useful for our favorite thing, organization. You may have noticed that the Sass file is named `grid` and the block name is also `grid.` This is on purpose, and makes it easier to track down where the styles are located in your files. Now we do have Sass sourcemaps, which will tell you the original Sass file and line number where a style rule came from. But it's also good to know that if you have a bug on an element that has the CSS class `grid__sidebar`, you could guess that you're looking for a file named `grid.scss`. 22 | 23 | The ampersand and underscore and hyphens in BEM do take some getting used to, but I think that they are more than worth it in the end to make working with your styles more organized and efficient. 24 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/16 - Default browser styles.md: -------------------------------------------------------------------------------- 1 | # Default browser styles 2 | 3 | One weird thing about CSS that I need to point out is related to that space between the widgets. We didn't add any margins or other properties to the widgets that would cause a space to occur. But one is there! What's going on here? 4 | 5 | The space itself is actually from some default browser styles that are applied to some HTML elements. One example is that a paragraph will automatically have margin-top and margin-bottom added to it, even if you don't say anything in your styles. We actually canceled out the default margin-top value in our `_typography.scss` file where we set margin-top of the h tags and the paragraph tags to zero. So just for demonstration purposes, let's comment out the `margin-top: 0` for the h tags and the paragraph tag. That way they will take the default margins from the browser. 6 | 7 | In the browser inspector, if I select the paragraph tag and then click on the `Layout` tab and the `Box Model` panel, it tells us that the paragraph has 16px of margin-top and margin-bottom. This 16px is from Firefox itself-- it adds the margin that's the same size as the font-size, which in our case is 1rem or 16px. And other browsers will do the same thing. If this seems weird and confusing to you, I'm right there with you. 8 | 9 | I think these automatic margins are sort of a holdover from back before CSS existed, and webpages were written with just straight-up HTML, so that they looked like Word documents. If you think about it from that point in time, it does kinda make sense that having some spacing added for you automatically would help save time when you're writing the website content. 10 | 11 | Unfortunately, even though we can control spacing now with CSS, we still have this feature that can cause unexpected behavior. So it's just good to know if you're wondering why some elements have spacing when you didn't give it spacing in your styles. 12 | 13 | And there's another very strange quirk that comes along with the automatic margins. And that's what is called "margin collapse." We can see this happening on the website right now. 14 | 15 | Another element that has default margins is the h2 and other h tags. If we select the h2 tag and go to the "Layout" tab again, it tells us that the h2 tag has a top and bottom margin. This margin is calculated by multiplying the font-size of the h tag by 0.83 for Firefox (and this exact amount might be slightly different across other browsers). So it's a margin of slightly less than the font-size itself. 16 | 17 | You might be wondering, if the h2 tag has that margin-top, why is the purple background from the sidebar widget not including the margin? Instead, the margin is going outside the purple box. And, under the h2 tag, there is space because of the margin-bottom, but there's also a margin-top from the paragraph tag underneath it. But if we hover over the h2 and then the paragraph tags, it looks like the paragraph's top margin is getting included in the h2's bottom margin. 18 | 19 | Both these weird things are because of margin collapse. If you have two elements and they have margins between them, the browser will only give a space that matches the biggest margin value-- the other margin collapses instead of getting added to the space. 20 | 21 | And in the same way, both the top margin of the h2 tag and the bottom margin of the paragraph tag collapse and don't get included in the parent sidebar widget element. 22 | 23 | How do you fix these weird quirks if you ever encounter them? You can get rid of the quirks if you apply some CSS style rules to the parent that creates what MDN (Mozilla Developer Network) calls a "block formatting context" which will get rid of the margin collapse effect -- https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context 24 | 25 | You might be doing some of these on your own without realizing it. If you add a border to the parent, like `border 1px solid`, the margins will then be included in the parent element. Or some padding, like `padding: 20px`. These are things that you might just add since we do want some extra space around the text in the sidebar widgets. This will also happen if you make the parent a flex or grid parent. 26 | 27 | MDN has a whole list of conditions that will create a new block formatting context. I don't fully understand it myself to be perfectly honest, but the way I understand it is, if you start adding additional styles to the parent it will get out of that old, default Word doc way of displaying the elements, and instead behave according to the explicit style rules that you're adding. Again this is a very weird quirk that I wish didn't happen, but it still is happening, so we need to learn to work with it. 28 | 29 | Anyway, that is a very long explanation, but back in our styles, let's uncomment the `margin-top` rules and then in the `_grid.scss` file add a little padding to our sidebar widgets. I'm going to set it to `u.rem(16)` to add 16px all around. Now we're ready to make the different widget themes! 30 | -------------------------------------------------------------------------------- /01 - Basic Course/01 - Getting Started/04 - Setting up project files.md: -------------------------------------------------------------------------------- 1 | # Setting up the project files 2 | 3 | Ok! So we've gone through some of the tools that we're using in the course. Now in this section I'm going to walk you through setting up the project files for the actual website. 4 | 5 | First off, create a new folder wherever you want to keep the project. 6 | 7 | I'm creating a new folder on my Desktop called "responsive-design-beginners." If you have a different location on your computer where you usually keep your GitHub projects, feel free to set the project up there. It doesn't matter a ton exactly where it's located. 8 | 9 | Now let's create a GitHub repository in this folder. 10 | 11 | Open GitHub Desktop and navigate to "File" > "Add local repository" and then select the folder you just created. GitHub Desktop will ask if you would like to create a repository here instead, since one doesn't exist yet. Click the "create a repository" link, and then check that all the settings are the way you want. I'm going to check the "Initialize this repository with a README" box, and set the License to MIT license so that it's open source. When you're ready, click "Create repository." 12 | 13 | When the repository is created, go ahead and open VS Code. In VS Code, navigate to "File" > "Open Folder" and select the project folder. 14 | 15 | Let's start by creating our `index.html` file. In that file I'm going to type the Emmet shortcut "exclamation point" and press enter to add some boilerplate HTML to the file. 16 | 17 | Let's change the title tag to say "Mythos," the name of our fictional agency. And then let's add a paragraph tag with some lorem ipsum placeholder text. We'll use an Emmet shortcut again by typing in `p>lorem50` and hitting enter when the "Emmet Abbreviation" dropdown pops up. This adds a paragraph tag and inside it, 50 words of lorem ipsum text. 18 | 19 | Now let's add tags for our CSS and JavaScript files. 20 | 21 | In the ``, type in `link` and then in the dropdown select `:css` to add a link tag. Then set the `href` attribute to `/dist/style.css`. This folder and file don't exist yet, but we'll be creating them later when we compile our Sass styles. 22 | 23 | Under the link tag, we'll load our JavaScript. Type in "script" and then in the dropdown select `script:src` and press enter. Then in the `src` attribute type in `/app/js/script.js`. We're not going to be processing our JavaScript file since we're not doing anything complex with it. So this will remain in the `app/js` folder. 24 | 25 | One last thing to add is a `defer` property in the script tag. This will ensure that the script loading won't block the loading of the rest of the website. 26 | 27 | In the `` tag let's add an h1 tag that also says "Mythos". We'll change this later but for now we just want some text on the page for when we test it in the browser. 28 | 29 | Save the `index.html` file and we are done with it for now. 30 | 31 | Let's now create our Sass and JavaScript files. 32 | 33 | In the left sidebar of our project, create a new folder called `app`. Then in the `app` folder, create a subfolder called `scss`. Then click on the `app` name and create another subfolder in it called `js`. 34 | 35 | So now, in your project file structure, we have the `index.html` file and the `app` folder in the project root. And then the `app` folder has the `js` and `scss` subfolders. 36 | 37 | Now let's create a Sass file. 38 | 39 | In the `scss` folder, create a file called `style.scss`. 40 | 41 | For now we're just going to put in some test styles. In the `body` selector, add `font-family: Arial, Helvetica, sans-serif;` and set the `background` to `hsl(0, 0%, 13%)` or whatever color you want. And then set the `color` property to `hsl(0, 0%, 87%)` or again whatever you want. 42 | 43 | As a sidenote, you may have noticed that I'm using HSL format for my colors.The HSL stands for hue, saturation, and lightness. You might be more familiar with HEX colors like `#000000`. 44 | 45 | However HSL colors are considered a bit better format because they make it a lot easier to darken, lighten, and adjust the saturation level. So I try to use HSL colors whenever I can, but you are welcome to use HEX or RGB if you like those better. 46 | 47 | VS Code actually makes it easy to convert between formats. If you hover over the color swatch you'll see a color picker pop up. Then if you click the color bar on the top, it will rotate between the different color formats. 48 | 49 | All right, back to the code. We're going to be deleting all this and reworking our Sass file later on in the course. These styles are just so we can test compiling Sass to CSS in the next section. 50 | 51 | Now let's create a JavaScript file. 52 | 53 | In the `js` folder, create a file called `script.js`. In the file create a `console.log` and have it say whatever you want, I'm going with the classic `hello world` message with a "wave" emoji and an "earth" emoji. 54 | 55 | Ok, that is all the stuff we're going to start with. In the next section we're going to talk about Sass. What it is, and how to compile your Sass to CSS. 56 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/09 - Order of media queries.md: -------------------------------------------------------------------------------- 1 | # Order of media queries matters due to the cascade 2 | 3 | One more thing that I want to mention is that if you have multiple media queries for a selector, the order is very important. To illustrate this, let's experiment with giving the main content different background colors at different viewport widths. 4 | 5 | We'll start with the blue color that we already have for mobile. Then let's create a new breakpoint for medium, and we'll set the medium to a green color. Then we'll add another media query for large or desktop, and make the background color orange. 6 | 7 | Now in the browser we can see as we slide the inspector panel, that the background color does change from blue to green to orange. 8 | 9 | This is working because in our styles the medium breakpoint is saying, at viewport widths of 700px and up, set the background color to green. And that style rule will override the default mobile style rules of blue. Then our second breakpoint says, at viewport widths of 900px and up, set the background color to orange. 10 | 11 | And this is what we want to do for min-width media queries. The default styles are for mobile, then as the viewport width increases it will trigger the medium, large, and then xlarge breakpoints. 12 | 13 | But, what happens if we put the media queries out of order, so that the large breakpoint is listed before the medium breakpoint? It's saying, default color is blue, then at widths of 900px and up set the background color to orange, but then on top of that, at widths of 700px and up set the background color to green. At desktop withs, do you think the background color will be orange or green? Let's find out. 14 | 15 | If you thought green, you are correct! And if we look at all widths from desktop down to mobile, the background color is green except for mobile which is blue. Why did this happen? This is due to the `cascade` in our styles, which is how CSS determines which styles will ultimately be used on the website for a selector. And this is why CSS stands for "Cascading Style Sheets." 16 | 17 | In CSS, if you have two rules that are the same level of specificity, the rule that occurs later on in the styles will override an earlier rule. So what's happening here is that the medium media query, which is 700px and up, is overriding the large media query for 900px and up, because it comes after the large media query in our code. Just for illustration purposes, what happens if we add another medium media query and set the background color to red? 18 | 19 | If we look at the website, the background will be red. And again, this is because the style rule with the red background color is overriding the style rule before it, with the green color. 20 | 21 | So putting the media queries back in the correct order, I'll delete that last red background color rule. And we'll have the default or mobile background color of blue, then for medium and up the background will be green, and for large and up the background will be orange. 22 | 23 | And let's check that that's working in the website. And it looks like yes, the background is going from blue to green to orange as the viewport increases. 24 | 25 | So, going back into our styles, when you're working with min-width media queries, you want to order them in increasing viewport widths. So starting with mobile and then going on up. And this is because the min-width media queries are saying, use these styles when the viewport width is at least this width, and on up. Then you can keep tacking on increasing viewport width media queries. 26 | 27 | So our styles here are saying, use a blue background color, and then at viewports that are greater than 700px use a green background color, and then at viewports greater than 900px use the orange background color. 28 | 29 | So then, what about max-width media queries like we have in the sidebar? For these, the default styles are desktop styles, and then you add media queries for viewports that are up to a certain width. So for our text-align center rule, we're adding that for viewports that are 899px and less. And that is for tablet widths. Then if we wanted to add another text-align rule for just mobile, we could add another breakpoint-down media query for "small" and set the text-align to say, text-align: right. 30 | 31 | Our styles are now saying, use the default text-align: left, unless the viewport is 899px or less, then use text-align: center, and then if the viewport is 699px or less, use text-align: right. 32 | 33 | You can see that this is a bit opposite of what we did with min-width media queries. When we're using max-width media queries, the default styles are for desktop widths, and then we keep tacking on decreasing viewport width media queries. 34 | 35 | It can be kind of hard to wrap your head around min-width and max-width media queries and breakpoints when you're first starting out. Don't worry if it seems kind of confusing at the beginning. 36 | 37 | But if you're noticing that your styles in media queries don't seem to be taking effect or are weirdly getting overwritten when you don't want that, try checking the order of media queries for that selector to see if maybe something is out of order. And try to play around with the order to see if it fixes your issue. 38 | -------------------------------------------------------------------------------- /03 - Ultimate Course/02 - Testimonial/01 - Setup.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | In this section we're going to be making some changes to the Testimonial section. 4 | 5 | If we look at the design, it looks very similar to what we currently have, but the colors are different. On our website now, we have a white background, the quotation mark images are teal, and the text is the dark gray. 6 | 7 | However in the new design, we kind of have a dark theme going. The background color is the blue-purple color that we have in the header and hero, the quotation mark images are a white color with 50% transparency, and the text is white. 8 | 9 | The reason I made this design change is because under the Testimonial section, we're going to be adding a new Blog Post section. And color-wise, since the Alternating Features section has a white background, and the Blog Post section will have a white background too, it made sense to make the Testimonial section between them have a dark background color. Just so things look better design-wise. 10 | 11 | And we're not just going to change the Testimonial colors and be done with it-- I'm going to create a color theme for this new design. Where just by adding a helper class to the Testimonial section tag, it will change all the colors in the section. 12 | 13 | This theming is something that can come in really handy if you want to have multiple styles available and you might be switching between them. And, we'll be setting up this theme with CSS custom properties in a way which I think is a little more organized and easier to read. 14 | 15 | Let's take a look at our current website, and figure out how we want to map our colors out. 16 | 17 | The background color we'll set on the "testimonial" class in the section tag. Then for the text, we can probably also set the color property also just in the "testimonial" class, since the h2 and paragraph tags will inherit that color. 18 | 19 | Then the other color we need to set is the quotation mark icons. Right now, we built those as image tags, but I think that we're going to want to change those to inline SVGs, like what we did in the footer with the social media icons. 20 | 21 | This will let us change the color of the SVG just in our styles, without needing a whole new image for the different colors. Okay, so that's three colors we'll need to set up. 22 | 23 | Now let's go to VS Code, and first go to the colors.scss file. So far in our website, we've been putting all the colors into global CSS custom properties that we've set on the ":root" pseudo-class. And this works just fine. 24 | 25 | However, if you end up working on a really large website with lots of pages and different components and styles, at some point, you might want to start separating out the colors into the components that they're being used in. 26 | 27 | So what we're going to do is create the Testimonial colors as custom properties, but instead of setting them on the ":root" element, we'll create them in the "testimonial" class. 28 | 29 | Limiting the scope of these custom properties to the Testimonial section means they can't be used outside of it. But that is perfectly fine for our purposes here. 30 | 31 | In our "testimonial" class, I'll start with the background color. Let's call this "--testimonial-bg". And initially, I'm going to set this to be our current color of white. So let's go to the colors.scss file, and I'm going to reuse the "main-bg" color since this is what we're using as the default background color on the website. 32 | 33 | So I'll copy that, and then back in the Testimonial styles, we'll load that "--main-bg" color with the var() function, and then paste it in. 34 | 35 | Next let's create the text color. I'm going to call this "--testimonial-text". And it's the dark gray that we've been using on the site, so let's go to colors.scss, and copy the "text-dark" custom prop, and paste it in a var() function. 36 | 37 | Okay, the last color we need to set is the quotation mark images. Let's create our custom prop and call it "--testimonial-icon". 38 | 39 | Then we need to get that teal color. In our colors, even though the teal color is used in some other places, like the "button-primary-bg" and in the gradient, I don't feel like they're related enough to the quotation mark image color to reuse those custom props. So let's go to the actual SVG file to get the color itself. 40 | 41 | I'm going to use the Quick Open menu, and type in "quotation-mark" and go to the SVG file. I'm going to wrap the lines with Alt+Z. 42 | 43 | And, in the path element, at the end is the "fill" color. So I'm going to copy that hex code, and paste it in as the value for the "testimonial-icon" color. And let's convert it to HSL, by clicking the color swatch, and clicking the title bar. 44 | 45 | Alright, we have our colors, now let's actually use them in our styles. The background color I mentioned we want to set it on the "testimonial" class section tag. 46 | 47 | So under the custom props, I'm going to add "background-color" and then set it to "var(--testimonial-bg)". Next I'm going to set the text color with "color" and then we'll set it to "var(--testimonial-text)". 48 | 49 | And let's save our changes. Right now, we haven't actually changed any colors, and it might seem redundant that we're adding more styles setting the background color and text color to the same colors they were before. 50 | 51 | But this will make sense once we build out the dark theme styles, which we'll be doing next. 52 | -------------------------------------------------------------------------------- /01 - Basic Course/04 - Global Styles/07 - Responsive typography and media queries.md: -------------------------------------------------------------------------------- 1 | # Media Queries 2 | 3 | Also, if you're not really into the clamp() function or it just seems like too much for you right now, you can always go back and use media queries. I know that some people are against using media queries these days, especially for typography. 4 | 5 | But in my opinion, they still get the job done, and the code in your styles is reasonably understandable, even though it takes more lines of code. It won't fluidly scale as you increase the viewport width, but I don't think it matters too much. 6 | 7 | Let me show you how you could set up the font-size styles using media queries. So if I comment out the font-size rule using clamp(), we'll leave the fallback font-size as our mobile size. And let's convert that to use our rem() function, so it should say "u.rem(42)". 8 | 9 | Then we can add a breakpoint mixin and use "medium" for tablet styles, and set the font-size to something between 42 and 72 pixels, like 60px. Then we can add another breakpoint mixin for the "large" size and set the font-size to 72. 10 | 11 | So again, this approach isn't as nice and efficient as the fluid clamp() function, because it requires more lines of code. If we save, and check out the website, the font size will change as the viewport changes. 12 | 13 | You can see the breakpoints where the font size jumps in size, since it's not using the clamp() function which makes the font size change based on the viewport width as you change it. But it does work, and I think a lot of websites are still using media queries for font-size changes. 14 | 15 | I just wanted to show you both options so that you can understand how they work. I'm going to comment out the media queries and uncomment the font-size using clamp() since I do think it's a better solution. 16 | 17 | Let's now set up our font-size for the h2 tag, and use the Fluid Typography Calculator for that. Since you've seen me do it for the h1 tag, if you want, you can try to do it yourself for the h2 tag styles. 18 | 19 | In the design, the h2 tag will be the smaller headings, like in the magenta full width block where it says "Angel investment matching in real time." So you'll need to get the font size for both desktop and mobile, and put them into the calculator. 20 | 21 | If you want to try it yourself, you can go ahead and pause the video now, and then unpause when you're done to see if you matched what I will be doing. 22 | 23 | [ pause ] 24 | 25 | Ok! Let's set up the h2 font sizes. 26 | 27 | Looking at the design, the headline text on desktop is 48px. And if we go to the mobile design it is 36px. 28 | 29 | So, going to the calculator, we'll set the Min Font Size to 36px since that's what's on the mobile design, and we don't want the font size to be smaller than that. And the Min Viewport I'll set to the iPhone viewport width at 375px. Then the Max Font Size will be 48px, and I'll set the Max Viewport to 1200px. 30 | 31 | Then let's copy the two font-size rules and paste it in our code, in the typography.scss file, for the h2 tag selector. And I'll reduce the decimals to be two places so they're not so long. 32 | 33 | And if you want to use the rem() function so we still have the pixel numbers, you can replace the fallback font-size with "u.rem(36)" so it's 36 pixels converted to rems. And in the clamp() function the minimum number can also be "u.rem(36)" and the maximum will be the desktop font-size, "u.rem(48)". 34 | 35 | Alright! Now we'll need to update the index.html file to include an h2 tag. So let's go to Figma and copy that h2 text "Angel investment matching in real time". Then in our index.html file, I'll duplicate the section tag, then in the copy, change the h1 tag to an h2 tag, and paste in the h2 text. 36 | 37 | And in the website you can see the new section. If we inspect that h2 heading you can see the font-size getting set using clamp(). And let's check that the font sizes are working. 38 | 39 | So I'm going to click on the Computed tab, and when we change the viewport down to a mobile width we can see the font-size goes down to 36px. Then if we increase it to a desktop width it maxes out at 48px. So that all looks good. 40 | 41 | Let's go back to the design, to see what other h-tag styles we will need to add. In the 3-column Features section under the header, I think the title for each column can be set with h3 tags. So let's set those up as well. 42 | 43 | First let's go to Figma and check the font sizes on desktop and mobile for these h3 tags. I'm going to select the header for the first 3-column feature, "AI-powered matching". It's 24px on desktop, and on mobile it's also 24px. Since they're the same, we don't need to use a clamp() function, which is kinda nice because it's less work for us. 44 | 45 | In our typography.scss file, let's create a new selector for the h3 tag, and in it set the font-size to "u.rem(24)". Then we'll want to add more markup using the h3 tag so we can check that it's working. 46 | 47 | In our index.html file, I'm going to select the section tag with the h2, duplicate it with Ctrl-D, then replace the h2 tag with an h3 tag. And for the header text, I'll go to the design and copy the "AI-powered matching" text and paste it in the h3 tag. Now let's check out the website. 48 | 49 | If we inspect the h3 tag, we can see that the font-size is set to 1.5rem, and in the "Computed" tab it says 24px, which is what we want! So we should be all set for the header tag styles for now. 50 | -------------------------------------------------------------------------------- /02 - Premium Course/05 - Testimonial/03 - Second quotation mark.md: -------------------------------------------------------------------------------- 1 | ## Second quotation mark 2 | 3 | Now let's work on the second quotation mark. First, let's figure out what selector we need to use for this one. You might think that since we did "first-child" for the first quotation mark, we should be able to use "last-child" for the second one, since it's the last "testimonial\_\_icon" element in the section. 4 | 5 | In our styles, under the "first-child" pseudo-class I'll add a new selector, "ampersand colon last-child" and in it I'll add a test style of "outline: 2px solid red". 6 | 7 | Unfortunately, when we save, nothing happens. And if we inspect the second quotation mark, our selector and style rule aren't there. And this is because like I mentioned in the previous section, the first-, last- or nth-child selectors work by first finding the child element of the group of sibling selectors that matches the order number, and then seeing if it matches the class or other selectors you have in the styles. 8 | 9 | So in this group of sibling selectors that are children of the figure tag, the last child is the "testimonial\_\_author-wrapper" div. And since that doesn't have the "testimonial\_\_icon" class, the style isn't getting applied. 10 | 11 | But, we can use the "nth-child" selector to target the second "testimonial\_\_icon". This might a bit tricky, especially if you haven't worked with these child pseudo-class selectors, but based on what you know so far, why don't you pause the video and try to figure out how to target that second "testimonial\_\_icon" in the styles. 12 | 13 | [ pause ] 14 | 15 | Alright! To use the "nth-child" selector, we need to figure out what order the element we want to target is in. In the figure tag, if I count, it is the 1, 2, 3 -- the third child in the figure tag. So to target that, let's go to our styles, and instead of "last-child" I'm going to change that to "nth-child()" and in the parentheses type in "3". 16 | 17 | And now it has the red outline from our styles. One thing to keep in mind, in a lot of programming we start counting from 0. But in this case, we start counting from 1. So it can be slightly confusing, but I try to think about it like "first-child" means 1, second child means "2", third means "3" and so on. 18 | 19 | Let's go back to the design to figure out where we need to position this quotation mark. If I select the quote text, and hold down Alt, the second quotation mark is 40px to the right and 30px below the text. So very similar spacing wise from the first quotation mark, just in a different direction. 20 | 21 | Back in our styles, just to make things easier to see, I'm going to add an outline to the quote text too. So in the "&\_\_quote" selector I'll add "outline: 2px solid blue". 22 | 23 | Now, for the quotation mark, the first thing we'll want to do is turn it upside-down. We can do this with the "rotate" property, and turn it 180 degrees with "180deg". 24 | 25 | Now, let's align it horizontally. We want to first get it all the way to the right side. We could set "right: 0", and now the right edge of the quotation mark is lined up with the right edge of the quote text. However, another thing you could do is instead of the "right" property, use "left" and set it to 100%. 26 | 27 | This moves the quotation mark farther over, because with the "left" property, we're positioning the left edge of the quotation mark, and the 100% means we're moving it 100% of the width of the parent, the figure tag, away from the left side. Meaning it's moving to the right. 28 | 29 | And this is kinda nice because since it's lined up, horizontally we only need to move it 40px more to the right. So in the "left" property, we can use calc() again, and then set it to "calc(100% + 40px)". 30 | 31 | Now we need to position it vertically. Since we haven't set any "top" or "bottom", right now the quotation mark is positioned vertically in the same place it would have been if it wasn't position absolute, but it was in the normal flow of the document. 32 | 33 | What I mean by this is that if I inspect the quote text and hover over the markup, you can see it has a bottom margin pushing down the quotation mark. And in the "Layout" we can see that the margin is 40px. And for the quote text, if I set "margin: 0" to remove it, you can see that the quotation mark, as well as the author info moves up. 34 | 35 | I would like to move the quotation mark up so that its bottom edge lines up with the bottom edge of the quote text. Then we can move it down 30px. 36 | 37 | But how should we do this? We actually can't use the "bottom" property because that will align it relative to the parent, which is the figure tag, which includes everything, including the author info. 38 | 39 | I think the best option is to use "translate" to move the quotation mark up. In the browser, let's try setting "translate" to "0" because we don't want to move it horizontally, and then "-40px". So now it's aligned with the bottom edge. 40 | 41 | And I want to move it up the height of the quotation mark image, so we can do that by adding to the "translate" value. We can subtract 100% from our -40px to do that. So I'll add "calc()" and in it it'll be "calc(-40px - 100%)". 42 | 43 | And now the bottom edges are lined up, so we can move it down 30px to match the design. So in the calc() function, I'll make it less negative by 30px, to move it down 30px. 44 | 45 | Alright, that looks pretty good! So let's remove the outlines from the styles. And we are pretty set with the desktop styles. 46 | -------------------------------------------------------------------------------- /01 - Basic Course/10 - Full-width CTA/04 - Sass extend at-rule.md: -------------------------------------------------------------------------------- 1 | # Sass @extend at-rule 2 | 3 | As I mentioned, the Sass `@extend` at-rule lets you apply all the styles from a different selector to your current one. Let's go to VS Code and I'll show you how we can extend the Full-width Feature rules to the Full-width CTA section. 4 | 5 | In VS Code, I'm going to have the fw-cta.scss file open, and then also open the fw-feature.scss file. Then I'm going to right-click the fw-feature.scss file and select `Split right` to have it open on the right half of the editor. Then in the left half, let's have the fw-cta.scss file open. 6 | 7 | Now, let's decide which selectors from the Full-width Feature styles we want to extend to the Full-width CTA styles. The `fw-feature` class has the white text color, and the `text-align: center` styles that we do want to use in the CTA. So let's start there. 8 | 9 | On the left, in the `fw-cta` class selector, I'm going to extend the `fw-feature` styles by writing `@extend` and then the selector we want to get the styles from, `.fw-feature`. However, when we save, the Sass compiler throws an error, so let's take a look at that. 10 | 11 | In the terminal, the error is coming from the fw-cta.scss file, and it says that the target selector `.fw-feature` was not found. This is because we need to load the fw-feature.scss file as a Sass module in the fw-cta.scss file in order for it to be accessible there. This is similar to how we need to load the util styles with the `@use` at-rule at the top of all our Sass partials. 12 | 13 | Let's load the `fw-feature` styles. Up at the top, under the util `@use` at-rule, I'm going to write `@use 'fw-feature'`. The fw-feature.scss file is in the same folder as the fw-cta.scss file, so we don't need to navigate to a different folder, and we don't need to write the underscore or the `.scss` file extension, just the name `fw-feature`. 14 | 15 | And now when we save, the compiler is successful and there is no error, which is great! Another thing to note about the `@extend` rule is that unlike the util styles, which use the namespace `u`, we don't need to add any namespaces to load the `fw-feature` class in the `@extend` rule. This is because for `@extend` we only need to type in the selector, the `fw-feature` class, so I think Sass treats it differently from when we're loading named functions and mixins from other Sass modules. 16 | 17 | Ok, now that we've added our `@extend` rule, let's check out our website and see if it worked. And it looks like the styles were successfully extended to the Full-width CTA section-- the text color is white, and all the content is centered. If we inspect the section tag, in the style rules, we can see that using the `@extend` rule created a compound selector for both `fw-cta` and `fw-feature` classes, and they are both using all 3 style rules that were originally just for the `fw-feature` class. 18 | 19 | Then, the background with linear-gradient() is getting added over the magenta background-color. 20 | 21 | One thing to keep in mind if you use `@extend` to reuse styles is that when the Sass is compiled to CSS, the extended styles are located in the part of the stylesheet where they originated from. In our website, you can see this in the compound `fw-cta, fw-feature` selector-- Firefox tells us that it's coming from the fw-feature.scss file, which is where the original style rules are located. 22 | 23 | Let's find where these styles are in the final, compiled CSS file in the browser. Up at the top, where we have the `Inspector` tool loaded, I'm going to click that double right angle bracket and go to `Style Editor`. Here, we can see a list of all the CSS and Sass files that are getting loaded on the website. 24 | 25 | Let's click on the `style.css` file, which is our compiled styles. This is a pretty cool feature because we had minified our style.css file, but here in the Firefox Style Editor they've unminified it so the styles are more readable. 26 | 27 | Anyway, let's click into the editor and press Ctrl-F, and search for `.fw-feature`, and then press Enter. And here on line [XXX] we can see that compound selector for both `fw-feature` and `fw-cta`, with those 3 style rules that we extended to the Full-width CTA section. Now let's do another search, this time for `.fw-cta`. And here we have the styles from the fw-cta.scss file, all the way at the bottom of the stylesheet. 28 | 29 | The reason for this is because, if we go back to VS Code, in the scss/components folder, the index.scss file there is forwarding the `fw-cta` styles last after everything else. If we go to the fw-cta.scss file, it does seem a little weird to have the extended styles from `fw-feature` not load in the actual `fw-cta` class. 30 | 31 | But this is how the `@extend` at-rule works-- in order to share the styles, it will take the selector using the `@extend` at-rule, which in our case is the `fw-cta` class, and it will add it to the originating selector, the `fw-feature` class, creating that compound selector. 32 | 33 | One downside of extending styles from another selector is that you might end up extending some style rules that you don't really want or need in the target selector. In our case, the `fw-cta` selector is getting the magenta background-color from the `fw-feature` styles, but we don't need it in the Full-width CTA section. 34 | 35 | And this is just one style rule which isn't a huge deal, but depending on the styles in the originating selector, you might be porting over a bunch of styles that you don't need. 36 | 37 | One way around this problem is to use Sass placeholders. 38 | -------------------------------------------------------------------------------- /01 - Basic Course/11 - Footer/05 - SVG styles.md: -------------------------------------------------------------------------------- 1 | # SVG styles 2 | 3 | Ok, so we have the markup for the SVG working. However, it looks like the color is set to black, not the dark gray text color. So let's start working on the SVG styles. 4 | 5 | With SVGs you can set the color of the path or other SVG elements with a `fill` attribute. We didn't set one in our markup, so it is defaulting to black-- we can see this in the `Computed` tab, if we check `Browser Styles` and then filter for `fill`. The fill is set to `rgb(0, 0, 0,)` or black. 6 | 7 | We could add a `fill` attribute right in our inline SVG, but since it's an inline SVG we can actually target the `fill` in the path right in our styles. And since we have multiple SVGs it would be more efficient to do it that way. 8 | 9 | I think we need to add some more classes to the SVG elements. If we go back to the index.html file, I'm going to add a class to the SVG and the path in the SVG. For the SVG class, let's call it something like `footer__social`. And then the path inside it, I'll add a class and call it `footer__social-path`. 10 | 11 | Now, let's add selectors for both those classes in the `footer.scss` file. After the `footer__link` selector, I'll add `&__social` and we'll leave the selector empty for now-- we will add styles to that later on. But we do want to set the fill color of the path now. So after `footer__social` let's add another selector and we'll say `&__social-path`. 12 | 13 | And this is targeting the path, so in this selector let's add the `fill` property and I want to set it to the same color as the text links, so if we look above that is set to `var(--text-dark)` so we can write the same thing for the fill. 14 | 15 | Ok, now when we save, on the website, the Twitter icon is dark gray instead of black. And if we want to double-check, we can go to the `Computed` tab, make sure the `path` element is selected in the source code panel, and with `fill` in the filter, we can see that it is no longer black but dark gray. 16 | 17 | That looks good! However I'm noticing that when hovering, the SVG doesn't change color like the text does. And ideally, we'd like the icon to also change to magenta on hover. 18 | 19 | This is one reason why I wanted to use inline SVGs for these icons instead of using an image tag. We can change target the path in the Twitter SVG and change the fill color right in our styles. 20 | 21 | We wouldn't be able to do this if we loaded the SVGs in image tags, like we did for the unicorn or laptop SVGs. So that's one benefit to using inline SVGs like what we're doing here. 22 | 23 | Let's look in our styles to see where to add the hover state style for the SVG path. In footer.scss, if we scroll down to the `footer__link` selector, we do have a hover state already-- this is where we change the text link color to magenta. 24 | 25 | Ideally, I'd like to put the SVG path's hover state style in the same hover pseudo-class as our text color change, so that anytime you hover over the anchor link, both the text and the SVG icon will change colors. 26 | 27 | So I want to target the `footer__social-path` inside the same hover pseudo-class. Under the `color` style rule, I'm going to nest another selector, and we will have to manually type out the whole class, `footer__social-path`. Then we can add the `fill` property, and since we want it to be the same magenta color as the text, we can copy that `var(--text-link-hover)` and paste it in for the fill. 28 | 29 | Having to type out the `footer__social-path` selector again inside this hover pseudo-class isn't totally ideal. Unfortunately, we can't use the ampersand like the other BEM selectors, because-- 1) the hover state will mess that up, and 2) even if we didn't have the hover state, using an ampersand inside the `footer__link` class selector would load `footer__link` which isn't what we want. 30 | 31 | What we actually would need is a way to only load the BEM block name, `footer` so then we could tack on the `__social-path`. 32 | 33 | Aside from writing out the class name, one alternative that I've seen used a lot is to create a Sass variable up at the top right inside the `footer` class. We could call it `$b` for the block name. All Sass variables need to start with the dollar sign. Then we would set it to `ampersand` to load the parent selector, which is the `footer` class. 34 | 35 | Then, down in the `footer__social-path`, instead of writing out `dot footer` we could load the `$b` variable. Since we're using the variable in a selector name, we need to indicate that we're using the `$b` variable, we don't want a literal `$b` in the selector. 36 | 37 | Loading a variable's value inside of a string is what's called `interpolation,` and it's a feature of programming languages that we can use with Sass To interpolate in Sass, we need to put the variable in a `hashtag curly bracket`, with a closing curly bracket at the end. So now, we have `#{$b}` and then the rest of the class name, `__social-path`. 38 | 39 | This does work, and again, I've seen it used a lot when you have some nesting that's a bit tricky like when you're working with the hover state of a parent element. I think either is fine-- either using the variable like we have, or just writing out the whole `footer__social-path` class name, even though it is slightly duplicate work. 40 | 41 | Ok, let's save our changes and see if it works. And on our website if we hover over the Twitter link, the icon does change to magenta along with the text! So things look good. Alright, now that we have the inline SVG loaded and it has the hover state, let's make sure it's sized and also aligned the way we want with the text. 42 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/10 - Responsive typography.md: -------------------------------------------------------------------------------- 1 | # Responsive Typography 2 | 3 | Aside from layout, making your typography responsive is another big part of responsive design. I'm going to show you two different ways that you can do this. 4 | 5 | In VS Code let's go into the `globals/_typography.scss` file and add some font-size styles for our h1 tag using media queries. First we need to import the "util" module by writing up at the top "@use '../util' as u;" Then we can set a font-size for mobile, like let's say "font-size: 28px" and then add a media query with our u.breakpoint mixin for medium and up and set that at "font-size: 36px" and then another breakpoint for large and up set at "font-size: 42px". And we'll have to load the util Sass module up at the top so we don't get an error. 6 | 7 | Now looking at the website, the h1 tag, which is the "Mythos" title, is going to get larger as the viewport increases from mobile to tablet to desktop. This was pretty standard for sizing your fonts and I'm pretty sure some frameworks and websites still use this method. It works and it's fine, which is why I wanted to show this to you. 8 | 9 | Now there are a few ways that we can make the text responsive with just one line of code in our styles. One way we can do this is by using a unit in CSS called "vw" or viewport width. One viewport width unit is equal to 1% of the device's viewport. So on a mobile phone that is 375px wide, 1vw or viewport width unit is equal to 3.75px. On a large screen size that's 1920px wide, 1vw would be 19.2px. There is also a viewport height unit which does the same thing for the height of the viewport, but for our purposes here we will be using viewport width. 10 | 11 | If we want the final font-size to be around 28px for a mobile device that's 375px wide, we can divide 28 by 375 to see what percentage of 375 28 is. So we get 0.07466 which converts to 7.5% if we round up. So if we set the font-size to 7.5vw, it should be 28px for mobile widths, and it will go up as the viewport increases. Let's see what this looks like. 12 | 13 | In the browser we'll select an iphone emulator, then when we inspect the h1 text we can the final size that results in the computed tab. And it's telling us the font size is 28.1167px. It's note completely exact but it's pretty close. Let's see what it looks like at tablet widths-- now the viewport width of an iPad is 810px, so 1 percent of that is 8.1px times 7.5vw equals 60.75, which is what we see here. You might notice this is a little big. And if we go to a desktop width the h1 tag is getting really big. Probably way too big. And it keeps getting bigger if you have a large monitor. 14 | 15 | This is not really ideal behavior. We don't want the font size to increase this much so quickly as the viewport width increases. One way we can sort of limit the rate of growth is to involve another number that's not dependent on viewport size in how the font-size is calculated. And we can do this with the CSS calc() function. Calc() lets you combine numbers of different units which is pretty cool. 16 | 17 | In our styles, let's replace the 7.5vw with "calc()" and in it, I'll say "16px + 2vw". What's happening here is that the 16px ensures that the font size will always be at least 16px. And the viewport number is now smaller at 2vw versus the 7.5vw, so the increase in size won't be as dramatic as we go up to larger devices. 18 | 19 | At mobile viewports of 375px, the final font-size will be 16px plus 2 percent of 375, which is 7.5px. The final font-size should be around 23.5px. Let's see how this looks in the browser. Going back in our inspector, the h1 computed font-size is indeed 23.5px. Then on iPad it's 32.2px, which is bigger but not by as much as last time. And if we go to desktop viewport widths, the font-size is bigger , somewhere between 36px and on up. 20 | 21 | This looks way better than what we had before. There is one problem that you might have noticed, and that's that while we have that 16px to give a minimum size to the text, it will continue to get larger as the viewport increases. So on really large screens the headline may still end up looking a bit bigger than we want. 22 | 23 | But, there is a solution to this! And that is the CSS clamp() function. The clamp function allows us to set a minimum and maximum value to our preferred "16px + 2vw" value. So what we can do is write: "clamp()" and in the function it takes 3 parameters. The first is the minimum number that we want to allow, and we'll put in "28px". The second parameter is what's called the "preferred value" and this is where we'll put the "16px + 2vw" which is what we want ideally want to use for the font-size, as long as it's within the bounds we want. The last parameter is the maximum value we want to allow. I'll set this to 40px. And you might note that within clamp() we don't need to use the calc() function, as it does that for you automatically. 24 | 25 | Now, in the browser, we can see that even on really narrow viewport widths, the font-size will not go below 28px. And as the viewport increases, the font-size grows but won't get larger than 40px. This overall is a pretty good solution for responsive typography that doesn't require media queries, which is pretty awesome. I will say that clamp() is not perfect in 100% of cases. There may be some edge cases where you don't always want that sort of linear increase in font-size as the viewport increases. But if you ever have a case like that you can always fallback to media queries if you need to. Again they work just fine, it's just nice to be able to write something in just 1 line versus multiple lines. 26 | -------------------------------------------------------------------------------- /01 - Basic Course/10 - Full-width CTA/06 - Sass mixins.md: -------------------------------------------------------------------------------- 1 | # Sass mixins 2 | 3 | For our placeholder styles, we had put them in the globals folder. However, that meant that we had to add another `@use` at-rule to load the global styles. For our mixin approach, I think I might prefer to move the shared styles into the util folder, along with the other Sass mixins and functions. That way the styles will get loaded along with all our other utils. 4 | 5 | In VS Code, I'm going to select the fullwidth.scss file, and drag it from the globals folder into the util folder. Then I'll go into the globals/index.scss file, select the `@forward 'fullwidth'` at-rule, cut it, save the file, and then go to the util folder's index.scss file and paste it there. 6 | 7 | We can also now remove the `@forward globals` rule from the fw-cta.scss file, and also from the fw-feature.scss file. So let's delete those. Now, let's go to the fullwidth.scss file, and we're going to change it from a placeholder to a mixin. I'm going to replace the `%fullwidth` with `@mixin fullwidth`. So now we've created a new mixin called `fullwidth` and it will generate the same rules as we had before. 8 | 9 | Let's go to the fw-cta.scss file first, and in it, instead of the `@extend %fullwidth` rule, I'm going to change it to say `@include u.fullwidth`. And because the mixin lives in the util folder we do need to use that `u` namespace. 10 | 11 | We also need to make these changes in the fw-feature.scss file, so let's go there. And I'll change the `@extend %fullwidth` to `@include u.fullwidth`. Ok, now we're using mixins for these shared fullwidth styles. Let's make sure everything is saved, and the compiler has no errors, which is good, and let's check out the website. 12 | 13 | Let's check out the Full-width CTA section-- I'm going to inspect the section tag. And now in the Rules, we can see that the `fw-cta` class has the background-image rule that we set in the fw-cta.scss file. But in the same selector it also has the color and text-align rules from the mixin. And you might notice, there's no more compound selector. These shared style rules have essentially been copied and pasted into the selector where we included the mixin. 14 | 15 | If we go back to the fw-cta.scss file, we can see that in the `fw-cta` class selector, we added the `fullwidth` mixin which added those 2 share style rules, and then we added the background-image rule. 16 | 17 | Unlike with the globals placeholder approach, the styles from the mixin are getting added right where the selector using the mixin is located. Which is one benefit that mixins have over placeholders, because the shared styles aren't getting added in unexpected places in the final CSS file. 18 | 19 | Let's look in our style.css file and see how our final styles look with the mixin rules added. 20 | 21 | If I go to the `Style Editor` tool and select `style.css` and then click into the editor and do a search for `fw-cta`, we can see that all the Full-width CTA styles are located all together at the end of the stylesheet. And this is where they should be, because the fw-cta.scss file is the last Sass partial that is getting forwarded in our styles. And if we search for `fw-feature` we can see that it also has the 2 style rules for that class. 22 | 23 | Let me show you another cool thing you can do with the mixin approach. In the Full-width Feature section, if we inspect the paragraph tag, we added some styles to limit the width to 70 characters and center it with `margin-inline: auto`. I'd like to share that style with any paragraph tag that is in a fullwidth section. 24 | 25 | Let's go back to VS Code, and in the fw-feature.scss I'm going to copy the `&__description` selector and all its rules, and then cut it, and paste it in the fullwidth.scss file in the fullwidth mixin. And now, if we reload the website, in the Full-width Feature section we can inspect the `fw-feature__description` paragraph, and it has the styles from the `fullwidth` mixin-- the `margin-inline: auto` and the `max-width: 70ch`. And, if we go to the Full-width CTA section and inspect that paragraph tag, it also has the same rules since it's using the `fullwidth` mixin too. 26 | 27 | Going back to the fullwidth.scss file, what we did was add that nested selector for the parent, a double underscore, and then `description`. So when we include the mixin in the fw-cta.scss file, the parent selector is the `fw-cta` class, and it targets the `fw-cta__description` class which we've used in the paragraph tag. 28 | 29 | And in the same way, in the fw-feature.scss file, the parent selector is the `fw-feature` class, so it targets the `fw-feature__description` class. We could do the same thing for the `fw-feature__image` styles, since that also is getting centered with `margin-inline: auto`. 30 | 31 | So we can select the entire style rule, cut it, and then paste it in the fullwidth.scss file in the `fullwidth` mixin. So now, in future sections that are full-width and have an image, we can center both the paragraph and image elements in that section, as long as they have the proper BEM element name of `description` or `image`. 32 | 33 | Let's check the website to make sure the styles for the paragraph and the image are still getting added. Ok, and in the Full-width Feature section, the `fw-feature__description` class has the two styles, and the `fw-feature__image` has the `margin-inline: auto`. And in the Full-width CTA section, the `fw-cta__description` paragraph has the 2 style rules. 34 | 35 | So, that's how we can share styles using mixins. I feel like this is a good approach that doesn't do anything potentially unexpected like with placeholders. 36 | 37 | Next up, let's see how to share styles using helper or utility classes. 38 | -------------------------------------------------------------------------------- /01 - Basic Course/06 - Hero/16 - Optional Grid desktop layout.md: -------------------------------------------------------------------------------- 1 | # Optional: Grid desktop layout 2 | 3 | Alright, so for our desktop grid layout, the first thing we need to figure out is what our grid template should look like for desktop. In our design, we have our 2 columns, and like we mentioned earlier, the left column has the text and takes up 6 columns, then the unicorn is on the right and it takes up 5 columns. 4 | 5 | So even though we need to change the order of the image and text, we can handle that later. Right now we should create our desktop grid template based on what we see in the design. In our styles, in the `hero__wrapper` large breakpoint, I'm going to add `grid-template-columns: 6fr 5fr`. 6 | 7 | This is similar to what we did with the `flex: 6` and `flex: 5` style rules. But where in flexbox we were setting the flex growth rate, with CSS grid we're creating the number and size of columns. The `fr` or fractional unit will divide up the available space between the columns, with the first column getting 6 parts and the second column 5 parts. 8 | 9 | Let's save and see how that looks. And in our website, we have our 2 columns. The most obvious thing we want to fix is switching the unicorn image and the text placement. Fortunately, in grid (and also in flexbox) we can use the `order` property to assign an order to the child items. By default, `order` is set to 0 for all elements, and then it will follow the order based on what comes first in the markup. 10 | 11 | Let's make the unicorn second-- just in the browser, in the `hero__image` styles, I'll add `order` and set it to 2. And now we can see that the unicorn is in the second column. And the column sizes didn't change-- they're always going to be set at the 6fr 5fr sizes that we created in the grid template. We're only assigning which column the grid child items get put into. 12 | 13 | Since we didn't assign an order to the `hero__text`, it is at `order: 0`, so technically we could set the unicorn to `order: 1` and it will still come after the hero text, as you can see. But I think it's a bit more intuitive to set it to `2` to have it come second. This is just my personal preference-- `order: 1` works just as well. 14 | 15 | Let's add that to our styles, for the `hero__image` selector, large breakpoint. I'm going to add `order: 2` before the `width` property, because I prefer putting my flex and grid styles before the other styles. And save, and on our website, we can see the unicorn is on the right for desktop. And if we reduce the viewport, on mobile the layout goes to 1 column, and the unicorn is first. Looks good! 16 | 17 | Going back to desktop, there's one other thing I can see that we need to change. If you want, pause the video, and compare what you have on the website with the desktop design in Figma, and see if you can identify what we need to change. 18 | 19 | Ok, so the thing that I noticed is that we need to vertically center the content on desktop, right now, the hero text is up at the top, but we'd like it to be centered to where the unicorn is, since the unicorn is taller than the hero text. And we also want the unicorn to be vertically centered on smaller desktop viewports, where the text is taller than the unicorn image. 20 | 21 | Again, if you want to try this yourself first, see if you know what style rule to add and where, in order to vertically center the grid content. You can always use the CSS Tricks Grid Guide for reference to help you find the property you need. 22 | 23 | If we go to our styles, the most efficient way to vertically center the grid child items is to go to the grid parent selector, `hero__wrapper`, and add `align-items: center`. I'm adding this under `justify-items`. This is our default styles which will affect mobile, but I don't think it will cause any issues to do it here. 24 | 25 | And if we save, and look at the website, we can see that on desktop the hero text is now vertically centered. If we go down to a smaller viewport, we can see at one point that the text is taller than the unicorn, and here the unicorn is centered vertically to the text. 26 | 27 | One thing I'm noticing is that the unicorn seems smaller than it should be. If we check the desktop design, the unicorn is 483px wide. But on our website, it's only [XXX] pixels wide. So we need to look through the styles to see what might be causing this issue. 28 | 29 | If we inspect the unicorn image, in the `Rules` tab, the unicorn has the `max-width` and `width` style rules. And that `width: 62%` is probably causing the unicorn to be smaller than we want. If we uncheck that rule, then the unicorn gets bigger. We originally needed the 62% for mobile styles, so we'll need to cancel it out for desktop styles. One thing we could do is in the desktop media query, set `width` to 100% like we had in our boilerplate styles. If we do this, it will override the 62% width. 30 | 31 | I think that might be the simplest way to adjust the width when going from mobile to desktop, so let's go into our styles and do that. In the `hero__image` class selector, in the large breakpoint, I'll add `width: 100%`. And when we save, and in our website the unicorn is now the correct size of 483px. 32 | 33 | Ok, so let's refresh to get back to our saved styles, and do one more check of the hero section, on desktop. Looks good, we have the 2 columns and the text and image are vertically centered. And as we go to mobile widths we go to 1 column, with the unicorn on top, and centered horizontally. 34 | 35 | So the hero styles look pretty good. If this was a real work project, the next thing I would do before showing this to my team is to do one more check, a bit more detailed, to make sure that all the elements are the right size, color, etc., and that the spacing is right. 36 | -------------------------------------------------------------------------------- /03 - Ultimate Course/01 - TopNav and Hamburger Menu/11 - Locking scroll.md: -------------------------------------------------------------------------------- 1 | ## Locking the scroll 2 | 3 | One other common design pattern with mobile menus that I've seen is to prevent scrolling on the main website content when the menu is open. Right now, we can scroll freely, which could potentially cause confusion if you accidentally scroll to a different part of the website. 4 | 5 | On our website, you can still see quite a bit of the main site when the menu is open, but a lot of mobile menus will cover the entire viewport, so if you scrolled you wouldn't notice until you closed the menu and were suddenly in a different part of the website. 6 | 7 | And even in our case, I think it would be a better user experience if you weren't able to scroll when the menu is open. 8 | 9 | You can prevent scrolling by adding the style rule "overflow: hidden" on the body tag. By default, the "overflow" property, which controls how the website handles additional content that doesn't fit inside the element, is set to "visible". 10 | 11 | On the body tag, this will result in having vertical scrollbars if the content in the body is bigger than the viewport, like we have. [ scroll ] 12 | 13 | But, in the browser styles, if I go to the body tag and set "overflow" to "hidden", we are not able to scroll anymore, because all the additional content has been hidden. 14 | 15 | This is the general approach to locking scrolling on the overall website. However, by itself it doesn't always work, especially with different browsers and mobile devices. So in this case, I think the best overall solution is to use an existing plugin that specializes in locking scrolling. 16 | 17 | The plugin that I've found is called "body-scroll-lock". So if we search for "body scroll lock github" we should be able to go to the repo. And in the Readme, it has some of the reasons why this plugin will probably save you time and headache. 18 | 19 | So, to install this on our website, let's scroll down to "Install" and then "Usage examples" until we get to the "Vanilla JS". 20 | 21 | This tells us we need to load the JavaScript file in our head, and then it has code snippets that we can use. Let's get the file we need-- it says "/lib/bodyScrollLock.js". 22 | 23 | And for those of you who are more advanced in JavaScript, you might prefer to install this in other ways like yarn or npm. But I'm going to be showing you a more beginner-friendly way of doing it. 24 | 25 | If we go back up to the top of the page, we'll navigate to the file that they had in the example. So the "lib" folder, and then the file they showed us was "bodyScrollLock.js". If we click on it, you can see the contents of the file and all the code in it. 26 | 27 | However, they also have a minified version-- if I click on the left sidebar on the "bodyScrollLock.min.js" file, it's the same code but it's been minimized, so just really condensed down to as few code as possible. This will help save the load on your server when loading the website. 28 | 29 | So I'm going to download this minimized file. And in the gray bar, on the right side there is a "download" button. So let's click that to download the file. 30 | 31 | And I'm going to go to the File Explorer, and in the Downloads folder, I'm going to copy that file, and then navigate to the project root, then let's put it in the "app/js" folder along with our script.js file. And paste it in. 32 | 33 | Now that we have the file, we need to load it in our index.html. In VS Code, we'll go there, and up in the head tag, I'm going to duplicate the script tag that we have already, and in the first one I'll load the plugin, so that we load the plugin code before our own JavaScript file. 34 | 35 | I'll delete the file name and the last forward slash, then re-type the slash to get the autocomplete, and select the bodyScrollLock.min.js file. And save. 36 | 37 | Now we have the body scroll lock code getting loaded on our website, and we need to write the code to actually lock the body scroll. Let's go back to the plugin website, and let's find that example code that they had for Vanilla JS. 38 | 39 | Okay, so in here, it says we want to target an element that we want to allow scrolling in. I think this is more for modal or pop-up windows, but I think we have to put something there, so we'll probably use the "topnav\_\_menu". 40 | 41 | Then, to lock the body tag, we'll run this "bodyScrollLock . disableBodyScroll()" function, and in the parameter we'll have the "topnav\_\_menu". 42 | 43 | Then to unlock it we do the same thing except using the "enableBodyScroll()" function. And those are the only two we need. We don't need that last one since it's for canceling multiple elements that have been locked. 44 | 45 | I'm going to copy that "bodyScrollLock.disableBodyScroll" code, so we can paste it in our code. 46 | 47 | And going back to our JavaScript file, we want to first disable the scrolling when we open the menu. So in "openMobileMenu()" I'll add this line, at the end. And I'll set its parameter to "menuTopNav" since that's the element that is visible when the menu is open. 48 | 49 | Then, I'll copy that line and we'll do the reverse in the closeMobileMenu() function. I'll paste it in and then instead of "disableBodyScroll" I'll rename it to "enableBodyScroll" to unlock the body scroll. 50 | 51 | Now let's save, and see if it works! Alright, so on our website initially we can scroll. And if I open the menu, and try to scroll, I am not able to scroll. But if I close the menu I'm able to scroll again! 52 | 53 | So that worked really well, and I think is one good example of how using other people's code can save you time. I do recommend doing your due diligence before using other people's code-- check the GitHub Issues and even look for reviews of it to see if it works for people. 54 | -------------------------------------------------------------------------------- /01 - Basic Course/05 - Top Navigation/08 - Hover states.md: -------------------------------------------------------------------------------- 1 | # Hover states 2 | 3 | Let's talk about hover states. 4 | 5 | When you're working with links and things that are clickable, it's generally considered a good user experience to change their styles when you hover over them, in order to signify that they are links. 6 | 7 | We can do this by adding a "hover" pseudo-class to our selectors for the top nav links. 8 | 9 | Let's start with the logo. We usually want to add the hover pseudo-class on the anchor tag itself, because links are what you are hovering over. So for the logo that would be the `topnav__homelink` class. 10 | 11 | Inside the `topnav__homelink` selector, we can add the hover pseudo-class by writing a `&:hover` selector. Pseudo-classes are selectors that indicate some kind of changed state, and they are always written with a single colon and then the name of the pseudo-class. "Hover" is one of the most commonly used ones, but there are many others. 12 | 13 | Then in the curly brackets, we want to write our changed styles when you hover over the homelink. 14 | 15 | One common hover state style is to reduce the opacity a little bit on hover, so it looks semi-transparent. We can do this by adding the `opacity` property and then setting it to a number less than 1. 16 | 17 | The number 1 means it's 100% opaque, so totally solid and not transparent at all. If we wanted 50% transparency we would set it to 0.5. That might be a bit too transparent and not readable, so let's set it to 0.8 so it's 80% opaque or solid. 18 | 19 | Now if we save and check out the website, if we hover over the logo, it gets semi-transparent. That might be a bit too much, so let's debug this in the browser and figure out what we want the opacity to be. 20 | 21 | One really helpful feature when you're working on hover states is that you can force the browser to display different pseudo-classes like hover. In the inspector, I'm going to make sure the `topnav__homelink` anchor tag is selected in the source code panel-- NOT the `topnav__logo` image tag. It has to be the anchor link. 22 | 23 | Then in the "Rules" panel, at the top to the right of the "Filter Styles" there's a little icon that says ":hov". If you click that the browser will display checkboxes for different states that you can force. 24 | 25 | Let's click the ":hover" checkbox, and now the opacity has been reduced, and we can see in the "Rules" panel the `topnav__homelink` now has the "hover" pseudo-class added to the selector, and we can see the opacity property set to 0.8. 26 | 27 | I'm going to increase this a bit to 0.9, so it will be 90% opaque. And if we toggle the "hover" checkbox, we can see how it changes. I think 0.9 looks ok, so let's go back in the code and change opacity to 0.9. And when we save and reload the website, we can hover over the logo and it will change to the hover state style. 28 | 29 | Ok! The last thing in the desktop navigation that we're going to work on is the hover state for the text links. First, let's check what selector we need to use for the text links. 30 | 31 | If you want to try this yourself, you can pause the video here to figure out what class we want to target in our styles, and add the hover state pseudo-class to the correct selector in the `topnav.scss` file. 32 | 33 | Alright. So if we inspect one of the text links, the anchor tag has the class `topnav__link`. So in VS Code, in the topnav.scss file, we'll be adding the hover state to the `&__link` selector. 34 | 35 | So under the styles we already have in `topnav__link`, we'll want to add an "ampersand colon hover" and then curly brackets to contain the hover style rules. 36 | 37 | What I want to do is add a bottom border when you hover over the links. In the :hover pseudo-class I'll add `text-decoration: underline`. 38 | 39 | Now in the website when we hover over a link, a white underline appears. It's white even though we didn't specify a color, because by default the underline will be the same color as the text color, which is set to white. 40 | 41 | Let's force that hover state on the text links by making sure one of the `topnav__link` items is selected in the source coe panel, then clicking the ":hov" icon and then checking the ":hover" checkbox underneath. And now it should have that white border displayed. 42 | 43 | By default the text-decoration underline will be 1px of thickness. We can customize the look of the underline a bit with some additional properties. For example, if I want to make the underline thicker I can add `text-decoration-thickness` and then set a size, like 2px. 44 | 45 | I can also change the color of the underline with `text-decoration-color` and then add a color value. 46 | 47 | Another cool part of using CSS custom properties for our colors is that they will get loaded in the browser and we can use them when debugging. If I start writing `var(--`, once I start writing the two dashes, you'll see the options for the different custom properties that we created pop up. 48 | 49 | If I press the down arrow we can navigate through all the options from our CSS styles. I'll choose `--button-primary-bg` and press "Enter", and now the underline is the teal color. We might want a bit more contrast, so let's change it back to white. I'll select the text-decoration-color and retype `var(--` and then select `--text-light`. 50 | 51 | One more thing we can customize is the position of the underline itself. I'd like to move it down a bit so there's a little space between the text and the underline. 52 | 53 | We can do this with `text-underline-offset` and set it to 4px, so it will be moved down a bit from the link text. Looks pretty good! I'm going to copy the additional styles we added starting with `text-decoration-thickness` and paste them in our code. 54 | 55 | And when we save and reload the website, we have our underlines happening on hover. 56 | -------------------------------------------------------------------------------- /01 - Basic Course/01 - Getting Started/05 - What is Sass.md: -------------------------------------------------------------------------------- 1 | # What is Sass? 2 | 3 | Alright, so we've started setting up our project files and folders. Now let's talk about Sass. Obviously when making websites, we want them to look good, and the way we do that is by writing style rules in CSS, or Cascading Style Sheets. However, especially if you're building large and complex websites, your CSS files can get really long and convoluted. This is one reason why developers often write their styles in Sass! 4 | 5 | So what is Sass? Sass stands for "Syntactically Awesome Style Sheets" and is a CSS preprocessor. 6 | 7 | The Sass language has features that makes it easier and more efficient for developers to use. But since browsers can't read Sass directly, you need to compile or process your Sass files into CSS in order to work on websites. 8 | 9 | There are two syntaxes that you can use when writing Sass. The original syntax, just called "Sass," is similar to CSS but doesn't use curly brackets or semicolons, instead simply relying on indentation and new lines to differentiate your style rules. Files using this syntax have the extension `.sass`. 10 | 11 | SCSS is the more popular syntax and the one that we'll be using in this course. It is much more similar to pure CSS, and an added benefit is that any CSS style rules are valid in SCSS as well. This means you can copy and paste pure CSS into your SCSS files with no problem. SCSS files have the extension `.scss`. 12 | 13 | In this course I might say both "Sass" and "SCSS" when talking about styles, but just know that I'm always referring to the SCSS syntax when I do. 14 | 15 | So, what's so great about Sass? Well, here are some of the major features in Sass that, in my opinion, make it awesome. 16 | 17 | First off, Sass lets you separate your styles out into multiple files called partials. With partials, instead of having to search through one giant long CSS file, you can store your styles in separate files. For example, you can keep all the styles for your website header in the `header.scss` file, the styles for your sidebar in `sidebar.scss`, and so on. 18 | 19 | This helps a ton when you have to fix a bug in, say your footer. If you know that all your footer styles live in a file called `footer.scss`, you can locate it much more quickly and easily. 20 | 21 | You can also store your Sass files in different subfolders for additional organizing, which is great when you have a lot of files. 22 | 23 | Sass partials also make working on a team with other developers easier. Since the styles are all in separate files, it reduces the chances of someone else working in the same file at the same time as you are, and creating a potential code conflict. 24 | 25 | One of my favorite Sass features is the ability to nest your style rules. This means that you can put a child style rule inside the style rule of its parent. This maintains the specificity of the child selector without having to keep typing the parent selector out. It may not be a big deal for one child element, but if you have dozens of child classes, this will save a lot of needless typing and repeating of the parent class! 26 | 27 | There's also the ampersand symbol which is a shorthand that refers to the parent selector. The ampersand combined with nesting helps a lot to reduce the amount you have to type, and it's awesome when you're writing styles in the BEM or block-element-modifier system. 28 | 29 | If you're not familiar with the BEM format, that's totally fine-- I'll be showing you how BEM works in the "Intro to Sass" section of this course. 30 | 31 | Mixins are another great feature of Sass. You can use mixins to create sets of style rules that you want to reuse with the `@mixin` at-rule, and then reuse those rules anywhere else in your styles. 32 | 33 | Before CSS custom properties came on the scene, Sass variables were a huge plus that let you store values for fonts, colors, and other properties. Nowadays, I've switched my Sass variables over to CSS custom properties for many cases, especially colors. But I'll still use Sass variables for a few things in this course. It may come in handy in case you have to work with a project or a framework that uses them. 34 | 35 | Again, for each of these features that I've talked about we'll be going how to use them in more detail later in this section. 36 | 37 | Alright, so we've talked about the great points of Sass and why I love it. But there is one main downside to using it. And that's that you need a tool of some kind to compile your Sass files to CSS. Whereas if you use pure CSS you can immediately load it in the browser and it works fine! 38 | 39 | In my opinion, the benefits far outweigh the costs. And adding knowledge of Sass to your resume will always help you when you're searching for a job. 40 | 41 | In the next section I'm going to cover two options that you have in this course for compiling Sass. 42 | 43 | The first option is more beginner friendly, using the VS Code Live Sass Compiler and Live Server extensions with just a little bit of customization in the settings. These extensions are a great tool for when you're just working locally in your own projects and need to compile Sass with minimal setup involved. If you want to follow this beginner route, go ahead to the video on the Live Sass Compiler. 44 | 45 | The other option is more advanced, using a Gulp workflow that will require you to install npm packages and run scripts on the command line. There is a lot more setup involved in this, but it's closer to what you would be doing in the real world for development and deployments. If you want to follow that more advanced route, go ahead to the videos on npm and Gulp. 46 | 47 | Feel free to choose the option that feels most comfortable for you at this moment. If you go the beginner route first, you can always come back later on and try the more advanced route. 48 | 49 | So let's get into the Sass compiling! 50 | -------------------------------------------------------------------------------- /01 - Basic Course/11 - Footer/06 - Sizing and aligning the SVG.md: -------------------------------------------------------------------------------- 1 | # Sizing and aligning the SVG 2 | 3 | Right now the SVG is just taking the same size as the `Twitter` text, which we will need to change. Let's first check the size of the social media icons in the design. In Figma, I'm going to zoom in on that `Follow` column so we can see everything better. 4 | 5 | If I select the Twitter icon, it's 18px wide and 15 pixels tall. Let's check Facebook, and that icon is 18px wide also, and 18px tall. Then Instagram is again 18px wide, and about 18px tall. And YouTube is 18px wide and 12.66px tall. 6 | 7 | They are all 18px wide, which was on purpose on my part in the design. You do want the icons to be the same width, so that it makes the text to the right all aligned the same way. If one of the icons was a different width then it could throw off the alignment. 8 | 9 | Anyway, since they are all the same width, we can add that 18px width as a style rule for all the social media icons. Going to our styles, in `footer__social` I'm going to set `width` to `u.rem(18)`. 10 | 11 | And unlike with the image tags, we don't actually need to set `height: auto` on the SVGs in order for them to have the correct aspect ratio. It's another interesting quirk of SVGs when they have a viewbox set-- the image itself will always maintain the correct aspect ratio, so if we change the width, the height will automatically adjust. 12 | 13 | And now when we save and go back to the website, we still have the scaled up browser font size, so we have big text, and the Twitter icon is also now bigger, which is great. Let's change that font size back to the default of 16. 14 | 15 | We also need to check on the alignment and spacing. I'm actually going to zoom in on the browser so it's a bit easier to see. If I hover over the SVG in the source code, with the grid lines we can see that the icon is a bit taller than the text, and it's kind of extending above the text. Ideally the icon and text should be vertically centered to one another. 16 | 17 | Looking at the markup in the source code, the flex parent should be the `footer__link` anchor link, and the flex children will be the SVG and then the `Twitter` text. 18 | 19 | Let's start writing our flexbox styles. In footer.scss, in the `footer__link` selector, I'll change `display: inline-block` to `display: inline-flex`. This is because if I set it to `display: flex`, the link will go all the way across and make not just the text clickable but also the empty space to the right. So inline-flex behaves pretty much the same as flex, except that it will only take up the amount of space as its content. 20 | 21 | And under that, I'm going to add `align-items: center` to vertically center the flex children. The other thing is that we want to add some space between the icon and the text, and I think a great way to do that is with the `gap` property. So let's check the design to see how much space there is. 22 | 23 | In Figma, if I select the Twitter icon and hold down Alt, there is 16 pixels of space between the icon and the text. Going back to our styles, still in the `footer__link`, I'll add `gap: u.rem(16)` to add the space. 24 | 25 | Let's save that and see how things look on the website. It looks pretty good! We have the space between icon and text, and if I hover over the `footer__link`, they also seem vertically centered to one another. So that works using flexbox. 26 | 27 | We can also do this with grid. Just in the browser I'm going to change the `display: inline-flex` to `display: inline-grid`. And inline-grid is the same as inline-flex, in that it behaves the same as `display: grid` but the grid container won't take up all the available horizontal space, it will only be as wide as the grid content. 28 | 29 | And with grid, we do need to set `grid-template-columns`, otherwise like you see here, the grid children won't automatically be on the same row like you do have with flexbox. We can add `grid-template-columns` and to make it simple I'm going to use the repeat() function, set it to `2` for 2 columns, and set the width of each column to `auto` so that they will be the width of the content. 30 | 31 | And now it matches the design-- we have the same gap as we did with the flexbox approach, and things are vertically centered. Again, you can use whichever approach you like the best-- in this case I think flexbox is easier because you don't have to write that additional line of code to set the grid template the same way you would with the CSS grid approach. 32 | 33 | Let's refresh to go back to our saved styles using flexbox. I think we're pretty good with the social media icon styles, so let's update the markup to add the other icons. Going back to VS Code, we have the index.html file. And let's get the SVG code for the other icons, starting with Facebook. 34 | 35 | I'm going to open the primary sidebar and in the img/social folder, we'll open the `facebook` SVG and then copy that code. And then I'm going to paste it inside the `footer__link` anchor link before the `Facebook` text. 36 | 37 | The next one is for Instagram, so I'm going to open the instagram.svg file, copy the code, and paste it in before the text. And let's open the last one, for YouTube, copy the code, and again paste it in before the text. 38 | 39 | We do need to add the `footer__social` and the `footer__social-path` classes to all the SVGs and paths too. I'm going to copy the whole `class=footer__social` from the Twitter SVG, and then paste it in after the `viewBox` for all the other SVGs. And then go back to the Twitter SVG path, copy the `class=footer__social-path` and then paste it in each of the other paths. 40 | 41 | And now let's save, and on the website we can see we have all the social media icons loaded and if we hover over each `Follow` link they all have the magenta hover state. Ok, so the `Follow` column should be all set now. 42 | 43 | Next up, let's get the layout working with CSS grid! 44 | -------------------------------------------------------------------------------- /03 - Ultimate Course/03 - Blog Posts/06 - Layout styles.md: -------------------------------------------------------------------------------- 1 | ## Layout styles 2 | 3 | Now that we have the card styles pretty much set, let's start looking at our layout. 4 | 5 | In the design for mobile the cards are all in 1 column, and then on desktop, we have the cards in 3 columns. To build a grid of block items like these cards, I think using grid and auto-fit would be a really good solution. 6 | 7 | I wouldn't really build this with flexbox, because while it is possible to get it to work, we're really trying to get these cards to conform to the 1 column or 3 column layout. When you have a specific layout requirement and you're trying to get the content to conform to it, grid is usually going to be the way you want to go. 8 | 9 | Flexbox is good when you just want to fit the content into the available space, and you don't care as much about the specific sizing or layout arrangement. 10 | 11 | Let's look at the website to see where we're at with the layout so far. Right now, each "blog\_\_item" card is a child of the "blog\_\_grid" div which we've made the grid parent. Things look good on mobile, but if we increase the viewport width, the cards will still be in the 1-column default layout and take up 100% of the width. 12 | 13 | So for wider viewports, we want to go into multiple columns. Let's start this by writing "grid-template-columns" so we can change our grid template. 14 | 15 | What do we want to set this to? Since the columns are all going to be the same width, we can use the "repeat()" function. This is going to be similar to what we did in the footer, where we used the repeat() function to have 2 columns on mobile and 4 columns on desktop. 16 | 17 | Let's start by creating 2 columns, and set it to "repeat(2, 1fr)", so we'll have 2 columns and divide the available width between them. 18 | 19 | Now when we save, on the website for mobile, we have 2 columns. Things do look squished for now. But as the viewport keeps increasing, we stay on 2 columns and the cards get wider. 20 | 21 | So how do we go from 1 to 3 columns? On the footer, we used media queries to switch between repeat 2 and repeat 4 columns. 22 | 23 | However, here I'm going to show you a more advanced method of going to multi columns without needing media queries. I'm going to change the number of columns from "2" to a new value called "auto-fit". 24 | 25 | Auto-fit is a really powerful feature in CSS grid that lets the browser decide the number of columns that can fit in the available space. But you can't just use it by itself-- if we just leave the styles like this and save, on the website the layout will only be 1-column, no matter what width we're at. 26 | 27 | This is because we set the column size to be 1fr, meaning it'll take up all available width. So the browser will only be able to fit 1 column on the available space. 28 | 29 | What we need to do is to instead of just having 1fr as our column width, to use another function in CSS grid called "minmax()". Minmax() takes two parameters, a minimum number and a maximum number. 30 | 31 | In order for it to work, you want to have one of the numbers be an absolute number, like 300px, and have the other one be a relative number like 1fr, auto, or a percentage. 32 | 33 | This can be hard to wrap your head around if you aren't super familiar with minmax(), but I'll show you how it works. Let's replace the 1fr value with minmax(). Then in the function, let's make the min number "u.rem(300)" for 300px, then add a comma and set the max number to be 1fr. 34 | 35 | What this will do is tell the browser that the cards have to be at least 300px, and then it will fit as many columns of 300px width onto the row. Then if there is any available space, it will allow the columns to grow to take up all available space in the parent. 36 | 37 | So when we save, let's go to the website and start with mobile. And I'm going to inspect one of the blog\_\_item elements and go to the Layout tab so we can monitor the width of the columns as they change. 38 | 39 | So on mobile the columns are 327px wide. And now let's drag out the right edge right until we hit that 700px breakpoint. And that is about... here. 40 | 41 | In the Rules tab we can see our grid template columns and auto-fit getting applied now, and we have two columns. And each column is [xxx] pixels wide. So the browser is starting with that 300px width and is able to fit 2 columns in the row, and since there's a little space left, each column grows to fit so all available space is taken up. 42 | 43 | Now let's keep increasing the viewport width. So the columns are progressively growing wider, and then once the browser can fit 3 columns of 300px wide at [xxx] wide, it changed the layout to be 3 columns. 44 | 45 | And if we can get at the exact breakpoint where the layout changes, if we inspect one of the blog\_\_item elements, we can see that they are exactly 300px wide, which is again coming from our minimum width that we set in the minmax() function. 46 | 47 | Then as we keep increasing the viewport width, the columns increase. And then when we max out the wrapper class at 1200, the entire content doesn't grow anymore, and we are left at 3 columns wide. 48 | 49 | This is just really cool that we can get a bit more flexible with CSS grid layouts, all with that one style rule for all devices. 50 | 51 | The cards are looking pretty good! However, I'm realizing that the title is supposed to be centered. If I go back to Figma and check, it is centered on both mobile and desktop. 52 | 53 | [ Center text with "fullwidth" class, create "fullwidth dark" class to use for FW Feature and FW CTA to have "color: var(--text-light)" ] 54 | 55 | However, one thing that I'm noticing is that because the gradients are all the same, it's making the cards look a little bit too same-y or monotonous, just from a design perspective. It looks a bit weird seeing the gradient cross cards going down. 56 | 57 | So next up we're going to try to add a little variation in the gradients across the different cards. 58 | -------------------------------------------------------------------------------- /01 - Basic Course/09 - Testimonial/05 - Quote and author styles.md: -------------------------------------------------------------------------------- 1 | # Quote text styles 2 | 3 | Next up is the quote text styles. Going into Figma, let's start with the mobile styles, and select the quote text. It's the same font-family that we've been using, Source Sans Pro, and it's bold and font-size is 24px. The line-height is 30px, and in our calculator if we divide 30 by 24 we get a line-height of 1.25. 4 | 5 | Then in the desktop version, we have a font-size of 36, and line-height of 45. If we divide 45 by 36 it's also 1.25. And the other font-styles are the same. The color is the dark gray that we have as our default text color. 6 | 7 | Let's go to our styles, and I'm going to go to the index.html file and check what selector we need to use. The blockquote tag has a class of `testimonial__quote`, so going into our testimonial styles, we'll be using the `quote` selector. 8 | 9 | I think I'm going to use the Fluid Typography Calculator to generate the font-size, so let's add the other styles. I'll add the `line-height: 1.25`, and then the text is bold, so I'll add `font-weight: 700`. And now let's get our font-sizes. 10 | 11 | Let's plug in those numbers. I need to refer back to the design-- the mobile font-size is 24 and the desktop font-size is 36. So I'll set the `Min Font Size` to 24px, and the `Max Font Size` to 36px. 12 | 13 | And now we'll copy the Result, and go back to VS Code and paste it in at the top of the `quote` styles. I'm going to round the decimals to 2 places to 1.16rem and 1.45rem. And now let's save, and check out the website. And the text looks good-- in the rules we can see our clamp() function for the font-size, and in the `Computed` tab I'm going to filter for `font-size` and we can see it's 36px for desktop. And when we slide over the dev tools panel it decreases until we hit 24px for mobile widths. 14 | 15 | Next, we need to add space under the quote text before the author photo. Going to the design, it looks like we have 40px of space on desktop, and on mobile we also have 40px. That makes things easier since it's always going to be the same. Going back to our styles, I'm going to add `margin-block-end` and set it to `u.rem(40)`. And now on our website we have that space under the quote text. 16 | 17 | Now, let's look at the author info. The author photo is 120px wide and tall, and it is a circle. 18 | 19 | I think we're good with just having the width set, and the height set to `auto` so that the full image will be displayed and it won't have to be constrained to a square. Let's refresh to get back to our saved styles. 20 | 21 | The next thing we wanted to do is to make the author photo a circle. We can actually accomplish this with the `border-radius` property. With border-radius, you can set it to a static length like 1rem. But to make a circle you want to set it to half the width or height, since we have a square image. And the easiest way I've found is to set it to 50%. And an added benefit is that if we change the image styles to be a different size than 120px, it will still be a circle-- assuming the image is a square. With a rectangular image, it would be an oval instead. 22 | 23 | So, let's add the `border-radius: 50%` rule to our styles. I'll go to VS Code, add `border-radius: 50%` to the `author-image`, and then when we go back to the website, the photo is a circle. Looks good! 24 | 25 | The last element in the Testimonial section is the author info. In the design, let's see what font styles we'll need to add. In the desktop design, the font-size is 24px, and the line-height is 31px, which, if we get the calculator, is 31 divided by 24, which is around 1.3 line-height. Then on mobile, we have a font-size of 20px, and a line-height of 26px. And if we divide 26 by 20 we get also 1.3. 26 | 27 | Ok, so the font-size is 20px on mobile and 24px on desktop. I know we made some global paragraph styles earlier, so let's see if the author info will match any of those. In VS Code, the paragraph styles are in the globals/typography.scss file. And if we check out the paragraph tag selector, we have the `medium` class. If we look at the clamp() function, the minimum font-size which is what will be used for mobile, is 20px, and the maximum font-size, which is what desktop will use, is 24px. And all paragraphs have a line-height of 1.3. So we should be able to use these styles by adding the `medium` class to the paragraph tag. 28 | 29 | Going to the index.html file, the author info is in the `figcaption` tag we created. And we didn't add a paragraph tag in the figcaption, but I think it's ok to add one nested in the `figcaption`. And then I'll take the text and move it into the paragraph tag. And so that the styles get added to the paragraph too, I'll cut that whole class from the figcaption and paste it in the paragraph tag. I think all the styles we need will be in the `medium` class, so let's add that to the paragraph tag. But I'll leave the `testimonial__author-description` class there for now, just in case we do need to add some Testimonial-specific styles to the description. 30 | 31 | And let's save, and on the website we now have our author info styles. Let's inspect the paragraph, and it looks like it has a bottom margin, which we don't want because it will offset when we try to vertically center it with the author photo. So I'm going to go back to our styles, and in the testimonial.scss file, in that `author-description` class selector, I'll add `margin-block-end: 0`. So it's good that we kept that paragraph selector. 32 | 33 | Now let's save, and back on the website, the paragraph doesn't have a bottom margin anymore. 34 | 35 | Ok, now that we have the styles set up for the Testimonial class elements, let's work on the responsive layout for the author photo and info. Looking at the design, on desktop we have the author photo on the left and the author info on the right, and they are vertically centered. And on mobile, we have them stacked to 1 column, with the author photo on top and the author text under it. And both are horizontally centered. 36 | -------------------------------------------------------------------------------- /01 - Basic Course/08 - Full-width Feature/03 - Paragraph and image styles.md: -------------------------------------------------------------------------------- 1 | # Paragraph and image styles 2 | 3 | Next up, let's check the paragraph styles. In the design, the desktop paragraph is 24px, and the line-height, which we should also check, is 31.2. Let's check the calculator, and divide 31.2 by 24 to get 1.3. The mobile paragraph is 20px font-size and 26px line-height. Using the calculator again, 26 divided by 20 is 1.3 also. 4 | 5 | Let's compare that with what we have on the website right now. If I inspect the paragraph, it is 1.125rem, which, if we go to the `Computed` tab, is 18px. And that's set in the typography.scss file. Going to VS Code, in the typography.scss file, we have some paragraph styles that we set up previously. What we want is on mobile to be 20px, and 24px on desktop. So we may have made the styles we need already. 6 | 7 | The default paragraph font-size is 18px, which is too small. It does have the right line-height, 1.3. Then we have a `medium` class, and if we look at the clamp() function, the first parameter is the minimum size, and that's 20px. And the last parameter is 24px. So that's actually the correct sizes for what we need. We should be able to just add that `medium` class to the paragraph in our index.html file. 8 | 9 | In our index.html file, I'm going to add `medium` to our paragraph class. And it doesn't matter too much where you put it in the order. Cool, so let's save, and now in the website in the `Computed` tab we have 24px font-size on desktop, and if we go down to a mobile width, it'll decrease until it gets to 20px. 10 | 11 | So that's the paragraph font styles all set. We also want to check the `margin-bottom` or `margin-block-end` of the paragraph. In the design, on desktop, the paragraph has 40px of space under it, and on mobile it also has 40px of bottom margin. On the website, the paragraph doesn't have any margin-bottom rules, so we'll need to add that. And I think I'll add it to the `medium` paragraph styles. 12 | 13 | So in VS Code, in the typography.scss file, in the `medium` class paragraph I'll add `margin-block-end` and set it to `u.rem(40)`. And now on our website we can see that new rule, and in the `Layout` tab we can confirm that it is 40px. 14 | 15 | Let's now compare what the design and the website look like, to see what else we need to style. The next thing that jumps out at me is the paragraph text is really long. If I look at the design, the paragraph doesn't go wider than the title text. So we'll need to limit the width, probably with a max-width property, like what we did for the 3-column Features description. 16 | 17 | Let's see what we did there. I'm going to inspect one of the 3-column descriptions, and it looks like we have a max-width set to 50ch or characters. Let's try that, just in the browser, for the Full-width Feature paragraph. I'm going to add `max-width` and set it to `50ch`. 18 | 19 | Ok, the paragraph is narrower, maybe a bit too narrow, and it's positioned to the left side of the wrapper. It's not centered because the paragraph tag is a block element, which means that the `text-align: center` rule won't affect it. 20 | 21 | So similar to the image which we set to `display: block`, we'll need to center the paragraph tag with `margin-inline: auto` to set the left and right margins to auto, which will make the margins equal widths, resulting in a centered paragraph. Now that looks good, let's tweak the max-width so it's a bit wider. I'm going to go up by 10 by clicking into the number, holding down Shift, and pressing the up arrow key a couple of times. Ok, 70ch actually looks pretty good. If we go to the design it looks very close to what we have here. So I'm going to copy those two rules we added in the browser, and I'm going to add them to our Full-width Feature styles. And that class for the paragraph is `fw-feature__description`. So in our fw-feature.scss file I'll paste it in there. And now let's save, and on the website the paragraph looks good! And as we decrease the viewport width, the text content gets narrower, and that looks good. 22 | 23 | Let's just double-check that we do have the laptop image at the right size for mobile. In the design it looks like it's going all the way to the left and right edges of the wrapper, and if I select it, it is 327px. Back in our website I'm going to turn on Responsive Design Mode and in iPhone mode inspect the laptop image. And it is 327px wide. So we are all good with the laptop image. 24 | 25 | We've gone through all the parts of this Full-width Feature section. Let's go back and do one more check to make sure that it matches the design. The desktop design and desktop website look good. And if we go to mobile on the website, and then look at the mobile design, those look like they match as well. 26 | 27 | Lastly, let's go back into our code and see if there's anything that we need to clean up. In our fw-feature.scss file, we didn't add any styles for the `wrapper` or `title` BEM elements. So I will delete those selectors since you don't want to have any empty selectors in your styles. It won't cause an error, but in general it's considered good practice to not have them. 28 | 29 | This section was a lot easier to build than the last one-- it was a simpler design instead of having to figure out the 3-column layout. 30 | 31 | And, since we used shared styles from the utility classes like the `wrapper` class, and global styles like our typography styles for a lot of the styles in this section, we didn't have to write that many styles specific to the Full-width Feature. Which makes things more efficient. That is one nice thing, as you build the website some things will get quicker if you're using shared styles like we have. 32 | 33 | Ok! Let's commit the changes that we've made to GitHub. In GitHub Desktop, I'm going to go to make sure we're in the `Changes` tab, do a quick check of the files that were changed or added, and yep, it looks like we want to commit all those changes. So in the bottom I'll write a commit message that says `Full-width Feature` and click `Commit to main` and then `Push origin` to push the commit up to GitHub. 34 | 35 | And next up, we'll be working on the Testimonial section! 36 | -------------------------------------------------------------------------------- /01 - Basic Course/02 - Intro to Sass and Responsive Design/18 - Helper and utility classes.md: -------------------------------------------------------------------------------- 1 | # Helper/Utility Classes 2 | 3 | And, since there's always more than one way or even more than two ways of accomplishing something, I'm going to show you one more approach that you can use when writing styles for different `themes` of elements. And that is helper or utility classes. 4 | 5 | Going back to our `_grid.scss` file, I'm going to delete this placeholder and move the padding style rule back to the `.grid__widget` class selector. And I'll delete the `@extend` rules in the `magenta` and `green` modifiers as well. Now we're back to having our generic widget styles of the padding in the `grid__widget` selector. 6 | 7 | And instead of using the `modifier` selectors for the magenta and green themes, I'm going to replace them with a whole new class selector. So `&--magenta` will become a `&.magenta` class and `&--green` modifier will become a `&.green` class. The reason we still need that ampersand is because the final selector will be `.grid__widget.magenta` with no space between the `grid__widget` and `magenta` classes. This selector will then look for an HTML element that has both classes `grid__widget` and `magenta` in the same element. If we had a space between `grid__widget` and `magenta` it would look for an element that has the class `magenta` that has a parent element of `grid__widget`. So not having the space means both classes are in the same element, and having the space means the classes are in a parent then a child element. And that's a pure CSS feature, not only in Sass. 8 | 9 | So in our HTML we'll update our classes. So in the first widget, we still want `grid__widget` as a class to get those generic widget styles. But then we can also add a `magenta` class to this element. And we can do the same for the green widget so that the element has the classes `grid__widget` and `green.` And we'll do the same for the third widget. Now in our website the widgets are all looking the way that they should. If we inspect that first widget, we can see in the Rules that the padding is coming from the `grid__widget` class, and the background-color is coming from the `magenta` class. And the same is true for the green widget. 10 | 11 | The `magenta` and `green` classes in this example are what we call `helper` or `utility` classes. This means that the class name has one or just a small number of style rules associated with it that are implied in the class name. One cool thing about utility classes is that they can be reused simply by adding that class name to elements. If we wanted to be able to reuse the magenta and green background colors for elements outside the widgets, we could move them to an entirely new Sass file. 12 | 13 | For example, we can take the utility clases from `_grid.scss` and move them into our `globals/_colors.scss` file. And we don't need the ampersand anymore since they're not nested in a parent selector, so it will just be `.magenta` and `.green`. 14 | 15 | Now in our website the widgets are taking the correct background color and the background colors are no longer associated with the widget styles but just the `magenta` and `green` class names. What's cooler is that we can now use these utility classes to apply styles simply by editing the HTML, and not having to touch our styles at all. So if we go into our index.html file and switch the magenta and green class names in our widgets, they will change and we didn't need to modify our styles at all. 16 | 17 | And we can even use the helper classes in the main element. I'm adding the `magenta` class to the `grid__main` element. However, the main is still blue if we load the website, even though we can see the magenta class name. What's happening is that even though the two style rules are both on style classes, meaning they have the same level of specificity, the utility classes are getting loaded first in our globals, and the `grid__main` styles come later on in the style.css file. This makes the `grid__main` background-color rule override the magenta rule. And we can see that in our inspector, which is why the `magenta` rule is getting crossed out. 18 | 19 | So if we did want to be able to control the background color of the main element, I would just remove the blue background-color from the `.grid__main` selector. And perhaps add it as another utility class of `blue` in the `_colors.scss` file. Now when we load our website the main element is magenta. And if we wanted to change it to blue we could simply replace the `magenta` class in `grid__main` with `blue`. And voila, it is changed. 20 | 21 | Since utility classes are reusable, they are a nice way to let you modify the styles without needing to keep creating new style rules. This comes in handy especially if your website uses a CMS or content management system like Wordpress. You can customize the website code so that you can set CSS classes on elements directly from the CMS. This is great if you're working on a team or have a client, and want to allow non-developers to make limited changes to the website without having to request a web developer to make the change in code and then having to deploy it. 22 | 23 | If you have a whole system of utility classes to control things like flexbox and grid layouts, background colors, and font sizes and styles, it also makes building new pages in an existing website easier because so much of the work to create the new page has been done already, and you can just add the utility classes that you need to the new page. This is exactly what utility-first frameworks like Tailwind are trying to do-- they're essentially a whole web design system and they let you build pages and elements from existing styles that they've created. All you have to do as the user is add the proper classes to the HTML elements. 24 | 25 | It is a different approach to building websites-- I know it's not for everyone. And if you're building a website from a completely custom design then you will still have to write all the styles to match that design. I personally like using a combination of mostly BEM with some utility classes. And you'll see more of this as we build out the actual course website later in this course. 26 | -------------------------------------------------------------------------------- /01 - Basic Course/05 - Top Navigation/02 - Creating a skip link.md: -------------------------------------------------------------------------------- 1 | # Creating a skip link 2 | 3 | Now, let's start writing the HTML markup for the top navigation. One thing that's good for accessibility is to add what's called a "skip link" to the top of the page. This will allow screen reader users and users who use only a keyboard to skip over the header and get right to the main content. 4 | 5 | If there is no skip link, these users will need to manually go through every navigation link before they hit the main content of the website. We don't have a lot of links in our navigation, but for websites that have huge menus with lots of links, having to go through every single one would be really annoying to get through. 6 | 7 | Let's go to VS Code and our index.html file. The skip link should be the first content on the website, so right inside the body tag I'm going to create a new anchor link and set the "href" value to "#main". This means that clicking this link will navigate the user to the element that has an ID of "main", which we'll be adding. 8 | 9 | Then I'll make the link text say "Skip to main content". Then in the main tag, we need to add an ID value of "main". This will make clicking on the skip link completely skip the header and top navigation and go straight to the main tag. Sometimes skip links are also called "jump links". 10 | 11 | Now if we look at the website, we can see the "Skip to main content" link up at the top. A couple more things we have to do is to visually hide this link so that screen readers can detect it, but it won't show up on the webpage. And, for keyboard users who might be pressing Tab to navigate the website, we also want to make it visible if it gets highlighted with Tab. 12 | 13 | To accomplish this, we'll be using that "visually-hidden" class that we added earlier for the hidden headers. It's in the boilerplate.scss file. We'll also need to add some additional styles so that when the skip link has what's called "focus" in CSS, it will become visible. 14 | 15 | First, let's add the "visually-hidden" class name to the a-tag. I'm going to copy the class name, and in the index.html file add a class to the link and paste in the class name. 16 | 17 | I know I could also just type the "visually-hidden" class name manually, but if I type it out and happen to have a typo, then the class name in the HTML won't match the class selector in our Sass file, and the styles won't work. 18 | 19 | So I often will copy and paste class names, especially if they're longer, just to make sure the names match. Or I'll try to check the class name after typing to make sure there's no typos. 20 | 21 | Anyway, let's check out the website-- and now the link is hidden. If I inspect it, we can see that it has the "visually-hidden" class styles. Now, what we want to do is to make it visible when it has focus from the keyboard. 22 | 23 | We can actually force this state in our developer tools so we can test what styles will work. If we select the link in the source code panel, then in the bottom panel we can click on the ":hov" and checking the ":focus" checkbox. Then if we click the "plus" symbol it will add a selector for the link with focus state, and we can add our rules there. 24 | 25 | Let's figure out what style rules we want to add to this focus state, to cancel out our visually-hidden styles. First let's undo the left of negative 10,000 by adding "left: 0". Then I also want to cancel out the width and height of 1px, so I'll set the width and height to auto. 26 | 27 | Ok! That seems to be working, we can see the skip link text. It is currently overlapping the main header text. And even after we build the rest of the design it may overlap something. So to help with readability, let's add a few more styles. 28 | 29 | First, I'll add a background color of white to the focus state, so that you can read it over the header text. And maybe add some padding around it, let's try 0.5 rems. 30 | 31 | And to help distinguish it from the other content around it, I'll also add a border of "1px solid". By not setting a border color, it will automatically take the border color from the text color, which is the purple visited link text color. So we'll leave that for now, and we can always tweak it later on. 32 | 33 | You might notice that I'm using pixels for the border instead of rem units. I know I said previously that you shouldn't ever use pixels, but I think in some situations pixels is fine. It's most important to use rems for font-size because you definitely want the font-size to increase if the browser base font size changes. 34 | 35 | But it's not as important for smaller sized properties like border or even padding, because it's really most important for the text to be readable, and if the border doesn't get thicker if you set your browser's font-size to something larger, it's not going to cause huge issues. 36 | 37 | So I think you could go either way for border and padding, in terms of using pixels or rems-- it won't matter quite as much as font-size. 38 | 39 | That looks pretty good! So let's copy just the rules we added, and not the selector. And then in our boilerplate Sass file I'll add a nested selector and write "ampersand colon focus" and then paste in the rules. 40 | 41 | The colon indicates that it's a pseudo-class-- pseudo-classes help you select how an element looks when it's interacted with in a certain way or falls under specific conditions, called "states." Some common states are hover (when you hover your mouse over the element) and focus (when you use the tab key to navigate through each focusable element on the page). 42 | 43 | Let's now test to see if the Skip Link focus state styles work! I'm going to reload the page and then hit the Tab key. And, the link appears! And if we hit "Enter" it will navigate to that link. You can see in the URL bar there's now a "hashtag main" added to the URL. 44 | 45 | And, navigating to the main tag takes the focus off the skip link, so it has disappeared. We can also do a test without navigating to the link. If I remove the main ID from the URL and reload, then hit Tab to make the skip link appear, and hit Tab to navigate off of the skip link, it will lose focus and disappear. So we now have the skip link working! 46 | --------------------------------------------------------------------------------