11<!DOCTYPE html>
22< html lang ="en ">
33 < head >
4- <!-- Required meta tags for correct character encoding and responsive layout -->
4+ <!--
5+ Document metadata
6+ - charset + viewport are essential for correct rendering and responsive behaviour.
7+ - No CSS/JS included (CYF requirement).
8+ -->
59 < meta charset ="utf-8 " />
610 < meta http-equiv ="X-UA-Compatible " content ="IE=edge " />
711 < meta name ="viewport " content ="width=device-width, initial-scale=1 " />
812
9- <!-- Page title shown in the browser tab -->
10- < title > My form exercise </ title >
13+ <!-- Title shown in the browser tab -->
14+ < title > Product Pick | T-shirt Order Form </ title >
1115
12- <!-- Optional description (not required for the task, but fine to keep) -->
13- < meta name ="description " content ="T-shirt order form with HTML validation. " />
16+ <!-- Optional: short page description -->
17+ < meta
18+ name ="description "
19+ content ="T-shirt order form using semantic HTML and built-in validation (no CSS or JavaScript). " />
1420 </ head >
1521
1622 < body >
17- <!-- Page header -->
23+ <!--
24+ Page header (semantic landmark)
25+ Helps screen reader users quickly understand the page topic.
26+ -->
1827 < header >
1928 < h1 > Product Pick</ h1 >
2029 </ header >
2130
22- <!-- Main content of the page -->
31+ <!-- Main content (semantic landmark) -->
2332 < main >
2433 <!--
25- Form Controls task requirements (CYF):
26- 1) Use HTML only (no CSS, no JavaScript)
27- 2) Do NOT add a form action attribute
28- 3) All fields are required
29- 4) Name must be valid: at least 2 characters
30- 5) Email must be valid (use input type="email")
31- 6) Colour: user must choose exactly 1 colour from 3 options
32- 7) Size: user must choose exactly 1 size from 6 options (XS, S, M, L, XL, XXL)
33- 8) All inputs must have associated labels
34- 9) Use semantic HTML and aim for Lighthouse Accessibility score = 100
34+ CYF Form Controls requirements checklist:
35+ 1) HTML only (no CSS, no JavaScript)
36+ 2) No form action attribute
37+ 3) All fields required
38+ 4) Name: minimum 2 characters AND must not be whitespace-only
39+ 5) Email: valid email format (type="email")
40+ 6) Colour: choose exactly 1 option from 3 predefined options
41+ 7) Size: choose exactly 1 option from 6 predefined options (XS, S, M, L, XL, XXL)
42+ 8) Every input has an associated label
43+ 9) Semantic structure + Lighthouse Accessibility = 100
44+ -->
45+
46+ <!--
47+ No action attribute: this form is for structure + validation only (CYF requirement).
48+ The browser will handle validation via required/minlength/pattern/type attributes.
3549 -->
3650 < form >
37- <!-- User guidance (helps usability and accessibility) -->
51+ <!-- Clear instruction for users -->
3852 < p > Please complete all required fields.</ p >
3953
40- <!-- Customer identity section -->
54+ <!-- Customer details (grouped for structure and navigation) -->
4155 < section aria-labelledby ="customer-details ">
4256 < h2 id ="customer-details "> Customer details</ h2 >
4357
44- <!-- Name: required, minlength 2 characters -->
58+ <!--
59+ Name validation:
60+ - required: must be filled
61+ - minlength=2: at least 2 characters
62+ - pattern rejects whitespace-only AND avoids leading/trailing whitespace:
63+ ^\S(.*\S)?$ => starts with non-space and ends with non-space (allows single-word or multi-word names)
64+ -->
4565 < p >
4666 < label for ="customer-name "> Name</ label > < br />
4767 < input
@@ -50,10 +70,16 @@ <h2 id="customer-details">Customer details</h2>
5070 type ="text "
5171 required
5272 minlength ="2 "
73+ pattern ="^\S(.*\S)?$ "
74+ title ="Name must be at least 2 characters and cannot be only spaces. "
5375 autocomplete ="name " />
5476 </ p >
5577
56- <!-- Email: required, validated by browser using type="email" -->
78+ <!--
79+ Email validation:
80+ - type="email" enables browser email format checks
81+ - required ensures it cannot be left blank
82+ -->
5783 < p >
5884 < label for ="customer-email "> Email</ label > < br />
5985 < input
@@ -65,16 +91,19 @@ <h2 id="customer-details">Customer details</h2>
6591 </ p >
6692 </ section >
6793
68- <!-- Product choices section -->
94+ <!-- T-shirt options (grouped for structure and navigation) -->
6995 < section aria-labelledby ="tshirt-options ">
7096 < h2 id ="tshirt-options "> T-shirt options</ h2 >
7197
72- <!-- Colour choice: radio group inside fieldset + legend (semantic + accessible) -->
98+ <!--
99+ Colour selection:
100+ - fieldset + legend provides an accessible group label for radio inputs
101+ - same name="colour" enforces selecting only one option
102+ - required on one radio ensures the group is required
103+ -->
73104 < fieldset >
74105 < legend > Colour</ legend >
75106
76- <!-- Radio buttons: same name="colour" means user can pick only one -->
77- <!-- required is applied to the first radio to enforce selecting one option -->
78107 < p >
79108 < input
80109 id ="colour-black "
@@ -96,14 +125,16 @@ <h2 id="tshirt-options">T-shirt options</h2>
96125 </ p >
97126 </ fieldset >
98127
99- <!-- Size choice: select with exactly 6 required options -->
128+ <!--
129+ Size selection:
130+ - select is required
131+ - disabled placeholder prevents accidental submission with a default size
132+ - exactly 6 size options as required by the task
133+ -->
100134 < p >
101135 < label for ="size "> Size</ label > < br />
102136 < select id ="size " name ="size " required >
103- <!-- Placeholder option prevents accidental default selection -->
104137 < option value ="" selected disabled > Choose a size</ option >
105-
106- <!-- Required set of 6 sizes -->
107138 < option value ="XS "> XS</ option >
108139 < option value ="S "> S</ option >
109140 < option value ="M "> M</ option >
@@ -114,18 +145,15 @@ <h2 id="tshirt-options">T-shirt options</h2>
114145 </ p >
115146 </ section >
116147
117- <!-- Submit button -->
148+ <!-- Submit button triggers built-in HTML validation -->
118149 < p >
119150 < button type ="submit "> Submit</ button >
120151 </ p >
121-
122- <!-- Note: No form action attribute is included on purpose (CYF requirement) -->
123152 </ form >
124153 </ main >
125154
126- <!-- Page footer -->
155+ <!-- Footer (semantic landmark) -->
127156 < footer >
128- <!-- Change this to your name -->
129157 < p > By Richard Frimpong</ p >
130158 </ footer >
131159 </ body >
0 commit comments