-
-
Notifications
You must be signed in to change notification settings - Fork 31
Description
Description
This change is related to freeCodeCamp/freeCodeCamp#61906.
The MCQ component in /learn is currently a custom one. We do plan to migrate it to QuizQuestion, but the component is not compatible now that we are adding the speaking feature.
The challenge with adding extra actions / buttons to the answers is that each button must line up visually with its corresponding answer, without being mixed into the radio group itself.
We can't use the following pattern, even though it's the simplest way to achieve the alignment:
<fieldset>
<legend>Question text</legend>
<label for="option-1">Option 1</label>
<input type="radio" id="option-1" />
<button>Practice speaking option 1</button>
<label for="option-2">Option 2</label>
<input type="radio" id="option-2" />
<button>Practice speaking option 2</button>
<label for="option-3">Option 3</label>
<input type="radio" id="option-3" />
<button>Practice speaking option 3</button>
</fieldset>The preferred structure is:
<fieldset>
<legend>Question text</legend>
<label for="option-1">Option 1</label>
<input type="radio" id="option-1" />
<label for="option-2">Option 2</label>
<input type="radio" id="option-2" />
<label for="option-3">Option 3</label>
<input type="radio" id="option-3" />
</fieldset>
<div>
<button>Practice speaking option 1</button>
<button>Practice speaking option 2</button>
<button>Practice speaking option 3</button>
</div>This keeps the radios semantically correct, and separate the extra buttons from the radio group.
The drawback is that alignment becomes more involved. We need JS to calculate the position of the action buttons: the button group can sit on the same row as the fieldset, but each button must be offset to match its corresponding answer, and this requires measuring the legend height as well as the heights of the option elements above each button to keep the offsets in sync.
For /learn, the temporary structure I went with is:
<fieldset>
<legend>Question text</legend>
<div>
<label for="option-1">Option 1</label>
<input type="radio" id="option-1" />
<label for="option-2">Option 2</label>
<input type="radio" id="option-2" />
<label for="option-3">Option 3</label>
<input type="radio" id="option-3" />
</div>
<div>
<button>Practice speaking option 1</button>
<button>Practice speaking option 2</button>
<button>Practice speaking option 3</button>
</div>
</fieldset>Which I know is not ideal, but it at least keeps the radios properly grouped. Having the button group as a sibling of the radio group allows us to handle the alignment through CSS grid.