diff --git a/.changeset/display-element-sizing.md b/.changeset/display-element-sizing.md
new file mode 100644
index 0000000000..0498a4675c
--- /dev/null
+++ b/.changeset/display-element-sizing.md
@@ -0,0 +1,5 @@
+---
+"jspsych": patch
+---
+
+Add `width: 100%` and `height: 100%` to `.jspsych-content` CSS to allow plugins to use percentage-based dimensions. This enables plugins to use `height: 100%` and `width: 100%` to fill the display element. The nested DOM structure (`.jspsych-display-element` > `.jspsych-content-wrapper` > `.jspsych-content`) is preserved to maintain compatibility with the progress bar and existing plugins.
diff --git a/examples/test-height-demo.html b/examples/test-height-demo.html
new file mode 100644
index 0000000000..9eb9f776f2
--- /dev/null
+++ b/examples/test-height-demo.html
@@ -0,0 +1,74 @@
+
+
+
+ jsPsych Display Element Height Test
+
+
+
+
+
+
+
jsPsych Display Element Sizing Test
+
+
+
+
+
diff --git a/packages/jspsych/src/index.scss b/packages/jspsych/src/index.scss
index 6e55f8d23d..052b5417ac 100644
--- a/packages/jspsych/src/index.scss
+++ b/packages/jspsych/src/index.scss
@@ -32,6 +32,8 @@
.jspsych-content {
text-align: center;
margin: auto; /* this is for overflowing content */
+ width: 100%;
+ height: 100%;
}
.jspsych-top {
diff --git a/packages/jspsych/tests/core/display-element-sizing.test.ts b/packages/jspsych/tests/core/display-element-sizing.test.ts
new file mode 100644
index 0000000000..2cbf563a74
--- /dev/null
+++ b/packages/jspsych/tests/core/display-element-sizing.test.ts
@@ -0,0 +1,86 @@
+import { clickTarget, startTimeline } from "@jspsych/test-utils";
+import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from "jspsych";
+
+import { initJsPsych } from "../../src";
+
+describe("Display element sizing", () => {
+ test("jspsych-content should have the jspsych-content class", async () => {
+ const jsPsych = initJsPsych();
+
+ class TestSizingPlugin implements JsPsychPlugin {
+ static info = {
+ name: "test-sizing",
+ version: "1.0.0",
+ parameters: {},
+ data: {},
+ };
+
+ constructor(private jsPsych: JsPsych) {}
+
+ trial(display_element: HTMLElement, trial: any) {
+ display_element.innerHTML = '
Test
';
+
+ // Check that the display element has the jspsych-content class
+ expect(display_element.classList.contains("jspsych-content")).toBe(true);
+
+ // Check that it's wrapped in jspsych-content-wrapper
+ const contentWrapper = display_element.parentElement;
+ expect(contentWrapper?.classList.contains("jspsych-content-wrapper")).toBe(true);
+
+ // Check that the content wrapper is inside jspsych-display-element
+ const displayContainer = contentWrapper?.parentElement;
+ expect(displayContainer?.classList.contains("jspsych-display-element")).toBe(true);
+
+ this.jsPsych.finishTrial();
+ }
+ }
+
+ await jsPsych.run([
+ {
+ type: TestSizingPlugin,
+ },
+ ]);
+ });
+
+ test("jspsych-content-wrapper should exist with progress bar", async () => {
+ const jsPsych = initJsPsych({
+ show_progress_bar: true,
+ });
+
+ class TestProgressPlugin implements JsPsychPlugin {
+ static info = {
+ name: "test-progress",
+ version: "1.0.0",
+ parameters: {},
+ data: {},
+ };
+
+ constructor(private jsPsych: JsPsych) {}
+
+ trial(display_element: HTMLElement, trial: any) {
+ // Verify progress bar exists
+ const progressBar = document.querySelector("#jspsych-progressbar-container");
+ expect(progressBar).not.toBeNull();
+
+ // Verify content wrapper still exists and has proper styling
+ const contentWrapper = display_element.parentElement;
+ expect(contentWrapper?.classList.contains("jspsych-content-wrapper")).toBe(true);
+
+ // Verify display element structure
+ const displayContainer = contentWrapper?.parentElement;
+ expect(displayContainer?.classList.contains("jspsych-display-element")).toBe(true);
+
+ // Progress bar should be a sibling of the content wrapper (both inside display element)
+ expect(displayContainer?.contains(progressBar)).toBe(true);
+
+ this.jsPsych.finishTrial();
+ }
+ }
+
+ await jsPsych.run([
+ {
+ type: TestProgressPlugin,
+ },
+ ]);
+ });
+});