2  CSS

learning goals
  • Understand how CSS controls the visual presentation of HTML elements
  • Learn CSS syntax including selectors, properties, and values
  • Master targeting HTML elements using tag names, classes, and IDs
  • Apply CSS properties for text styling, layout, and visual design
  • Organize CSS using external stylesheets and understand cascading rules
  • Create common experimental layouts including centering, side-by-side, and grid arrangements
  • Troubleshoot common CSS issues and syntax errors

2.1 Introduction

Okay, now we’ve began putting HTML elements on a page. Using our house-building analogy, this is like we have all the materials now in a pile in front of our house. However a pile of lumber does not make a house. We’re going to start reasoning about how to put together these things, how to create our blueprints, our plans. CSS is really powerful and can accomplish a wide variety of things: colors, sizes, order, positioning, hiding, showing, animation, etc. We’ll scratch the surface here, but know you can do a lot with just CSS. It’s a deep subject and a powerful tool.

Like HTML, CSS is not a programming language. It’s a list of rules that you give the browser. You’ll provide rules to the browser like “all h1s will be colored red.” or “any element with the ‘lime’ class will be green”.

2.2 CSS Rules

CSS works by applying rules to HTML elements. You can target elements in three main ways: by their tag name, by a class you assign to them, or by a unique ID. Let’s see all three approaches in action:

<h1>This is the main title</h1>
<p class="highlight">This paragraph has a class</p>
<p>This is a regular paragraph with no styling</p>
<p id="unique-paragraph">This paragraph has an id</p>
/* Target by tag name */
h1 {
  color: blue;
  font-size: 32px;
  text-align: center;
}

/* Target by class (note the dot) */
.highlight {
  background-color: yellow;
  padding: 10px;
}

/* Target by ID (note the hash) */
#unique-paragraph {
  color: limegreen;
  font-decoration: underline
}

Every CSS rule follows the same basic pattern. Let’s break down the syntax:

/* Target by tag name */
selector {
  property: value;
  property: value;
}

/* Target by class (note the dot) */
.selector {
  property: value;
  property: value;
}

/* Target by ID (note the hash) */
#selector {
  property: value;
  property: value;
}

Selector - This tells CSS which HTML elements to style. It can be a tag name (h1), a class name (.highlight), or an ID (#main-title). Take note that we use the . (dot) to refer to a class and # to refer to an id.

Curly braces - The opening { and closing } contain all the styling rules for that selector.

Property - This is what aspect of the element you want to change (like color, font-size, or background-color).

Colon - The : separates the property from its value.

Value - This is what you want to set the property to (like red, 20px, or center).

Semicolon - The ; ends each property-value pair. Think of it like a period at the end of a sentence.

*Note that failing to follow these syntax rules precisely will result in your page not rendering correctly or not rendering at all because of the error.

2.2.1 Multiple Properties

You can apply as many style rules as you’d like to each selector. Let’s make our h1 even more distinctive:

<h1>This is an h1.</h1>
h1 {
  color: limegreen;
  font-size: 60px;
  font-weight: normal;
  text-decoration: underline;
  text-transform: uppercase;
  border: 3px solid pink;
}

Notice the HTML is still just <h1>This is a styled heading</h1>. All the visual changes come from the CSS rules in our stylesheet.

2.2.2 Multiple Rules

You can also create multiple rules using classes, and apply them to a single element like this:

<p class="lime-green">This is a paragraph</p>
<p class="lime-green big-font">This is a paragraph</p>
<p class="lime-green big-font underlined">This is a paragraph</p>
<p class="lime-green underlined">This is a paragraph</p>
.lime-green {
  color: limegreen;
}

.big-font {
  font-size: 25px;
}

.underlined {
  text-decoration: underline
}

2.2.3 Common CSS Properties

There are about ~350 properties that you can use but to be honest you’ll never use all of them. Maybe fifty to a hundred are used frequently and the rest are a long tail that are rarely used.

You can read more about all of the CSS properties here: W3 Schools

Here is a partial list of the most common CSS properties we might use:

<div class="container">
  <div class="demo-element">
    This element demonstrates many CSS properties at once!
  </div>
</div>
.container {
  width: 500px;
  height: 300px;
  background-color: #f8f9fa;
  border: 2px solid #dee2e6;
  margin: 20px auto;
  position: relative;
}

.demo-element {
  /* Text Properties */
  color: white;
  font-size: 18px;
  font-weight: bold;
  font-family: Arial, sans-serif;
  text-align: center;
  text-decoration: underline;
  text-transform: uppercase;
  line-height: 1.4;
  letter-spacing: 1px;

  /* Box Model Properties */
  width: 300px;
  height: 120px;
  background-color: #3498db;
  border: 3px solid #2980b9;
  border-radius: 15px;
  margin: 20px auto;
  padding: 20px;

  /* Layout Properties */
  display: flex;
  position: absolute;
  top: 50px;
  left: 50px;

  /* Visual Properties */
  opacity: 0.9;
  cursor: pointer;
  box-shadow: 5px 5px 15px rgba(0,0,0,0.3);

  /* Flexbox for centering text */
  justify-content: center;
  align-items: center;
}

.demo-element:hover {
  background-color: #2980b9;
  transform: scale(1.05);
}

Most Common CSS Properties by Category:

Text Properties:

`color` - Sets text color
`font-size` - Controls text size (px, em, rem, %)
`font-weight` - Controls boldness (normal, bold, 100-900)
`font-family` - Sets the typeface (Arial, serif, sans-serif)
`font-style` - Makes text italic or normal
`text-align` - Aligns text (left, center, right, justify)
`text-decoration` - Adds underlines, strikethrough, etc.
`text-transform` - Changes case (uppercase, lowercase, capitalize)
`line-height` - Controls spacing between lines
`letter-spacing` - Controls spacing between characters

Box Model Properties:

`width` / `height `- Sets element dimensions
`margin` - Space outside the element
`padding` - Space inside the element
`border` - Creates borders around elements
`border-radius` - Rounds corners
`background-color` - Sets background color
`background-image` - Sets background images

Layout Properties:

`display` - Controls how elements are displayed (block, inline, flex, none)
`position` - Controls positioning (static, relative, absolute, fixed)
`top` / `right` / `bottom` / `left` - Position offsets
`float` - Makes elements float left or right
`clear` - Controls floating behavior
`z-index` - Controls stacking order

Visual Properties:

`opacity` - Controls transparency (0-1)
`visibility` - Shows or hides elements (visible, hidden)
`overflow` - Controls what happens when content is too big (visible, hidden, scroll)
`cursor` - Changes mouse cursor appearance
`box-shadow` - Adds shadows to elements

These properties form the foundation of most CSS styling you’ll do in your psychology experiments.

Please note that you are not expected to memorize what all these properties are the exact syntax for using them. You can always look up the CSS property you need on a site like W3 Schools

2.3 Commenting in CSS

You may (or may not) have noticed that the comments look a little different in CSS than HTML. This is because CSS is a different language than HTML and has different syntax. Whereas in HTML we used <!-- and --> to open and close our comments, in CSS, we use /* and */ to open and close comments.

Here they are in action:

<!-- Commenting in HTML looks like this -->

<p class="lime-green">This is a paragraph</p>
<p class="lime-green big-font">This is a paragraph</p>
<p class="lime-green big-font underlined">This is a paragraph</p>
<p class="lime-green underlined">This is a paragraph</p>

<!-- 
Comments
can
be multiple
lines 
-->
/* This is a comment in CSS and will be ignored by the browser */

.lime-green {
  color: limegreen;
}

.big-font {
  font-size: 25px;
}

.underlined {
  text-decoration: underline
}

/*
Comments 
can still
be multiple
lines
*/

2.4 External CSS Stylesheets

Throughout this chapter, we’ve been writing CSS rules in a separate “CSS tab” in our examples. In real web development, this represents an external stylesheet - a separate .css file that contains all your styling rules. This is the most common and recommended approach because it keeps your HTML clean and your styles organized.

In practice, you would typically have a folder, and inside that folder at least two files: index.html (this is where your html code goes) and style.css (this is where your CSS code goes).

Then you would link to your CSS file inside your HTML so the browser knows to apply those style rules to your page. You do that inside the <head> </head> of the HTML document using <link rel="stylesheet" href="styles.css">.

<!DOCTYPE html>
<html>
<head>
  <title>My Experiment</title>
  <link rel="stylesheet" href="style.css">   
</head>
<body>
  <div class="instruction-page">
    <h1 class="page-title">Welcome to the Experiment!</h1>
    <p class="instruction-text">Follow the instructions below...</p>
    <button class="start-button">Start</button>
  </div>
</body>
</html>
.instruction-page {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}

.page-title {
  color: #2c3e50;
  font-size: 28px;
  text-align: center;
}

.instruction-text {
  font-size: 16px;
  line-height: 1.5;
  margin: 20px 0;
}

.start-button {
  background-color: #3498db;
  color: white;
  padding: 12px 24px;
  border: none;
  border-radius: 5px;
  font-size: 16px;
  cursor: pointer;
  display: block;
  margin: 20px auto;
}

The key line is <link rel="stylesheet" href="styles.css"> in the HTML head section. This tells the browser to load and apply the CSS rules from the styles.css file.

You’ll note that <link> is a self-closing tag, so we don’t need to add the </link>. There are also two attributes inside the tag. The first is rel="stylesheet", which tells the browser this particular link is a stylesheet. The second is href="style.css" which tells the browser where to look for the file. In this case, it would look in the same folder as the index.html file.

2.5 Inline Styling

Sometimes you need to apply styles directly to individual HTML elements. This is called inline styling, and you do it using the style attribute:

<div style="background-color:lightpink;">
  <p>This paragraph is not styled.</p>
  <p style="color: red; font-size: 20px; background-color: yellow;">
    This paragraph uses inline styling.
  </p>
  <p style="text-decoration: underline">This paragraph is underlined.</p>
</div>
/* There's no CSS here! */

You’ll notice that the syntax is different for inline styles. We now follow this pattern: style="property: value;" and if you want multiple style properties, you need to separate them with a semi-colon like this: style="property: value; property: value".

Inline styling can be useful in specific situations, especially when programming jsPsych experiments. We’ll see later how and when we might want to use inline styling. For now, we can think of external CSS rules as being good for creating reusable style rules that we might want to apply more than once, whereas inline styling can be useful when we are writing one-time-use HTML code that isn’t being reused multiple times.

For example, if you’re creating multiple instruction pages that all need the same button styling, you’d use a CSS class like .start-button that you can apply to any button. But if you’re generating a unique stimulus display where each element needs a different color based on experimental conditions, inline styling might be more practical.

<!-- Reusable styling with CSS classes -->
<button class="start-button">Start Experiment</button>
<button class="start-button">Continue</button>

<!-- One-time styling with inline styles -->
<div style="color: red; position: absolute; top: 100px; left: 200px;">Target A</div>
<div style="color: blue; position: absolute; top: 150px; left: 300px;">Target B</div>

2.6 Cascading Rules

Two final points to make about how CSS rules are implemented by the browser. CSS stands for “Cascading Style Sheets,” and the “cascading” part refers to two key principles that determine which styles get applied when you have multiple competing rules.

Understanding these two rules helps you predict which styles will actually be applied when you have multiple competing rules.

2.6.1 Rule 1: Child elements inherit style properties from their parents

Many CSS properties are inherited, meaning child elements automatically get the same styling as their parent elements:

<div class="parent">
  <h2>This heading is inside the div</h2>
  <p>This paragraph is also inside the div</p>
  <div class="child">
    <p>This paragraph is nested even deeper</p>
  </div>
</div>
.parent {
  color: blue;
  font-family: Arial, sans-serif;
  font-size: 18px;
}

.child {
  font-style: italic;
}

Notice how all the text inside the .parent div inherited the blue color and Arial font, even though we only applied those styles to the parent container. The deeply nested paragraph got both the inherited styles from .parent and the italic style from .child.

2.6.2 Rule 2: More specific selectors override more general selectors

When multiple CSS rules could apply to the same element, the more specific rule takes precedence:

<div class="container">
  <p>Regular paragraph</p>
  <p class="special">Paragraph with a class</p>
  <p id="unique" class="special">Paragraph with both class and ID</p>
  <p class="special" style="color: purple;">Paragraph with inline style</p>
</div>
/* Least specific: targets all paragraphs */
p {
  color: black;
  font-size: 14px;
}

/* More specific: targets paragraphs with class "special" */
.special {
  color: green;
  font-weight: bold;
}

/* Most specific: targets the element with ID "unique" */
#unique {
  color: red;
  text-decoration: underline;
}

/* Inline styles (in HTML) are even more specific than IDs */

CSS follows this hierarchy from least to most specific:

  1. Tag selectors (p, h1, div) - Least specific
  2. Class selectors (.special, .highlight) - More specific
  3. ID selectors (#unique, #header) - Very specific
  4. Inline styles (style="color: red;") - Most specific

When rules conflict, the more specific rule wins. When rules have the same specificity, the last one in the CSS file wins.

2.7 CSS for Simple Layouts

In psychology experiments, you’ll often need to arrange stimuli in specific layouts: centering a single stimulus on the screen, placing multiple stimuli side-by-side for comparison, or creating grids of items for memory or visual search tasks. Here are the most common layout techniques you’ll use.

2.7.1 Centering Stimuli

Centering is probably the most common layout need in experiments. Most single stimulus presentations need to be perfectly centered:

<div class="center-container">
  <div class="stimulus">
    <div class="target-word">YELLOW</div>
  </div>
</div>
.center-container {
  width: 100%;
  height: 400px;
  background-color: #f8f9fa;
  border: 2px solid #dee2e6;

  /* Flexbox method for centering */
  display: flex;
  justify-content: center;
  align-items: center;
}

.stimulus {
  text-align: center;
  padding: 20px;
  background-color: white;
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.target-word {
  font-size: 48px;
  font-weight: bold;
  color: blue;
  margin: 20px 0;
  letter-spacing: 3px;
}

The key properties for centering are display: flex, justify-content: center (centers horizontally), and align-items: center (centers vertically).

Flexbox is a very useful method for arranging elements on the screen. You can read more about it here: CSS Tricks: Flexbox.

2.7.2 Side-by-Side Stimuli

For comparison tasks or paired stimuli, you’ll often want elements arranged horizontally:

<div class="comparison-task">
  <h3>Which image is brighter?</h3>
  <div class="stimulus-pair">
    <div class="stimulus-item">
      <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Face-smile.svg/120px-Face-smile.svg.png" alt="Stimulus A" />
      <div class="stimulus-label">A</div>
    </div>
    <div class="stimulus-item">
      <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Face-smile.svg/120px-Face-smile.svg.png" alt="Stimulus B" />
      <div class="stimulus-label">B</div>
    </div>
  </div>
</div>
.comparison-task {
  text-align: center;
  padding: 20px;
}

.stimulus-pair {
  display: flex;
  justify-content: center;
  gap: 80px;
  margin-top: 30px;
}

.stimulus-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
}

.stimulus-item img {
  border: 3px solid #dee2e6;
  border-radius: 10px;
  background-color: white;
}

.stimulus-label {
  font-size: 24px;
  font-weight: bold;
  color: #495057;
}

The gap property creates consistent spacing between stimuli, and flex-direction: column stacks the image and label vertically within each stimulus.

2.7.3 Grid Layout for Multiple Stimuli

For displaying multiple stimuli in a grid (like in memory tasks, visual search experiments, or stimulus arrays):

<div class="memory-task">
  <h3>Study these items for the memory test</h3>
  <div class="stimulus-grid">
    <div class="grid-stimulus">CAT</div>
    <div class="grid-stimulus">DOG</div>
    <div class="grid-stimulus">BIRD</div>
    <div class="grid-stimulus">FISH</div>
    <div class="grid-stimulus">TREE</div>
    <div class="grid-stimulus">HOUSE</div>
    <div class="grid-stimulus">CAR</div>
    <div class="grid-stimulus">BOOK</div>
    <div class="grid-stimulus">PHONE</div>
  </div>
</div>
.memory-task {
  text-align: center;
  padding: 20px;
}

.stimulus-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  max-width: 400px;
  margin: 30px auto;
}

.grid-stimulus {
  width: 100px;
  height: 100px;
  background-color: #e9ecef;
  border: 2px solid #adb5bd;
  border-radius: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 16px;
  font-weight: bold;
  color: #495057;
}

The display: grid property creates a grid container, and grid-template-columns: repeat(3, 1fr) creates three equal-width columns. You can change the number to create different grid sizes (2x2, 4x4, etc.).

2.8 Troubleshooting: Why isn’t my CSS working?

CSS can be frustrating when your styles don’t appear as expected. Here are the most common issues and how to fix them: Check Your Syntax

2.8.1 1. Check for simple syntax errors

<div class="example-box">This box should be styled</div>
/* WRONG - Missing semicolon */
.example-box {
  color: red
  font-size: 20px;
}

/* WRONG - Typo in property name */
.example-box {
  colr: red;
  font-size: 20px;
}

/* WRONG - Missing colon */
.example-box {
  color red;
  font-size: 20px;
}

/* CORRECT */
.example-box {
  color: red;
  font-size: 20px;
}

Common syntax mistakes:

  • Missing semicolons (;) at the end of property-value pairs
  • Typos in property names (colr instead of color)
  • Missing colons (:) between property and value
  • Missing opening or closing curly braces ({ })

2.8.2 2. Check your selectors

Make sure your CSS selector matches your HTML exactly:

<div class="my-container">
  <p id="special-text">This paragraph has an ID</p>
  <p class="highlight">This paragraph has a class</p>
</div>
/* WRONG - Missing dot for class */
my-container {
  background-color: lightblue;
}

/* WRONG - Missing hash for ID */
special-text {
  color: red;
}

/* WRONG - Typo in class name */
.highlght {
  background-color: yellow;
}

/* CORRECT */
.my-container {
  background-color: lightblue;
}

#special-text {
  color: red;
}

.highlight {
  background-color: yellow;
}

Common selector mistakes:

  • Class selectors need a dot: .class-name
  • ID selectors need a hash: #id-name
  • Tag selectors need no prefix: p, div, h1
  • Spelling must match exactly (case-sensitive!)

2.8.3 3. Check for Specificity Conflicts

Sometimes your CSS is correct, but a more specific rule is overriding it, or an element is inheriting properties you don’t want:

<div id="container">
  <p class="text">This text should be blue, but appears red</p>
</div>

<div class="red-section">
  <h2>This heading inherits red color</h2>
  <p class="should-be-black">This paragraph should be black, not red</p>
</div>
/* Specificity conflict example */
.text {
  color: blue;
}

#container .text {
  color: red; /* More specific - this rule wins */
}

/* Inheritance problem example */
.red-section {
  color: red; /* This gets inherited by all children */
}

.should-be-black {
  /* This doesn't work because color is inherited */
  /* Need to explicitly override: */
  color: black;
}

Two common specificity problems:

Specificity conflicts: If your style isn’t applying, check if there’s a more specific rule overriding it. Remember the specificity hierarchy: inline styles > IDs > classes > tags.

Unwanted inheritance: Sometimes child elements inherit properties from their parents that you don’t want. Properties like color, font-family, and font-size are inherited automatically. To fix this, you need to explicitly override the inherited property:

/* Problem: Child inherits unwanted color */
.parent {
  color: red;
}

/* Solution: Explicitly override in child */
.child {
  color: black; /* Override the inherited red */
}

If your style isn’t working, check both whether a more specific rule is overriding it AND whether the element is inheriting an unwanted property from a parent element.