If you’re seeing this, the site behind it is likely broken!

Hi, there. I use these course sites as little sandboxes to experiment with and learn various “brand new” CSS properties—and your browser does not support (at least) one of them. Apologies. It “should” always work in current/updating Safari and Chrome!

  • Typography & Interaction

    ’25–26

  • The Syllabus

  • Our Class

  • Unit Nº 1: “Type and the Web”

    Wks. 1–6

    • Week Nº 1

      Aug. 29

    • Everything Is a “Web Page”

    • Week Nº 2

      Sep. 5

    • It’s All About Type

    • Week Nº 3

      Sep. 12

    • An Intro to HTML

    • Week Nº 4

      Sep. 19

    • An Intro to CSS

    • Week Nº 5

      Sep. 26

    • The Box Model

    • Project Nº 1: “Manuscript”

      Oct. 3

    • Week Nº 6

      Oct. 3

  • Unit Nº 2: “There Is No Perfect Layout”

    Wks. 7–10

    • Week Nº 7

      Oct. 10

    • Responsive Design

    • DevTools (Web Inspector)

    • Week Nº 8

      Oct. 17

    • Finally, Flexbox

    • And (CSS) Grid

    • Week Nº 9

      Oct. 24

    • Some Additional, Advanced CSS

    • Project Nº 2: “Spread”

      Oct. 31

    • Week Nº 10

      Oct. 31

  • Unit Nº 3: “Typography as Interface”

    Wks. 11–15

    • Week Nº 11

      Nov. 7

    • Working with Images

    • Week Nº 12

      Nov. 14

    • Week Nº 13

      Nov. 21

    • Thanksgiving Week

    • Project Nº 3: “Binding”

      Dec. 5

    • Week Nº 14

      Dec. 5

    • Week Nº 15

      Dec. 12

  • Winter Break

  • Unit Nº 4: “Interface as Interface”

    Wks. 16–21

    • Week Nº 16

      Jan. 21

    • Week Nº 17

      Jan. 28

    • An Intro to JavaScript

    • The Muscles of the Web

      JavaScript is the language/​format for adding interactivity to a web page⁠—based on actions or events from the user. Where do we even start with JS? (Everyone says jay-ess.) It is so massive and often seems unapproachable. So we’ll go through a bit of background, and then start with some very practical examples you might want in your work.

      • JavaScript: Adding interactivity – MDN
        There are literally millions of sites about JS, but let’s start with MDN.

      • JavaScript – MDN
        Another MDN into.

      • Highest-scored JavaScript Questions – Stack Overflow
        It’s like Reddit for code! (Always check the year on answers. Some are old !)

      • The Modern Javascript Tutorial
        This reference goes very advanced/​in-depth.

      • Eloquent JavaScript
        Also goes deep.

      Going back to a very early analogy, JavaScript is the muscles of the web. Like HTML (the bones) and CSS (the skin), it is ultimately still just text that is parsed by our browsers. Like CSS, it can live within HTML documents, but is usually saved separately with the extension .js .

      JavaScript was first created by Brendan Eich over just 10 days in 1995, and has been through a myriad of evolutions, paths, missteps, and enhancements since then. It has nothing formally to do with Java, confusingly⁠—other than being contemporaries and sort-of competitor, thus the name. (Coffee-culture was really big in the 90s!) JavaScript won the race, by every measure, and is ubiquitous on the modern web.




      The idea was to make something that Web designers, people who may or may not have much programming training, could use to add a little bit of animation or a little bit of smarts to their Web forms and their Web pages.

      Brendan Eich, 2008

      Like HTML/​CSS, JavaScript was a malleable, interpreted (not compiled) language running in the browser⁠—meaning the source code could be seen by anyone, and anyone could borrow or modify it for their needs. You could always “pop the hood” to see how it worked. And then as our computers⁠—and thus our browsers⁠—became faster and cheaper, JS was used for more and more things.

      Remember that now the tendrils of JavaScript are almost everywhere⁠—running headless on servers, rendering whole sites, talking to hardware, processing NASA images, and so on. It’s web technologies, all the way down.

      Libraries /​ Frameworks vs. Plain /​ Vanilla JS

      You’ll often hear folks talk about libraries or frameworks in the context of JavaScript⁠—one of the ways it is so malleable. These are collections of Javascript code with their own specific purpose, ideas, paradigms, and syntax that expand upon what the language can do (or can do quickly or easily) on its own, out of the box.

      Things like jQuery (very old-school, now), Node, React, Vue, Angular, D3, and p5 (to name some popular ones) are all written in and are interfaced with (controlled by) JavaScript as well. They are often created to do something JavaScript doesn’t yet support on its own (in/​famously, jQuery) or with a niche use/​focus (like data-visualization, with D3). There are many, many frameworks and libraries.

      When you write JS without libraries, it is called plain or vanilla JavaScript.

      The language has evolved so much that we can do a lot, here, and this is where we’ll start. And while JS does many things, we’ll first just use it in the most simple way⁠—to make our web pages more interactive.

      Where Does JS Live?

      Very much like CSS, JavaScript code can live in several places:

      1. Inline as attributes on elements
      2. Inside <‍script> elements within HTML documents
      3. As separate/​external .js files (the right way), via src="" attributes

      1. Inline Event Handlers

      JS was first added directly in attributes in HTML tags, just like CSS⁠—but attached and “listening” for specific events:

      						<button onclick="alert('The button was clicked!');">Click here!</button>
      
      			
      	

      Note the single quotes when nested/​inside doubles!

      This works for very, very simple things, but⁠—for many of the same reasons as inline CSS⁠—is brittle and doesn’t scale with complexity, or across multiple pages. Try writing a whole, elaborate function in there, let alone an entire framework! No good.

      Use caution: outdated examples abound

      You might see these inline events in old examples/​code, but don’t use these now! If you see them, it’s probably an indication the code is outdated (or your developers are feral).

      2. Wrapped in <‍script> Tags

      And again like CSS, JavaScript can be enclosed in its own special tag, the <‍script> element.

      • <‍script> The Script element – MDN
        More minutia on using these in-HTML elements.

      • Document: querySelector() method – MDN
        This is how you find/​specify/​target HTML elements in JS.

      • EventTarget: addEventListener() method – MDN
        And then listen for events happening on them⁠—onclick is a shorthand.

      These are also often, somewhat confusingly, called inline scripts.

      Anything inside the tag should be written in JavaScript syntax and will be executed right away⁠—in the order/​position of the tag within the HTML document. This is why you will often see them right before </body>, so they can “see” the whole page before!

      Since this script isn’t directly on an element anymore (as above), we then have to identify the target element with a querySelector, and then attach an addEventListener on it, listening for the click event:

    • #

    • <>

    • ↗

    • Note the different // comment syntax for JS! And we had to add cursor: pointer; for the button in our CSS, to indicate it is actionable. Mind your affordances!

      3. Separate /​ External .js Files

      By far the most robust, flexible way to include JavaScript is externally⁠—again, like CSS. The difference here is that instead of a <link> element, we still use a (now empty) <‍script> tag, with the addition of a defer and src="filename.js" attribute:

      • defer property – MDN
        Needed for <head> scripts to “see” your HTML!
      						<script defer src="script.js"></script>
      
      			
      	

      Michael has always disliked this empty-tag syntax; what can you do.

      This will still run when the document gets to the <‍script> (and in its place/​order) as before⁠—but the additional defer attribute allows it to “see” the HTML (not yet loaded) below it. Without this attribute, it doesn’t know about the rest of the page!

      Prior to (the relatively recent) defer, you could wrap logic in a DOMContentLoaded or load event listener. You’ll likely see this is older examples/​suggestions online!

      We can then move the script up into our <head>, along with our other external files:

    • #

    • <>

    • ↗

    • Stays readable/​clean with long documents and lots of files. Where there is one JS file, there are often many!

      It’s the same exact JavaScript and behavior as the inline example above⁠—but now moved over into a nice, separate, JS-syntax-highlighted file that can be re-used across pages. This is the way.

      The most resilient, easiest way to use JavaScript is in a separate file⁠—just like CSS, for all the same reasons.

      Oh Also, <noscript>

      Some folks block/​disable JavaScript⁠—for performance or accessibility reasons, or to hide advertising/​annoyances, and so on. This is less and less common these days, since so many sites completely rely on JS. It isn’t always feasible to replicate your site behavior entirely without JS, but you can use a special <noscript> tag to show content only when scripting is turned off:

      						<noscript class="warning">
      	Our site uses JavaScript for some of its functionality, which is disabled in your browser.
      </noscript>
      
      			
      	

      You can test these by disabling JavaScript in your DevTools.

      Adding /​ Removing a Class

      Okay, time for a more practical example: probably the most common thing you will use JS for⁠—especially as we’re starting out⁠—is simply to add or remove (toggle) a class from something when the user interacts with your page (such as clicking on a menu).

      • Storing the information you need⁠—Variables – MDN
        Variables are always going to make your life easier.

      • Element: classList property – MDN
        Controls the CSS classes on an HTML element.

      Like with our earlier transition examples, the element needs two states in your CSS: without the class and then with the class. The JavaScript interaction/​event will just switch between them, and our CSS transition will smooth out the change. Keep in mind here that the JS doesn’t (and shouldn’t/​needn’t) do anything visual, itself! That is still the domain of our styles.

      We’ll again use querySelector to target our elements⁠—but here we’ll store them as variables to keep our code readable and reusable. These are much like their CSS counterparts! Mind your ergonomics.

      Then using our variables, we’ll again add an addEventListener to listen for a click, now modifying the classList (CSS classes) of a different element⁠—to switch between our two states:

    • #

    • <>

    • ↗

    • Note the camelCase variable names, which is the JavaScript convention. Longer, more-descriptive names will help as your code gets more complex.

      JavaScript’s querySelector takes any CSS selector, even other classes⁠—and will return the first matching instance. The classList can be modified on any element in your HTML (or sometimes, even just on document.body itself)! You can also specifically use classList.add and classList.remove, if you don’t want or need to separate the on-and-off behavior from classList.toggle !

      You can do many, many things with this basic “toggle a class” JS! It’s the basis for much of the interactivity you see online.

      Opening a Modal

      You might also want to use JavaScript to “open” a modal <dialog> element⁠—which you might use for a menu, an overlay, or a lightbox. (In the software sense, a modal means your visitor must interact with the <dialog> before they can do anything else.)

      • <dialog>: The Dialog element – MDN
        You used to have to write a lot more JS for these!

      • ::backdrop – MDN
        Style the overlays behind them.

      You could (and used to) do this by adding/​removing classes⁠—but this newer element uses JS to toggle an open attribute (akin to <details>/​<summary>) for the two states. This approach gives us some nice “free”, built-in behaviors: making the rest of the page inert, adding a ::backdrop pseudo-element, stopping background scrolling (this still needs CSS!), and even listening to Esc for dismissing/​closing the modal.

      It’s a lot of useful behavior without too much code:

    • #

    • <>

    • ↗

    • Note the style.css changes to make the dialog appear as we want. This is all a bit hokey, but better than it used to be!

      Watching for Scrolling

      Another very common, designer-y use for JavaScript is to do something when an element enters or exits the viewport, scrolling into or out of view⁠—like fading, highlighting, or moving something in. Remember, acknowledging and responding to the viewport is always very web-y!

      • Intersection Observer API – MDN
        Watch for things entering/​exiting the viewport.

      • if…else – MDN
        Conditional logic blocks, “if this then that.”

      Again we’ll need two states in our CSS, defined with and without a class. But now we’ll make use of the user’s scrolling⁠—instead of a click event⁠—to toggle the between the two visual states. Our JS still only adds/​removes the class!

      This used to be unnecessarily hard in JavaScript, and was one of the things jQuery was created to help with. Nowadays we can easily use IntersectionObserver to watch the element:

    • #

    • <>

    • ↗

    • Note the if /​ else statement, an example of conditional logic!

      Loops

      You will often want to use this on multiple elements⁠—and remember, when in code, don’t repeat yourself! In JS, when we want to do something over and over we’re talking about loops.

      • Element: querySelectorAll() method – MDN
        Gets multiple elements.

      • forEach() – MDN
        And “loop” through them.

      We can use querySelectorAll to select multiple elements⁠—which gives us a NodeList (a kind of Array)⁠—and then use a forEach loop to run the same class for each of them:

    • #

    • <>

    • ↗

    • Here we’ve also adjusted the rootMargin from the full-viewport default with an inset, so the elements don’t transition immediately.

      Implementation always subject to change

      Much of our (designer) need for JavaScript’s IntersectionObserver is moving fully into CSS with its new scroll-driven animations.

      These are usually a safe progressive enhancement, as they’ll just appear static in older browsers/​Firefox.

      Some Miscellaneous JS Tips

      Alright, that is a lot. Like we’ve been saying⁠—JavaScript is A Whole Thing. Here are some other tips, as you start to explore:

      • Using alert(yourVariable) for telemetry/​debugging can quickly be pretty annoying⁠—instead, you can use console.log(yourVariable) to show messages in the DevTools console.

        A quick console.log('Hello world!') can check if things are plugged in right. The console will also show any JavaScript errors!

        In other languages, these functions are often, ironically, called print.

      • Search on Stack Overflow ! (Though it’s… probably on the way out.) Another person has likely had your problem, before.

        Many people don’t really know JS (Michael included)… so much as they really know how to find things elsewhere on the internet: Stack Overflow, Codepen, and so on.

      • This brings us back to LLM⁠s, large language models (“artificial intelligence”)⁠—tools like Chat⁠sGPT, GitHub Copilot, Claude Code, etc.

        These can be useful; we use them ourselves. But much like Stack Overflow or any other resource online, you have to know what to look for⁠—and need a level of understanding to do this to, and to discern the value from the noise/​code salad.

      All resources require attribution

      We don’t want you to treat code/​examples from anywhere as a “black box”⁠—we we are here to learn and understand.

      Copying wholesale from these tools⁠—or any other source⁠—does not demonstrate your understanding. We’ll remind you of our class policy on this. Always properly/​fully attribute and explain to us what you have learned!

      • Ignore any examples/​suggestions that have lots of dollar signs, like $("something").else⁠—it means this is jQuery, and so is very outdated! (And Eric really, really doesn’t like jQuery.)

      • You’ll also likely see examples/​suggestions that wrap some logic in a DOMContentLoaded (or load) event listener⁠—which will run the contents after the whole page is available, no matter where the <‍script> element is located in the HTML. But we’ll use the modern defer attribute to avoid this dance!

        Old way

        						<script src="script.js"></script>
        
        			
        	
        						document.addEventListener('DOMContentLoaded', () => {
        	console.log('Runs after the page is loaded!')
        })
        
        			
        	

        New/​better way

        						<script defer src="script.js"></script>
        
        			
        	
        						console.log('Runs after the page is loaded!')
        
        			
        	
      • To quickly get recent/​modern, vanilla JavaScript results, instead include “ES⁠6+ ” in your searches and prompts⁠—this refers to a more recent, easier-to-use syntax. Models often now skew/​default towards this, but not always!

      • Relatedly, if you see “arrow functions” (with => ) it is a pretty good sign the answer is relatively recent.

        Declaring variables with let and const (instead of the older var ) is another good sign.

      • Like HTML/​CSS, JS does not really care about whitespace or tabbing. Use them for your own clarity!

      • But it is case-sensitive! So this and This are not the same. (The most common JS convention is camelCase.)

      • Many new-to-JS problems are caused by unclosed blocks and groupings. Akin to HTML’s <> </> and CSS’s { }, always mind your matching { } and ( ) in JS!

      • You’ll also see a lot of semicolons ; but secretly you (almost never) actually need them! Declutter your code.

      Any application that can be written in JavaScript, will eventually be written in JavaScript.

      Jeff Atwood, 2007

    • Week Nº 18

      Feb. 4

    • Week Nº 19

      Feb. 11

    • Week Nº 20

      Feb. 18

    • Project Nº 4: “Links”

      Feb. 25

    • Week Nº 21

      Feb. 25

  • Unit Nº 5: “If All You Have Is a Hammer, Everything Looks like a Nail”

    Wks. 22–30

    • Week Nº 22

      Mar. 4

    • Putting a (Link/​Meta) Bow on It

    • Week Nº 23

      Mar. 11

    • Spring Break

    • Week Nº 24

      Mar. 25

    • Week Nº 25

      Apr. 1

    • Week Nº 26

      Apr. 8

    • Week Nº 27

      Apr. 15

    • Project Nº 5: “Functions”

      Apr. 22

    • Week Nº 28

      Apr. 22

    • Week Nº 29

      Apr. 29

    • Week Nº 30

      May 6

    • “Everything Else”

  • Project “Index”

    May 15

  • The end