Проверка работает, а люди застревают
У учебного задания есть трудность, ради которой его придумали: нужно самому выбрать способ решения и проверить его. Непонятное условие добавляет другую работу — угадать, какой результат имел в виду автор. Долгое прохождение ещё не позволяет отличить одно от другого. Прежде чем упрощать задание, я бы выяснил, что именно пытаются сделать ученики.
В основе материала — случай из разработки курсов, о котором я рассказывал в 2014 году. Пример проверки и ссылки на спецификации подготовлены в октябре 2026 года.
На курсах HTML и CSS в HTML Academy мы сталкивались с заданием, которое выделялось по времени прохождения. Когда посмотрели упражнение и комментарии учеников, выяснилось, что им непонятно, чего от них хотят. После правки условия время у следующей группы вернулось к обычным значениям. Об этом случае я рассказывал в 2014 году.
Время помогло выбрать задание для разбора, но не объяснило причину задержки. Она могла быть и в проверке, и в интерфейсе, и в том, что предыдущий урок не подготовил ученика. Править условие имело смысл после того, как мы поняли затруднение.
Покажу такой разбор на отдельном учебном примере. Упражнение и числа ниже придуманы; это не данные того курса. Пройдём от заметной задержки до изменения условия, проверяя по пути другие возможные причины.
Какую задачу написал автор
Ученик уже познакомился с внешними и внутренними отступами. Теперь нужно выбрать подходящее свойство по требуемому результату. В редакторе есть карточка с текстом и видимой рамкой. Начальная разметка такая:
<article class="card">
<p>Содержимое карточки</p>
</article>
.card {
border: 1px solid black;
}
.card p {
margin: 0;
}
Разметка фиксирована. В этом примере ученик меняет только отступы карточки, остальные свойства остаются прежними. В условии написано:
Сделайте одинаковые отступы по 16 пикселей вокруг карточки. Размер рамки и оформление текста менять не нужно.
Автор ждёт внутренние отступы карточки. Ученик читает «вокруг карточки» и добавляет margin: 16px. Появляется расстояние снаружи, проверка не проходит. Проверка отвечает: «Проверьте отступы карточки».
Это правдоподобное прочтение условия. Внешний отступ как раз расположен снаружи рамки, внутренний отделяет рамку от содержимого. Такое разделение есть и в описании блочной модели CSS. Но автор уже знает, какой результат задумал, и при повторном чтении мысленно добавляет это знание к словам задания.
Подсказка «здесь нужен padding» поможет пройти упражнение, но выбор свойства за ученика уже сделаем мы.
Что означают восемь попыток
Для разбора возьмём восемь учеников, впервые открывших это упражнение. Назовём исходное условие версией A. Каждую попытку наблюдаем 30 минут от открытия. Если за это время получено успешное решение, записываем время до него; иначе отмечаем, что в пределах окна попытка не завершена. Повторные нажатия кнопки проверки относятся к той же попытке.
В таблице есть время, в течение которого вкладка была скрыта. Оно помогает заметить возможный перерыв, но не измеряет мыслительную работу. На открытой вкладке тоже можно отвлечься, а на другой вкладке можно читать справочник по CSS.
| Попытка A | Завершена за 30 минут | До успеха или конца окна, с | Из них вкладка скрыта, с | Нажатий проверки | Первое изменение |
|---|---|---|---|---|---|
| 01 | Да | 120 | 0 | 1 | padding |
| 02 | Да | 180 | 0 | 2 | margin |
| 03 | Да | 240 | 0 | 3 | margin |
| 04 | Да | 300 | 0 | 4 | margin |
| 05 | Да | 1500 | 1200 | 2 | margin |
| 06 | Нет | 1800 | 0 | 5 | margin |
| 07 | Нет | 1800 | 1680 | 1 | Без изменения |
| 08 | Нет | 1800 | 0 | 4 | margin |
Успели закончить пять человек из восьми, то есть 62,5%. В знаменателе стоят начавшие это упражнение. Если из двадцати начавших курс его открыли только наши восемь человек, то доля дошедших до упражнения будет восемь из двадцати. Пять из двадцати покажут, какая часть исходной группы успела его закончить. Эти числа описывают путь от начала курса, включая потери на предыдущих заданиях. Для разбора нынешнего упражнения сравниваем закончивших с теми, кто его начал.
Времена успешных попыток: 120, 180, 240, 300 и 1500 секунд. Медиана равна 240 секундам, среднее 468. Одна длинная попытка заметно сдвинула среднее. У неё есть и возможное объяснение: двадцать минут вкладка была скрыта.
Если вычесть скрытое время, среднее по успешным станет 228 секунд. Это полезный дополнительный расчёт, но называть его «временем решения» я бы не стал. Мы вычли время по признаку видимости вкладки, а не по признаку работы над задачей. Для попытки 05 после такого вычитания остаётся пять минут; что человек делал в остальные двадцать, таблица не говорит.
При этом оба средних значения вообще не учитывают попытки 06 и 08. Ученики несколько раз проверяли решение и не получили успеха в течение получаса. Если в отчёте оставить только время прошедших, эти незавершённые попытки исчезнут из него. Но и подставить 1800 как время их успешного решения нельзя: успеха не было. Пока мы знаем только, что за отведённое окно попытка не завершена.
Попытку 07 тоже не стоит объявлять отказом из-за непонятного задания. Видим одну проверку и почти всё время в скрытой вкладке. Возможно, человек ушёл. Возможно, искал ответ. Отсутствие успеха известно, причина неизвестна.
Поэтому я бы оставил рядом долю завершивших и время среди завершивших. Здесь первое число не даёт второму создать слишком благополучную картину. А повторяющийся выбор margin уже подсказывает, какую часть упражнения стоит посмотреть внимательнее.
Сначала проверим собственный тест
Проверяющий код может требовать буквальную запись автора или читать не тот элемент. Тогда правка текста заставит людей подстраиваться под ошибку, которую следовало исправить в программе.
Для нашего упражнения проверка выглядит так. card передаётся из документа с решением; неизменяемая разметка уже содержит нужный элемент.
export function check(card) {
const style = getComputedStyle(card);
const properties = ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'];
return properties.every(property => style[property] === '16px');
}
Здесь проверяется конкретное требование: внутренний отступ карточки с каждой стороны равен 16 пикселям. Функция не разбирает весь CSS и не утверждает, что страница во всём правильная. Разметку и остальные свойства в этом упражнении не меняют. Если разрешить менять содержимое или скрывать карточку, понадобятся другие условия проверки.
Мы читаем отдельные свойства через getComputedStyle(). Поэтому подходящее значение может быть задано сокращённым padding или четырьмя отдельными декларациями. Проверка не требует одной конкретной строки в редакторе.
Для начала достаточно прогнать её на нескольких заранее известных решениях:
| Добавленный CSS | Ожидаемый ответ |
|---|---|
| Ничего | Не принять |
margin: 16px |
Не принять |
padding: 16px |
Принять |
Каждая сторона задана отдельным padding-* по 16 пикселей |
Принять |
padding: 16px 8px |
Не принять |
padding: 1rem при размере шрифта корневого элемента 16 пикселей |
Принять |
На этих вариантах тест принимает задуманный результат и подходящие способы его получить. Вариант с внешним отступом отклоняется именно потому, что внутренний отступ остался нулевым. Это соответствует авторскому замыслу. Соответствие формулировке для ученика мы пока не установили.
Что ещё могло задержать ученика
Исправная функция проверки ещё не означает, что всё упражнение работает как задумано. Я бы отдельно прошёл упражнение с известным решением через тот же редактор, которым пользуется ученик. Если код не доходит до предпросмотра или отметка успеха не обновляется, проверка функции в изоляции этого не заметит.
В нашем учебном разборе примем, что новое значение видно сразу, кнопка запускает проверку, а результат соответствует коду. Решение с нужными отступами принимается и через интерфейс. Это условие примера, а не вывод из таблицы времени. В настоящем продукте его пришлось бы проверить на поддерживаемых устройствах.
Возможно, ученики ещё не различают виды отступов. Ответа на вопрос «вам понятно?» здесь недостаточно. Я бы попросил ученика до изменения кода показать, где должно появиться расстояние, и объяснить, почему он выбрал это место.
Два учебных ответа звучат по-разному. «Я хочу отодвинуть рамку от соседних элементов, здесь же написано вокруг карточки» показывает осмысленный выбор внешнего отступа. «Не знаю, чем они отличаются, попробовал первое свойство из справочника» оставляет вопрос к предшествующему объяснению. В обоих случаях в редакторе будет margin, но править придётся разные части обучения.
Для продолжения нашего примера предположим, что в нескольких таких разговорах ученики указывают именно на расстояние снаружи. Когда им предлагают отдельно показать область между рамкой и текстом, они различают эти места. Такие ответы поддерживают предположение о непонятном условии. Но у остальных могут быть другие затруднения, в том числе с самой блочной моделью.
Сообщение «Проверьте отступы карточки» тоже почти не помогает. Оно повторяет спорное слово, не уточняя, какое несовпадение увидела программа. В результате ученик может долго менять числовое значение правильного, по его мнению, свойства.
Я бы записал это отдельной находкой. Но если сейчас поменять и условие, и сообщение об ошибке, по следующей группе уже не получится понять, какое из изменений помогло. Для первого шага в нашем примере оставим проверку и её ответ прежними, а исправим текст задания.
Новое условие не обязано содержать ответ
Можно написать так:
Добавьте карточке
padding: 16px.
Ученик сможет перепечатать готовую декларацию. Выбирать свойство ему больше не понадобится, хотя именно ради этого и было упражнение.
Мне больше подходит другое уточнение:
Между рамкой карточки и её содержимым должно быть по 16 пикселей свободного места с каждой стороны. Измените CSS карточки. Размер рамки и оформление текста менять не нужно.
Теперь названо место, в котором мы ждём расстояние. Свойство по-прежнему предстоит выбрать ученику. Если он понимает различие внешнего и внутреннего отступов, у него есть достаточно сведений для решения. Если не понимает, условие хотя бы не подталкивает его к другой задаче.
В этом упражнении слово «содержимое» относится к единственному абзацу, у которого заранее сняты собственные отступы. Это часть исходных условий. Если в карточке окажутся вложенные элементы со своими margin, расстояние между рамкой и буквами уже не будет описываться одним padding карточки. Тогда менять придётся и пример, а не надеяться на удачную редактуру одной строки.
Сохраним новую формулировку как версию B. Для уже начатых попыток оставим условие A. Иначе мы получим запись о длинной попытке, внутри которой менялось само задание, и станем объяснять её одной из двух версий задним числом.
Что произошло со следующей группой
Возьмём ещё восемь первых попыток, теперь с условием B. Окно наблюдения осталось прежним, 30 минут. Вторая таблица тоже учебная: на ней разберём, какие выводы можно сделать из такого наблюдения.
| Попытка B | Завершена за 30 минут | До успеха или конца окна, с | Из них вкладка скрыта, с | Нажатий проверки | Первое изменение |
|---|---|---|---|---|---|
| 01 | Да | 120 | 0 | 1 | padding |
| 02 | Да | 120 | 0 | 1 | padding |
| 03 | Да | 180 | 0 | 2 | padding |
| 04 | Да | 180 | 0 | 1 | padding |
| 05 | Да | 240 | 0 | 2 | margin |
| 06 | Да | 300 | 0 | 2 | padding |
| 07 | Да | 1440 | 1260 | 1 | padding |
| 08 | Нет | 1800 | 0 | 3 | padding |
Теперь завершили семь человек из восьми, 87,5 %. Медиана среди завершивших снизилась с 240 до 180 секунд. Внешний отступ первым выбрал один человек; в версии A таких было шесть. Последнее наблюдение ближе к нашей причине изменения, чем само по себе уменьшение времени: люди реже начинают решать задачу про расстояние снаружи.
При этом один ученик по-прежнему не закончил, хотя начал с padding. В данном наборе причина не записана. Возможно, он менял только одну сторону или вводил неподходящее значение. Выбрать объяснение по имени свойства нельзя; нужно посмотреть продолжение этой попытки или спросить самого ученика.
У версии B тоже есть длительная успешная попытка со скрытой вкладкой. Среднее время составляет примерно 369 секунд, а после вычитания скрытого времени примерно 189. Разрыв между этими величинами напоминает, почему одного среднего было мало ещё до правки текста.
Я бы не назвал разницу между 62,5 % и 87,5 % доказанным эффектом новой формулировки. Это разные небольшие группы, прошедшие задание последовательно. У второй мог быть другой опыт, она могла иначе пройти предыдущее упражнение. Случайного распределения между версиями здесь нет. Даже одинаковый код и одинаковое окно наблюдения не делают состав групп одинаковым.
Новую формулировку стоит оставить прежде всего потому, что она устраняет найденную двусмысленность. В разговоре ученики объяснили, как поняли прежний текст, а после уточнения реже выбирали внешний отступ. Это согласуется с нашей версией причины. Чтобы измерить влияние правки на время прохождения, понадобятся сопоставимые группы и больше данных.
Быстрее ещё не значит понятнее
Остаётся проверить, что мы сохранили учебную задачу. Одного успеха в этой карточке мало: ученик мог подобрать свойство и не разобраться, почему оно подошло.
Следующее упражнение можно дать с другим результатом: между рамками двух соседних карточек требуется свободное место, а расстояние от рамки до содержимого должно остаться прежним. Готовое слово padding из предыдущего решения здесь уже не помогает. Полезно попросить сначала показать нужную область на рисунке, затем выбрать свойство и проверить результат.
Если ученик снова увеличивает расстояние внутри карточки, тему предстоит разобрать подробнее. Уточнение первой формулировки сняло одну помеху, но не заменило объяснение CSS. Если он различает оба случая и может объяснить свой выбор, у нас появляется основание говорить о понимании, которого сама скорость не показывала.