Deploy your Terrarium
## Deploy your Terrarium You can deploy, or publish your Terrarium on the web using Azure Static Web Apps. 1. Fork this repo 2. Press this button π [](https://portal.azure.com/#create/Microsoft.StaticApp) 3. Follow the setup wizard to create your app. - Set the App root to either /solution or the root of your codebase. - Thereβs no API in this app, so you can skip the API configuration. - A .github folder will be created automatically to help Azure Static Web Apps build and publish your app.
Terrarium Project Part 1: Introduction to HTML
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 lesson, you'll create the HTML structure for a 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. 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. ## Pre-Lecture Quiz Pre-lecture quiz ## Setting Up Your Project 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. ### Task: Create Your Project Structure You'll create a dedicated folder for your terrarium project and add your first HTML file. Here are two approaches you can use: 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 Option 2: Using Terminal Commands 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 ## Understanding HTML Document Structure 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. Let's start by adding the essential foundation that every HTML document needs. ### The DOCTYPE Declaration and Root Element The first two lines of any HTML file serve as the document's "introduction" to the browser: 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 ### π Pedagogical Check-in Pause and Reflect: Before continuing, make sure you understand: - β Why every HTML document needs a DOCTYPE declaration - β What the <html> root element contains - β How this structure helps browsers render pages correctly Quick Self-Test: Can you explain in your own words what "standards-compliant rendering" means? ## Adding Essential Document Metadata 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. 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. ### Task: Add the Document Head Insert this <head> section between your opening and closing <html> tags: 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 ## Building the Document Body 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. Let's add the body structure and understand how HTML tags work together to create meaningful content. ### 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: 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. ### Working with Images and Layout Containers 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. 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. 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 (14 plant images total) 3. Copy all plant images into your new images folder ### Task: Create the Plant Display Layout Now add the plant images organized in two columns between your <body></body> tags: 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 ### π Pedagogical Check-in Structure Understanding: Take a moment to review your HTML structure: - β Can you identify the main containers in your layout? - β Do you understand why each image has a unique ID? - β How would you describe the purpose of the plant-holder divs? Visual Inspection: Open your HTML file in a browser. You should see: - A basic list of plant images - Images organized in two columns - Simple, unstyled layout Remember: This plain appearance is exactly what HTML should look like before CSS styling! 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 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. 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. ### Adding a Semantic Page Title Let's add a proper heading to your terrarium page. Insert this line right after your opening <body> tag: 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: ## Creating the Terrarium Container 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. 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): 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 ### π Pedagogical Check-in HTML Structure Mastery: Before moving forward, ensure you can: - β Explain the difference between HTML structure and visual appearance - β Identify semantic vs. non-semantic HTML elements - β Describe how proper markup benefits accessibility - β Recognize the complete document tree structure Testing Your Understanding: Try opening your HTML file in a browser with JavaScript disabled and CSS removed. This shows you the pure semantic structure you've created! --- ## GitHub Copilot Agent Challenge Use the Agent mode to complete the following challenge: Description: Create a semantic HTML structure for a plant care guide section that could be added to the terrarium project. 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. Learn more about agent mode here. ## Explore HTML History Challenge Learning About Web Evolution HTML has evolved significantly since Tim Berners-Lee created the first web browser at CERN in 1990. 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 to understand how web standards evolve to improve user experience. ## Post-Lecture Quiz Post-lecture quiz ## Review & Self Study 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 - 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 on Microsoft Learn - Understand how HTML integrates with CSS and JavaScript - Learn about web performance and SEO best practices 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? ### β‘ What You Can Do in the Next 5 Minutes - [ ] Open DevTools (F12) and inspect the HTML structure of your favorite website - [ ] Create a simple HTML file with basic tags: <h1>, <p>, and <img> - [ ] Validate your HTML using the W3C HTML Validator online - [ ] Try adding a comment to your HTML using <!-- comment --> ### π― What You Can Accomplish This Hour - [ ] Complete the post-lesson quiz and review semantic HTML concepts - [ ] Build a simple webpage about yourself using proper HTML structure - [ ] Experiment with different heading levels and text formatting tags - [ ] Add images and links to practice multimedia integration - [ ] Research HTML5 features you haven't tried yet ### π Your Week-Long HTML Journey - [ ] Complete the terrarium project assignment with semantic markup - [ ] Create an accessible webpage using ARIA labels and roles - [ ] Practice form creation with various input types - [ ] Explore HTML5 APIs like localStorage or geolocation - [ ] Study responsive HTML patterns and mobile-first design - [ ] Review other developers' HTML code for best practices ### π Your Month-Long Web Foundation - [ ] Build a portfolio website showcasing your HTML mastery - [ ] Learn HTML templating with a framework like Handlebars - [ ] Contribute to open source projects by improving HTML documentation - [ ] Master advanced HTML concepts like custom elements - [ ] Integrate HTML with CSS frameworks and JavaScript libraries - [ ] Mentor others learning HTML fundamentals ## π― Your HTML Mastery Timeline ### π οΈ Your HTML Toolkit Summary After completing this lesson, you now have: - Document Structure: Complete HTML5 foundation with proper DOCTYPE - Semantic Markup: Meaningful tags that enhance accessibility and SEO - Image Integration: Proper file organization and alt text practices - Layout Containers: Strategic use of divs with descriptive class names - Accessibility Awareness: Understanding of screen reader navigation - Modern Standards: Current HTML5 practices and deprecated tag knowledge - Project Foundation: Solid base for CSS styling and JavaScript interactivity Next Steps: Your HTML structure is ready for CSS styling! The semantic foundation you've built will make the next lesson much easier to understand. ## Assignment Practice your HTML: Build a blog mockup
Terrarium Project Part 2: Introduction to CSS
Remember how your HTML terrarium looked quite basic? CSS is where we transform that plain structure into something visually appealing. If HTML is like building the frame of a house, then CSS is everything that makes it feel like home - the paint colors, the furniture arrangement, the lighting, and how the rooms flow together. Think of how the Palace of Versailles started as a simple hunting lodge, but careful attention to decoration and layout transformed it into one of the world's most magnificent buildings. Today, we'll transform your terrarium from functional to polished. You'll learn how to position elements precisely, make layouts respond to different screen sizes, and create the visual appeal that makes websites engaging. By the end of this lesson, you'll see how strategic CSS styling can dramatically improve your project. Let's add some style to your terrarium. ## Pre-Lecture Quiz Pre-lecture quiz ## Getting Started with CSS CSS is often thought of as just "making things pretty," but it serves a much broader purpose. CSS is like being the director of a movie - you control not just how everything looks, but how it moves, responds to interaction, and adapts to different situations. Modern CSS is remarkably capable. You can write code that automatically adjusts layouts for phones, tablets, and desktop computers. You can create smooth animations that guide users' attention where needed. The results can be quite impressive when everything works together. 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 completed the HTML structure for your terrarium from the previous lesson and have it ready to be styled. ### Setting Up Your CSS File 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, then link it in your HTML document's <head> section: 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 Ever wondered why CSS is called "Cascading" Style Sheets? Styles cascade down like a waterfall, and sometimes they conflict with each other. Consider how military command structures work - a general order might say "all troops wear green," but a specific order to your unit might say "wear dress blues for the ceremony." The more specific instruction takes precedence. CSS follows similar logic, and understanding this hierarchy makes debugging much more manageable. ### Experimenting with Cascade Priority Let's see the cascade in action by creating a style conflict. First, add an inline style to your <h1> tag: 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 Next, add this rule to your style.css file: 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 Inheritance in Action CSS inheritance works like genetics - elements inherit certain properties from their parent elements. If you set the font family on the body element, all text inside automatically uses that same font. It's similar to how the Habsburg family's distinctive jawline appeared across generations without being specified for each individual. However, not everything gets inherited. Text styles like fonts and colors do inherit, but layout properties like margins and borders do not. Just as children might inherit physical traits but not their parents' fashion choices. ### Observing Font Inheritance Let's see inheritance in action by setting a font family on the <body> element: 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: β 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? ### π Pedagogical Check-in CSS Foundation Understanding: Before moving to selectors, ensure you can: - β Explain the difference between cascade and inheritance - β Predict which style will win in a specificity conflict - β Identify which properties inherit from parent elements - β Connect CSS files to HTML properly Quick Test: If you have these styles, what color will an <h1> inside a <div class="special"> be? Answer: Red (element selector directly targets h1) ## Mastering CSS Selectors CSS selectors are your way of targeting specific elements for styling. They work like giving precise directions - instead of saying "the house," you might say "the blue house with the red door on Maple Street." CSS provides different ways to be specific, and choosing the right selector is like choosing the appropriate tool for the task. Sometimes you need to style every door in the neighborhood, and sometimes just one specific door. ### 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: 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. ### ID Selectors for Unique Elements 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. Let's create the styling for our terrarium's side containers where the plants will live: 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 β 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: ### Class Selectors for Reusable Styles 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. 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: 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: 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 β Critical Thinking: Why do we need both .plant-holder and .plant selectors? What would happen if we tried to use just one? ## Understanding CSS Positioning CSS positioning is like being the stage director for a play - you direct where every actor stands and how they move around the stage. Some actors follow the standard formation, while others need specific positioning for dramatic effect. Once you understand positioning, many layout challenges become manageable. Need a navigation bar that stays at the top while users scroll? Positioning handles that. Want a tooltip that appears at a specific location? That's positioning too. ### The Five Position Values ### Positioning in Our Terrarium Our terrarium uses a strategic combination of positioning types to create the desired layout: 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 β 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? ### π Pedagogical Check-in CSS Positioning Mastery: Pause to verify your understanding: - β Can you explain why plants need absolute positioning for drag-and-drop? - β Do you understand how relative containers create positioning context? - β Why do the side containers use absolute positioning? - β What would happen if you removed position declarations entirely? Real-World Connection: Think about how CSS positioning mirrors real-world layout: - Static: Books on a shelf (natural order) - Relative: Moving a book slightly but keeping its spot - Absolute: Placing a bookmark at an exact page number - Fixed: A sticky note that stays visible as you flip pages ## Building the Terrarium with CSS Now we'll build a glass jar using only CSS - no images or graphics software required. Creating realistic-looking glass, shadows, and depth effects using positioning and transparency demonstrates CSS's visual capabilities. This technique mirrors how architects in the Bauhaus movement used simple geometric forms to create complex, beautiful structures. Once you understand these principles, you'll recognize the CSS techniques behind many web designs. ### 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: 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'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 in the official specification. β 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? ### π Pedagogical Check-in CSS Visual Design Understanding: Confirm your grasp of visual CSS: - β How do percentage-based dimensions create responsive design? - β Why does opacity create the glass transparency effect? - β What role does z-index play in layering elements? - β How do border-radius values create the jar shape? Design Principle: Notice how we're building complex visuals from simple shapes: 1. Rectangles β Rounded rectangles β Jar components 2. Flat colors β Opacity β Glass effect 3. Individual elements β Layered composition β 3D appearance --- ## GitHub Copilot Agent Challenge π Use the Agent mode to complete the following challenge: Description: Create a CSS animation that makes the terrarium plants gently sway back and forth, simulating a natural breeze effect. This will help you practice CSS animations, transforms, and keyframes while enhancing the visual appeal of your terrarium. Prompt: Add CSS keyframe animations to make the plants in the terrarium sway gently from side to side. Create a swaying animation that rotates each plant slightly (2-3 degrees) left and right with a duration of 3-4 seconds, and apply it to the .plant class. Make sure the animation loops infinitely and has an easing function for natural movement. Learn more about agent mode here. ## π Challenge: Adding Glass Reflections Ready to enhance your terrarium with realistic glass reflections? This technique will add depth and realism to the design. You'll create subtle highlights that simulate how light reflects off glass surfaces. This approach is similar to how Renaissance painters like Jan van Eyck used light and reflection to make painted glass appear three-dimensional. Here's what you're aiming for: 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 ## Expand Your CSS Knowledge CSS can feel complex initially, but understanding these core concepts provides a solid foundation for more advanced techniques. Your next CSS learning areas: - Flexbox - simplifies alignment and distribution of elements - CSS Grid - provides powerful tools for creating complex layouts - CSS Variables - reduces repetition and improves maintainability - Responsive design - ensures sites work well across different screen sizes ### Interactive Learning Resources Practice these concepts with these engaging, hands-on games: - πΈ Flexbox Froggy - Master Flexbox through fun challenges - π± Grid Garden - Learn CSS Grid by growing virtual carrots - π― CSS Battle - Test your CSS skills with coding challenges ### Additional Learning For comprehensive CSS fundamentals, complete this Microsoft Learn module: Style your HTML app with CSS ### β‘ What You Can Do in the Next 5 Minutes - [ ] Open DevTools and inspect CSS styles on any website using the Elements panel - [ ] Create a simple CSS file and link it to an HTML page - [ ] Try changing colors using different methods: hex, RGB, and named colors - [ ] Practice the box model by adding padding and margin to a div ### π― What You Can Accomplish This Hour - [ ] Complete the post-lesson quiz and review CSS fundamentals - [ ] Style your HTML page with fonts, colors, and spacing - [ ] Create a simple layout using flexbox or grid - [ ] Experiment with CSS transitions for smooth effects - [ ] Practice responsive design with media queries ### π Your Week-Long CSS Adventure - [ ] Complete the terrarium styling assignment with creative flair - [ ] Master CSS Grid by building a photo gallery layout - [ ] Learn CSS animations to bring your designs to life - [ ] Explore CSS preprocessors like Sass or Less - [ ] Study design principles and apply them to your CSS - [ ] Analyze and recreate interesting designs you find online ### π Your Month-Long Design Mastery - [ ] Build a complete responsive website design system - [ ] Learn CSS-in-JS or utility-first frameworks like Tailwind - [ ] Contribute to open source projects with CSS improvements - [ ] Master advanced CSS concepts like CSS custom properties and containment - [ ] Create reusable component libraries with modular CSS - [ ] Mentor others learning CSS and share design knowledge ## π― Your CSS Mastery Timeline ### π οΈ Your CSS Toolkit Summary After completing this lesson, you now have: - Cascade Understanding: How styles inherit and override each other - Selector Mastery: Precise targeting with elements, classes, and IDs - Positioning Skills: Strategic element placement and layering - Visual Design: Creating glass effects, shadows, and transparency - Responsive Techniques: Percentage-based layouts that adapt to any screen - Code Organization: Clean, maintainable CSS structure - Modern Practices: Using relative units and accessible design patterns Next Steps: Your terrarium now has both structure (HTML) and style (CSS). The final lesson will add interactivity with JavaScript! ## Assignment CSS Refactoring
Terrarium Project Part 3: DOM Manipulation and JavaScript Closures
Welcome to one of the most engaging aspects of web development - making things interactive! The Document Object Model (DOM) is like a bridge between your HTML and JavaScript, and today we'll use it to bring your terrarium to life. When Tim Berners-Lee created the first web browser, he envisioned a web where documents could be dynamic and interactive - the DOM makes that vision possible. We'll also explore JavaScript closures, which might sound intimidating initially. Think of closures as creating "memory pockets" where your functions can remember important information. It's like each plant in your terrarium having its own data record to track its position. By the end of this lesson, you'll understand how natural and useful they are. Here's what we're building: a terrarium where users can drag and drop plants anywhere they want. You'll learn the DOM manipulation techniques that power everything from drag-and-drop file uploads to interactive games. Let's make your terrarium come alive. ## Pre-Lecture Quiz Pre-lecture quiz ## Understanding the DOM: Your Gateway to Interactive Web Pages The Document Object Model (DOM) is how JavaScript communicates with your HTML elements. When your browser loads an HTML page, it creates a structured representation of that page in memory - that's the DOM. Think of it as a family tree where every HTML element is a family member that JavaScript can access, modify, or rearrange. DOM manipulation transforms static pages into interactive websites. Every time you see a button change color on hover, content update without page refresh, or elements you can drag around, that's DOM manipulation at work. 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 ## JavaScript Closures: Creating Organized, Powerful Code A JavaScript closure is like giving a function its own private workspace with persistent memory. Consider how Darwin's finches on the GalΓ‘pagos Islands each developed specialized beaks based on their specific environment - closures work similarly, creating specialized functions that "remember" their specific context even after their parent function has finished. In our terrarium, closures help each plant remember its own position independently. This pattern appears throughout professional JavaScript development, making it a valuable concept to understand. 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. ## Before We Begin: Setting Up for Success You'll need your HTML and CSS files from the previous terrarium lessons - we're about to make that static design interactive. If you're joining for the first time, completing those lessons first will provide important context. Here's what we'll build: - Smooth drag-and-drop for all terrarium plants - Coordinate tracking so plants remember their positions - A complete interactive interface using vanilla JavaScript - Clean, organized code using closure patterns ## Setting Up Your JavaScript File Let's create the JavaScript file that will make your terrarium interactive. Step 1: Create your script file 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: Why the defer attribute is important: - Ensures your JavaScript waits until all HTML is loaded - Prevents errors where JavaScript looks for elements that aren't ready yet - Guarantees all your plant elements are available for interaction - Provides better performance than placing scripts at the page bottom --- ## Connecting JavaScript to Your HTML Elements Before we can make elements draggable, JavaScript needs to locate them in the DOM. Think of this like a library cataloging system - once you have the catalog number, you can find exactly the book you need and access all its contents. We'll use the document.getElementById() method to make these connections. It's like having a precise filing system - you provide an ID, and it locates exactly the element you need in your HTML. ### Enabling Drag Functionality for All Plants Add this code to your script.js file: 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 ### π Pedagogical Check-in DOM Connection Understanding: Before moving to drag functionality, verify you can: - β Explain how document.getElementById() locates HTML elements - β Understand why we use unique IDs for each plant - β Describe the purpose of the defer attribute in script tags - β Recognize how JavaScript and HTML connect through the DOM Quick Self-Test: What would happen if two elements had the same ID? Why does getElementById() return only one element? Answer: IDs should be unique; if duplicated, only the first element is returned --- ## 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. 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. ### Understanding Closures with a Simple Example Let me demonstrate closures with a simple example that illustrates the concept: Here's what's happening in this closure pattern: - Creates a private count variable that only exists within this closure - The inner function can access and modify that outer variable (the closure mechanism) - When we return the inner function, it maintains its connection to that private data - Even after createCounter() finishes execution, count persists and remembers its value ### Why Closures Are Perfect for Drag Functionality For our terrarium, each plant needs to remember its current position coordinates. Closures provide the perfect solution: 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 ### 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: 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 ### Why Use Pointer Events? You might wonder why we use onpointerdown instead of the more familiar onclick. Here's the reasoning: Why pointer events are perfect for what we're building: - Works great whether someone's using a mouse, finger, or even a stylus - Feels the same on a laptop, tablet, or phone - Handles the actual dragging motion (not just click-and-done) - Creates a smooth experience that users expect from modern web apps ### π Pedagogical Check-in Event Handling Understanding: Pause to confirm your grasp of events: - β Why do we use pointer events instead of mouse events? - β How do closure variables persist between function calls? - β What role does preventDefault() play in smooth dragging? - β Why do we attach listeners to the document instead of individual elements? Real-World Connection: Think about drag-and-drop interfaces you use daily: - File uploads: Dragging files into a browser window - Kanban boards: Moving tasks between columns - Image galleries: Rearranging photo order - Mobile interfaces: Swiping and dragging on touchscreens --- ## The pointerDrag Function: Capturing the Start of a Drag 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. Add this function inside your dragElement closure, right after the line terrariumElement.onpointerdown = pointerDrag;: 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 ### Understanding Event Prevention The e.preventDefault() line is crucial for smooth dragging: 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 ### Coordinate Tracking System The e.clientX and e.clientY properties give us precise mouse/touch coordinates: 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: 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 ## Completing the Drag System: Movement and Cleanup 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. ### The elementDrag Function: Tracking Movement Add the elementDrag function right after the closing curly bracket of pointerDrag: 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 ### The stopElementDrag Function: Cleaning Up Add the cleanup function after the closing curly bracket of elementDrag: 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: 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 ## Bringing It All Together: Your Complete Drag System 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 Now test your interactive terrarium! Open your index.html file in a web browser and try the functionality: 1. Click and hold any plant to start dragging 2. Move your mouse or finger and watch the plant follow smoothly 3. Release to drop the plant in its new position 4. Experiment with different arrangements to explore the interface π₯ Achievement: You've created a fully interactive web application using core concepts that professional developers use daily. That drag-and-drop functionality uses the same principles behind file uploads, kanban boards, and many other interactive interfaces. ### π Pedagogical Check-in Complete System Understanding: Verify your mastery of the full drag system: - β How do closures maintain independent state for each plant? - β Why is the coordinate calculation math necessary for smooth movement? - β What would happen if we forgot to clean up event listeners? - β How does this pattern scale to more complex interactions? Code Quality Reflection: Review your complete solution: - Modular design: Each plant gets its own closure instance - Event efficiency: Proper setup and cleanup of listeners - Cross-device support: Works on desktop and mobile - Performance conscious: No memory leaks or redundant calculations --- ## GitHub Copilot Agent Challenge π Use the Agent mode to complete the following challenge: Description: Enhance the terrarium project by adding a reset functionality that returns all plants to their original positions with smooth animations. 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. Learn more about agent mode here. ## π 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 ## Post-Lecture Quiz Post-lecture quiz ## 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: ### 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 - Comprehensive pointer event reference - W3C Pointer Events Specification - Official standards documentation - JavaScript Closures Deep Dive - Advanced closure patterns Browser Compatibility: - CanIUse.com - Check feature support across browsers - MDN Browser Compatibility Data - Detailed compatibility information 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 ### β‘ What You Can Do in the Next 5 Minutes - [ ] Open browser DevTools and type document.querySelector('body') in the console - [ ] Try changing a webpage's text using innerHTML or textContent - [ ] Add a click event listener to any button or link on a webpage - [ ] Inspect the DOM tree structure using the Elements panel ### π― What You Can Accomplish This Hour - [ ] Complete the post-lesson quiz and review DOM manipulation concepts - [ ] Create an interactive webpage that responds to user clicks - [ ] Practice event handling with different event types (click, mouseover, keypress) - [ ] Build a simple to-do list or counter using DOM manipulation - [ ] Explore the relationship between HTML elements and JavaScript objects ### π Your Week-Long JavaScript Journey - [ ] Complete the interactive terrarium project with drag-and-drop functionality - [ ] Master event delegation for efficient event handling - [ ] Learn about the event loop and asynchronous JavaScript - [ ] Practice closures by building modules with private state - [ ] Explore modern DOM APIs like Intersection Observer - [ ] Build interactive components without using frameworks ### π Your Month-Long JavaScript Mastery - [ ] Create a complex single-page application using vanilla JavaScript - [ ] Learn a modern framework (React, Vue, or Angular) and compare it to vanilla DOM - [ ] Contribute to open source JavaScript projects - [ ] Master advanced concepts like web components and custom elements - [ ] Build performant web applications with optimal DOM patterns - [ ] Teach others about DOM manipulation and JavaScript fundamentals ## π― Your JavaScript DOM Mastery Timeline ### π οΈ Your JavaScript Toolkit Summary After completing this lesson, you now have: - DOM Mastery: Element selection, property manipulation, and tree navigation - Event Expertise: Cross-device interaction handling with pointer events - Closure Understanding: Private state management and function persistence - Interactive Systems: Complete drag-and-drop implementation from scratch - Performance Awareness: Proper event cleanup and memory management - Modern Patterns: Code organization techniques used in professional development - User Experience: Creating intuitive, responsive interfaces Professional Skills Gained: You've built features using the same techniques as: - Trello/Kanban boards: Card dragging between columns - File upload systems: Drag-and-drop file handling - Image galleries: Photo arrangement interfaces - Mobile apps: Touch-based interaction patterns Next Level: You're ready to explore modern frameworks like React, Vue, or Angular that build upon these fundamental DOM manipulation concepts! ## Assignment Work a bit more with the DOM
My Terrarium: A project to learn about HTML, CSS, and DOM manipulation using JavaScript π΅π±
A small drag and drop code-meditation. With a little HTML, JS and CSS, you can build a web interface, style it, and add an interaction. ## Credits Written with β₯οΈ by Jen Looper The terrarium created via CSS was inspired by Jakub Mandra's glass jar codepen. The artwork was hand drawn by Jen Looper using Procreate. ## Deploy your Terrarium You can deploy, or publish your terrarium to the web using Azure Static Web Apps. 1. Fork this repo 2. Press this button [](https://portal.azure.com/?feature.customportal=false&WT.mc_id=academic-77807-sagibbon#create/Microsoft.StaticApp) 3. Walk through the wizard creating your app. Make sure you set the app root to either be /solution or the root of your codebase. There's no API in this app, so don't worry about adding that. A .github folder will be created in your forked repo that will help Azure Static Web Apps' build service build and publish your app to a new URL.