adding part 3

softchris-patch-9
chris 2 months ago
parent 62a6a5377e
commit ff34c52aa7

@ -3,74 +3,87 @@
![Introduction to HTML](../../sketchnotes/webdev101-html.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
## Pre-Lecture Quiz
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/15)
HTML, or HyperText Markup Language, is the foundation of every website you've ever visited. Think of HTML as the skeleton that gives structure to web pages it defines where content goes, how it's organized, and what each piece represents. While CSS will later "dress up" your HTML with colors and layouts, and JavaScript will bring it to life with interactivity, HTML provides the essential structure that makes everything else possible.
In this exciting lesson, you'll create the HTML structure for a beautiful virtual terrarium interface. This hands-on project will teach you fundamental HTML concepts while building something visually engaging. You'll learn how to organize content using semantic elements, work with images, and create the foundation for an interactive web application.
> Check out video
By the end of this lesson, you'll have a working HTML page displaying plant images in organized columns, ready for styling in the next lesson. Don't worry if it looks basic at first that's exactly what HTML should do before CSS adds the visual polish. Let's dive in and start building your first web project!
>
> [![Git and GitHub basics video](https://img.youtube.com/vi/1TvxJKBzhyQ/0.jpg)](https://www.youtube.com/watch?v=1TvxJKBzhyQ)
## Pre-Lecture Quiz
### Introduction
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/15)
HTML, or HyperText Markup Language, is the 'skeleton' of the web. If CSS 'dresses up' your HTML and JavaScript brings it to life, HTML is the body of your web application. HTML's syntax even reflects that idea, as it includes "head", "body", and "footer" tags.
> 📺 **Watch and Learn**: Check out this helpful video overview
>
> [![HTML Fundamentals Video](https://img.youtube.com/vi/1TvxJKBzhyQ/0.jpg)](https://www.youtube.com/watch?v=1TvxJKBzhyQ)
In this lesson, we're going to use HTML to layout the 'skeleton' of our virtual terrarium's interface. It will have a title and three columns: a right and a left column where the draggable plants live, and a center area that will be the actual glass-looking terrarium. By the end of this lesson, you will be able to see the plants in the columns, but the interface will look a little strange; don't worry, in the next section you will add CSS styles to the interface to make it look better.
## Setting Up Your Project
### Task
Before we dive into HTML code, let's set up a proper workspace for your terrarium project. Creating an organized file structure from the beginning is a crucial habit that will serve you well throughout your web development journey.
On your computer, create a folder called 'terrarium' and inside it, a file called 'index.html'. You can do this in Visual Studio Code after you create your terrarium folder by opening a new VS Code window, clicking 'open folder', and navigating to your new folder. Click the small 'file' button in the Explorer pane and create the new file:
### Task: Create Your Project Structure
![explorer in VS Code](images/vs-code-index.png)
You'll create a dedicated folder for your terrarium project and add your first HTML file. Here are two approaches you can use:
Or
**Option 1: Using Visual Studio Code**
1. Open Visual Studio Code
2. Click "File" → "Open Folder" or use `Ctrl+K, Ctrl+O` (Windows/Linux) or `Cmd+K, Cmd+O` (Mac)
3. Create a new folder called `terrarium` and select it
4. In the Explorer pane, click the "New File" icon
5. Name your file `index.html`
Use these commands on your git bash:
* `mkdir terrarium`
* `cd terrarium`
* `touch index.html`
* `code index.html` or `nano index.html`
![VS Code Explorer showing new file creation](images/vs-code-index.png)
> index.html files indicate to a browser that it is the default file in a folder; URLs such as `https://anysite.com/test` might be built using a folder structure including a folder called `test` with `index.html` inside it; `index.html` doesn't have to show in a URL.
**Option 2: Using Terminal Commands**
```bash
mkdir terrarium
cd terrarium
touch index.html
code index.html
```
---
**Here's what these commands accomplish:**
- **Creates** a new directory called `terrarium` for your project
- **Navigates** into the terrarium directory
- **Creates** an empty `index.html` file
- **Opens** the file in Visual Studio Code for editing
## The DocType and html tags
> 💡 **Pro Tip**: The filename `index.html` is special in web development. When someone visits a website, browsers automatically look for `index.html` as the default page to display. This means a URL like `https://mysite.com/projects/` will automatically serve the `index.html` file from the `projects` folder without needing to specify the filename in the URL.
The first line of an HTML file is its doctype. It's a little surprising that you need to have this line at the very top of the file, but it tells older browsers that the browser needs to render the page in a standard mode, following the current html specification.
## Understanding HTML Document Structure
> Tip: in VS Code, you can hover over a tag and get information about its use from the MDN Reference guides.
Every HTML document follows a specific structure that browsers need to understand and display correctly. Think of this structure like a formal letter it has required elements in a particular order that help the recipient (in this case, the browser) process the content properly.
The second line should be the `<html>` tag's opening tag, followed right now by its closing tag `</html>`. These tags are the root elements of your interface.
Let's start by adding the essential foundation that every HTML document needs.
### Task
### The DOCTYPE Declaration and Root Element
Add these lines at the top of your `index.html` file:
The first two lines of any HTML file serve as the document's "introduction" to the browser:
```HTML
```html
<!DOCTYPE html>
<html></html>
```
✅ There are a few different modes that can be determined by setting the DocType with a query string: [Quirks Mode and Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). These modes used to support really old browsers that aren't normally used nowadays (Netscape Navigator 4 and Internet Explorer 5). You can stick to the standard doctype declaration.
**Understanding what this code does:**
- **Declares** the document type as HTML5 using `<!DOCTYPE html>`
- **Creates** the root `<html>` element that will contain all page content
- **Establishes** modern web standards for proper browser rendering
- **Ensures** consistent display across different browsers and devices
---
> 💡 **VS Code Tip**: Hover over any HTML tag in VS Code to see helpful information from MDN Web Docs, including usage examples and browser compatibility details.
## The document's 'head'
> 📚 **Learn More**: The DOCTYPE declaration prevents browsers from entering "quirks mode," which was used to support very old websites. Modern web development uses the simple `<!DOCTYPE html>` declaration to ensure [standards-compliant rendering](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode).
The 'head' area of the HTML document includes crucial information about your web page, also known as [metadata](https://developer.mozilla.org/docs/Web/HTML/Element/meta). In our case, we tell the web server to which this page will be sent to be rendered, these four things:
## Adding Essential Document Metadata
- the page's title
- page metadata including:
- the 'character set', telling about what character encoding is used in the page
- browser information, including `x-ua-compatible` which indicates that the IE=edge browser is supported
- information about how the viewport should behave when it is loaded. Setting the viewport to have an initial scale of 1 controls the zoom level when the page is first loaded.
The `<head>` section of an HTML document contains crucial information that browsers and search engines need, but that visitors don't see directly on the page. Think of it as the "behind-the-scenes" information that helps your webpage work properly and appear correctly across different devices and platforms.
### Task
This metadata tells browsers how to display your page, what character encoding to use, and how to handle different screen sizes all essential for creating professional, accessible web pages.
Add a 'head' block to your document in between the opening and closing `<html>` tags.
### Task: Add the Document Head
Insert this `<head>` section between your opening and closing `<html>` tags:
```html
<head>
@ -81,17 +94,28 @@ Add a 'head' block to your document in between the opening and closing `<html>`
</head>
```
✅ What would happen if you set a viewport meta tag like this: `<meta name="viewport" content="width=600">`? Read more about the [viewport](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag).
**Breaking down what each element accomplishes:**
- **Sets** the page title that appears in browser tabs and search results
- **Specifies** UTF-8 character encoding for proper text display worldwide
- **Ensures** compatibility with modern versions of Internet Explorer
- **Configures** responsive design by setting the viewport to match device width
- **Controls** initial zoom level to display content at natural size
---
> 🤔 **Think About This**: What would happen if you set a viewport meta tag like this: `<meta name="viewport" content="width=600">`? This would force the page to always be 600 pixels wide, breaking responsive design! Learn more about [proper viewport configuration](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag).
## The document's `body`
## Building the Document Body
### HTML Tags
The `<body>` element contains all the visible content of your webpage everything users will see and interact with. While the `<head>` section provided instructions to the browser, the `<body>` section contains the actual content: text, images, buttons, and other elements that create your user interface.
In HTML, you add tags to your .html file to create elements of a web page. Each tag usually has an opening and closing tag, like this: `<p>hello</p>` to indicate a paragraph. Create your interface's body by adding a set of `<body>` tags inside the `<html>` tag pair; your markup now looks like this:
Let's add the body structure and understand how HTML tags work together to create meaningful content.
### Task
### Understanding HTML Tag Structure
HTML uses paired tags to define elements. Most tags have an opening tag like `<p>` and a closing tag like `</p>`, with content in between: `<p>Hello, world!</p>`. This creates a paragraph element containing the text "Hello, world!".
### Task: Add the Body Element
Update your HTML file to include the `<body>` element:
```html
<!DOCTYPE html>
@ -106,17 +130,28 @@ In HTML, you add tags to your .html file to create elements of a web page. Each
</html>
```
Now, you can start building out your page. Normally, you use `<div>` tags to create the separate elements in a page. We'll create a series of `<div>` elements which will contain images.
**Here's what this complete structure provides:**
- **Establishes** the basic HTML5 document framework
- **Includes** essential metadata for proper browser rendering
- **Creates** an empty body ready for your visible content
- **Follows** modern web development best practices
Now you're ready to add the visible elements of your terrarium! We'll use `<div>` elements as containers to organize different sections of content, and `<img>` elements to display the plant images.
### Images
### Working with Images and Layout Containers
One html tag that doesn't need a closing tag is the `<img>` tag, because it has a `src` element that contains all the information the page needs to render the item.
Images are special in HTML because they use "self-closing" tags. Unlike elements like `<p></p>` that wrap around content, the `<img>` tag contains all the information it needs within the tag itself using attributes like `src` for the image file path and `alt` for accessibility.
Create a folder in your app called `images` and in that, add all the images in the [source code folder](../solution/images); (there are 14 images of plants).
Before adding images to your HTML, you'll need to organize your project files properly by creating an images folder and adding the plant graphics.
### Task
**First, set up your images:**
1. Create a folder called `images` inside your terrarium project folder
2. Download the plant images from the [solution folder](../solution/images) (14 plant images total)
3. Copy all plant images into your new `images` folder
Add those plant images into two columns between the `<body></body>` tags:
### Task: Create the Plant Display Layout
Now add the plant images organized in two columns between your `<body></body>` tags:
```html
<div id="page">
@ -169,37 +204,62 @@ Add those plant images into two columns between the `<body></body>` tags:
</div>
```
> Note: Spans vs. Divs. Divs are considered 'block' elements, and Spans are 'inline'. What would happen if you transformed these divs to spans?
**Step by step, here's what's happening in this code:**
- **Creates** a main page container with `id="page"` to hold all content
- **Establishes** two column containers: `left-container` and `right-container`
- **Organizes** 7 plants in the left column and 7 plants in the right column
- **Wraps** each plant image in a `plant-holder` div for individual positioning
- **Applies** consistent class names for CSS styling in the next lesson
- **Assigns** unique IDs to each plant image for JavaScript interaction later
- **Includes** proper file paths pointing to the images folder
With this markup, the plants now show up on the screen. It looks pretty bad, because they aren't yet styled using CSS, and we'll do that in the next lesson.
> 🤔 **Consider This**: Notice that all images currently have the same alt text "plant". This isn't ideal for accessibility! Screen reader users would hear "plant" repeated 14 times without knowing which specific plant each image shows. Can you think of better, more descriptive alt text for each image?
Each image has alt text that will appear even if you can't see or render an image. This is an important attribute to include for accessibility. Learn more about accessibility in future lessons; for now, remember that the alt attribute provides alternative information for an image if a user for some reason cannot view it (because of slow connection, an error in the src attribute, or if the user uses a screen reader).
> 📝 **HTML Element Types**: `<div>` elements are "block-level" and take up full width, while `<span>` elements are "inline" and only take up necessary width. What do you think would happen if you changed all these `<div>` tags to `<span>` tags?
✅ Did you notice that each image has the same alt tag? Is this good practice? Why or why not? Can you improve this code?
With this markup added, the plants will appear on screen, though they won't look polished yet that's what CSS is for in the next lesson! For now, you have a solid HTML foundation that properly organizes your content and follows accessibility best practices.
---
## Using Semantic HTML for Accessibility
## Semantic markup
Semantic HTML means choosing HTML elements based on their meaning and purpose, not just their appearance. When you use semantic markup, you're communicating the structure and meaning of your content to browsers, search engines, and assistive technologies like screen readers.
In general, it's preferable to use meaningful 'semantics' when writing HTML. What does that mean? It means that you use HTML tags to represent the type of data or interaction they were designed for. For example, the main title text on a page should use an `<h1>` tag.
This approach makes your websites more accessible to users with disabilities and helps search engines better understand your content. It's a fundamental principle of modern web development that creates better experiences for everyone.
Add the following line right below your opening `<body>` tag:
### Adding a Semantic Page Title
Let's add a proper heading to your terrarium page. Insert this line right after your opening `<body>` tag:
```html
<h1>My Terrarium</h1>
```
Using semantic markup such as having headers be `<h1>` and unordered lists be rendered as `<ul>` helps screen readers navigate through a page. In general, buttons should be written as `<button>` and lists should be `<li>`. While it's _possible_ to use specially styled `<span>` elements with click handlers to mock buttons, it's better for disabled users to use technologies to determine where on a page a button resides, and to interact with it, if the element appears as a button. For this reason, try to use semantic markup as much as possible.
**Why semantic markup matters:**
- **Helps** screen readers navigate and understand page structure
- **Improves** search engine optimization (SEO) by clarifying content hierarchy
- **Enhances** accessibility for users with visual impairments or cognitive differences
- **Creates** better user experiences across all devices and platforms
- **Follows** web standards and best practices for professional development
**Examples of semantic vs. non-semantic choices:**
✅ Take a look at a screen reader and [how it interacts with a web page](https://www.youtube.com/watch?v=OUDV1gqs9GA). Can you see why having non semantic markup might frustrate the user?
| Purpose | ✅ Semantic Choice | ❌ Non-Semantic Choice |
|---------|-------------------|------------------------|
| Main heading | `<h1>Title</h1>` | `<div class="big-text">Title</div>` |
| Navigation | `<nav><ul><li></li></ul></nav>` | `<div class="menu"><div></div></div>` |
| Button | `<button>Click me</button>` | `<span onclick="...">Click me</span>` |
| Article content | `<article><p></p></article>` | `<div class="content"><div></div></div>` |
## The terrarium
> 🎥 **See It in Action**: Watch [how screen readers interact with web pages](https://www.youtube.com/watch?v=OUDV1gqs9GA) to understand why semantic markup is crucial for accessibility. Notice how proper HTML structure helps users navigate efficiently!
The last part of this interface involves creating markup that will be styled to create a terrarium.
## Creating the Terrarium Container
### Task:
Now let's add the HTML structure for the terrarium itself the glass container where plants will eventually be placed. This section demonstrates an important concept: HTML provides structure, but without CSS styling, these elements won't be visible yet.
Add this markup above the last `</div>` tag:
The terrarium markup uses descriptive class names that will make CSS styling intuitive and maintainable in the next lesson.
### Task: Add the Terrarium Structure
Insert this markup above the last `</div>` tag (before the closing tag of the page container):
```html
<div id="terrarium">
@ -213,7 +273,14 @@ Add this markup above the last `</div>` tag:
</div>
```
✅ Even though you added this markup to the screen, you see absolutely nothing render. Why?
**Understanding this terrarium structure:**
- **Creates** a main terrarium container with a unique ID for styling
- **Defines** separate elements for each visual component (top, walls, dirt, bottom)
- **Includes** nested elements for glass reflection effects (glossy elements)
- **Uses** descriptive class names that clearly indicate each element's purpose
- **Prepares** the structure for CSS styling that will create the glass terrarium appearance
> 🤔 **Notice Something?**: Even though you added this markup, you don't see anything new on the page! This perfectly illustrates how HTML provides structure while CSS provides appearance. These `<div>` elements exist but have no visual styling yet that's coming in the next lesson!
---
@ -225,9 +292,24 @@ Use the Agent mode to complete the following challenge:
**Prompt:** Create a semantic HTML section that includes a main heading "Plant Care Guide", three subsections with headings "Watering", "Light Requirements", and "Soil Care", each containing a paragraph of plant care information. Use proper semantic HTML tags like `<section>`, `<h2>`, `<h3>`, and `<p>` to structure the content appropriately.
## 🚀Challenge
## 🚀 Explore HTML History Challenge
**Learning About Web Evolution**
There are some wild 'older' tags in HTML that are still fun to play with, though you shouldn't use deprecated tags such as [these tags](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) in your markup. Still, can you use the old `<marquee>` tag to make the h1 title scroll horizontally? (if you do, don't forget to remove it afterwards)
HTML has evolved significantly since its creation in the 1990s. Some older tags like `<marquee>` are now deprecated because they don't work well with modern accessibility standards and responsive design principles.
**Try This Experiment:**
1. Temporarily wrap your `<h1>` title in a `<marquee>` tag: `<marquee><h1>My Terrarium</h1></marquee>`
2. Open your page in a browser and observe the scrolling effect
3. Consider why this tag was deprecated (hint: think about user experience and accessibility)
4. Remove the `<marquee>` tag and return to semantic markup
**Reflection Questions:**
- How might a scrolling title affect users with visual impairments or motion sensitivity?
- What modern CSS techniques could achieve similar visual effects more accessibly?
- Why is it important to use current web standards instead of deprecated elements?
Explore more about [obsolete and deprecated HTML elements](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) to understand how web standards evolve to improve user experience.
## Post-Lecture Quiz
@ -236,9 +318,31 @@ There are some wild 'older' tags in HTML that are still fun to play with, though
## Review & Self Study
HTML is the 'tried and true' building block system that has helped build the web into what it is today. Learn a little about its history by studying some old and new tags. Can you figure out why some tags were deprecated and some added? What tags might be introduced in the future?
**Deepen Your HTML Knowledge**
HTML has been the foundation of the web for over 30 years, evolving from a simple document markup language to a sophisticated platform for building interactive applications. Understanding this evolution helps you appreciate modern web standards and make better development decisions.
**Recommended Learning Paths:**
1. **HTML History and Evolution**
- Research the timeline from HTML 1.0 to HTML5
- Explore why certain tags were deprecated (accessibility, mobile-friendliness, maintainability)
- Investigate emerging HTML features and proposals
2. **Semantic HTML Deep Dive**
- Study the complete list of [HTML5 semantic elements](https://developer.mozilla.org/docs/Web/HTML/Element)
- Practice identifying when to use `<article>`, `<section>`, `<aside>`, and `<main>`
- Learn about ARIA attributes for enhanced accessibility
3. **Modern Web Development**
- Explore [building responsive websites](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon) on Microsoft Learn
- Understand how HTML integrates with CSS and JavaScript
- Learn about web performance and SEO best practices
Learn more about building sites for the web and mobile devices at [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon).
**Reflection Questions:**
- Which deprecated HTML tags did you discover, and why were they removed?
- What new HTML features are being proposed for future versions?
- How does semantic HTML contribute to web accessibility and SEO?
## Assignment

@ -1,39 +1,138 @@
# HTML Practice Assignment: Build a Blog Mockup
## Objective
## Learning Objectives
Design and hand-code the HTML structure for a personal blog homepage. This exercise will help you practice semantic HTML, layout planning, and code organization.
Apply your HTML knowledge by designing and coding a complete blog homepage structure. This hands-on assignment will reinforce semantic HTML concepts, accessibility best practices, and professional code organization skills that you'll use throughout your web development journey.
## Instructions
**By completing this assignment, you will:**
- Practice planning website layouts before coding
- Apply semantic HTML elements appropriately
- Create accessible, well-structured markup
- Develop professional coding habits with comments and organization
1. **Design Your Blog Mockup**
- Sketch a visual mockup of your blog homepage. Include key sections such as header, navigation, main content, sidebar, and footer.
- You may use paper and scan your sketch, or use digital tools (e.g., Figma, Adobe XD, Canva, or even PowerPoint).
## Project Requirements
2. **Identify HTML Elements**
- List the HTML elements you plan to use for each section (e.g., `<header>`, `<nav>`, `<main>`, `<article>`, `<aside>`, `<footer>`, `<section>`, `<h1>``<h6>`, `<p>`, `<img>`, `<ul>`, `<li>`, `<a>`, etc.).
### Part 1: Design Planning (Visual Mockup)
3. **Write the HTML Markup**
- Hand-code the HTML for your mockup. Focus on semantic structure and best practices.
- Include at least 10 distinct HTML elements.
- Add comments to explain your choices and structure.
**Create a visual mockup of your blog homepage that includes:**
- Header with site title and navigation
- Main content area with at least 2-3 blog post previews
- Sidebar with additional information (about section, recent posts, categories)
- Footer with contact information or links
4. **Submit Your Work**
- Upload your sketch/mockup and your HTML file.
- Optionally, provide a brief reflection (23 sentences) on your design decisions.
**Mockup Creation Options:**
- **Hand-drawn sketch**: Use paper and pencil, then photograph or scan your design
- **Digital tools**: Figma, Adobe XD, Canva, PowerPoint, or any drawing application
- **Wireframe tools**: Balsamiq, MockFlow, or similar wireframing software
## Rubric
**Label your mockup sections** with the HTML elements you plan to use (e.g., "Header - `<header>`", "Blog Posts - `<article>`").
| Criteria | Exemplary | Adequate | Needs Improvement |
|------------------|--------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
| Visual Mockup | Clear, detailed mockup with labeled sections and thoughtful layout | Basic mockup with some labeled sections | Minimal or unclear mockup; lacks section labels |
| HTML Elements | Uses 10+ semantic HTML elements; demonstrates understanding of structure and best practices | Uses 59 HTML elements; some semantic structure | Uses fewer than 5 elements; lacks semantic structure |
| Code Quality | Well-organized, readable code with comments; follows HTML standards | Mostly organized code; few comments | Disorganized code; lacks comments |
| Reflection | Insightful reflection on design choices and challenges | Basic reflection | No reflection or lacks relevance |
### Part 2: HTML Element Planning
## Tips
**Create a list mapping each section of your mockup to specific HTML elements:**
- Use semantic HTML tags for better accessibility and SEO.
- Organize your code with indentation and comments.
- Refer to [MDN HTML Elements Reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) for guidance.
- Think about how your layout could be extended or styled in future assignments.
```
Example:
- Site Header → <header>
- Main Navigation → <nav> with <ul> and <li>
- Blog Post → <article> with <h2>, <p>, <time>
- Sidebar → <aside> with <section> elements
- Page Footer → <footer>
```
**Required Elements to Include:**
Your HTML must contain at least 10 different semantic elements from this list:
- `<header>`, `<nav>`, `<main>`, `<article>`, `<section>`, `<aside>`, `<footer>`
- `<h1>`, `<h2>`, `<h3>`, `<p>`, `<ul>`, `<li>`, `<a>`
- `<img>`, `<time>`, `<blockquote>`, `<strong>`, `<em>`
### Part 3: HTML Implementation
**Code your blog homepage following these standards:**
1. **Document Structure**: Include proper DOCTYPE, html, head, and body elements
2. **Semantic Markup**: Use HTML elements for their intended purpose
3. **Accessibility**: Include proper alt text for images and meaningful link text
4. **Code Quality**: Use consistent indentation and meaningful comments
5. **Content**: Include realistic blog content (you can use placeholder text)
**Sample HTML Structure:**
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Personal Blog</title>
</head>
<body>
<!-- Main site header -->
<header>
<h1>My Blog Title</h1>
<nav>
<!-- Navigation menu -->
</nav>
</header>
<!-- Main content area -->
<main>
<!-- Blog posts go here -->
</main>
<!-- Sidebar content -->
<aside>
<!-- Additional information -->
</aside>
<!-- Site footer -->
<footer>
<!-- Footer content -->
</footer>
</body>
</html>
```
### Part 4: Reflection
**Write a brief reflection (3-5 sentences) addressing:**
- Which HTML elements were you most confident using?
- What challenges did you encounter while planning or coding?
- How did semantic HTML help organize your content?
- What would you do differently in your next HTML project?
## Submission Checklist
**Before submitting, ensure you have:**
- [ ] Visual mockup with labeled HTML elements
- [ ] Complete HTML file with proper document structure
- [ ] At least 10 different semantic HTML elements used appropriately
- [ ] Meaningful comments explaining your code structure
- [ ] Valid HTML syntax (test in a browser)
- [ ] Written reflection addressing the prompt questions
## Assessment Rubric
| Criteria | Exemplary (4) | Proficient (3) | Developing (2) | Beginning (1) |
|----------|---------------|----------------|----------------|---------------|
| **Planning & Design** | Detailed, well-labeled mockup showing clear understanding of layout and HTML semantic structure | Clear mockup with most sections labeled appropriately | Basic mockup with some labeling, shows general understanding | Minimal or unclear mockup, lacks proper section identification |
| **Semantic HTML Usage** | Uses 10+ semantic elements appropriately, demonstrates deep understanding of HTML structure and accessibility | Uses 8-9 semantic elements correctly, shows good understanding of semantic markup | Uses 6-7 semantic elements, some confusion about appropriate usage | Uses fewer than 6 elements or misuses semantic elements |
| **Code Quality & Organization** | Exceptionally well-organized, properly indented code with comprehensive comments and perfect HTML syntax | Well-organized code with good indentation, helpful comments, and valid syntax | Mostly organized code with some comments, minor syntax issues | Poor organization, minimal comments, multiple syntax errors |
| **Accessibility & Best Practices** | Excellent accessibility considerations, meaningful alt text, proper heading hierarchy, follows all modern HTML best practices | Good accessibility features, appropriate use of headings and alt text, follows most best practices | Some accessibility considerations, basic alt text and heading structure | Limited accessibility features, poor heading structure, doesn't follow best practices |
| **Reflection & Learning** | Insightful reflection demonstrating deep understanding of HTML concepts and thoughtful analysis of the learning process | Good reflection showing understanding of key concepts and some self-awareness of learning | Basic reflection with limited insight into HTML concepts or learning process | Minimal or missing reflection, shows little understanding of concepts learned |
## Learning Resources
**Essential References:**
- [MDN HTML Elements Reference](https://developer.mozilla.org/docs/Web/HTML/Element) - Complete guide to all HTML elements
- [HTML5 Semantic Elements](https://developer.mozilla.org/docs/Web/HTML/Element#content_sectioning) - Understanding semantic markup
- [Web Accessibility Guidelines](https://www.w3.org/WAI/WCAG21/quickref/) - Creating accessible web content
- [HTML Validator](https://validator.w3.org/) - Check your HTML syntax
**Pro Tips for Success:**
- Start with your mockup before writing any code
- Use the browser's developer tools to inspect your HTML structure
- Test your page with different screen sizes (even without CSS)
- Read your HTML aloud to check if the structure makes logical sense
- Consider how a screen reader would interpret your page structure
> 💡 **Remember**: This assignment focuses on HTML structure and semantics. Don't worry about visual styling that's what CSS is for! Your page might look plain, but it should be well-structured and meaningful.

@ -3,249 +3,416 @@
![Introduction to CSS](../../sketchnotes/webdev101-css.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
CSS, or Cascading Style Sheets, is where the magic of web design truly begins. While HTML provides the structure and content of your webpage, CSS transforms it from a plain document into a visually stunning, interactive experience. Think of HTML as the foundation and walls of a house, while CSS is the interior design, paint, lighting, and all the beautiful details that make it feel like home.
In this lesson, you'll discover how CSS works hand-in-hand with HTML to create responsive, beautiful web applications. You'll learn fundamental concepts like the cascade, inheritance, and positioning while building your terrarium's visual design. These concepts form the foundation of all modern web design, from simple personal websites to complex web applications.
By the end of this lesson, you'll have transformed your basic HTML terrarium into a beautiful, styled web application. You'll understand how CSS selectors work, how to position elements precisely, and how to create layouts that look great on any screen size. Let's dive into the world of CSS and bring your terrarium to life!
## Pre-Lecture Quiz
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/17)
### Introduction
## Getting Started with CSS
CSS is much more than just "making things look pretty" it's a powerful language that controls every aspect of how your content appears and behaves on screen. From simple color changes to complex animations, CSS gives you complete control over the user experience.
CSS, or Cascading Style Sheets, solve an important problem of web development: how to make your web site look nice. Styling your apps makes them more usable and nicer-looking; you can also use CSS to create Responsive Web Design (RWD) - allowing your apps to look good no matter what screen size they are displayed on. CSS is not only about making your app look nice; its spec includes animations and transforms that can enable sophisticated interactions for your apps. The CSS Working Group helps maintain current CSS specifications; you can follow their work at [World Wide Web Consortium's site](https://www.w3.org/Style/CSS/members).
Modern CSS includes incredible features like responsive design capabilities, allowing your applications to automatically adapt to different screen sizes and devices. You'll also discover CSS animations, transitions, and transforms that can create engaging, interactive experiences for your users.
> Note, CSS is a language that evolves, like everything on the web, and not all browsers support newer parts of the specification. Always check your implementations by consulting [CanIUse.com](https://caniuse.com).
> 💡 **Pro Tip**: CSS is constantly evolving with new features and capabilities. Always check [CanIUse.com](https://caniuse.com) to verify browser support for newer CSS features before using them in production projects.
In this lesson, we're going to add styles to our online terrarium and learn more about several CSS concepts: the cascade, inheritance, and the use of selectors, positioning, and using CSS to build layouts. In the process we will layout the terrarium and create the actual terrarium itself.
**Here's what we'll accomplish in this lesson:**
- **Creates** a complete visual design for your terrarium using modern CSS techniques
- **Explores** fundamental concepts like the cascade, inheritance, and CSS selectors
- **Implements** responsive positioning and layout strategies
- **Builds** the terrarium container using CSS shapes and styling
### Prerequisite
You should have the HTML for your terrarium built and ready to be styled.
You should have completed the HTML structure for your terrarium from the previous lesson and have it ready to be styled.
> Check out video
> 📺 **Video Resource**: Check out this helpful video walkthrough
>
> [![CSS Basics Tutorial](https://img.youtube.com/vi/6yIdOIV9p1I/0.jpg)](https://www.youtube.com/watch?v=6yIdOIV9p1I)
>
> [![Git and GitHub basics video](https://img.youtube.com/vi/6yIdOIV9p1I/0.jpg)](https://www.youtube.com/watch?v=6yIdOIV9p1I)
### Setting Up Your CSS File
### Task
Before we can start styling, we need to connect CSS to our HTML. This connection tells the browser where to find the styling instructions for our terrarium.
In your terrarium folder, create a new file called `style.css`. Import that file in the `<head>` section:
In your terrarium folder, create a new file called `style.css`, then link it in your HTML document's `<head>` section:
```html
<link rel="stylesheet" href="./style.css" />
```
---
**Here's what this code does:**
- **Creates** a connection between your HTML and CSS files
- **Tells** the browser to load and apply the styles from `style.css`
- **Uses** the `rel="stylesheet"` attribute to specify this is a CSS file
- **References** the file path with `href="./style.css"`
## Understanding the CSS Cascade
## The Cascade
The "cascade" in Cascading Style Sheets refers to how the browser decides which styles to apply when multiple rules target the same element. Think of it like a waterfall styles flow down from multiple sources, and the browser needs to determine which one wins.
Cascading Style Sheets incorporate the idea that the styles 'cascade' such that the application of a style is guided by its priority. Styles set by a web site author take priority over those set by a browser. Styles set 'inline' take priority over those set in an external style sheet.
Understanding cascade priority helps you write more predictable CSS and debug styling conflicts effectively. The cascade follows a specific hierarchy that every web developer should understand.
### Task
### Experimenting with Cascade Priority
Add the inline style "color: red" to your `<h1>` tag:
Let's see the cascade in action by creating a style conflict. First, add an inline style to your `<h1>` tag:
```HTML
```html
<h1 style="color: red">My Terrarium</h1>
```
Then, add the following code to your `style.css` file:
**What this code does:**
- **Applies** a red color directly to the `<h1>` element using inline styling
- **Uses** the `style` attribute to embed CSS directly in the HTML
- **Creates** the highest priority style rule for this specific element
```CSS
Next, add this rule to your `style.css` file:
```css
h1 {
color: blue;
color: blue;
}
```
✅ Which color displays in your web app? Why? Can you find a way to override styles? When would you want to do this, or why not?
**In the above, we've:**
- **Defined** a CSS rule that targets all `<h1>` elements
- **Set** the text color to blue using an external stylesheet
- **Created** a lower priority rule compared to inline styles
---
**Knowledge Check**: Which color displays in your web app? Why does that color win? Can you think of scenarios where you might want to override styles?
> 💡 **CSS Priority Order (highest to lowest):**
> 1. **Inline styles** (style attribute)
> 2. **IDs** (#myId)
> 3. **Classes** (.myClass) and attributes
> 4. **Element selectors** (h1, div, p)
> 5. **Browser defaults**
## Inheritance
## CSS Inheritance in Action
Styles are inherited from an ancestor style to a descendent, such that nested elements inherit the styles of their parents.
CSS inheritance is like family traits children automatically receive certain characteristics from their parents unless specifically overridden. This powerful feature helps you write more efficient CSS by setting styles once on parent elements.
### Task
Inheritance works for specific properties like fonts, colors, and text styling, but not for layout properties like margins, borders, or positioning. Understanding which properties inherit helps you structure your CSS more effectively.
Set the body's font to a given font, and check to see a nested element's font:
### Observing Font Inheritance
```CSS
Let's see inheritance in action by setting a font family on the `<body>` element:
```css
body {
font-family: helvetica, arial, sans-serif;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
```
Open your browser's console to the 'Elements' tab and observe the H1's font. It inherits its font from the body, as stated within the browser:
**Breaking down what happens here:**
- **Sets** the font family for the entire page by targeting the `<body>` element
- **Uses** a font stack with fallback options for better browser compatibility
- **Applies** modern system fonts that look great across different operating systems
- **Ensures** all child elements inherit this font unless specifically overridden
Open your browser's developer tools (F12), navigate to the Elements tab, and inspect your `<h1>` element. You'll see that it inherits the font family from the body:
![inherited font](images/1.png)
✅ Can you make a nested style inherit a different property?
**Experiment Time**: Try setting other inheritable properties on the `<body>` like `color`, `line-height`, or `text-align`. What happens to your heading and other elements?
---
> 📝 **Inheritable Properties Include**: `color`, `font-family`, `font-size`, `line-height`, `text-align`, `visibility`
>
> **Non-Inheritable Properties Include**: `margin`, `padding`, `border`, `width`, `height`, `position`
## CSS Selectors
## Mastering CSS Selectors
### Tags
CSS selectors are like addresses that tell the browser exactly which elements to style. Just as you need a specific address to deliver mail to the right house, you need precise selectors to apply styles to the right elements.
So far, your `style.css` file has only a few tags styled, and the app looks pretty strange:
There are several types of selectors, each with different levels of specificity and use cases. Learning to choose the right selector for each situation is a key skill in CSS development.
```CSS
### Element Selectors (Tags)
Element selectors target HTML elements by their tag name. They're perfect for setting base styles that apply broadly across your page:
```css
body {
font-family: helvetica, arial, sans-serif;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
}
h1 {
color: #3a241d;
text-align: center;
color: #3a241d;
text-align: center;
font-size: 2.5rem;
margin-bottom: 1rem;
}
```
This way of styling a tag gives you control over unique elements, but you need to control the styles of many plants in your terrarium. To do that, you need to leverage CSS selectors.
**Understanding these styles:**
- **Sets** consistent typography across the entire page with the `body` selector
- **Removes** default browser margins and padding for better control
- **Styles** all heading elements with color, alignment, and spacing
- **Uses** `rem` units for scalable, accessible font sizing
While element selectors work well for general styling, you'll need more specific selectors to style individual components like the plants in your terrarium.
### Ids
### ID Selectors for Unique Elements
Add some style to layout the left and right containers. Since there is only one left container and only one right container, they are given ids in the markup. To style them, use `#`:
ID selectors use the `#` symbol and target elements with specific `id` attributes. Since IDs must be unique on a page, they're perfect for styling individual, special elements like our left and right plant containers.
```CSS
Let's create the styling for our terrarium's side containers where the plants will live:
```css
#left-container {
background-color: #eee;
width: 15%;
left: 0px;
top: 0px;
position: absolute;
height: 100%;
padding: 10px;
background-color: #f5f5f5;
width: 15%;
left: 0;
top: 0;
position: absolute;
height: 100vh;
padding: 1rem;
box-sizing: border-box;
}
#right-container {
background-color: #eee;
width: 15%;
right: 0px;
top: 0px;
position: absolute;
height: 100%;
padding: 10px;
background-color: #f5f5f5;
width: 15%;
right: 0;
top: 0;
position: absolute;
height: 100vh;
padding: 1rem;
box-sizing: border-box;
}
```
Here, you have placed these containers with absolute positioning to the far left and right of the screen, and used percentages for their width so that they can scale for small mobile screens.
**Here's what this code accomplishes:**
- **Positions** containers at the far left and right edges using `absolute` positioning
- **Uses** `vh` (viewport height) units for responsive height that adapts to screen size
- **Applies** `box-sizing: border-box` so padding is included in the total width
- **Removes** unnecessary `px` units from zero values for cleaner code
- **Sets** a subtle background color that's easier on the eyes than stark gray
✅ This code is quite repeated, thus not "DRY" (Don't Repeat Yourself); can you find a better way to style these ids, perhaps with an id and a class? You would need to change the markup and refactor the CSS:
**Code Quality Challenge**: Notice how this CSS violates the DRY (Don't Repeat Yourself) principle. Can you refactor it using both an ID and a class?
**Improved approach:**
```html
<div id="left-container" class="container"></div>
<div id="right-container" class="container"></div>
```
```css
.container {
background-color: #f5f5f5;
width: 15%;
top: 0;
position: absolute;
height: 100vh;
padding: 1rem;
box-sizing: border-box;
}
#left-container {
left: 0;
}
#right-container {
right: 0;
}
```
### Classes
### Class Selectors for Reusable Styles
In the example above, you styled two unique elements on the screen. If you want styles to apply to many elements on the screen, you can use CSS classes. Do this to layout the plants in the left and right containers.
Class selectors use the `.` symbol and are perfect when you want to apply the same styles to multiple elements. Unlike IDs, classes can be reused throughout your HTML, making them ideal for consistent styling patterns.
Notice that each plant in the HTML markup has a combination of ids and classes. The ids here are used by the JavaScript that you will add later to manipulate the terrarium plant placement. The classes, however, give all the plants a given style.
In our terrarium, each plant needs similar styling but also needs individual positioning. We'll use a combination of classes for shared styles and IDs for unique positioning.
**Here's the HTML structure for each plant:**
```html
<div class="plant-holder">
<img class="plant" alt="plant" id="plant1" src="./images/plant1.png" />
<img class="plant" alt="Decorative plant for terrarium" id="plant1" src="./images/plant1.png" />
</div>
```
Add the following to your `style.css` file:
**Key elements explained:**
- **Uses** `class="plant-holder"` for consistent container styling across all plants
- **Applies** `class="plant"` for shared image styling and behavior
- **Includes** unique `id="plant1"` for individual positioning and JavaScript interaction
- **Provides** descriptive alt text for screen reader accessibility
Now add these styles to your `style.css` file:
```CSS
```css
.plant-holder {
position: relative;
height: 13%;
left: -10px;
position: relative;
height: 13%;
left: -0.6rem;
}
.plant {
position: absolute;
max-width: 150%;
max-height: 150%;
z-index: 2;
position: absolute;
max-width: 150%;
max-height: 150%;
z-index: 2;
transition: transform 0.3s ease;
}
.plant:hover {
transform: scale(1.05);
}
```
Notable in this snippet is the mixture of relative and absolute positioning, which we'll cover in the next section. Take a look at the way heights are handled by percentages:
**Breaking down these styles:**
- **Creates** relative positioning for the plant holder to establish a positioning context
- **Sets** each plant holder to 13% height, ensuring all plants fit vertically without scrolling
- **Shifts** holders slightly left to better center plants within their containers
- **Allows** plants to scale responsively with `max-width` and `max-height` properties
- **Uses** `z-index` to layer plants above other elements in the terrarium
- **Adds** a subtle hover effect with CSS transitions for better user interaction
You set the height of the plant holder to 13%, a good number to ensure that all the plants are displayed in each vertical container without need for scrolling.
**Critical Thinking**: Why do we need both `.plant-holder` and `.plant` selectors? What would happen if we tried to use just one?
You set the plant holder to move to the left to allow the plants to be more centered within their container. The images have a large amount of transparent background so as to make them more draggable, so need to be pushed to the left to fit better on the screen.
> 💡 **Design Pattern**: The container (`.plant-holder`) controls layout and positioning, while the content (`.plant`) controls appearance and scaling. This separation makes the code more maintainable and flexible.
Then, the plant itself is given a max-width of 150%. This allows it to scale down as the browser scales down. Try resizing your browser; the plants stay in their containers but scale down to fit.
## Understanding CSS Positioning
Also notable is the use of z-index, which controls the relative altitude of an element (so that the plants sit on top of the container and appear to sit inside the terrarium).
CSS positioning is like giving directions to elements on your page you're telling them exactly where to appear and how to behave when the page layout changes. Mastering positioning is essential for creating sophisticated layouts and interactive features.
✅ Why do you need both a plant holder and a plant CSS selector?
There are five positioning values, each with distinct behaviors that serve different design needs. Understanding when and how to use each one will dramatically improve your CSS skills.
## CSS Positioning
### The Five Position Values
Mixing position properties (there are static, relative, fixed, absolute, and sticky positions) can be a little tricky, but when done properly it gives you good control over the elements on your pages.
| Position Value | Behavior | Use Case |
|----------------|----------|----------|
| `static` | Default flow, ignores top/left/right/bottom | Normal document layout |
| `relative` | Positioned relative to its normal position | Small adjustments, creating positioning context |
| `absolute` | Positioned relative to nearest positioned ancestor | Precise placement, overlays |
| `fixed` | Positioned relative to viewport | Navigation bars, floating elements |
| `sticky` | Switches between relative and fixed based on scroll | Headers that stick when scrolling |
Absolute positioned elements are positioned relative to their nearest positioned ancestors, and if there are none, it is positioned according to the document body.
### Positioning in Our Terrarium
Our terrarium uses a strategic combination of positioning types to create the desired layout:
```css
/* Container positioning */
.container {
position: absolute; /* Removes from normal flow */
/* ... other styles ... */
}
Relative positioned elements are positioned based on the CSS's directions to adjust its placement away from its initial position.
/* Plant holder positioning */
.plant-holder {
position: relative; /* Creates positioning context */
/* ... other styles ... */
}
/* Plant positioning */
.plant {
position: absolute; /* Allows precise placement within holder */
/* ... other styles ... */
}
```
In our sample, the `plant-holder` is a relative-positioned element that is positioned within an absolute-positioned container. The resultant behavior is that the side bar containers are pinned left and right, and the plant-holder is nested, adjusting itself within the side bars, giving space for the plants to be placed in a vertical row.
**Understanding the positioning strategy:**
- **Absolute containers** are removed from normal document flow and pinned to screen edges
- **Relative plant holders** create a positioning context while staying in document flow
- **Absolute plants** can be positioned precisely within their relative containers
- **This combination** allows plants to stack vertically while being individually positionable
> The `plant` itself also has absolute positioning, necessary to making it draggable, as you will discover in the next lesson.
> 🎯 **Why This Matters**: The `plant` elements need absolute positioning to become draggable in the next lesson. Absolute positioning removes them from the normal layout flow, making drag-and-drop interactions possible.
✅ Experiment with switching the types of positioning of the side containers and the plant-holder. What happens?
**Experiment Time**: Try changing the positioning values and observe the results:
- What happens if you change `.container` from `absolute` to `relative`?
- How does the layout change if `.plant-holder` uses `absolute` instead of `relative`?
- What occurs when you switch `.plant` to `relative` positioning?
## CSS Layouts
## Building the Terrarium with CSS
Now you will use what you learned to build the terrarium itself, all using CSS!
Now comes the exciting part using pure CSS to create the visual terrarium container! We'll use positioning, shapes, and layering to build a realistic glass jar that will house our plants.
First, style the `.terrarium` div children as a rounded rectangle using CSS:
This section demonstrates how CSS can create complex visual designs using simple geometric shapes, strategic positioning, and visual effects like transparency and layering.
```CSS
### Creating the Glass Jar Components
Let's build the terrarium jar piece by piece. Each part uses absolute positioning and percentage-based sizing for responsive design:
```css
.jar-walls {
height: 80%;
width: 60%;
background: #d1e1df;
border-radius: 1rem;
position: absolute;
bottom: 0.5%;
left: 20%;
opacity: 0.5;
z-index: 1;
height: 80%;
width: 60%;
background: #d1e1df;
border-radius: 1rem;
position: absolute;
bottom: 0.5%;
left: 20%;
opacity: 0.5;
z-index: 1;
box-shadow: inset 0 0 2rem rgba(0, 0, 0, 0.1);
}
.jar-top {
width: 50%;
height: 5%;
background: #d1e1df;
position: absolute;
bottom: 80.5%;
left: 25%;
opacity: 0.7;
z-index: 1;
width: 50%;
height: 5%;
background: #d1e1df;
position: absolute;
bottom: 80.5%;
left: 25%;
opacity: 0.7;
z-index: 1;
border-radius: 0.5rem 0.5rem 0 0;
}
.jar-bottom {
width: 50%;
height: 1%;
background: #d1e1df;
position: absolute;
bottom: 0%;
left: 25%;
opacity: 0.7;
width: 50%;
height: 1%;
background: #d1e1df;
position: absolute;
bottom: 0;
left: 25%;
opacity: 0.7;
border-radius: 0 0 0.5rem 0.5rem;
}
.dirt {
width: 60%;
height: 5%;
background: #3a241d;
position: absolute;
border-radius: 0 0 1rem 1rem;
bottom: 1%;
left: 20%;
opacity: 0.7;
z-index: -1;
width: 60%;
height: 5%;
background: #3a241d;
position: absolute;
border-radius: 0 0 1rem 1rem;
bottom: 1%;
left: 20%;
opacity: 0.7;
z-index: -1;
}
```
Note the use of percentages here. If you scale your browser down, you can see how the jar scales as well. Also notice the widths and height percentages for the jar elements and how each element is absolutely positioned in the center, pinned to the bottom of the viewport.
**Understanding the terrarium construction:**
- **Uses** percentage-based dimensions for responsive scaling across all screen sizes
- **Positions** elements absolutely to stack and align them precisely
- **Applies** different opacity values to create the glass transparency effect
- **Implements** `z-index` layering so plants appear inside the jar
- **Adds** subtle box-shadow and refined border-radius for more realistic appearance
### Responsive Design with Percentages
Notice how all dimensions use percentages rather than fixed pixel values:
**Why this matters:**
- **Ensures** the terrarium scales proportionally on any screen size
- **Maintains** the visual relationships between jar components
- **Provides** a consistent experience from mobile phones to large desktop monitors
- **Allows** the design to adapt without breaking the visual layout
### CSS Units in Action
We are also using `rem` for the border-radius, a font-relative length. Read more about this type of relative measurement in the [CSS spec](https://www.w3.org/TR/css-values-3/#font-relative-lengths).
We're using `rem` units for border-radius, which scale relative to the root font size. This creates more accessible designs that respect user font preferences. Learn more about [CSS relative units](https://www.w3.org/TR/css-values-3/#font-relative-lengths) in the official specification.
✅ Try changing the jar colors and opacity vs. those of the dirt. What happens? Why?
**Visual Experimentation**: Try modifying these values and observe the effects:
- Change the jar opacity from 0.5 to 0.8 how does this affect the glass appearance?
- Adjust the dirt color from `#3a241d` to `#8B4513` what visual impact does this have?
- Modify the `z-index` of the dirt to 2 what happens to the layering?
---
@ -259,23 +426,45 @@ Use the Agent mode to complete the following challenge:
---
## 🚀 Challenge: Adding Glass Reflections
Enhance the realism of your terrarium by adding glass shine effects! Create bubble-like reflections that make the jar appear more three-dimensional and glass-like.
## 🚀Challenge
Add a 'bubble' shine to the left bottom area of the jar to make it look more glasslike. You will be styling the `.jar-glossy-long` and `.jar-glossy-short` to look like a reflected shine. Here's how it would look:
You'll need to style the `.jar-glossy-long` and `.jar-glossy-short` classes to create realistic light reflections. Here's what the finished terrarium should look like:
![finished terrarium](./images/terrarium-final.png)
To complete the post-lecture quiz, go through this Learn module: [Style your HTML app with CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
**Your challenge:**
- **Create** subtle white or light-colored oval shapes for the glass reflections
- **Position** them strategically on the left side of the jar
- **Apply** appropriate opacity and blur effects for realistic light reflection
- **Use** `border-radius` to create organic, bubble-like shapes
- **Experiment** with gradients or box-shadows for enhanced realism
## Post-Lecture Quiz
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/18)
## Review & Self Study
## Expand Your CSS Knowledge
CSS appears simple on the surface, but creating pixel-perfect, responsive designs that work across all browsers and devices requires practice and knowledge of modern techniques.
**Essential CSS skills to master next:**
- **Flexbox** for one-dimensional layouts and component design
- **CSS Grid** for two-dimensional layouts and complex page structures
- **CSS Custom Properties** (variables) for maintainable, dynamic styling
- **Responsive design patterns** using media queries and fluid layouts
### Interactive Learning Resources
Practice these concepts with these engaging, hands-on games:
- 🐸 [Flexbox Froggy](https://flexboxfroggy.com/) - Master Flexbox through fun challenges
- 🌱 [Grid Garden](https://codepip.com/games/grid-garden/) - Learn CSS Grid by growing virtual carrots
- 🎯 [CSS Battle](https://cssbattle.dev/) - Test your CSS skills with coding challenges
### Additional Learning
CSS seems deceptively straightforward, but there are many challenges when trying to style an app perfectly for all browsers and all screen sizes. CSS-Grid and Flexbox are tools that have been developed to make the job a little more structured and more reliable. Learn about these tools by playing [Flexbox Froggy](https://flexboxfroggy.com/) and [Grid Garden](https://codepip.com/games/grid-garden/).
For comprehensive CSS fundamentals, complete this Microsoft Learn module: [Style your HTML app with CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
## Assignment

@ -2,26 +2,119 @@
## Objective
Refactor the terrarium project to use **Flexbox** or **CSS Grid** for layout. Update the HTML and CSS as needed to achieve a modern, responsive design. You do not need to implement draggable elements—focus on layout and styling only.
Transform your terrarium project to use modern CSS layout techniques! Refactor the current absolute positioning approach to implement **Flexbox** or **CSS Grid** for a more maintainable, responsive design. This assignment challenges you to apply modern CSS standards while maintaining the visual appeal of your terrarium.
## Instructions
Understanding when and how to use different layout methods is a crucial skill for modern web development. This exercise bridges traditional positioning techniques with contemporary CSS layout systems.
1. **Create a new version** of the terrarium app. Update the markup and CSS to use Flexbox or CSS Grid for layout.
2. **Ensure the art and elements are in place** as in the original version.
3. **Test your design** in at least two different browsers (e.g., Chrome, Firefox, Edge).
4. **Take screenshots** of your terrarium in each browser to demonstrate cross-browser compatibility.
5. **Submit** your updated code and screenshots.
## Assignment Instructions
## Rubric
### Phase 1: Analysis and Planning
1. **Review your current terrarium code** - Identify which elements are currently using absolute positioning
2. **Choose your layout method** - Decide whether Flexbox or CSS Grid better suits your design goals
3. **Sketch your new layout structure** - Plan how containers and plant elements will be organized
| Criteria | Exemplary | Adequate | Needs Improvement |
|------------|--------------------------------------------------------------------------|---------------------------------------|----------------------------------------|
| Layout | Fully refactored using Flexbox or CSS Grid; visually appealing and responsive | Some elements refactored; partial use of Flexbox or Grid | Little or no use of Flexbox or Grid; layout unchanged |
| Cross-Browser | Screenshots provided for multiple browsers; consistent appearance | Screenshots for one browser; minor inconsistencies | No screenshots or major inconsistencies |
| Code Quality | Clean, well-organized HTML/CSS; clear comments | Some organization; few comments | Disorganized code; lacks comments |
### Phase 2: Implementation
1. **Create a new version** of your terrarium project in a separate folder
2. **Update the HTML structure** as needed to support your chosen layout method
3. **Refactor the CSS** to use Flexbox or CSS Grid instead of absolute positioning
4. **Maintain visual consistency** - Ensure your plants and terrarium jar appear in the same positions
5. **Implement responsive behavior** - Your layout should adapt gracefully to different screen sizes
## Tips
### Phase 3: Testing and Documentation
1. **Cross-browser testing** - Verify your design works in Chrome, Firefox, Edge, and Safari
2. **Responsive testing** - Check your layout on mobile, tablet, and desktop screen sizes
3. **Documentation** - Add comments to your CSS explaining your layout choices
4. **Screenshots** - Capture your terrarium in different browsers and screen sizes
- Review [Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) and [CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) guides.
- Use browser developer tools to test responsiveness.
- Comment your code for clarity.
## Technical Requirements
### Layout Implementation
- **Choose ONE**: Implement either Flexbox OR CSS Grid (not both for the same elements)
- **Responsive Design**: Use relative units (`rem`, `em`, `%`, `vw`, `vh`) instead of fixed pixels
- **Accessibility**: Maintain proper semantic HTML structure and alt text
- **Code Quality**: Use consistent naming conventions and organize CSS logically
### Modern CSS Features to Include
```css
/* Example Flexbox approach */
.terrarium-container {
display: flex;
flex-direction: column;
min-height: 100vh;
align-items: center;
justify-content: center;
}
.plant-containers {
display: flex;
justify-content: space-between;
width: 100%;
max-width: 1200px;
}
/* Example Grid approach */
.terrarium-layout {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-template-rows: auto 1fr;
min-height: 100vh;
gap: 1rem;
}
```
### Browser Support Requirements
- **Chrome/Edge**: Latest 2 versions
- **Firefox**: Latest 2 versions
- **Safari**: Latest 2 versions
- **Mobile browsers**: iOS Safari, Chrome Mobile
## Deliverables
1. **Updated HTML file** with improved semantic structure
2. **Refactored CSS file** using modern layout techniques
3. **Screenshot collection** showing cross-browser compatibility:
- Desktop view (1920x1080)
- Tablet view (768x1024)
- Mobile view (375x667)
- At least 2 different browsers
4. **README.md file** documenting:
- Your layout choice (Flexbox vs Grid) and reasoning
- Challenges faced during refactoring
- Browser compatibility notes
- Instructions for running your code
## Assessment Rubric
| Criteria | Exemplary (4) | Proficient (3) | Developing (2) | Beginning (1) |
|----------|---------------|----------------|---------------|---------------|
| **Layout Implementation** | Masterful use of Flexbox/Grid with advanced features; fully responsive | Correct implementation with good responsive behavior | Basic implementation with minor responsive issues | Incomplete or incorrect layout implementation |
| **Code Quality** | Clean, well-organized CSS with meaningful comments and consistent naming | Good organization with some comments | Adequate organization with minimal comments | Poor organization; difficult to understand |
| **Cross-Browser Compatibility** | Perfect consistency across all required browsers with screenshots | Good compatibility with minor differences documented | Some compatibility issues that don't break functionality | Major compatibility problems or missing testing |
| **Responsive Design** | Exceptional mobile-first approach with smooth breakpoints | Good responsive behavior with appropriate breakpoints | Basic responsive features with some layout issues | Limited or broken responsive behavior |
| **Documentation** | Comprehensive README with detailed explanations and insights | Good documentation covering all required elements | Basic documentation with minimal explanations | Incomplete or missing documentation |
## Helpful Resources
### Layout Method Guides
- 📖 [A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
- 📖 [A Complete Guide to CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/)
- 📖 [Flexbox vs Grid - Choose the Right Tool](https://blog.webdevsimplified.com/2022-11/flexbox-vs-grid/)
### Browser Testing Tools
- 🛠️ [Browser DevTools Responsive Mode](https://developer.chrome.com/docs/devtools/device-mode/)
- 🛠️ [Can I Use - Feature Support](https://caniuse.com/)
- 🛠️ [BrowserStack - Cross-browser Testing](https://www.browserstack.com/)
### Code Quality Tools
- ✅ [CSS Validator](https://jigsaw.w3.org/css-validator/)
- ✅ [HTML Validator](https://validator.w3.org/)
- ✅ [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
## Bonus Challenges
🌟 **Advanced Layouts**: Implement both Flexbox AND Grid in different parts of your design
🌟 **Animation Integration**: Add CSS transitions or animations that work with your new layout
🌟 **Dark Mode**: Implement a CSS custom properties-based theme switcher
🌟 **Container Queries**: Use modern container query techniques for component-level responsiveness
> 💡 **Remember**: The goal isn't just to make it work, but to understand WHY your chosen layout method is the best solution for this particular design challenge!

@ -1,23 +1,41 @@
# Terrarium Project Part 3: DOM Manipulation and a Closure
# Terrarium Project Part 3: DOM Manipulation and JavaScript Closures
![DOM and a closure](../../sketchnotes/webdev101-js.png)
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
Welcome to the exciting world of DOM manipulation! The Document Object Model (DOM) is like a bridge between your HTML structure and JavaScript functionality, allowing you to create truly interactive web experiences. In this lesson, you'll discover how to make your beautiful terrarium come alive by enabling users to drag and rearrange plants anywhere on the screen.
You'll also encounter one of JavaScript's most powerful concepts: closures. Think of closures as a way to create "private spaces" in your code where functions can remember and access variables even after their parent function has finished running. This might sound complex now, but by the end of this lesson, you'll see how closures help us build elegant, maintainable code for our interactive features.
By completing this lesson, you'll transform your static terrarium into a dynamic, engaging project where users can customize their plant arrangements. You'll gain practical experience with event handling, coordinate tracking, and the fundamental DOM manipulation techniques that power modern web applications. Let's bring your terrarium to life!
## Pre-Lecture Quiz
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/19)
### Introduction
## Understanding the DOM: Your Gateway to Interactive Web Pages
The Document Object Model (DOM) is essentially JavaScript's way of "talking to" your HTML elements. When a web browser loads your HTML page, it creates a live representation of that page in memory this is the DOM. Think of it like a family tree where every HTML element is a family member that JavaScript can visit, modify, or rearrange.
Understanding DOM manipulation is crucial because it's what transforms static web pages into dynamic, interactive experiences. Every time you see a website respond to your clicks, update content without refreshing, or animate elements, that's DOM manipulation in action.
![DOM tree representation](./images/dom-tree.png)
> A representation of the DOM and the HTML markup that references it. From [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites)
Manipulating the DOM, or the "Document Object Model", is a key aspect of web development. According to [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "The Document Object Model (DOM) is the data representation of the objects that comprise the structure and content of a document on the web." The challenges around DOM manipulation on the web have often been the impetus behind using JavaScript frameworks instead of vanilla JavaScript to manage the DOM, but we will manage on our own!
**Here's what makes the DOM powerful:**
- **Provides** a structured way to access any element on your page
- **Enables** dynamic content updates without page refreshes
- **Allows** real-time response to user interactions like clicks and drags
- **Creates** the foundation for modern interactive web applications
In addition, this lesson will introduce the idea of a [JavaScript closure](https://developer.mozilla.org/docs/Web/JavaScript/Closures), which you can think of as a function enclosed by another function so that the inner function has access to the outer function's scope.
## JavaScript Closures: Creating Organized, Powerful Code
> JavaScript closures are a vast and complex topic. This lesson touches on the most basic idea that in this terrarium's code, you will find a closure: an inner function and an outer function constructed in a way to allow the inner function access to the outer function's scope. For much more information on how this works, please visit the [extensive documentation](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
A [JavaScript closure](https://developer.mozilla.org/docs/Web/JavaScript/Closures) is like having a function with its own private workspace. Imagine a function that can "remember" variables from its surrounding environment, even after that environment has finished executing. This creates powerful possibilities for organizing code and maintaining state.
We will use a closure to manipulate the DOM.
In our terrarium project, closures help us create dragging functionality where each plant remembers its position and behavior independently. This pattern is fundamental to JavaScript and appears throughout professional web development.
Think of the DOM as a tree, representing all the ways that a web page document can be manipulated. Various APIs (Application Program Interfaces) have been written so that programmers, using their programming language of choice, can access the DOM and edit, change, rearrange, and otherwise manage it.
> 💡 **Learning Note**: Closures are a deep topic in JavaScript. This lesson focuses on practical application you'll see how closures naturally emerge when building interactive features. As you grow as a developer, you'll discover more advanced closure patterns and uses.
![DOM tree representation](./images/dom-tree.png)
@ -25,28 +43,54 @@ Think of the DOM as a tree, representing all the ways that a web page document c
In this lesson, we will complete our interactive terrarium project by creating the JavaScript that will allow a user to manipulate the plants on the page.
### Prerequisite
## Before We Begin: Setting Up for Success
To complete this lesson, you'll need the HTML and CSS files from the previous terrarium lessons. These provide the visual foundation that we'll now make interactive. By the end of this lesson, you'll have transformed your static terrarium into a dynamic workspace where users can drag plants anywhere on the screen.
**What you'll accomplish:**
- **Creates** smooth drag-and-drop functionality for all terrarium plants
- **Implements** coordinate tracking to remember plant positions
- **Builds** a complete interactive user interface using vanilla JavaScript
- **Applies** closure patterns for clean, organized code structure
## Setting Up Your JavaScript File
You should have the HTML and CSS for your terrarium built. By the end of this lesson you will be able to move the plants into and out of the terrarium by dragging them.
Let's start by creating the JavaScript file that will power your terrarium's interactivity.
### Task
**Step 1: Create your script file**
In your terrarium folder, create a new file called `script.js`. Import that file in the `<head>` section:
In your terrarium folder, create a new file called `script.js`.
**Step 2: Link the JavaScript to your HTML**
Add this script tag to the `<head>` section of your `index.html` file:
```html
<script src="./script.js" defer></script>
<script src="./script.js" defer></script>
```
> Note: use `defer` when importing an external JavaScript file into the html file so as to allow the JavaScript to execute only after the HTML file has been fully loaded. You could also use the `async` attribute, which allows the script to execute while the HTML file is parsing, but in our case, it's important to have the HTML elements fully available for dragging before we allow the drag script to be executed.
**Understanding the `defer` attribute:**
- **Ensures** your JavaScript runs only after the HTML is completely loaded
- **Prevents** errors that occur when JavaScript tries to access elements that don't exist yet
- **Guarantees** all your plant elements are ready for manipulation
- **Provides** better performance than placing scripts in the `<body>` tag
> ⚠️ **Important**: The `defer` attribute is crucial for DOM manipulation. Without it, your JavaScript might try to access HTML elements before they're created, causing errors.
---
## The DOM elements
## Connecting JavaScript to Your HTML Elements
The first thing you need to do is to create references to the elements that you want to manipulate in the DOM. In our case, they are the 14 plants currently waiting in the side bars.
Before we can make elements draggable, JavaScript needs to "find" them in the DOM. Think of this like getting a direct phone line to each plant once we have that connection, we can tell each plant how to behave when users interact with it.
### Task
We'll use the `document.getElementById()` method to establish these connections. This method searches through the entire DOM tree and returns a reference to the element with the specified ID.
```html
### Enabling Drag Functionality for All Plants
Add this code to your `script.js` file:
```javascript
// Enable drag functionality for all 14 plants
dragElement(document.getElementById('plant1'));
dragElement(document.getElementById('plant2'));
dragElement(document.getElementById('plant3'));
@ -63,135 +107,298 @@ dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
```
What's going on here? You are referencing the document and looking through its DOM to find an element with a particular Id. Remember in the first lesson on HTML that you gave individual Ids to each plant image (`id="plant1"`)? Now you will make use of that effort. After identifying each element, you pass that item to a function called `dragElement` that you'll build in a minute. Thus, the element in the HTML is now drag-enabled, or will be shortly.
**Here's what this code accomplishes:**
- **Locates** each plant element in the DOM using its unique ID
- **Retrieves** a JavaScript reference to each HTML element
- **Passes** each element to a `dragElement` function (which we'll create next)
- **Prepares** every plant for drag-and-drop interaction
- **Connects** your HTML structure to JavaScript functionality
✅ Why do we reference elements by Id? Why not by their CSS class? You might refer to the previous lesson on CSS to answer this question.
> 🎯 **Why Use IDs Instead of Classes?** IDs provide unique identifiers for specific elements, while CSS classes are designed for styling groups of elements. When JavaScript needs to manipulate individual elements, IDs offer the precision and performance we need.
> 💡 **Pro Tip**: Notice how we're calling `dragElement()` for each plant individually. This approach ensures that each plant gets its own independent dragging behavior, which is essential for smooth user interaction.
---
## The Closure
## Building the Drag Element Closure
Now we'll create the heart of our dragging functionality: a closure that manages the dragging behavior for each plant. This closure will contain multiple inner functions that work together to track mouse movements and update element positions.
Now you are ready to create the dragElement closure, which is an outer function that encloses an inner function or functions (in our case, we will have three).
Closures are perfect for this task because they allow us to create "private" variables that persist between function calls, giving each plant its own independent coordinate tracking system.
Closures are useful when one or more functions need to access an outer function's scope. Here's an example:
### Understanding Closures with a Simple Example
Let's start with a basic closure example to understand the concept:
```javascript
function displayCandy(){
let candy = ['jellybeans'];
function addCandy(candyType) {
candy.push(candyType)
}
addCandy('gumdrops');
function createCounter() {
let count = 0; // Private variable
function increment() {
count++; // Inner function can access outer variable
return count;
}
return increment; // Return the inner function
}
displayCandy();
console.log(candy)
const myCounter = createCounter();
console.log(myCounter()); // 1
console.log(myCounter()); // 2
```
In this example, the displayCandy function surrounds a function that pushes a new candy type into an array that already exists in the function. If you were to run this code, the `candy` array would be undefined, as it is a local variable (local to the closure).
**Breaking down what happens here:**
- **Creates** a private `count` variable that's only accessible within the closure
- **Defines** an inner function that can access and modify the outer variable
- **Returns** the inner function, creating a persistent connection to the private data
- **Maintains** the `count` value between function calls, even after `createCounter()` finishes
✅ How can you make the `candy` array accessible? Try moving it outside the closure. This way, the array becomes global, rather than remaining only available to the closure's local scope.
### Why Closures Are Perfect for Drag Functionality
### Task
For our terrarium, each plant needs to remember its current position coordinates. Closures provide the perfect solution:
Under the element declarations in `script.js`, create a function:
**Key benefits for our project:**
- **Maintains** private position variables for each plant independently
- **Preserves** coordinate data between drag events
- **Prevents** variable conflicts between different draggable elements
- **Creates** clean, organized code structure
> 🎯 **Learning Goal**: You don't need to master every aspect of closures right now. Focus on seeing how they help us organize code and maintain state for our dragging functionality.
### Creating the dragElement Function
Now let's build the main function that will handle all the dragging logic. Add this function below your plant element declarations:
```javascript
function dragElement(terrariumElement) {
//set 4 positions for positioning on the screen
let pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
terrariumElement.onpointerdown = pointerDrag;
// Initialize position tracking variables
let pos1 = 0, // Previous mouse X position
pos2 = 0, // Previous mouse Y position
pos3 = 0, // Current mouse X position
pos4 = 0; // Current mouse Y position
// Set up the initial drag event listener
terrariumElement.onpointerdown = pointerDrag;
}
```
`dragElement` get its `terrariumElement` object from the declarations at the top of the script. Then, you set some local positions at `0` for the object passed into the function. These are the local variables that will be manipulated for each element as you add drag and drop functionality within the closure to each element. The terrarium will be populated by these dragged elements, so the application needs to keep track of where they are placed.
**Understanding the position tracking system:**
- **`pos1` and `pos2`**: Store the difference between old and new mouse positions
- **`pos3` and `pos4`**: Track the current mouse coordinates
- **`terrariumElement`**: The specific plant element we're making draggable
- **`onpointerdown`**: The event that triggers when the user starts dragging
**Here's how the closure pattern works:**
- **Creates** private position variables for each plant element
- **Maintains** these variables throughout the dragging lifecycle
- **Ensures** each plant tracks its own coordinates independently
- **Provides** a clean interface through the `dragElement` function
In addition, the terrariumElement that is passed to this function is assigned a `pointerdown` event, which is part of the [web APIs](https://developer.mozilla.org/docs/Web/API) designed to help with DOM management. `onpointerdown` fires when a button is pushed, or in our case, a draggable element is touched. This event handler works on both [web and mobile browsers](https://caniuse.com/?search=onpointerdown), with a few exceptions.
### Why Use Pointer Events?
✅ The [event handler `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) has much more support cross-browser; why wouldn't you use it here? Think about the exact type of screen interaction you're trying to create here.
We're using `onpointerdown` instead of the more common `onclick` event for important reasons:
| Event Type | Best For | Limitations |
|------------|----------|-------------|
| `onclick` | Simple button clicks | Doesn't support dragging gestures |
| `onpointerdown` | Touch and mouse interactions | Modern browsers (widely supported) |
| `onmousedown` | Mouse-only interactions | Doesn't work on touch devices |
**What makes pointer events ideal:**
- **Supports** both mouse and touch interactions seamlessly
- **Provides** consistent behavior across desktop and mobile devices
- **Enables** smooth dragging gestures rather than simple clicks
- **Offers** better user experience for interactive elements
> 💡 **Modern Web Development**: Pointer events represent the modern standard for handling user interactions. They automatically handle the complexity of supporting different input methods (mouse, touch, stylus) with a single API.
---
## The Pointerdrag function
## The pointerDrag Function: Capturing the Start of a Drag
The `terrariumElement` is ready to be dragged around; when the `onpointerdown` event is fired, the function `pointerDrag` is invoked. Add that function right under this line: `terrariumElement.onpointerdown = pointerDrag;`:
When a user presses down on a plant (whether with a mouse click or finger touch), the `pointerDrag` function springs into action. This function captures the initial coordinates and sets up the dragging system.
### Task
Add this function inside your `dragElement` closure, right after the line `terrariumElement.onpointerdown = pointerDrag;`:
```javascript
function pointerDrag(e) {
e.preventDefault();
console.log(e);
pos3 = e.clientX;
pos4 = e.clientY;
// Prevent default browser behavior (like text selection)
e.preventDefault();
// Capture the initial mouse/touch position
pos3 = e.clientX; // X coordinate where drag started
pos4 = e.clientY; // Y coordinate where drag started
// Set up event listeners for the dragging process
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
}
```
Several things happen. First, you prevent the default events that normally happen on pointerdown from occurring by using `e.preventDefault();`. This way you have more control over the interface's behavior.
**Step by step, here's what's happening:**
- **Prevents** default browser behaviors that could interfere with dragging
- **Records** the exact coordinates where the user started the drag gesture
- **Establishes** event listeners for the ongoing drag movement
- **Prepares** the system to track mouse/finger movement across the entire document
> Come back to this line when you've built the script file completely and try it without `e.preventDefault()` - what happens?
### Understanding Event Prevention
Second, open `index.html` in a browser window, and inspect the interface. When you click a plant, you can see how the 'e' event is captured. Dig into the event to see how much information is gathered by one pointer down event!
The `e.preventDefault()` line is crucial for smooth dragging:
Next, note how the local variables `pos3` and `pos4` are set to e.clientX. You can find the `e` values in the inspection pane. These values capture the x and y coordinates of the plant at the moment you click on it or touch it. You will need fine-grained control over the behavior of the plants as you click and drag them, so you keep track of their coordinates.
**Without prevention, browsers might:**
- **Select** text when dragging across the page
- **Trigger** context menus on right-click drag
- **Interfere** with our custom dragging behavior
- **Create** visual artifacts during the drag operation
✅ Is it becoming more clear why this entire app is built with one big closure? If it wasn't, how would you maintain scope for each of the 14 draggable plants?
> 🔍 **Experiment**: After completing this lesson, try removing `e.preventDefault()` and see how it affects the dragging experience. You'll quickly understand why this line is essential!
Complete the initial function by adding two more pointer event manipulations under `pos4 = e.clientY`:
### Coordinate Tracking System
```html
The `e.clientX` and `e.clientY` properties give us precise mouse/touch coordinates:
| Property | What It Measures | Use Case |
|----------|------------------|----------|
| `clientX` | Horizontal position relative to the viewport | Tracking left-right movement |
| `clientY` | Vertical position relative to the viewport | Tracking up-down movement |
**Understanding these coordinates:**
- **Provides** pixel-perfect positioning information
- **Updates** in real-time as the user moves their pointer
- **Remains** consistent across different screen sizes and zoom levels
- **Enables** smooth, responsive drag interactions
### Setting Up Document-Level Event Listeners
Notice how we attach the move and stop events to the entire `document`, not just the plant element:
```javascript
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
```
Now you are indicating that you want the plant to be dragged along with the pointer as you move it, and for the dragging gesture to stop when you deselect the plant. `onpointermove` and `onpointerup` are all parts of the same API as `onpointerdown`. The interface will throw errors now as you have not yet defined the `elementDrag` and the `stopElementDrag` functions, so build those out next.
## The elementDrag and stopElementDrag functions
**Why attach to the document:**
- **Continues** tracking even when the mouse leaves the plant element
- **Prevents** drag interruption if the user moves quickly
- **Provides** smooth dragging across the entire screen
- **Handles** edge cases where the cursor moves outside the browser window
> ⚡ **Performance Note**: We'll clean up these document-level listeners when dragging stops to avoid memory leaks and performance issues.
## Completing the Drag System: Movement and Cleanup
You will complete your closure by adding two more internal functions that will handle what happens when you drag a plant and stop dragging it. The behavior you want is that you can drag any plant at any time and place it anywhere on the screen. This interface is quite un-opinionated (there is no drop zone for example) to allow you to design your terrarium exactly as you like it by adding, removing, and repositioning plants.
Now we'll add the two remaining functions that handle the actual dragging movement and the cleanup when dragging stops. These functions work together to create smooth, responsive plant movement across your terrarium.
### Task
### The elementDrag Function: Tracking Movement
Add the `elementDrag` function right after the closing curly bracket of `pointerDrag`:
```javascript
function elementDrag(e) {
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
console.log(pos1, pos2, pos3, pos4);
terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
// Calculate the distance moved since the last event
pos1 = pos3 - e.clientX; // Horizontal distance moved
pos2 = pos4 - e.clientY; // Vertical distance moved
// Update the current position tracking
pos3 = e.clientX; // New current X position
pos4 = e.clientY; // New current Y position
// Apply the movement to the element's position
terrariumElement.style.top = (terrariumElement.offsetTop - pos2) + 'px';
terrariumElement.style.left = (terrariumElement.offsetLeft - pos1) + 'px';
}
```
In this function, you do a lot of editing of the initial positions 1-4 that you set as local variables in the outer function. What's going on here?
As you drag, you reassign `pos1` by making it equal to `pos3` (which you set earlier as `e.clientX`) minus the current `e.clientX` value. You do a similar operation to `pos2`. Then, you reset `pos3` and `pos4` to the new X and Y coordinates of the element. You can watch these changes in the console as you drag. Then, you manipulate the plant's css style to set its new position based on the new positions of `pos1` and `pos2`, calculating the plant's top and left X and Y coordinates based on comparing its offset with these new positions.
> `offsetTop` and `offsetLeft` are CSS properties that set an element's position based on that of its parent; its parent can be any element that is not positioned as `static`.
All this recalculation of positioning allows you to fine-tune the behavior of the terrarium and its plants.
**Understanding the coordinate mathematics:**
- **`pos1` and `pos2`**: Calculate how far the mouse has moved since the last update
- **`pos3` and `pos4`**: Store the current mouse position for the next calculation
- **`offsetTop` and `offsetLeft`**: Get the element's current position on the page
- **Subtraction logic**: Moves the element by the same amount the mouse moved
**Here's the movement calculation breakdown:**
1. **Measures** the difference between old and new mouse positions
2. **Calculates** how much to move the element based on mouse movement
3. **Updates** the element's CSS position properties in real-time
4. **Stores** the new position as the baseline for the next movement calculation
### Visual Representation of the Math
```mermaid
sequenceDiagram
participant Mouse
participant JavaScript
participant Plant
Mouse->>JavaScript: Move from (100,50) to (110,60)
JavaScript->>JavaScript: Calculate: moved 10px right, 10px down
JavaScript->>Plant: Update position by +10px right, +10px down
Plant->>Plant: Render at new position
```
### Task
### The stopElementDrag Function: Cleaning Up
The final task to complete the interface is to add the `stopElementDrag` function after the closing curly bracket of `elementDrag`:
Add the cleanup function after the closing curly bracket of `elementDrag`:
```javascript
function stopElementDrag() {
document.onpointerup = null;
document.onpointermove = null;
// Remove the document-level event listeners
document.onpointerup = null;
document.onpointermove = null;
}
```
This small function resets the `onpointerup` and `onpointermove` events so that you can either restart your plant's progress by starting to drag it again, or start dragging a new plant.
**Why cleanup is essential:**
- **Prevents** memory leaks from lingering event listeners
- **Stops** the dragging behavior when the user releases the plant
- **Allows** other elements to be dragged independently
- **Resets** the system for the next drag operation
**What happens without cleanup:**
- Event listeners continue running even after dragging stops
- Performance degrades as unused listeners accumulate
- Unexpected behavior when interacting with other elements
- Browser resources are wasted on unnecessary event handling
### Understanding CSS Position Properties
Our dragging system manipulates two key CSS properties:
| Property | What It Controls | How We Use It |
|----------|------------------|---------------|
| `top` | Distance from the top edge | Vertical positioning during drag |
| `left` | Distance from the left edge | Horizontal positioning during drag |
**Key insights about offset properties:**
- **`offsetTop`**: Current distance from the top of the positioned parent element
- **`offsetLeft`**: Current distance from the left of the positioned parent element
- **Positioning context**: These values are relative to the nearest positioned ancestor
- **Real-time updates**: Changes immediately when we modify the CSS properties
✅ What happens if you don't set these events to null?
> 🎯 **Design Philosophy**: This drag system is intentionally flexible there are no "drop zones" or restrictions. Users can place plants anywhere, giving them complete creative control over their terrarium design.
Now you have completed your project!
## Bringing It All Together: Your Complete Drag System
🥇Congratulations! You have finished your beautiful terrarium. ![finished terrarium](./images/terrarium-final.png)
Congratulations! You've just built a sophisticated drag-and-drop system using vanilla JavaScript. Your complete `dragElement` function now contains a powerful closure that manages:
**What your closure accomplishes:**
- **Maintains** private position variables for each plant independently
- **Handles** the complete drag lifecycle from start to finish
- **Provides** smooth, responsive movement across the entire screen
- **Cleans** up resources properly to prevent memory leaks
- **Creates** an intuitive, creative interface for terrarium design
### Testing Your Interactive Terrarium
Open your `index.html` file in a web browser and test your creation:
1. **Click and hold** any plant to start dragging
2. **Move your mouse or finger** to see the plant follow smoothly
3. **Release** to place the plant in its new position
4. **Experiment** with different arrangements and layouts
🥇 **You've created something amazing!** Your terrarium is now a fully interactive web application that demonstrates fundamental concepts used in professional web development.
![finished terrarium](./images/terrarium-final.png)
---
@ -203,21 +410,64 @@ Use the Agent mode to complete the following challenge:
**Prompt:** Create a reset button that, when clicked, animates all plants back to their original sidebar positions using CSS transitions. The function should store the original positions when the page loads and smoothly transition plants back to those positions over 1 second when the reset button is pressed.
## 🚀Challenge
## 🚀 Additional Challenge: Expand Your Skills
Ready to take your terrarium to the next level? Try implementing these enhancements:
**Creative Extensions:**
- **Double-click** a plant to bring it to the front (z-index manipulation)
- **Add visual feedback** like a subtle glow when hovering over plants
- **Implement boundaries** to prevent plants from being dragged outside the terrarium
- **Create a save function** that remembers plant positions using localStorage
- **Add sound effects** for picking up and placing plants
Add new event handler to your closure to do something more to the plants; for example, double-click a plant to bring it to the front. Get creative!
> 💡 **Learning Opportunity**: Each of these challenges will teach you new aspects of DOM manipulation, event handling, and user experience design.
## Post-Lecture Quiz
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/20)
## Review & Self Study
## Review & Self Study: Deepening Your Understanding
You've mastered the fundamentals of DOM manipulation and closures, but there's always more to explore! Here are some pathways to expand your knowledge and skills.
### Alternative Drag and Drop Approaches
We used pointer events for maximum flexibility, but web development offers multiple approaches:
| Approach | Best For | Learning Value |
|----------|----------|----------------|
| [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) | File uploads, formal drag zones | Understanding native browser capabilities |
| [Touch Events](https://developer.mozilla.org/docs/Web/API/Touch_events) | Mobile-specific interactions | Mobile-first development patterns |
| CSS `transform` properties | Smooth animations | Performance optimization techniques |
### Advanced DOM Manipulation Topics
**Next steps in your learning journey:**
- **Event delegation**: Handling events efficiently for multiple elements
- **Intersection Observer**: Detecting when elements enter/leave the viewport
- **Mutation Observer**: Watching for changes in the DOM structure
- **Web Components**: Creating reusable, encapsulated UI elements
- **Virtual DOM concepts**: Understanding how frameworks optimize DOM updates
### Essential Resources for Continued Learning
**Technical Documentation:**
- [MDN Pointer Events Guide](https://developer.mozilla.org/docs/Web/API/Pointer_events) - Comprehensive pointer event reference
- [W3C Pointer Events Specification](https://www.w3.org/TR/pointerevents1/) - Official standards documentation
- [JavaScript Closures Deep Dive](https://developer.mozilla.org/docs/Web/JavaScript/Closures) - Advanced closure patterns
While dragging elements around the screen seems trivial, there are many ways to do this and many pitfalls, depending on the effect you seek. In fact, there is an entire [drag and drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) that you can try. We didn't use it in this module because the effect we wanted was somewhat different, but try this API on your own project and see what you can achieve.
**Browser Compatibility:**
- [CanIUse.com](https://caniuse.com/) - Check feature support across browsers
- [MDN Browser Compatibility Data](https://github.com/mdn/browser-compat-data) - Detailed compatibility information
Find more information on pointer events on the [W3C docs](https://www.w3.org/TR/pointerevents1/) and on [MDN web docs](https://developer.mozilla.org/docs/Web/API/Pointer_events).
**Practice Opportunities:**
- **Build** a puzzle game using similar drag mechanics
- **Create** a kanban board with drag-and-drop task management
- **Design** an image gallery with draggable photo arrangements
- **Experiment** with touch gestures for mobile interfaces
Always check browser capabilities using [CanIUse.com](https://caniuse.com/).
> 🎯 **Learning Strategy**: The best way to solidify these concepts is through practice. Try building variations of draggable interfaces each project will teach you something new about user interaction and DOM manipulation.
## Assignment

@ -1,11 +1,123 @@
# Work a bit more with the DOM
# DOM Element Investigation Assignment
## Overview
Now that you've experienced the power of DOM manipulation firsthand, it's time to explore the broader world of DOM interfaces. This assignment will deepen your understanding of how different web technologies interact with the DOM beyond just dragging elements.
## Learning Objectives
By completing this assignment, you will:
- **Research** and understand a specific DOM interface in depth
- **Analyze** real-world implementations of DOM manipulation
- **Connect** theoretical concepts to practical applications
- **Develop** skills in technical documentation and analysis
## Instructions
Research the DOM a little more by 'adopting' a DOM element. Visit the MDN's [list of DOM interfaces](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) and pick one. Find it being used on a web site in the web, and write an explanation of how it is used.
### Step 1: Choose Your DOM Interface
Visit MDN's comprehensive [list of DOM interfaces](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) and select one interface that interests you. Consider choosing from these categories for variety:
**Beginner-Friendly Options:**
- `Element.classList` - Managing CSS classes dynamically
- `Document.querySelector()` - Advanced element selection
- `Element.addEventListener()` - Event handling beyond pointer events
- `Window.localStorage` - Client-side data storage
**Intermediate Challenges:**
- `Intersection Observer API` - Detecting element visibility
- `MutationObserver` - Watching DOM changes
- `Drag and Drop API` - Alternative to our pointer-based approach
- `Geolocation API` - Accessing user location
**Advanced Exploration:**
- `Web Components` - Custom elements and shadow DOM
- `Canvas API` - Programmatic graphics
- `Web Workers` - Background processing
- `Service Workers` - Offline functionality
### Step 2: Research and Document
Create a comprehensive analysis (300-500 words) that includes:
#### Technical Overview
- **Define** what your chosen interface does in clear, beginner-friendly language
- **Explain** the key methods, properties, or events it provides
- **Describe** the types of problems it's designed to solve
#### Real-World Implementation
- **Find** a website that uses your chosen interface (inspect the code or research examples)
- **Document** the specific implementation with code snippets if possible
- **Analyze** why the developers chose this approach
- **Explain** how it enhances the user experience
#### Practical Application
- **Compare** your interface to the techniques we used in the terrarium project
- **Suggest** how your interface could enhance or extend the terrarium functionality
- **Identify** other projects where this interface would be valuable
### Step 3: Code Example
Include a simple, working code example that demonstrates your interface in action. This should be:
- **Functional** - The code should actually work when tested
- **Commented** - Explain what each part does
- **Relevant** - Connected to a realistic use case
- **Beginner-friendly** - Understandable to someone learning web development
## Submission Format
Structure your submission with clear headings:
```markdown
# [Interface Name] DOM Investigation
## What It Does
[Technical overview]
## Real-World Example
[Website analysis and implementation details]
## Code Demonstration
[Your working example with comments]
## Reflection
[How this connects to our terrarium project and future applications]
```
## Assessment Rubric
| Criteria | Exemplary (A) | Proficient (B) | Developing (C) | Needs Improvement (D) |
|----------|---------------|----------------|----------------|----------------------|
| **Technical Understanding** | Demonstrates deep understanding with accurate explanations and proper terminology | Shows solid understanding with mostly accurate explanations | Basic understanding with some misconceptions | Limited understanding with significant errors |
| **Real-World Analysis** | Identifies and thoroughly analyzes actual implementation with specific examples | Finds real example with adequate analysis | Locates example but analysis lacks depth | Vague or inaccurate real-world connection |
| **Code Example** | Working, well-commented code that clearly demonstrates the interface | Functional code with adequate comments | Code works but needs better documentation | Code has errors or poor explanation |
| **Writing Quality** | Clear, engaging writing with proper structure and technical communication | Well-organized with good technical writing | Adequate organization and clarity | Poor organization or unclear communication |
| **Critical Thinking** | Makes insightful connections between concepts and suggests innovative applications | Shows good analytical thinking and relevant connections | Some analysis present but could be deeper | Limited evidence of critical thinking |
## Tips for Success
**Research Strategies:**
- **Start** with MDN documentation for authoritative information
- **Look** for code examples on GitHub or CodePen
- **Check** popular websites using browser developer tools
- **Watch** tutorial videos for visual explanations
**Writing Guidelines:**
- **Use** your own words rather than copying documentation
- **Include** specific examples and code snippets
- **Explain** technical concepts as if teaching a friend
- **Connect** your interface to broader web development concepts
**Code Example Ideas:**
- **Create** a simple demo that showcases the interface's main features
- **Build** on concepts from our terrarium project where relevant
- **Focus** on functionality over visual design
- **Test** your code to ensure it works correctly
## Submission Deadline
[Insert deadline here]
## Rubric
## Questions?
| Criteria | Exemplary | Adequate | Needs Improvement |
| -------- | --------------------------------------------- | ------------------------------------------------ | ----------------------- |
| | Paragraph write-up is presented, with example | Paragraph write-up is presented, without example | No writeup is presented |
If you need clarification on any aspect of this assignment, don't hesitate to ask! This investigation will deepen your understanding of how the DOM enables the interactive web experiences we use every day.

Loading…
Cancel
Save