; PSY 1903
PSY 1903 Programming for Psychologists

CSS Fundamentals

For a very quick overview of CSS, watch this video: CSS in 100 seconds.

CSS, or Cascading Style Sheets, is a stylesheet language used to describe the presentation of HTML documents. CSS controls the layout, colors, fonts, and overall visual appearance of web pages.

CSS has three basic ingredients:

  1. Selectors: Select which HTML elements to style.
  2. Properties: Define what aspect of the element to style.
  3. Values: Specify the style applied to the property.

The syntax for these ingredients looks like this:

selector {
    property: value;
}

For example, if you wanted to change the font size and color of all paragraph (p) elements on the page, your CSS would look like this:

p {
    color: blue;
    font-size: 16px;
}

In this example, the selector is p.

The properties are color and font-size.

The values are blue and 16px.

Selecting by class

In addition to selecting elements by type, you can add identifying attributes to elements for more selective styling. For example, if you wanted to apply styles just a subset of paragraph elements, you could add a class attribute to those elements like so:

<p>Hello 1</p>
<p class='special'>Hello 2</p>
<p class='special'>Hello 3</p>
<p>Hello 4</p>

...then select just those elements by class name using a period followed by the class name:

p {
    color: blue;
    font-size: 16px;
}

/* Select elements by class name */
.special {
    font-size: 25px;
}

Results:

Observations:

  • Comments in CSS are made in CSS using this syntax: /* comment */
  • The color blue is applied to all paragraph elements, regardless of class, because it was set with an element selector p {...}
  • The font-size of 25px in the .special class selector overrides the font-size of 16px for the paragraph element. This is because class selectors take precedence over element selectors.

Applying CSS to HTML

There are a few ways to connect your CSS to HTML but we will focus on external CSS where CSS is placed in an external file and then linked to our HTML files (very similar to how we linked our JavaScript files).

To do this, create a file with a .css (e.g. styles.css) extension alongside your other project files. Within this file, you can start with a very obvious style, just to test that the styles are being applied:

body {
    background-color:yellow;
}

To connect this style sheet, update your HTML file adding a new link line after the jsPsych-specific CSS is included:

<link href='https://unpkg.com/jspsych/css/jspsych.css' rel='stylesheet' type='text/css'>
<link href='styles.css' rel='stylesheet' type='text/css'>

Reloading your experiment in the browser, you should see it now has a yellow background, confirming your CSS styles were successfully linked and applied.

Of course you should not leave your experiment with a yellow background - that was just for testing purposes - so be sure to update your CSS file accordingly once you’ve confirmed the connection.

Reference

CSS has about 500 different style properties to choose from (see: MDN CSS Reference).

CSS properties can be grouped into several categories, including but not limited to:

  • Box Model: width, height, padding, margin, border, box-sizing, etc.
  • Positioning: position, top, right, bottom, left, z-index, float, clear, etc.
  • Color and Background: color, background-color, background-image, background-position, background-size, background-repeat, etc.
  • Text and Fonts: font-family, font-size, font-weight, font-style, line-height, text-align, text-decoration, text-transform, letter-spacing, word-spacing, etc.
  • Flexbox: display, flex-direction, justify-content, align-items, align-content, flex-wrap, flex-grow, flex-shrink, flex-basis, etc.
  • Grid Layout: grid-template-columns, grid-template-rows, grid-template-areas, grid-gap, grid-column, grid-row, grid-area, etc.
  • Animations and Transitions: animation, animation-name, animation-duration, animation-timing-function, transition, transition-property, transition-duration, transition-timing-function, etc.
  • Filters: filter, blur, brightness, contrast, drop-shadow, grayscale, etc.
  • Layout: display, overflow, visibility, clip, float, clear, vertical-align, etc.
  • Others: cursor, opacity, visibility, content, outline, outline-color, outline-style, outline-width, pointer-events, etc.

When it comes to CSS, we will bend our AI guideline of avoiding have AI generate code for you. CSS is a quirky syntax language to learn, and unless you plan on using it every day, we encourage harnessing the powers of AI to help generate CSS for you if needed.

How much styling do you need?

All of our experiments are linking a default jsPsych stylesheet that applies some baseline styles to our pages:

<link href='https://unpkg.com/jspsych/css/jspsych.css' rel='stylesheet' type='text/css' />

In general, the styles provided in jspsych.css present a clear and legible interface for your experiments, and there’s not a lot of need for custom styling on top of this.

There are a few instances though, where styling may be necessary or may enhance your experiment, as demonstrated in the following examples.

EST Colors

In the Emotional Stroop Task you will have the need to display your stimuli in different text colors. One way to do this is to define classes for the respective colors:

.red {
    color: red;
}

.green {
    color: green;
}

.blue {
    color: blue;
}

Then, you can dynamically apply these color classes. Here is a simplified example:

// Create a randomized array of colors
let colors = jsPsych.randomization.repeat(['red', 'green', 'blue'], 1);

// Choose the last color from the colors array
let color = colors.pop();

let trial = {
    type: jsPsychHtmlKeyboardResponse,
    choices: ['f', 'j'],
    // Dynamically set the class based on our randomly chosen color
    stimulus: `
        <span class='${color}'>ball</span>`
    ,
};
timeline.push(trial);

IAT Layout

In an Implicit Association Task, you need to display two category words on the left and right side of the screen, with a main word in the middle like so:

To accomplish this layout, the stimulus is set up so each category is in a span element with a class of category1 and category2 for styling purposes. Following the categories is a div element with the main word:

Example trial showing this HTML structure (words are hard-coded for the purpose of this example):

let trial = {
    type: jsPsychHtmlKeyboardResponse,
    choices: ['f', 'j'],
    stimulus: `
        <span class='category1'> <strong>family</strong> (press F)</span>
        <span class='category2'> <strong>career</strong> (press J)</span>
        <p class='word'>home</p>`
    ,
};

The styling for these elements look like this:

.category1 {
    margin-right: 100px;
}

.category2 {
    margin-left: 100px;
}

.word {
    margin-top: 100px;
    font-size: 60px;
}

Keyboard instruction styling

When prompting participants to enter keyboard responses, you can draw attention to the key that should be pressed by styling the key output like a keyboard key. Example:

To accomplish this, you can use/adapt this .key class:

.key {
    border: 1px solid black;
    border-radius: 2px;
    display: inline-block;
    padding: 5px 10px;
}

Example applying the above class:

let blockIntroTrial = {
      type: jsPsychHtmlKeyboardResponse,
      stimulus: `
          <p>You are about to see a series of characters.</p>
          <p>If the characters make up a word, press the <span class='key'>F</span> key.</p>
          <p>If the characters do not make up a word, press the <span class='key'>J</span> key.</p>
          <p>Press <span class='key'>SPACE</span> to begin.</p>
          `,
      choices: [' '],
};

CSS Loader

CSS can be used to animate elements on the page. To demonstrate this, let’s add a loading icon that spins to our resultsTrial trial:

We’ll get the CSS code for our loader from https://cssloaders.github.io.

To set this up, first add a <span class='loader'></span> element:

let resultsTrial = {
    type: jsPsychHtmlKeyboardResponse,
    choices: ['NO KEYS'],
    async: false,
    stimulus: function () {
        return `
                <h1>Please wait...</h1>
                <span class='loader'></span>
                <p>We are saving the results of your inputs.</p>
            `;
    },
    // ...etc...

Then add these styles to your CSS file:

.loader {
    width: 48px;
    height: 48px;
    border: 5px solid #000;
    border-bottom-color: transparent;
    border-radius: 50%;
    display: inline-block;
    box-sizing: border-box;
    animation: rotation 1s linear infinite;
}

@keyframes rotation {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

To test your loader is working, comment out the following line in your results trial:

jsPsych.finishTrial();

This will cause your experiment to never progress past the loading trial, which will allow you to study what it looks like and do any content/css tweaks. Once everything looks good, re-enable the above line.