fix: add kbd tags to validation messages for clarity

- Wrap HTML element names in <kbd> tags in all validation messages
- Apply consistent formatting to both English and German lessons
- Make hints clearer about which elements/attributes to use
- Fix mobile editor layout overflow issue
This commit is contained in:
2025-12-25 15:55:26 +01:00
parent 2c8d46d592
commit 027232f5e8
27 changed files with 230 additions and 222 deletions

View File

@@ -21,12 +21,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "p", "value": "p",
"message": "Add a <p> paragraph element" "message": "Add a <kbd>&lt;p&gt;</kbd> paragraph element"
}, },
{ {
"type": "parent_child", "type": "parent_child",
"value": { "parent": "p", "child": "strong" }, "value": { "parent": "p", "child": "strong" },
"message": "Wrap the word 'important' with <strong> tags" "message": "Wrap the word 'important' with <kbd>&lt;strong&gt;</kbd> tags"
} }
] ]
}, },
@@ -45,22 +45,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "header", "value": "header",
"message": "Add a <header> element" "message": "Add a <kbd>&lt;header&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "main", "value": "main",
"message": "Add a <main> element" "message": "Add a <kbd>&lt;main&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "footer", "value": "footer",
"message": "Add a <footer> element" "message": "Add a <kbd>&lt;footer&gt;</kbd> element"
}, },
{ {
"type": "parent_child", "type": "parent_child",
"value": { "parent": "header", "child": "h1" }, "value": { "parent": "header", "child": "h1" },
"message": "Add an <h1> heading inside your header" "message": "Add an <kbd>&lt;h1&gt;</kbd> heading inside your header"
} }
] ]
}, },
@@ -79,17 +79,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "div", "value": "div",
"message": "Wrap everything in a <div> element" "message": "Wrap everything in a <kbd>&lt;div&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "span", "value": "span",
"message": "Add a <span> around the word 'highlighted'" "message": "Add a <kbd>&lt;span&gt;</kbd> around the word 'highlighted'"
}, },
{ {
"type": "element_text", "type": "element_text",
"value": { "selector": "span", "text": "highlighted" }, "value": { "selector": "span", "text": "highlighted" },
"message": "The <span> should contain the word 'highlighted'" "message": "The <kbd>&lt;span&gt;</kbd> should contain the word 'highlighted'"
} }
] ]
} }

View File

@@ -21,51 +21,51 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "form", "value": "form",
"message": "Wrap everything in a <form> element" "message": "Wrap everything in a <kbd>&lt;form&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "label", "value": "label",
"message": "Add a <label> for your input" "message": "Add a <kbd>&lt;label&gt;</kbd> for your input"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "input", "value": "input",
"message": "Add an <input> element" "message": "Add an <kbd>&lt;input&gt;</kbd> element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "label", "attr": "for", "value": null }, "value": { "selector": "label", "attr": "for", "value": null },
"message": "Add a 'for' attribute to your label" "message": "Add a <kbd>for</kbd> attribute to your label"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input", "attr": "id", "value": null }, "value": { "selector": "input", "attr": "id", "value": null },
"message": "Add an 'id' attribute to your input" "message": "Add an <kbd>id</kbd> attribute to your input"
} }
] ]
}, },
{ {
"id": "input-types", "id": "input-types",
"title": "Input Types", "title": "Input Types",
"description": "Different input types provide appropriate keyboards and validation:<br><br><kbd>type=\"text\"</kbd> - General text<br><kbd>type=\"email\"</kbd> - Email with @ validation<br><kbd>type=\"password\"</kbd> - Hidden characters<br><kbd>type=\"number\"</kbd> - Numeric keyboard<br><kbd>type=\"tel\"</kbd> - Phone keyboard", "description": "Different input types provide appropriate keyboards and validation:<br><br><kbd>type=\"text\"</kbd> - General text<br><kbd>type=<kbd>\"email\"</kbd></kbd> - Email with @ validation<br><kbd>type=<kbd>\"password\"</kbd></kbd> - Hidden characters<br><kbd>type=\"number\"</kbd> - Numeric keyboard<br><kbd>type=\"tel\"</kbd> - Phone keyboard",
"task": "Create a login form with two fields:<br>1. An email field: <kbd>&lt;label for=\"email\"&gt;Email:&lt;/label&gt;</kbd> and <kbd>&lt;input type=\"email\" id=\"email\"&gt;</kbd><br>2. A password field: <kbd>&lt;label for=\"password\"&gt;Password:&lt;/label&gt;</kbd> and <kbd>&lt;input type=\"password\" id=\"password\"&gt;</kbd>", "task": "Create a login form with two fields:<br>1. An email field: <kbd>&lt;label for=\"email\"&gt;Email:&lt;/label&gt;</kbd> and <kbd>&lt;input type=<kbd>\"email\"</kbd> id=\"email\"&gt;</kbd><br>2. A password field: <kbd>&lt;label for=\"password\"&gt;Password:&lt;/label&gt;</kbd> and <kbd>&lt;input type=<kbd>\"password\"</kbd> id=\"password\"&gt;</kbd>",
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <!-- Add email and password inputs -->\n</form>", "initialCode": "<form>\n <!-- Add email and password inputs -->\n</form>",
"solution": "<form>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n \n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\" name=\"password\">\n</form>", "solution": "<form>\n <label for=\"email\">Email:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\">\n \n <label for=\"password\">Password:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\">\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "element_exists", "type": "element_exists",
"value": "input[type='email']", "value": "input[type='email']",
"message": "Add an input with type=\"email\"" "message": "Add an input with type=<kbd>\"email\"</kbd>"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "input[type='password']", "value": "input[type='password']",
"message": "Add an input with type=\"password\"" "message": "Add an input with type=<kbd>\"password\"</kbd>"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -82,8 +82,8 @@
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } button { width: 100%; margin-top: 20px; padding: 10px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } button:hover { background: #1565c0; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } button { width: 100%; margin-top: 20px; padding: 10px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } button:hover { background: #1565c0; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\">\n \n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\">\n \n <!-- Add submit button -->\n</form>", "initialCode": "<form>\n <label for=\"email\">Email:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\">\n \n <label for=\"password\">Password:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\">\n \n <!-- Add submit button -->\n</form>",
"solution": "<form>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\">\n \n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\">\n \n <button type=\"submit\">Sign In</button>\n</form>", "solution": "<form>\n <label for=\"email\">Email:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\">\n \n <label for=\"password\">Password:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\">\n \n <button type=\"submit\">Sign In</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {

View File

@@ -14,19 +14,19 @@
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-of-type { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid { border-color: #d32f2f; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-of-type { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid { border-color: #d32f2f; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n \n <label for=\"email\">Email: *</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n \n <button type=\"submit\">Submit</button>\n</form>", "initialCode": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n \n <label for=\"email\">Email: *</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\">\n \n <button type=\"submit\">Submit</button>\n</form>",
"solution": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\" required>\n \n <label for=\"email\">Email: *</label>\n <input type=\"email\" id=\"email\" name=\"email\" required>\n \n <button type=\"submit\">Submit</button>\n</form>", "solution": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\" required>\n \n <label for=\"email\">Email: *</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\" required>\n \n <button type=\"submit\">Submit</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[name='name']", "attr": "required", "value": true }, "value": { "selector": "input[name='name']", "attr": "required", "value": true },
"message": "Add the 'required' attribute to the name input" "message": "Add the <kbd>required</kbd> attribute to the name input"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[name='email']", "attr": "required", "value": true }, "value": { "selector": "input[name='email']", "attr": "required", "value": true },
"message": "Add the 'required' attribute to the email input" "message": "Add the <kbd>required</kbd> attribute to the email input"
} }
] ]
}, },
@@ -38,73 +38,73 @@
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-bottom: 5px; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid:not(:placeholder-shown) { border-color: #d32f2f; } small { display: block; font-size: 12px; color: #666; margin-top: 4px; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-bottom: 5px; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid:not(:placeholder-shown) { border-color: #d32f2f; } small { display: block; font-size: 12px; color: #666; margin-top: 4px; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\" name=\"password\" required aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Must be 8-20 characters</small>\n \n <button type=\"submit\">Create Account</button>\n</form>", "initialCode": "<form>\n <label for=\"password\">Password:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\" required aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Must be 8-20 characters</small>\n \n <button type=\"submit\">Create Account</button>\n</form>",
"solution": "<form>\n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\" name=\"password\" required minlength=\"8\" maxlength=\"20\" placeholder=\"Enter password\" aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Must be 8-20 characters</small>\n \n <button type=\"submit\">Create Account</button>\n</form>", "solution": "<form>\n <label for=\"password\">Password:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\" required minlength=\"8\" maxlength=\"20\" placeholder=\"Enter password\" aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Must be 8-20 characters</small>\n \n <button type=\"submit\">Create Account</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[type='password']", "attr": "minlength", "value": "8" }, "value": { "selector": "input[type='password']", "attr": "minlength", "value": "8" },
"message": "Add minlength=\"8\" to the password input" "message": "Add <kbd>minlength</kbd>=\"8\" to the password input"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[type='password']", "attr": "maxlength", "value": "20" }, "value": { "selector": "input[type='password']", "attr": "maxlength", "value": "20" },
"message": "Add maxlength=\"20\" to the password input" "message": "Add <kbd>maxlength</kbd>=\"20\" to the password input"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[type='password']", "attr": "placeholder", "value": null }, "value": { "selector": "input[type='password']", "attr": "placeholder", "value": null },
"message": "Add a placeholder to hint what to enter" "message": "Add a <kbd>placeholder</kbd> to hint what to enter"
} }
] ]
}, },
{ {
"id": "complete-registration", "id": "complete-registration",
"title": "Complete Registration Form", "title": "Complete Registration Form",
"description": "Build a complete registration form with all validation concepts:<br><br>- Required fields marked with *<br>- Email validation (use type=\"email\")<br>- Password with length constraints<br>- Terms checkbox (required)<br>- Submit button", "description": "Build a complete registration form with all validation concepts:<br><br>- Required fields marked with *<br>- Email validation (use type=<kbd>\"email\"</kbd>)<br>- Password with length constraints<br>- Terms checkbox (required)<br>- Submit button",
"task": "Complete the registration form. Add required attributes, proper input types, and validation constraints.", "task": "Complete the registration form. Add required attributes, proper input types, and validation constraints.",
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 400px; background: #f5f5f5; padding: 25px; border-radius: 8px; } h2 { margin-top: 0; margin-bottom: 20px; } label { display: block; margin-top: 15px; margin-bottom: 5px; font-weight: 500; } input[type='text'], input[type='email'], input[type='password'] { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; font-size: 14px; } input:focus { outline: 2px solid #1976d2; border-color: transparent; } input[type='checkbox'] { width: auto; margin-right: 8px; vertical-align: middle; } label:has(input[type='checkbox']) { display: flex; align-items: center; font-weight: normal; } button { width: 100%; margin-top: 20px; padding: 12px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; font-weight: 500; } button:hover { background: #1565c0; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 400px; background: #f5f5f5; padding: 25px; border-radius: 8px; } h2 { margin-top: 0; margin-bottom: 20px; } label { display: block; margin-top: 15px; margin-bottom: 5px; font-weight: 500; } input[type='text'], input[type='email'], input[type='password'] { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; font-size: 14px; } input:focus { outline: 2px solid #1976d2; border-color: transparent; } input[type='checkbox'] { width: auto; margin-right: 8px; vertical-align: middle; } label:has(input[type='checkbox']) { display: flex; align-items: center; font-weight: normal; } button { width: 100%; margin-top: 20px; padding: 12px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; font-weight: 500; } button:hover { background: #1565c0; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <h2>Create Account</h2>\n \n <label for=\"fullname\">Full Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\">\n \n <label for=\"email\">Email *</label>\n <input id=\"email\" name=\"email\">\n \n <label for=\"password\">Password *</label>\n <input id=\"password\" name=\"password\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\">\n I agree to the Terms of Service *\n </label>\n \n <button type=\"submit\">Register</button>\n</form>", "initialCode": "<form>\n <h2>Create Account</h2>\n \n <label for=\"fullname\">Full Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\">\n \n <label for=\"email\">Email *</label>\n <input id=\"email\" name=\"email\">\n \n <label for=\"password\">Password *</label>\n <input id=\"password\" name=\"password\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\">\n I agree to the Terms of Service *\n </label>\n \n <button type=\"submit\">Register</button>\n</form>",
"solution": "<form>\n <h2>Create Account</h2>\n \n <label for=\"fullname\">Full Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\" required>\n \n <label for=\"email\">Email *</label>\n <input type=\"email\" id=\"email\" name=\"email\" required>\n \n <label for=\"password\">Password *</label>\n <input type=\"password\" id=\"password\" name=\"password\" required minlength=\"8\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\" required>\n I agree to the Terms of Service *\n </label>\n \n <button type=\"submit\">Register</button>\n</form>", "solution": "<form>\n <h2>Create Account</h2>\n \n <label for=\"fullname\">Full Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\" required>\n \n <label for=\"email\">Email *</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\" required>\n \n <label for=\"password\">Password *</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\" required minlength=\"8\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\" required>\n I agree to the Terms of Service *\n </label>\n \n <button type=\"submit\">Register</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "#fullname", "attr": "required", "value": true }, "value": { "selector": "#fullname", "attr": "required", "value": true },
"message": "Make the full name field required" "message": "Make the full name field <kbd>required</kbd>"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "#email", "attr": "type", "value": "email" }, "value": { "selector": "#email", "attr": "type", "value": "email" },
"message": "Set the email input type to 'email'" "message": "Set the email input <kbd>type=\"email\"</kbd>"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "#email", "attr": "required", "value": true }, "value": { "selector": "#email", "attr": "required", "value": true },
"message": "Make the email field required" "message": "Make the email field <kbd>required</kbd>"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "#password", "attr": "type", "value": "password" }, "value": { "selector": "#password", "attr": "type", "value": "password" },
"message": "Set the password input type to 'password'" "message": "Set the password input <kbd>type=\"password\"</kbd>"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "#password", "attr": "required", "value": true }, "value": { "selector": "#password", "attr": "required", "value": true },
"message": "Make the password field required" "message": "Make the password field <kbd>required</kbd>"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "#password", "attr": "minlength", "value": "8" }, "value": { "selector": "#password", "attr": "minlength", "value": "8" },
"message": "Add minlength=\"8\" to password" "message": "Add <kbd>minlength</kbd>=\"8\" to password"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "#terms", "attr": "required", "value": true }, "value": { "selector": "#terms", "attr": "required", "value": true },
"message": "Make the terms checkbox required" "message": "Make the terms checkbox <kbd>required</kbd>"
} }
] ]
} }

View File

@@ -21,22 +21,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "details", "value": "details",
"message": "Add a <details> element" "message": "Add a <kbd>&lt;details&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "summary", "value": "summary",
"message": "Add a <summary> inside the details" "message": "Add a <kbd>&lt;summary&gt;</kbd> inside the details"
}, },
{ {
"type": "parent_child", "type": "parent_child",
"value": { "parent": "details", "child": "summary" }, "value": { "parent": "details", "child": "summary" },
"message": "The <summary> must be inside <details>" "message": "The <kbd>&lt;summary&gt;</kbd> must be inside <kbd>&lt;details&gt;</kbd>"
}, },
{ {
"type": "parent_child", "type": "parent_child",
"value": { "parent": "details", "child": "p" }, "value": { "parent": "details", "child": "p" },
"message": "Add a <p> inside <details> for the hidden content" "message": "Add a <kbd>&lt;p&gt;</kbd> inside <kbd>&lt;details&gt;</kbd> for the hidden content"
} }
] ]
}, },
@@ -55,7 +55,7 @@
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "details", "attr": "open", "value": true }, "value": { "selector": "details", "attr": "open", "value": true },
"message": "Add the 'open' attribute to <details>" "message": "Add the <kbd>open</kbd> attribute to <details>"
} }
] ]
}, },
@@ -74,7 +74,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "h1", "value": "h1",
"message": "Add an <h1> heading for the FAQ title" "message": "Add an <kbd>&lt;h1&gt;</kbd> heading for the FAQ title"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -84,12 +84,12 @@
{ {
"type": "element_count", "type": "element_count",
"value": { "selector": "summary", "min": 3 }, "value": { "selector": "summary", "min": 3 },
"message": "Each <details> needs a <summary> for the question" "message": "Each <kbd>&lt;details&gt;</kbd> needs a <summary> for the question"
}, },
{ {
"type": "element_count", "type": "element_count",
"value": { "selector": "details p", "min": 3 }, "value": { "selector": "details p", "min": 3 },
"message": "Each <details> needs a <p> for the answer" "message": "Each <kbd>&lt;details&gt;</kbd> needs a <p> for the answer"
} }
] ]
} }

View File

@@ -21,22 +21,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "progress", "value": "progress",
"message": "Add a <progress> element" "message": "Add a <kbd>&lt;progress&gt;</kbd> element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "progress", "attr": "value", "value": "70" }, "value": { "selector": "progress", "attr": "value", "value": "70" },
"message": "Set value=\"70\" on the progress element" "message": "Set <kbd>value=</kbd>\"70\" on the progress element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "progress", "attr": "max", "value": "100" }, "value": { "selector": "progress", "attr": "max", "value": "100" },
"message": "Set max=\"100\" on the progress element" "message": "Set <kbd>max=</kbd>\"100\" on the progress element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "label", "value": "label",
"message": "Add a <label> for the progress bar" "message": "Add a <kbd>&lt;label&gt;</kbd> for the progress bar"
} }
] ]
}, },
@@ -55,12 +55,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "progress", "value": "progress",
"message": "Add a <progress> element" "message": "Add a <kbd>&lt;progress&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "p", "value": "p",
"message": "Add a <p> with loading text" "message": "Add a <kbd>&lt;p&gt;</kbd> with loading text"
} }
] ]
}, },
@@ -79,22 +79,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "meter", "value": "meter",
"message": "Add a <meter> element" "message": "Add a <kbd>&lt;meter&gt;</kbd> element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "meter", "attr": "value", "value": "0.8" }, "value": { "selector": "meter", "attr": "value", "value": "0.8" },
"message": "Set value=\"0.8\" on the meter" "message": "Set <kbd>value=</kbd>\"0.8\" on the meter"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "meter", "attr": "low", "value": "0.2" }, "value": { "selector": "meter", "attr": "low", "value": "0.2" },
"message": "Set low=\"0.2\" to define the low threshold" "message": "Set <kbd>low=</kbd>\"0.2\" to define the low threshold"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "label", "value": "label",
"message": "Add a <label> for the meter" "message": "Add a <kbd>&lt;label&gt;</kbd> for the meter"
} }
] ]
} }

View File

@@ -21,12 +21,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "datalist", "value": "datalist",
"message": "Add a <datalist> element" "message": "Add a <kbd>&lt;datalist&gt;</kbd> element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input", "attr": "list", "value": "browsers" }, "value": { "selector": "input", "attr": "list", "value": "browsers" },
"message": "Connect the input to datalist using list=\"browsers\"" "message": "Connect the input to datalist using <kbd>list=</kbd>\"browsers\""
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -36,7 +36,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "label", "value": "label",
"message": "Add a <label> for the input" "message": "Add a <kbd>&lt;label&gt;</kbd> for the input"
} }
] ]
}, },
@@ -55,17 +55,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "datalist", "value": "datalist",
"message": "Add a <datalist> element" "message": "Add a <kbd>&lt;datalist&gt;</kbd> element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "datalist", "attr": "id", "value": "countries" }, "value": { "selector": "datalist", "attr": "id", "value": "countries" },
"message": "Set id=\"countries\" on the datalist" "message": "Set <kbd>id=</kbd>\"countries\" on the datalist"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input", "attr": "list", "value": "countries" }, "value": { "selector": "input", "attr": "list", "value": "countries" },
"message": "Connect the input using list=\"countries\"" "message": "Connect the input using <kbd>list=</kbd>\"countries\""
}, },
{ {
"type": "element_count", "type": "element_count",

View File

@@ -31,7 +31,7 @@
{ {
"type": "element_count", "type": "element_count",
"value": { "selector": "article h2", "min": 2 }, "value": { "selector": "article h2", "min": 2 },
"message": "Add an <h2> inside each article" "message": "Add an <kbd>&lt;h2&gt;</kbd> inside each article"
} }
] ]
}, },

View File

@@ -21,17 +21,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "dialog", "value": "dialog",
"message": "Add a <dialog> element" "message": "Add a <kbd>&lt;dialog&gt;</kbd> element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "dialog", "attr": "open", "value": true }, "value": { "selector": "dialog", "attr": "open", "value": true },
"message": "Add the 'open' attribute to show the dialog" "message": "Add the <kbd>open</kbd> attribute to show the dialog"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "dialog h2", "value": "dialog h2",
"message": "Add an <h2> heading inside the dialog" "message": "Add an <kbd>&lt;h2&gt;</kbd> heading inside the dialog"
}, },
{ {
"type": "element_exists", "type": "element_exists",
@@ -60,7 +60,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "dialog[open]", "value": "dialog[open]",
"message": "Add a <dialog> with the open attribute" "message": "Add a <kbd>&lt;dialog&gt;</kbd> with the open attribute"
}, },
{ {
"type": "element_exists", "type": "element_exists",

View File

@@ -15,23 +15,23 @@
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #f0f4f8; } form { max-width: 400px; } fieldset { border: 2px solid #3498db; border-radius: 10px; padding: 20px; background: white; } legend { color: #3498db; font-weight: 600; padding: 0 10px; font-size: 1.1rem; } label { display: block; margin: 15px 0 5px; color: #333; font-weight: 500; } input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; } input:focus { outline: 2px solid #3498db; border-color: transparent; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #f0f4f8; } form { max-width: 400px; } fieldset { border: 2px solid #3498db; border-radius: 10px; padding: 20px; background: white; } legend { color: #3498db; font-weight: 600; padding: 0 10px; font-size: 1.1rem; } label { display: block; margin: 15px 0 5px; color: #333; font-weight: 500; } input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; } input:focus { outline: 2px solid #3498db; border-color: transparent; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<!-- Create a form with a fieldset group -->", "initialCode": "<!-- Create a form with a fieldset group -->",
"solution": "<form>\n <fieldset>\n <legend>Personal Info</legend>\n <label for=\"name\">Name:</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n </fieldset>\n</form>", "solution": "<form>\n <fieldset>\n <legend>Personal Info</legend>\n <label for=\"name\">Name:</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n <label for=\"email\">Email:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\">\n </fieldset>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "element_exists", "type": "element_exists",
"value": "form", "value": "form",
"message": "Add a <form> element" "message": "Add a <kbd>&lt;form&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "fieldset", "value": "fieldset",
"message": "Add a <fieldset> inside the form" "message": "Add a <kbd>&lt;fieldset&gt;</kbd> inside the form"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "legend", "value": "legend",
"message": "Add a <legend> to title your fieldset" "message": "Add a <kbd>&lt;legend&gt;</kbd> to title your fieldset"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -54,23 +54,23 @@
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; margin: 0; box-sizing: border-box; } form { max-width: 450px; margin: 0 auto; } fieldset { border: none; border-radius: 15px; padding: 30px; background: white; box-shadow: 0 10px 40px rgba(0,0,0,0.2); } legend { color: #667eea; font-weight: 700; padding: 0; font-size: 1.5rem; margin-bottom: 10px; } label { display: block; margin: 20px 0 8px; color: #333; font-weight: 500; } input, textarea { width: 100%; padding: 12px; border: 2px solid #e0e0e0; border-radius: 8px; font-size: 16px; box-sizing: border-box; font-family: inherit; } input:focus, textarea:focus { outline: none; border-color: #667eea; } textarea { resize: vertical; min-height: 100px; } button { margin-top: 20px; width: 100%; padding: 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; } button:hover { opacity: 0.9; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; margin: 0; box-sizing: border-box; } form { max-width: 450px; margin: 0 auto; } fieldset { border: none; border-radius: 15px; padding: 30px; background: white; box-shadow: 0 10px 40px rgba(0,0,0,0.2); } legend { color: #667eea; font-weight: 700; padding: 0; font-size: 1.5rem; margin-bottom: 10px; } label { display: block; margin: 20px 0 8px; color: #333; font-weight: 500; } input, textarea { width: 100%; padding: 12px; border: 2px solid #e0e0e0; border-radius: 8px; font-size: 16px; box-sizing: border-box; font-family: inherit; } input:focus, textarea:focus { outline: none; border-color: #667eea; } textarea { resize: vertical; min-height: 100px; } button { margin-top: 20px; width: 100%; padding: 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; } button:hover { opacity: 0.9; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<!-- Create a contact form with textarea -->", "initialCode": "<!-- Create a contact form with textarea -->",
"solution": "<form>\n <fieldset>\n <legend>Contact Us</legend>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n <label for=\"message\">Message:</label>\n <textarea id=\"message\" name=\"message\" rows=\"4\"></textarea>\n <button type=\"submit\">Send Message</button>\n </fieldset>\n</form>", "solution": "<form>\n <fieldset>\n <legend>Contact Us</legend>\n <label for=\"email\">Email:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\">\n <label for=\"message\">Message:</label>\n <textarea id=\"message\" name=\"message\" rows=\"4\"></textarea>\n <button type=\"submit\">Send Message</button>\n </fieldset>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "element_exists", "type": "element_exists",
"value": "fieldset", "value": "fieldset",
"message": "Add a <fieldset> element" "message": "Add a <kbd>&lt;fieldset&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "legend", "value": "legend",
"message": "Add a <legend> element" "message": "Add a <kbd>&lt;legend&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "textarea", "value": "textarea",
"message": "Add a <textarea> for the message" "message": "Add a <kbd>&lt;textarea&gt;</kbd> for the message"
}, },
{ {
"type": "element_exists", "type": "element_exists",
@@ -93,7 +93,7 @@
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #fafafa; } form { max-width: 500px; } fieldset { border: 1px solid #ddd; border-radius: 10px; padding: 20px; margin-bottom: 20px; background: white; } legend { color: #2c3e50; font-weight: 600; padding: 0 10px; } label { display: block; margin: 15px 0 5px; color: #555; } input, textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; font-family: inherit; } input:focus, textarea:focus { outline: 2px solid #3498db; border-color: transparent; } textarea { resize: vertical; min-height: 80px; } button { width: 100%; padding: 14px; background: #2c3e50; color: white; border: none; border-radius: 8px; font-size: 16px; cursor: pointer; } button:hover { background: #34495e; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #fafafa; } form { max-width: 500px; } fieldset { border: 1px solid #ddd; border-radius: 10px; padding: 20px; margin-bottom: 20px; background: white; } legend { color: #2c3e50; font-weight: 600; padding: 0 10px; } label { display: block; margin: 15px 0 5px; color: #555; } input, textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; font-family: inherit; } input:focus, textarea:focus { outline: 2px solid #3498db; border-color: transparent; } textarea { resize: vertical; min-height: 80px; } button { width: 100%; padding: 14px; background: #2c3e50; color: white; border: none; border-radius: 8px; font-size: 16px; cursor: pointer; } button:hover { background: #34495e; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<!-- Create a form with multiple fieldsets -->", "initialCode": "<!-- Create a form with multiple fieldsets -->",
"solution": "<form>\n <fieldset>\n <legend>Account Info</legend>\n <label for=\"username\">Username:</label>\n <input type=\"text\" id=\"username\" name=\"username\">\n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\" name=\"password\">\n </fieldset>\n <fieldset>\n <legend>Preferences</legend>\n <label for=\"bio\">Bio:</label>\n <textarea id=\"bio\" name=\"bio\"></textarea>\n </fieldset>\n <button type=\"submit\">Register</button>\n</form>", "solution": "<form>\n <fieldset>\n <legend>Account Info</legend>\n <label for=\"username\">Username:</label>\n <input type=\"text\" id=\"username\" name=\"username\">\n <label for=\"password\">Password:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\">\n </fieldset>\n <fieldset>\n <legend>Preferences</legend>\n <label for=\"bio\">Bio:</label>\n <textarea id=\"bio\" name=\"bio\"></textarea>\n </fieldset>\n <button type=\"submit\">Register</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {

View File

@@ -21,17 +21,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "figure", "value": "figure",
"message": "Add a <figure> element" "message": "Add a <kbd>&lt;figure&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "figure img", "value": "figure img",
"message": "Add an <img> inside the figure" "message": "Add an <kbd>&lt;img&gt;</kbd> inside the figure"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "figcaption", "value": "figcaption",
"message": "Add a <figcaption> for the caption" "message": "Add a <kbd>&lt;figcaption&gt;</kbd> for the caption"
} }
] ]
}, },
@@ -50,22 +50,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "figure", "value": "figure",
"message": "Add a <figure> element" "message": "Add a <kbd>&lt;figure&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "pre", "value": "pre",
"message": "Add a <pre> element for preformatted text" "message": "Add a <kbd>&lt;pre&gt;</kbd> element for preformatted text"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "code", "value": "code",
"message": "Add a <code> element for the code" "message": "Add a <kbd>&lt;code&gt;</kbd> element for the code"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "figcaption", "value": "figcaption",
"message": "Add a <figcaption> describing the code" "message": "Add a <kbd>&lt;figcaption&gt;</kbd> describing the code"
} }
] ]
}, },
@@ -84,7 +84,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "figure", "value": "figure",
"message": "Add a <figure> element" "message": "Add a <kbd>&lt;figure&gt;</kbd> element"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -94,7 +94,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "figcaption", "value": "figcaption",
"message": "Add a <figcaption> for the gallery" "message": "Add a <kbd>&lt;figcaption&gt;</kbd> for the gallery"
} }
] ]
} }

View File

@@ -21,12 +21,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "table", "value": "table",
"message": "Add a <table> element" "message": "Add a <kbd>&lt;table&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "caption", "value": "caption",
"message": "Add a <caption> for the table title" "message": "Add a <kbd>&lt;caption&gt;</kbd> for the table title"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -55,22 +55,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "table", "value": "table",
"message": "Add a <table> element" "message": "Add a <kbd>&lt;table&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "caption", "value": "caption",
"message": "Add a <caption> element" "message": "Add a <kbd>&lt;caption&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "thead", "value": "thead",
"message": "Add a <thead> for the header section" "message": "Add a <kbd>&lt;thead&gt;</kbd> for the header section"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "tbody", "value": "tbody",
"message": "Add a <tbody> for the data rows" "message": "Add a <kbd>&lt;tbody&gt;</kbd> for the data rows"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -94,27 +94,27 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "table", "value": "table",
"message": "Add a <table> element" "message": "Add a <kbd>&lt;table&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "caption", "value": "caption",
"message": "Add a <caption> element" "message": "Add a <kbd>&lt;caption&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "thead", "value": "thead",
"message": "Add a <thead> section" "message": "Add a <kbd>&lt;thead&gt;</kbd> section"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "tbody", "value": "tbody",
"message": "Add a <tbody> section" "message": "Add a <kbd>&lt;tbody&gt;</kbd> section"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "tfoot", "value": "tfoot",
"message": "Add a <tfoot> section for the total" "message": "Add a <kbd>&lt;tfoot&gt;</kbd> section for the total"
}, },
{ {
"type": "element_count", "type": "element_count",

View File

@@ -21,7 +21,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "marquee", "value": "marquee",
"message": "Add a <marquee> element" "message": "Add a <kbd>&lt;marquee&gt;</kbd> element"
} }
] ]
}, },
@@ -40,12 +40,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "marquee", "value": "marquee",
"message": "Add a <marquee> element" "message": "Add a <kbd>&lt;marquee&gt;</kbd> element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "marquee", "attr": "behavior", "value": "alternate" }, "value": { "selector": "marquee", "attr": "behavior", "value": "alternate" },
"message": "Add behavior=\"alternate\" to make it bounce" "message": "Add <kbd>behavior=</kbd>\"alternate\" to make it bounce"
} }
] ]
}, },
@@ -64,17 +64,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "marquee", "value": "marquee",
"message": "Add a <marquee> element" "message": "Add a <kbd>&lt;marquee&gt;</kbd> element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "marquee", "attr": "direction", "value": "left" }, "value": { "selector": "marquee", "attr": "direction", "value": "left" },
"message": "Add direction=\"left\" for horizontal scrolling" "message": "Add <kbd>direction=</kbd>\"left\" for horizontal scrolling"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "marquee", "attr": "scrollamount", "value": "5" }, "value": { "selector": "marquee", "attr": "scrollamount", "value": "5" },
"message": "Add scrollamount=\"5\" for smooth speed" "message": "Add <kbd>scrollamount=</kbd>\"5\" for smooth speed"
} }
] ]
} }

View File

@@ -21,22 +21,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "svg", "value": "svg",
"message": "Add an <svg> element" "message": "Add an <kbd>&lt;svg&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "circle", "value": "circle",
"message": "Add a <circle> element inside the SVG" "message": "Add a <kbd>&lt;circle&gt;</kbd> element inside the SVG"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "circle", "attr": "cx", "value": "100" }, "value": { "selector": "circle", "attr": "cx", "value": "100" },
"message": "Set cx=\"100\" for the circle's horizontal center" "message": "Set <kbd>cx=</kbd>\"100\" for the circle's horizontal center"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "circle", "attr": "cy", "value": "100" }, "value": { "selector": "circle", "attr": "cy", "value": "100" },
"message": "Set cy=\"100\" for the circle's vertical center" "message": "Set <kbd>cy=</kbd>\"100\" for the circle's vertical center"
} }
] ]
}, },
@@ -55,17 +55,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "svg", "value": "svg",
"message": "Add an <svg> element" "message": "Add an <kbd>&lt;svg&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "rect", "value": "rect",
"message": "Add a <rect> element" "message": "Add a <kbd>&lt;rect&gt;</kbd> element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "line", "value": "line",
"message": "Add a <line> element" "message": "Add a <kbd>&lt;line&gt;</kbd> element"
} }
] ]
}, },
@@ -84,7 +84,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "svg", "value": "svg",
"message": "Add an <svg> element" "message": "Add an <kbd>&lt;svg&gt;</kbd> element"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -94,7 +94,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "line", "value": "line",
"message": "Add a <line> for the smile" "message": "Add a <kbd>&lt;line&gt;</kbd> for the smile"
} }
] ]
} }

View File

@@ -21,12 +21,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "p", "value": "p",
"message": "Füge ein <p> Absatz-Element hinzu" "message": "Füge ein <kbd>&lt;p&gt;</kbd> Absatz-Element hinzu"
}, },
{ {
"type": "parent_child", "type": "parent_child",
"value": { "parent": "p", "child": "strong" }, "value": { "parent": "p", "child": "strong" },
"message": "Umschließe das Wort 'wichtigen' mit <strong>-Tags" "message": "Umschließe das Wort 'wichtigen' mit <kbd>&lt;strong&gt;</kbd>-Tags"
} }
] ]
}, },
@@ -45,22 +45,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "header", "value": "header",
"message": "Füge ein <header>-Element hinzu" "message": "Füge ein <kbd>&lt;header&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "main", "value": "main",
"message": "Füge ein <main>-Element hinzu" "message": "Füge ein <kbd>&lt;main&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "footer", "value": "footer",
"message": "Füge ein <footer>-Element hinzu" "message": "Füge ein <kbd>&lt;footer&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "parent_child", "type": "parent_child",
"value": { "parent": "header", "child": "h1" }, "value": { "parent": "header", "child": "h1" },
"message": "Füge eine <h1>-Überschrift in deinem Header hinzu" "message": "Füge eine <kbd>&lt;h1&gt;</kbd>-Überschrift in deinem Header hinzu"
} }
] ]
}, },
@@ -79,17 +79,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "div", "value": "div",
"message": "Umschließe alles mit einem <div>-Element" "message": "Umschließe alles mit einem <kbd>&lt;div&gt;</kbd>-Element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "span", "value": "span",
"message": "Füge ein <span> um das Wort 'hervorgehoben' hinzu" "message": "Füge ein <kbd>&lt;span&gt;</kbd> um das Wort 'hervorgehoben' hinzu"
}, },
{ {
"type": "element_text", "type": "element_text",
"value": { "selector": "span", "text": "hervorgehoben" }, "value": { "selector": "span", "text": "hervorgehoben" },
"message": "Das <span> sollte das Wort 'hervorgehoben' enthalten" "message": "Das <kbd>&lt;span&gt;</kbd> sollte das Wort 'hervorgehoben' enthalten"
} }
] ]
} }

View File

@@ -21,51 +21,51 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "form", "value": "form",
"message": "Umschließe alles mit einem <form>-Element" "message": "Umschließe alles mit einem <kbd>&lt;form&gt;</kbd>-Element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "label", "value": "label",
"message": "Füge ein <label> für deine Eingabe hinzu" "message": "Füge ein <kbd>&lt;label&gt;</kbd> für deine Eingabe hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "input", "value": "input",
"message": "Füge ein <input>-Element hinzu" "message": "Füge ein <kbd>&lt;input&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "label", "attr": "for", "value": null }, "value": { "selector": "label", "attr": "for", "value": null },
"message": "Füge ein 'for'-Attribut zu deinem Label hinzu" "message": "Füge ein <kbd>for</kbd>-Attribut zu deinem Label hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input", "attr": "id", "value": null }, "value": { "selector": "input", "attr": "id", "value": null },
"message": "Füge ein 'id'-Attribut zu deiner Eingabe hinzu" "message": "Füge ein <kbd>id</kbd>-Attribut zu deiner Eingabe hinzu"
} }
] ]
}, },
{ {
"id": "input-types", "id": "input-types",
"title": "Eingabetypen", "title": "Eingabetypen",
"description": "Verschiedene Eingabetypen bieten passende Tastaturen und Validierung:<br><br><kbd>type=\"text\"</kbd> - Allgemeiner Text<br><kbd>type=\"email\"</kbd> - E-Mail mit @-Validierung<br><kbd>type=\"password\"</kbd> - Versteckte Zeichen<br><kbd>type=\"number\"</kbd> - Numerische Tastatur<br><kbd>type=\"tel\"</kbd> - Telefon-Tastatur", "description": "Verschiedene Eingabetypen bieten passende Tastaturen und Validierung:<br><br><kbd>type=\"text\"</kbd> - Allgemeiner Text<br><kbd>type=<kbd>\"email\"</kbd></kbd> - E-Mail mit @-Validierung<br><kbd>type=<kbd>\"password\"</kbd></kbd> - Versteckte Zeichen<br><kbd>type=\"number\"</kbd> - Numerische Tastatur<br><kbd>type=\"tel\"</kbd> - Telefon-Tastatur",
"task": "Erstelle ein Anmeldeformular mit zwei Feldern:<br>1. Ein E-Mail-Feld: <kbd>&lt;label for=\"email\"&gt;E-Mail:&lt;/label&gt;</kbd> und <kbd>&lt;input type=\"email\" id=\"email\"&gt;</kbd><br>2. Ein Passwort-Feld: <kbd>&lt;label for=\"password\"&gt;Passwort:&lt;/label&gt;</kbd> und <kbd>&lt;input type=\"password\" id=\"password\"&gt;</kbd>", "task": "Erstelle ein Anmeldeformular mit zwei Feldern:<br>1. Ein E-Mail-Feld: <kbd>&lt;label for=\"email\"&gt;E-Mail:&lt;/label&gt;</kbd> und <kbd>&lt;input type=<kbd>\"email\"</kbd> id=\"email\"&gt;</kbd><br>2. Ein Passwort-Feld: <kbd>&lt;label for=\"password\"&gt;Passwort:&lt;/label&gt;</kbd> und <kbd>&lt;input type=<kbd>\"password\"</kbd> id=\"password\"&gt;</kbd>",
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <!-- Füge E-Mail- und Passwort-Eingaben hinzu -->\n</form>", "initialCode": "<form>\n <!-- Füge E-Mail- und Passwort-Eingaben hinzu -->\n</form>",
"solution": "<form>\n <label for=\"email\">E-Mail:</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n \n <label for=\"password\">Passwort:</label>\n <input type=\"password\" id=\"password\" name=\"password\">\n</form>", "solution": "<form>\n <label for=\"email\">E-Mail:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\">\n \n <label for=\"password\">Passwort:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\">\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "element_exists", "type": "element_exists",
"value": "input[type='email']", "value": "input[type='email']",
"message": "Füge eine Eingabe mit type=\"email\" hinzu" "message": "Füge eine Eingabe mit type=<kbd>\"email\"</kbd> hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "input[type='password']", "value": "input[type='password']",
"message": "Füge eine Eingabe mit type=\"password\" hinzu" "message": "Füge eine Eingabe mit type=<kbd>\"password\"</kbd> hinzu"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -82,8 +82,8 @@
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } button { width: 100%; margin-top: 20px; padding: 10px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } button:hover { background: #1565c0; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } button { width: 100%; margin-top: 20px; padding: 10px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } button:hover { background: #1565c0; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <label for=\"email\">E-Mail:</label>\n <input type=\"email\" id=\"email\">\n \n <label for=\"password\">Passwort:</label>\n <input type=\"password\" id=\"password\">\n \n <!-- Füge Absende-Button hinzu -->\n</form>", "initialCode": "<form>\n <label for=\"email\">E-Mail:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\">\n \n <label for=\"password\">Passwort:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\">\n \n <!-- Füge Absende-Button hinzu -->\n</form>",
"solution": "<form>\n <label for=\"email\">E-Mail:</label>\n <input type=\"email\" id=\"email\">\n \n <label for=\"password\">Passwort:</label>\n <input type=\"password\" id=\"password\">\n \n <button type=\"submit\">Anmelden</button>\n</form>", "solution": "<form>\n <label for=\"email\">E-Mail:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\">\n \n <label for=\"password\">Passwort:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\">\n \n <button type=\"submit\">Anmelden</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {

View File

@@ -14,19 +14,19 @@
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-of-type { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid { border-color: #d32f2f; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-of-type { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid { border-color: #d32f2f; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n \n <label for=\"email\">E-Mail: *</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n \n <button type=\"submit\">Absenden</button>\n</form>", "initialCode": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n \n <label for=\"email\">E-Mail: *</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\">\n \n <button type=\"submit\">Absenden</button>\n</form>",
"solution": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\" required>\n \n <label for=\"email\">E-Mail: *</label>\n <input type=\"email\" id=\"email\" name=\"email\" required>\n \n <button type=\"submit\">Absenden</button>\n</form>", "solution": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\" required>\n \n <label for=\"email\">E-Mail: *</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\" required>\n \n <button type=\"submit\">Absenden</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[name='name']", "attr": "required", "value": true }, "value": { "selector": "input[name='name']", "attr": "required", "value": true },
"message": "Füge required zum Namensfeld hinzu" "message": "Füge <kbd>required</kbd> zum Namensfeld hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[name='email']", "attr": "required", "value": true }, "value": { "selector": "input[name='email']", "attr": "required", "value": true },
"message": "Füge required zum E-Mail-Feld hinzu" "message": "Füge <kbd>required</kbd> zum E-Mail-Feld hinzu"
} }
] ]
}, },
@@ -38,37 +38,37 @@
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-bottom: 5px; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid:not(:placeholder-shown) { border-color: #d32f2f; } small { display: block; font-size: 12px; color: #666; margin-top: 4px; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-bottom: 5px; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid:not(:placeholder-shown) { border-color: #d32f2f; } small { display: block; font-size: 12px; color: #666; margin-top: 4px; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <label for=\"password\">Passwort:</label>\n <input type=\"password\" id=\"password\" name=\"password\" required aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Muss 8-20 Zeichen lang sein</small>\n \n <button type=\"submit\">Konto erstellen</button>\n</form>", "initialCode": "<form>\n <label for=\"password\">Passwort:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\" required aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Muss 8-20 Zeichen lang sein</small>\n \n <button type=\"submit\">Konto erstellen</button>\n</form>",
"solution": "<form>\n <label for=\"password\">Passwort:</label>\n <input type=\"password\" id=\"password\" name=\"password\" required minlength=\"8\" maxlength=\"20\" placeholder=\"Passwort eingeben\" aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Muss 8-20 Zeichen lang sein</small>\n \n <button type=\"submit\">Konto erstellen</button>\n</form>", "solution": "<form>\n <label for=\"password\">Passwort:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\" required minlength=\"8\" maxlength=\"20\" placeholder=\"Passwort eingeben\" aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Muss 8-20 Zeichen lang sein</small>\n \n <button type=\"submit\">Konto erstellen</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[type='password']", "attr": "minlength", "value": "8" }, "value": { "selector": "input[type='password']", "attr": "minlength", "value": "8" },
"message": "Füge minlength=\"8\" zum Passwort hinzu" "message": "Füge <kbd>minlength</kbd>=\"8\" zum Passwort hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[type='password']", "attr": "maxlength", "value": "20" }, "value": { "selector": "input[type='password']", "attr": "maxlength", "value": "20" },
"message": "Füge maxlength=\"20\" zum Passwort hinzu" "message": "Füge <kbd>maxlength</kbd>=\"20\" zum Passwort hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input[type='password']", "attr": "placeholder", "value": null }, "value": { "selector": "input[type='password']", "attr": "placeholder", "value": null },
"message": "Füge einen Placeholder hinzu, der andeutet, was einzugeben ist" "message": "Füge einen <kbd>placeholder</kbd> hinzu, der andeutet, was einzugeben ist"
} }
] ]
}, },
{ {
"id": "complete-registration", "id": "complete-registration",
"title": "Vollständiges Registrierungsformular", "title": "Vollständiges Registrierungsformular",
"description": "Erstelle ein vollständiges Registrierungsformular mit allen Validierungskonzepten:<br><br>- Pflichtfelder mit * markiert<br>- E-Mail-Validierung (type=\"email\" verwenden)<br>- Passwort mit Längenbeschränkungen<br>- AGB-Checkbox (Pflichtfeld)<br>- Absende-Button", "description": "Erstelle ein vollständiges Registrierungsformular mit allen Validierungskonzepten:<br><br>- Pflichtfelder mit * markiert<br>- E-Mail-Validierung (type=<kbd>\"email\"</kbd> verwenden)<br>- Passwort mit Längenbeschränkungen<br>- AGB-Checkbox (Pflichtfeld)<br>- Absende-Button",
"task": "Vervollständige das Registrierungsformular. Füge required-Attribute, passende Eingabetypen und Validierungsbeschränkungen hinzu.", "task": "Vervollständige das Registrierungsformular. Füge <kbd>required</kbd>-Attribute, passende Eingabetypen und Validierungsbeschränkungen hinzu.",
"previewHTML": "", "previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 400px; background: #f5f5f5; padding: 25px; border-radius: 8px; } h2 { margin-top: 0; margin-bottom: 20px; } label { display: block; margin-top: 15px; margin-bottom: 5px; font-weight: 500; } input[type='text'], input[type='email'], input[type='password'] { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; font-size: 14px; } input:focus { outline: 2px solid #1976d2; border-color: transparent; } input[type='checkbox'] { width: auto; margin-right: 8px; vertical-align: middle; } label:has(input[type='checkbox']) { display: flex; align-items: center; font-weight: normal; } button { width: 100%; margin-top: 20px; padding: 12px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; font-weight: 500; } button:hover { background: #1565c0; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 400px; background: #f5f5f5; padding: 25px; border-radius: 8px; } h2 { margin-top: 0; margin-bottom: 20px; } label { display: block; margin-top: 15px; margin-bottom: 5px; font-weight: 500; } input[type='text'], input[type='email'], input[type='password'] { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; font-size: 14px; } input:focus { outline: 2px solid #1976d2; border-color: transparent; } input[type='checkbox'] { width: auto; margin-right: 8px; vertical-align: middle; } label:has(input[type='checkbox']) { display: flex; align-items: center; font-weight: normal; } button { width: 100%; margin-top: 20px; padding: 12px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; font-weight: 500; } button:hover { background: #1565c0; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<form>\n <h2>Konto erstellen</h2>\n \n <label for=\"fullname\">Vollständiger Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\">\n \n <label for=\"email\">E-Mail *</label>\n <input id=\"email\" name=\"email\">\n \n <label for=\"password\">Passwort *</label>\n <input id=\"password\" name=\"password\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\">\n Ich stimme den Nutzungsbedingungen zu *\n </label>\n \n <button type=\"submit\">Registrieren</button>\n</form>", "initialCode": "<form>\n <h2>Konto erstellen</h2>\n \n <label for=\"fullname\">Vollständiger Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\">\n \n <label for=\"email\">E-Mail *</label>\n <input id=\"email\" name=\"email\">\n \n <label for=\"password\">Passwort *</label>\n <input id=\"password\" name=\"password\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\">\n Ich stimme den Nutzungsbedingungen zu *\n </label>\n \n <button type=\"submit\">Registrieren</button>\n</form>",
"solution": "<form>\n <h2>Konto erstellen</h2>\n \n <label for=\"fullname\">Vollständiger Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\" required>\n \n <label for=\"email\">E-Mail *</label>\n <input type=\"email\" id=\"email\" name=\"email\" required>\n \n <label for=\"password\">Passwort *</label>\n <input type=\"password\" id=\"password\" name=\"password\" required minlength=\"8\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\" required>\n Ich stimme den Nutzungsbedingungen zu *\n </label>\n \n <button type=\"submit\">Registrieren</button>\n</form>", "solution": "<form>\n <h2>Konto erstellen</h2>\n \n <label for=\"fullname\">Vollständiger Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\" required>\n \n <label for=\"email\">E-Mail *</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\" required>\n \n <label for=\"password\">Passwort *</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\" required minlength=\"8\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\" required>\n Ich stimme den Nutzungsbedingungen zu *\n </label>\n \n <button type=\"submit\">Registrieren</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
@@ -99,7 +99,7 @@
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "#password", "attr": "minlength", "value": "8" }, "value": { "selector": "#password", "attr": "minlength", "value": "8" },
"message": "Füge minlength=\"8\" zum Passwort hinzu" "message": "Füge <kbd>minlength</kbd>=\"8\" zum Passwort hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",

View File

@@ -21,22 +21,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "details", "value": "details",
"message": "Füge ein <details>-Element hinzu" "message": "Füge ein <kbd>&lt;details&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "summary", "value": "summary",
"message": "Füge ein <summary> innerhalb von details hinzu" "message": "Füge ein <kbd>&lt;summary&gt;</kbd> innerhalb von details hinzu"
}, },
{ {
"type": "parent_child", "type": "parent_child",
"value": { "parent": "details", "child": "summary" }, "value": { "parent": "details", "child": "summary" },
"message": "Das <summary> muss innerhalb von <details> sein" "message": "Das <kbd>&lt;summary&gt;</kbd> muss innerhalb von <details> sein"
}, },
{ {
"type": "parent_child", "type": "parent_child",
"value": { "parent": "details", "child": "p" }, "value": { "parent": "details", "child": "p" },
"message": "Füge ein <p> innerhalb von <details> für den versteckten Inhalt hinzu" "message": "Füge ein <kbd>&lt;p&gt;</kbd> innerhalb von <details> für den versteckten Inhalt hinzu"
} }
] ]
}, },
@@ -55,7 +55,7 @@
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "details", "attr": "open", "value": true }, "value": { "selector": "details", "attr": "open", "value": true },
"message": "Füge das 'open'-Attribut zu <details> hinzu" "message": "Füge das <kbd>open</kbd>-Attribut zu <details> hinzu"
} }
] ]
}, },
@@ -74,7 +74,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "h1", "value": "h1",
"message": "Füge eine <h1>-Überschrift für den FAQ-Titel hinzu" "message": "Füge eine <kbd>&lt;h1&gt;</kbd>-Überschrift für den FAQ-Titel hinzu"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -84,12 +84,12 @@
{ {
"type": "element_count", "type": "element_count",
"value": { "selector": "summary", "min": 3 }, "value": { "selector": "summary", "min": 3 },
"message": "Jedes <details> braucht ein <summary> für die Frage" "message": "Jedes <kbd>&lt;details&gt;</kbd> braucht ein <kbd>&lt;summary&gt;</kbd> für die Frage"
}, },
{ {
"type": "element_count", "type": "element_count",
"value": { "selector": "details p", "min": 3 }, "value": { "selector": "details p", "min": 3 },
"message": "Jedes <details> braucht ein <p> für die Antwort" "message": "Jedes <kbd>&lt;details&gt;</kbd> braucht ein <kbd>&lt;p&gt;</kbd> für die Antwort"
} }
] ]
} }

View File

@@ -21,22 +21,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "progress", "value": "progress",
"message": "Füge ein <progress>-Element hinzu" "message": "Füge ein <kbd>&lt;progress&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "progress", "attr": "value", "value": "70" }, "value": { "selector": "progress", "attr": "value", "value": "70" },
"message": "Setze value=\"70\" beim Progress-Element" "message": "Setze <kbd>value=</kbd>\"70\" beim Progress-Element"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "progress", "attr": "max", "value": "100" }, "value": { "selector": "progress", "attr": "max", "value": "100" },
"message": "Setze max=\"100\" beim Progress-Element" "message": "Setze <kbd>max=</kbd>\"100\" beim Progress-Element"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "label", "value": "label",
"message": "Füge ein <label> für den Fortschrittsbalken hinzu" "message": "Füge ein <kbd>&lt;label&gt;</kbd> für den Fortschrittsbalken hinzu"
} }
] ]
}, },
@@ -55,12 +55,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "progress", "value": "progress",
"message": "Füge ein <progress>-Element hinzu" "message": "Füge ein <kbd>&lt;progress&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "p", "value": "p",
"message": "Füge ein <p> mit Ladetext hinzu" "message": "Füge ein <kbd>&lt;p&gt;</kbd> mit Ladetext hinzu"
} }
] ]
}, },
@@ -79,22 +79,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "meter", "value": "meter",
"message": "Füge ein <meter>-Element hinzu" "message": "Füge ein <kbd>&lt;meter&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "meter", "attr": "value", "value": "0.8" }, "value": { "selector": "meter", "attr": "value", "value": "0.8" },
"message": "Setze value=\"0.8\" beim Meter" "message": "Setze <kbd>value=</kbd>\"0.8\" beim Meter"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "meter", "attr": "low", "value": "0.2" }, "value": { "selector": "meter", "attr": "low", "value": "0.2" },
"message": "Setze low=\"0.2\", um den niedrigen Schwellenwert zu definieren" "message": "Setze <kbd>low=</kbd>\"0.2\", um den niedrigen Schwellenwert zu definieren"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "label", "value": "label",
"message": "Füge ein <label> für das Meter hinzu" "message": "Füge ein <kbd>&lt;label&gt;</kbd> für das Meter hinzu"
} }
] ]
} }

View File

@@ -21,12 +21,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "datalist", "value": "datalist",
"message": "Füge ein <datalist>-Element hinzu" "message": "Füge ein <kbd>&lt;datalist&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input", "attr": "list", "value": "browsers" }, "value": { "selector": "input", "attr": "list", "value": "browsers" },
"message": "Verbinde das Eingabefeld mit der Datalist über list=\"browsers\"" "message": "Verbinde das Eingabefeld mit der Datalist über <kbd>list=</kbd>\"browsers\""
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -36,7 +36,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "label", "value": "label",
"message": "Füge ein <label> für die Eingabe hinzu" "message": "Füge ein <kbd>&lt;label&gt;</kbd> für die Eingabe hinzu"
} }
] ]
}, },
@@ -55,17 +55,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "datalist", "value": "datalist",
"message": "Füge ein <datalist>-Element hinzu" "message": "Füge ein <kbd>&lt;datalist&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "datalist", "attr": "id", "value": "countries" }, "value": { "selector": "datalist", "attr": "id", "value": "countries" },
"message": "Setze id=\"countries\" bei der Datalist" "message": "Setze <kbd>id=</kbd>\"countries\" bei der Datalist"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "input", "attr": "list", "value": "countries" }, "value": { "selector": "input", "attr": "list", "value": "countries" },
"message": "Verbinde das Eingabefeld über list=\"countries\"" "message": "Verbinde das Eingabefeld über <kbd>list=</kbd>\"countries\""
}, },
{ {
"type": "element_count", "type": "element_count",

View File

@@ -31,7 +31,7 @@
{ {
"type": "element_count", "type": "element_count",
"value": { "selector": "article h2", "min": 2 }, "value": { "selector": "article h2", "min": 2 },
"message": "Füge ein <h2> in jeden Article ein" "message": "Füge ein <kbd>&lt;h2&gt;</kbd> in jeden Article ein"
} }
] ]
}, },

View File

@@ -21,17 +21,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "dialog", "value": "dialog",
"message": "Füge ein <dialog>-Element hinzu" "message": "Füge ein <kbd>&lt;dialog&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "dialog", "attr": "open", "value": true }, "value": { "selector": "dialog", "attr": "open", "value": true },
"message": "Füge das 'open'-Attribut hinzu, um den Dialog anzuzeigen" "message": "Füge das <kbd>open</kbd>-Attribut hinzu, um den Dialog anzuzeigen"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "dialog h2", "value": "dialog h2",
"message": "Füge eine <h2>-Überschrift im Dialog hinzu" "message": "Füge eine <kbd>&lt;h2&gt;</kbd>-Überschrift im Dialog hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
@@ -60,7 +60,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "dialog[open]", "value": "dialog[open]",
"message": "Füge ein <dialog> mit dem open-Attribut hinzu" "message": "Füge ein <kbd>&lt;dialog&gt;</kbd> mit dem open-Attribut hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",

View File

@@ -15,23 +15,23 @@
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #f0f4f8; } form { max-width: 400px; } fieldset { border: 2px solid #3498db; border-radius: 10px; padding: 20px; background: white; } legend { color: #3498db; font-weight: 600; padding: 0 10px; font-size: 1.1rem; } label { display: block; margin: 15px 0 5px; color: #333; font-weight: 500; } input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; } input:focus { outline: 2px solid #3498db; border-color: transparent; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #f0f4f8; } form { max-width: 400px; } fieldset { border: 2px solid #3498db; border-radius: 10px; padding: 20px; background: white; } legend { color: #3498db; font-weight: 600; padding: 0 10px; font-size: 1.1rem; } label { display: block; margin: 15px 0 5px; color: #333; font-weight: 500; } input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; } input:focus { outline: 2px solid #3498db; border-color: transparent; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<!-- Erstelle ein Formular mit einer Fieldset-Gruppe -->", "initialCode": "<!-- Erstelle ein Formular mit einer Fieldset-Gruppe -->",
"solution": "<form>\n <fieldset>\n <legend>Persönliche Daten</legend>\n <label for=\"name\">Name:</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n <label for=\"email\">E-Mail:</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n </fieldset>\n</form>", "solution": "<form>\n <fieldset>\n <legend>Persönliche Daten</legend>\n <label for=\"name\">Name:</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n <label for=\"email\">E-Mail:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\">\n </fieldset>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "element_exists", "type": "element_exists",
"value": "form", "value": "form",
"message": "Füge ein <form>-Element hinzu" "message": "Füge ein <kbd>&lt;form&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "fieldset", "value": "fieldset",
"message": "Füge ein <fieldset> im Formular hinzu" "message": "Füge ein <kbd>&lt;fieldset&gt;</kbd> im Formular hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "legend", "value": "legend",
"message": "Füge ein <legend> für den Titel hinzu" "message": "Füge ein <kbd>&lt;legend&gt;</kbd> für den Titel hinzu"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -54,23 +54,23 @@
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; margin: 0; box-sizing: border-box; } form { max-width: 450px; margin: 0 auto; } fieldset { border: none; border-radius: 15px; padding: 30px; background: white; box-shadow: 0 10px 40px rgba(0,0,0,0.2); } legend { color: #667eea; font-weight: 700; padding: 0; font-size: 1.5rem; margin-bottom: 10px; } label { display: block; margin: 20px 0 8px; color: #333; font-weight: 500; } input, textarea { width: 100%; padding: 12px; border: 2px solid #e0e0e0; border-radius: 8px; font-size: 16px; box-sizing: border-box; font-family: inherit; } input:focus, textarea:focus { outline: none; border-color: #667eea; } textarea { resize: vertical; min-height: 100px; } button { margin-top: 20px; width: 100%; padding: 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; } button:hover { opacity: 0.9; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; margin: 0; box-sizing: border-box; } form { max-width: 450px; margin: 0 auto; } fieldset { border: none; border-radius: 15px; padding: 30px; background: white; box-shadow: 0 10px 40px rgba(0,0,0,0.2); } legend { color: #667eea; font-weight: 700; padding: 0; font-size: 1.5rem; margin-bottom: 10px; } label { display: block; margin: 20px 0 8px; color: #333; font-weight: 500; } input, textarea { width: 100%; padding: 12px; border: 2px solid #e0e0e0; border-radius: 8px; font-size: 16px; box-sizing: border-box; font-family: inherit; } input:focus, textarea:focus { outline: none; border-color: #667eea; } textarea { resize: vertical; min-height: 100px; } button { margin-top: 20px; width: 100%; padding: 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; } button:hover { opacity: 0.9; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<!-- Erstelle ein Kontaktformular mit Textarea -->", "initialCode": "<!-- Erstelle ein Kontaktformular mit Textarea -->",
"solution": "<form>\n <fieldset>\n <legend>Kontaktiere uns</legend>\n <label for=\"email\">E-Mail:</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n <label for=\"message\">Nachricht:</label>\n <textarea id=\"message\" name=\"message\" rows=\"4\"></textarea>\n <button type=\"submit\">Nachricht senden</button>\n </fieldset>\n</form>", "solution": "<form>\n <fieldset>\n <legend>Kontaktiere uns</legend>\n <label for=\"email\">E-Mail:</label>\n <input type=<kbd>\"email\"</kbd> id=\"email\" name=\"email\">\n <label for=\"message\">Nachricht:</label>\n <textarea id=\"message\" name=\"message\" rows=\"4\"></textarea>\n <button type=\"submit\">Nachricht senden</button>\n </fieldset>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {
"type": "element_exists", "type": "element_exists",
"value": "fieldset", "value": "fieldset",
"message": "Füge ein <fieldset>-Element hinzu" "message": "Füge ein <kbd>&lt;fieldset&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "legend", "value": "legend",
"message": "Füge ein <legend>-Element hinzu" "message": "Füge ein <kbd>&lt;legend&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "textarea", "value": "textarea",
"message": "Füge eine <textarea> für die Nachricht hinzu" "message": "Füge eine <kbd>&lt;textarea&gt;</kbd> für die Nachricht hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
@@ -93,7 +93,7 @@
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #fafafa; } form { max-width: 500px; } fieldset { border: 1px solid #ddd; border-radius: 10px; padding: 20px; margin-bottom: 20px; background: white; } legend { color: #2c3e50; font-weight: 600; padding: 0 10px; } label { display: block; margin: 15px 0 5px; color: #555; } input, textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; font-family: inherit; } input:focus, textarea:focus { outline: 2px solid #3498db; border-color: transparent; } textarea { resize: vertical; min-height: 80px; } button { width: 100%; padding: 14px; background: #2c3e50; color: white; border: none; border-radius: 8px; font-size: 16px; cursor: pointer; } button:hover { background: #34495e; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #fafafa; } form { max-width: 500px; } fieldset { border: 1px solid #ddd; border-radius: 10px; padding: 20px; margin-bottom: 20px; background: white; } legend { color: #2c3e50; font-weight: 600; padding: 0 10px; } label { display: block; margin: 15px 0 5px; color: #555; } input, textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; font-family: inherit; } input:focus, textarea:focus { outline: 2px solid #3498db; border-color: transparent; } textarea { resize: vertical; min-height: 80px; } button { width: 100%; padding: 14px; background: #2c3e50; color: white; border: none; border-radius: 8px; font-size: 16px; cursor: pointer; } button:hover { background: #34495e; }",
"sandboxCSS": "", "sandboxCSS": "",
"initialCode": "<!-- Erstelle ein Formular mit mehreren Fieldsets -->", "initialCode": "<!-- Erstelle ein Formular mit mehreren Fieldsets -->",
"solution": "<form>\n <fieldset>\n <legend>Kontodaten</legend>\n <label for=\"username\">Benutzername:</label>\n <input type=\"text\" id=\"username\" name=\"username\">\n <label for=\"password\">Passwort:</label>\n <input type=\"password\" id=\"password\" name=\"password\">\n </fieldset>\n <fieldset>\n <legend>Einstellungen</legend>\n <label for=\"bio\">Bio:</label>\n <textarea id=\"bio\" name=\"bio\"></textarea>\n </fieldset>\n <button type=\"submit\">Registrieren</button>\n</form>", "solution": "<form>\n <fieldset>\n <legend>Kontodaten</legend>\n <label for=\"username\">Benutzername:</label>\n <input type=\"text\" id=\"username\" name=\"username\">\n <label for=\"password\">Passwort:</label>\n <input type=<kbd>\"password\"</kbd> id=\"password\" name=\"password\">\n </fieldset>\n <fieldset>\n <legend>Einstellungen</legend>\n <label for=\"bio\">Bio:</label>\n <textarea id=\"bio\" name=\"bio\"></textarea>\n </fieldset>\n <button type=\"submit\">Registrieren</button>\n</form>",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"validations": [ "validations": [
{ {

View File

@@ -21,17 +21,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "figure", "value": "figure",
"message": "Füge ein <figure>-Element hinzu" "message": "Füge ein <kbd>&lt;figure&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "figure img", "value": "figure img",
"message": "Füge ein <img> in die Figure ein" "message": "Füge ein <kbd>&lt;img&gt;</kbd> in die Figure ein"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "figcaption", "value": "figcaption",
"message": "Füge ein <figcaption> für die Beschriftung hinzu" "message": "Füge ein <kbd>&lt;figcaption&gt;</kbd> für die Beschriftung hinzu"
} }
] ]
}, },
@@ -50,22 +50,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "figure", "value": "figure",
"message": "Füge ein <figure>-Element hinzu" "message": "Füge ein <kbd>&lt;figure&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "pre", "value": "pre",
"message": "Füge ein <pre>-Element für formatierten Text hinzu" "message": "Füge ein <kbd>&lt;pre&gt;</kbd>-Element für formatierten Text hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "code", "value": "code",
"message": "Füge ein <code>-Element für den Code hinzu" "message": "Füge ein <kbd>&lt;code&gt;</kbd>-Element für den Code hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "figcaption", "value": "figcaption",
"message": "Füge ein <figcaption> hinzu, das den Code beschreibt" "message": "Füge ein <kbd>&lt;figcaption&gt;</kbd> hinzu, das den Code beschreibt"
} }
] ]
}, },
@@ -84,7 +84,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "figure", "value": "figure",
"message": "Füge ein <figure>-Element hinzu" "message": "Füge ein <kbd>&lt;figure&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -94,7 +94,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "figcaption", "value": "figcaption",
"message": "Füge ein <figcaption> für die Galerie hinzu" "message": "Füge ein <kbd>&lt;figcaption&gt;</kbd> für die Galerie hinzu"
} }
] ]
} }

View File

@@ -21,12 +21,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "table", "value": "table",
"message": "Füge ein <table>-Element hinzu" "message": "Füge ein <kbd>&lt;table&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "caption", "value": "caption",
"message": "Füge eine <caption> als Tabellentitel hinzu" "message": "Füge eine <kbd>&lt;caption&gt;</kbd> als Tabellentitel hinzu"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -55,22 +55,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "table", "value": "table",
"message": "Füge ein <table>-Element hinzu" "message": "Füge ein <kbd>&lt;table&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "caption", "value": "caption",
"message": "Füge ein <caption>-Element hinzu" "message": "Füge ein <kbd>&lt;caption&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "thead", "value": "thead",
"message": "Füge ein <thead> für den Kopfbereich hinzu" "message": "Füge ein <kbd>&lt;thead&gt;</kbd> für den Kopfbereich hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "tbody", "value": "tbody",
"message": "Füge ein <tbody> für die Datenzeilen hinzu" "message": "Füge ein <kbd>&lt;tbody&gt;</kbd> für die Datenzeilen hinzu"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -94,27 +94,27 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "table", "value": "table",
"message": "Füge ein <table>-Element hinzu" "message": "Füge ein <kbd>&lt;table&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "caption", "value": "caption",
"message": "Füge ein <caption>-Element hinzu" "message": "Füge ein <kbd>&lt;caption&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "thead", "value": "thead",
"message": "Füge einen <thead>-Abschnitt hinzu" "message": "Füge einen <kbd>&lt;thead&gt;</kbd>-Abschnitt hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "tbody", "value": "tbody",
"message": "Füge einen <tbody>-Abschnitt hinzu" "message": "Füge einen <kbd>&lt;tbody&gt;</kbd>-Abschnitt hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "tfoot", "value": "tfoot",
"message": "Füge einen <tfoot>-Abschnitt für die Summe hinzu" "message": "Füge einen <kbd>&lt;tfoot&gt;</kbd>-Abschnitt für die Summe hinzu"
}, },
{ {
"type": "element_count", "type": "element_count",

View File

@@ -21,7 +21,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "marquee", "value": "marquee",
"message": "Füge ein <marquee>-Element hinzu" "message": "Füge ein <kbd>&lt;marquee&gt;</kbd>-Element hinzu"
} }
] ]
}, },
@@ -40,12 +40,12 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "marquee", "value": "marquee",
"message": "Füge ein <marquee>-Element hinzu" "message": "Füge ein <kbd>&lt;marquee&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "marquee", "attr": "behavior", "value": "alternate" }, "value": { "selector": "marquee", "attr": "behavior", "value": "alternate" },
"message": "Füge behavior=\"alternate\" zum Springen hinzu" "message": "Füge <kbd>behavior=</kbd>\"alternate\" zum Springen hinzu"
} }
] ]
}, },
@@ -64,17 +64,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "marquee", "value": "marquee",
"message": "Füge ein <marquee>-Element hinzu" "message": "Füge ein <kbd>&lt;marquee&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "marquee", "attr": "direction", "value": "left" }, "value": { "selector": "marquee", "attr": "direction", "value": "left" },
"message": "Füge direction=\"left\" für horizontales Scrollen hinzu" "message": "Füge <kbd>direction=</kbd>\"left\" für horizontales Scrollen hinzu"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "marquee", "attr": "scrollamount", "value": "5" }, "value": { "selector": "marquee", "attr": "scrollamount", "value": "5" },
"message": "Füge scrollamount=\"5\" für flüssige Geschwindigkeit hinzu" "message": "Füge <kbd>scrollamount=</kbd>\"5\" für flüssige Geschwindigkeit hinzu"
} }
] ]
} }

View File

@@ -21,22 +21,22 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "svg", "value": "svg",
"message": "Füge ein <svg>-Element hinzu" "message": "Füge ein <kbd>&lt;svg&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "circle", "value": "circle",
"message": "Füge ein <circle>-Element in das SVG ein" "message": "Füge ein <kbd>&lt;circle&gt;</kbd>-Element in das SVG ein"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "circle", "attr": "cx", "value": "100" }, "value": { "selector": "circle", "attr": "cx", "value": "100" },
"message": "Setze cx=\"100\" für das horizontale Zentrum" "message": "Setze <kbd>cx=</kbd>\"100\" für das horizontale Zentrum"
}, },
{ {
"type": "attribute_value", "type": "attribute_value",
"value": { "selector": "circle", "attr": "cy", "value": "100" }, "value": { "selector": "circle", "attr": "cy", "value": "100" },
"message": "Setze cy=\"100\" für das vertikale Zentrum" "message": "Setze <kbd>cy=</kbd>\"100\" für das vertikale Zentrum"
} }
] ]
}, },
@@ -55,17 +55,17 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "svg", "value": "svg",
"message": "Füge ein <svg>-Element hinzu" "message": "Füge ein <kbd>&lt;svg&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "rect", "value": "rect",
"message": "Füge ein <rect>-Element hinzu" "message": "Füge ein <kbd>&lt;rect&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_exists", "type": "element_exists",
"value": "line", "value": "line",
"message": "Füge ein <line>-Element hinzu" "message": "Füge ein <kbd>&lt;line&gt;</kbd>-Element hinzu"
} }
] ]
}, },
@@ -84,7 +84,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "svg", "value": "svg",
"message": "Füge ein <svg>-Element hinzu" "message": "Füge ein <kbd>&lt;svg&gt;</kbd>-Element hinzu"
}, },
{ {
"type": "element_count", "type": "element_count",
@@ -94,7 +94,7 @@
{ {
"type": "element_exists", "type": "element_exists",
"value": "line", "value": "line",
"message": "Füge eine <line> für das Lächeln hinzu" "message": "Füge eine <kbd>&lt;line&gt;</kbd> für das Lächeln hinzu"
} }
] ]
} }

View File

@@ -976,24 +976,32 @@ input:checked + .toggle-slider::before {
.left-panel, .left-panel,
.right-panel { .right-panel {
width: 100%; width: 100%;
min-height: 50vh; flex-shrink: 0;
border-right: none; border-right: none;
} }
.left-panel { .left-panel {
min-height: 80vh;
border-bottom: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);
} }
.right-panel {
min-height: 50vh;
}
.instructions { .instructions {
max-height: 30vh; max-height: 25vh;
overflow-y: auto;
} }
.editor-section { .editor-section {
flex: 1;
min-height: 50vh; min-height: 50vh;
} }
.editor-content { .editor-content {
min-height: 40vh; flex: 1;
min-height: 45vh;
} }
.preview-wrapper { .preview-wrapper {