From 4a70d80e85a8123678c575560fbc905942597454 Mon Sep 17 00:00:00 2001 From: Sadman Soumique Date: Thu, 20 Aug 2026 13:35:57 +0600 Subject: [PATCH 1/5] feat(quiz): enhance styles for draw and pin image questions in quiz layout --- .../scss/frontend/learning-area/_quiz.scss | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/assets/src/scss/frontend/learning-area/_quiz.scss b/assets/src/scss/frontend/learning-area/_quiz.scss index 4688d6fa32..16cce397a3 100644 --- a/assets/src/scss/frontend/learning-area/_quiz.scss +++ b/assets/src/scss/frontend/learning-area/_quiz.scss @@ -52,6 +52,30 @@ $tutor-quiz-content-bottom-offset: calc( overflow: auto; } + &[data-question-layout-view='single_question']:has(.tutor-quiz-question[data-question='draw_image']), + &[data-question-layout-view='single_question']:has(.tutor-quiz-question[data-question='pin_image']), + &[data-question-layout-view='question_pagination']:has(.tutor-quiz-question[data-question='draw_image']), + &[data-question-layout-view='question_pagination']:has(.tutor-quiz-question[data-question='pin_image']) { + .tutor-quiz-questions { + justify-content: flex-start; + overflow: hidden; + } + + .tutor-quiz-question-wrapper { + flex: 1 1 auto; + min-height: 0; + max-height: none; + overflow: hidden; + } + + .tutor-quiz-question { + height: 100%; + min-height: 0; + margin-block: 0; + overflow: hidden; + } + } + &[data-question-layout-view='single_question'] { &:has(.tutor-quiz-questions-pagination) { .tutor-quiz-question-wrapper { @@ -1104,6 +1128,50 @@ $tutor-quiz-content-bottom-offset: calc( } } + &-submission[data-question-layout-view='single_question'], + &-submission[data-question-layout-view='question_pagination'] { + [data-question='draw_image'], + [data-question='pin_image'] { + .tutor-quiz-question-header { + flex-shrink: 0; + } + + .tutor-draw-image-question, + .tutor-pin-image-question { + @include tutor-flex(column, center, center); + flex: 1 1 auto; + min-height: 0; + margin-top: 0; + width: 100%; + container-type: size; + } + + .tutor-draw-image-actions { + flex-shrink: 0; + align-self: stretch; + } + + .tutor-draw-image-wrapper, + .tutor-pin-image-wrapper { + position: relative; + flex: 0 1 auto; + min-height: 0; + max-height: 100%; + width: fit-content; + max-width: 100%; + + img { + display: block; + max-height: 100cqh; + max-width: 100cqw; + width: auto; + height: auto; + object-fit: contain; + } + } + } + } + &-footer { padding-block: $tutor-spacing-8; margin-top: auto; From 00b45e1bea420c3795746f5f3dd78f1e7ecb79dd Mon Sep 17 00:00:00 2001 From: Sadman Soumique Date: Thu, 20 Aug 2026 16:27:17 +0600 Subject: [PATCH 2/5] feat(quiz): improve styles for puzzle question layout in quiz component --- .../scss/frontend/learning-area/_quiz.scss | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/assets/src/scss/frontend/learning-area/_quiz.scss b/assets/src/scss/frontend/learning-area/_quiz.scss index 16cce397a3..19e65954c4 100644 --- a/assets/src/scss/frontend/learning-area/_quiz.scss +++ b/assets/src/scss/frontend/learning-area/_quiz.scss @@ -76,6 +76,32 @@ $tutor-quiz-content-bottom-offset: calc( } } + // Puzzle: card fills the viewport slot; board + scatter scroll inside the card body. + &[data-question-layout-view='single_question']:has(.tutor-quiz-question[data-question='puzzle']), + &[data-question-layout-view='question_pagination']:has(.tutor-quiz-question[data-question='puzzle']) { + .tutor-quiz-questions { + justify-content: flex-start; + overflow: hidden; + } + + .tutor-quiz-question-wrapper { + flex: 1 1 auto; + min-height: 0; + max-height: 100%; + overflow: hidden; + @include tutor-flex(column); + } + + .tutor-quiz-question { + flex: 1 1 auto; + min-height: 0; + max-height: 100%; + height: auto; + margin-block: 0; + overflow: hidden; + } + } + &[data-question-layout-view='single_question'] { &:has(.tutor-quiz-questions-pagination) { .tutor-quiz-question-wrapper { @@ -1170,6 +1196,28 @@ $tutor-quiz-content-bottom-offset: calc( } } } + + // Puzzle: card stays viewport-bound; board keeps natural size; scroll happens on the puzzle body. + [data-question='puzzle'] { + .tutor-quiz-question-header { + flex-shrink: 0; + } + + .tutor-puzzle-question { + @include tutor-flex(column, center, flex-start); + flex: 1 1 auto; + flex-grow: 1; + // Force flex item to honor parent height so overflow-y:auto creates a scrollport. + height: 0; + min-height: 0; + margin-top: 0; + width: 100%; + overflow-x: hidden; + overflow-y: auto; + overscroll-behavior: contain; + -webkit-overflow-scrolling: touch; + } + } } &-footer { From 95dddcf518959ba531b9be734dff44881810293e Mon Sep 17 00:00:00 2001 From: Sadman Soumique Date: Tue, 25 Aug 2026 12:36:44 +0600 Subject: [PATCH 3/5] feat(quiz): improve layout and styling for quiz question components - Added new variable `$tutor-quiz-draw-pin-chrome` for better spacing calculations. - Adjusted flex properties for `.tutor-quiz-question-wrapper-active` to enhance layout responsiveness. - Updated styles for various question types to ensure proper content sizing and overflow handling. - Improved alignment and overflow behavior for quiz questions in different layouts. --- .../scss/frontend/learning-area/_quiz.scss | 84 ++++++++++++------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/assets/src/scss/frontend/learning-area/_quiz.scss b/assets/src/scss/frontend/learning-area/_quiz.scss index eefad843fb..bfd651e3f7 100644 --- a/assets/src/scss/frontend/learning-area/_quiz.scss +++ b/assets/src/scss/frontend/learning-area/_quiz.scss @@ -9,6 +9,9 @@ $tutor-quiz-pagination-height: 60px; $tutor-quiz-content-bottom-offset: calc( #{$tutor-quiz-pagination-gap-from-footer} + #{$tutor-quiz-pagination-height} + #{$tutor-spacing-2} ); +// Chrome inside the questions slot for draw/pin: meta, card padding/gap, header, actions. +// Plain sum string so it interpolates cleanly into a single outer calc(). +$tutor-quiz-draw-pin-chrome: '#{$tutor-spacing-5} + 2.5rem + #{$tutor-spacing-8} * 2 + #{$tutor-spacing-7} + 4.5rem + 3rem'; .tutor-quiz { &-submission { @@ -52,53 +55,74 @@ $tutor-quiz-content-bottom-offset: calc( overflow: auto; } - &[data-question-layout-view='single_question']:has(.tutor-quiz-question[data-question='draw_image']), - &[data-question-layout-view='single_question']:has(.tutor-quiz-question[data-question='pin_image']), - &[data-question-layout-view='question_pagination']:has(.tutor-quiz-question[data-question='draw_image']), - &[data-question-layout-view='question_pagination']:has(.tutor-quiz-question[data-question='pin_image']) { + // Scope to the active question only — all questions stay in the DOM (x-show), + // so a bare :has([data-question='…']) would leak layout rules to other types. + // Draw/pin: keep the card content-sized (hugs the scaled image) while the + // questions slot remains the size container that caps the image to the viewport. + &[data-question-layout-view='single_question']:has( + .tutor-quiz-question-wrapper-active .tutor-quiz-question[data-question='draw_image'] + ), + &[data-question-layout-view='single_question']:has( + .tutor-quiz-question-wrapper-active .tutor-quiz-question[data-question='pin_image'] + ), + &[data-question-layout-view='question_pagination']:has( + .tutor-quiz-question-wrapper-active .tutor-quiz-question[data-question='draw_image'] + ), + &[data-question-layout-view='question_pagination']:has( + .tutor-quiz-question-wrapper-active .tutor-quiz-question[data-question='pin_image'] + ) { .tutor-quiz-questions { - justify-content: flex-start; + justify-content: center; overflow: hidden; + container-type: size; } - .tutor-quiz-question-wrapper { - flex: 1 1 auto; + .tutor-quiz-question-wrapper-active { + flex: 0 1 auto; min-height: 0; - max-height: none; + max-height: 100%; + width: 100%; overflow: hidden; - } + @include tutor-flex(column); - .tutor-quiz-question { - height: 100%; - min-height: 0; - margin-block: 0; - overflow: hidden; + .tutor-quiz-question { + flex: 0 1 auto; + height: auto; + min-height: 0; + max-height: 100%; + margin-block: 0; + overflow: auto; + } } } // Puzzle: card fills the viewport slot; board + scatter scroll inside the card body. - &[data-question-layout-view='single_question']:has(.tutor-quiz-question[data-question='puzzle']), - &[data-question-layout-view='question_pagination']:has(.tutor-quiz-question[data-question='puzzle']) { + &[data-question-layout-view='single_question']:has( + .tutor-quiz-question-wrapper-active .tutor-quiz-question[data-question='puzzle'] + ), + &[data-question-layout-view='question_pagination']:has( + .tutor-quiz-question-wrapper-active .tutor-quiz-question[data-question='puzzle'] + ) { .tutor-quiz-questions { justify-content: flex-start; overflow: hidden; } - .tutor-quiz-question-wrapper { + .tutor-quiz-question-wrapper-active { flex: 1 1 auto; min-height: 0; max-height: 100%; overflow: hidden; @include tutor-flex(column); - } - .tutor-quiz-question { - flex: 1 1 auto; - min-height: 0; - max-height: 100%; - height: auto; - margin-block: 0; - overflow: hidden; + .tutor-quiz-question { + flex: 1 1 auto; + min-height: 0; + max-height: 100%; + height: auto; + margin-block: 0; + overflow: hidden; + } } } @@ -1253,11 +1277,10 @@ $tutor-quiz-content-bottom-offset: calc( .tutor-draw-image-question, .tutor-pin-image-question { @include tutor-flex(column, center, center); - flex: 1 1 auto; + flex: 0 1 auto; min-height: 0; margin-top: 0; width: 100%; - container-type: size; } .tutor-draw-image-actions { @@ -1270,14 +1293,15 @@ $tutor-quiz-content-bottom-offset: calc( position: relative; flex: 0 1 auto; min-height: 0; - max-height: 100%; width: fit-content; max-width: 100%; img { display: block; - max-height: 100cqh; - max-width: 100cqw; + // Cap against the questions slot (size container), not a stretched card. + // Interpolate the whole value so Sass does not strip the outer calc(). + max-height: #{"min(744px, calc(100cqh - (#{$tutor-quiz-draw-pin-chrome})))"}; + max-width: 100%; width: auto; height: auto; object-fit: contain; From 298a804aa7f60742616fb1b1f561a4158ab644a8 Mon Sep 17 00:00:00 2001 From: Sadman Soumique Date: Tue, 25 Aug 2026 12:53:01 +0600 Subject: [PATCH 4/5] fix(quiz): remove unnecessary margin from quiz question styling - Removed the `margin-block` property from the quiz question styles to improve layout consistency and prevent unwanted spacing issues. --- assets/src/scss/frontend/learning-area/_quiz.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/assets/src/scss/frontend/learning-area/_quiz.scss b/assets/src/scss/frontend/learning-area/_quiz.scss index bfd651e3f7..c8bff89bb0 100644 --- a/assets/src/scss/frontend/learning-area/_quiz.scss +++ b/assets/src/scss/frontend/learning-area/_quiz.scss @@ -90,7 +90,6 @@ $tutor-quiz-draw-pin-chrome: '#{$tutor-spacing-5} + 2.5rem + #{$tutor-spacing-8} height: auto; min-height: 0; max-height: 100%; - margin-block: 0; overflow: auto; } } From 36cc1a2715872351a83e85533e6923a334e057cf Mon Sep 17 00:00:00 2001 From: Sadman Soumique Date: Tue, 25 Aug 2026 13:30:41 +0600 Subject: [PATCH 5/5] refactor(quiz): update puzzle question styling for improved layout - Adjusted flex properties and dimensions for the puzzle question components to prevent stretching and ensure proper content sizing. - Enhanced the styling of the modal and quiz question wrapper to maintain a centered layout and improve overflow handling. - Updated comments to reflect the new behavior of the puzzle question layout. --- .../modals/QuestionPreviewModal.tsx | 34 +++++++++++++++---- .../scss/frontend/learning-area/_quiz.scss | 19 +++++------ 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/assets/src/js/v3/entries/course-builder/components/modals/QuestionPreviewModal.tsx b/assets/src/js/v3/entries/course-builder/components/modals/QuestionPreviewModal.tsx index 595a242a28..4bdb419252 100644 --- a/assets/src/js/v3/entries/course-builder/components/modals/QuestionPreviewModal.tsx +++ b/assets/src/js/v3/entries/course-builder/components/modals/QuestionPreviewModal.tsx @@ -574,25 +574,42 @@ const getPreviewFrameStyles = () => ` } /* - * Puzzle preview: board capped at min(52vh, 460px) like draw/pin; piece pool grows with content - * (no internal scroll), same as the live student scatter area on mobile. + * Puzzle preview: match student learning-area — content-sized card (no forced fill). + * Board keeps the course-builder cap; scatter grows with pieces (no inner stretch). + * Wrapper stays centered in the modal like other question previews. */ + .tutor-quiz-question-wrapper:has([data-question='puzzle']), + .tutor-quiz-question[data-question='puzzle'] { + flex: 0 1 auto; + height: auto; + max-height: none; + min-height: 0; + margin-block: 0; + } + .tutor-quiz-question[data-question='puzzle'] .quiz-question-ans-choice-area.tutor-puzzle-question { box-sizing: border-box; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + flex: 0 1 auto; width: 100%; max-width: 100%; min-width: 0; - align-items: center; - margin-top: 24px; + height: auto; + max-height: none; + margin-top: 0; + overflow: visible; } .tutor-quiz-question[data-question='puzzle'] .tutor-puzzle-playground { box-sizing: border-box; + flex: 0 0 auto; width: auto; max-width: 100%; max-height: min(52vh, 460px); height: auto; - flex-shrink: 0; margin-inline: auto; overflow: hidden; } @@ -608,10 +625,13 @@ const getPreviewFrameStyles = () => ` .tutor-quiz-question[data-question='puzzle'] .tutor-puzzle-scatter { box-sizing: border-box; + flex: 0 0 auto; width: 100%; max-width: 100%; - min-height: 96px; - margin-top: 12px; + min-height: 150px; + height: auto; + max-height: none; + margin-top: 0; overflow: visible; } diff --git a/assets/src/scss/frontend/learning-area/_quiz.scss b/assets/src/scss/frontend/learning-area/_quiz.scss index c8bff89bb0..c29728504b 100644 --- a/assets/src/scss/frontend/learning-area/_quiz.scss +++ b/assets/src/scss/frontend/learning-area/_quiz.scss @@ -95,7 +95,7 @@ $tutor-quiz-draw-pin-chrome: '#{$tutor-spacing-5} + 2.5rem + #{$tutor-spacing-8} } } - // Puzzle: card fills the viewport slot; board + scatter scroll inside the card body. + // Puzzle: don't stretch the card when board/scatter are short; scroll only when they overflow. &[data-question-layout-view='single_question']:has( .tutor-quiz-question-wrapper-active .tutor-quiz-question[data-question='puzzle'] ), @@ -108,18 +108,18 @@ $tutor-quiz-draw-pin-chrome: '#{$tutor-spacing-5} + 2.5rem + #{$tutor-spacing-8} } .tutor-quiz-question-wrapper-active { - flex: 1 1 auto; + flex: 0 1 auto; min-height: 0; max-height: 100%; + width: 100%; overflow: hidden; @include tutor-flex(column); .tutor-quiz-question { - flex: 1 1 auto; + flex: 0 1 auto; + height: auto; min-height: 0; max-height: 100%; - height: auto; - margin-block: 0; overflow: hidden; } } @@ -1308,7 +1308,7 @@ $tutor-quiz-draw-pin-chrome: '#{$tutor-spacing-5} + 2.5rem + #{$tutor-spacing-8} } } - // Puzzle: card stays viewport-bound; board keeps natural size; scroll happens on the puzzle body. + // Puzzle: content-sized body; scrolls only when board + scatter exceed the card. [data-question='puzzle'] { .tutor-quiz-question-header { flex-shrink: 0; @@ -1316,11 +1316,10 @@ $tutor-quiz-draw-pin-chrome: '#{$tutor-spacing-5} + 2.5rem + #{$tutor-spacing-8} .tutor-puzzle-question { @include tutor-flex(column, center, flex-start); - flex: 1 1 auto; - flex-grow: 1; - // Force flex item to honor parent height so overflow-y:auto creates a scrollport. - height: 0; + flex: 0 1 auto; min-height: 0; + max-height: 100%; + height: auto; margin-top: 0; width: 100%; overflow-x: hidden;