{ "$schema": "../schemas/code-crispies-module-schema.json", "id": "css-advanced-selectors", "title": "Adv. Selectors", "description": "Master advanced CSS selector techniques including attribute selectors, combinators, and pseudo-classes. This module builds on basic selectors to give you precise control over element targeting, enabling sophisticated styling patterns and interactive effects.", "difficulty": "intermediate", "lessons": [ { "id": "attribute-selectors", "title": "[attribute]", "description": "Attribute selectors allow you to target elements based on their HTML attributes and attribute values. They are incredibly powerful for styling forms, links, and other elements with specific attributes. The basic syntax uses square brackets: [attribute] selects elements with that attribute, [attribute=\"value\"] selects elements where the attribute equals exactly that value, and [attribute^=\"value\"] selects elements where the attribute starts with that value. You can style these selected elements using properties like border to add visual boundaries and background-color to highlight specific form fields or links.", "task": "Create a CSS rule using an attribute selector that targets all input elements with type=\"text\". Give them a lightblue background and a 2px solid blue border.", "previewHTML": "
", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } form { max-width: 300px; } label { display: block; margin-bottom: 5px; } input, button { padding: 8px; margin-bottom: 10px; border-radius: 4px; }", "sandboxCSS": "", "codePrefix": "/* Target input elements with type=\"text\" using an attribute selector */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "input[type=\"text\"] {\n background-color: lightblue;\n border: 2px solid blue;\n}", "validations": [ { "type": "regex", "value": "^input\\[type=\"text\"\\]\\s*{", "message": "Use input[type=\"text\"] { âĻ } as your attribute selector", "options": { "caseSensitive": true } }, { "type": "contains", "value": "background-color:", "message": "Include the background-color property" }, { "type": "property_value", "value": { "property": "background-color", "expected": "lightblue" }, "message": "Set the background color to lightblue" }, { "type": "regex", "value": "background-color:\\s*[^;]*;", "message": "Make sure to close the background-color declaration with a semicolon ;" }, { "type": "contains", "value": "border:", "message": "Include the border property" }, { "type": "property_value", "value": { "property": "border", "expected": "2px solid blue" }, "message": "Set the border to 2px solid blue" }, { "type": "regex", "value": "input\\[type=\"text\"\\]\\s*{[^}]*}", "message": "Make sure to close your CSS rule with a closing brace }", "options": { "caseSensitive": true } } ] }, { "id": "attribute-partial-matching", "title": "Attr Matching", "description": "Attribute selectors support partial matching patterns that let you target elements based on portions of attribute values. The [attribute^=\"value\"] selector matches elements where the attribute starts with the specified value, [attribute$=\"value\"] matches where it ends with the value, and [attribute*=\"value\"] matches where the value appears anywhere within the attribute. These patterns are particularly useful for styling external links, file types, or elements with class names that follow naming conventions. When styling these matched elements, you can use properties like color to change text color and text-decoration to add visual emphasis like underlines.", "task": "Create a CSS rule that targets all anchor elements (a) with href attributes starting with \"https\". Style them with green text color and underline text decoration.", "previewHTML": "This link outside nav should not be affected.
", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } nav { border: 2px solid navy; padding: 15px; background-color: aliceblue; margin-bottom: 15px; } ul { list-style-type: none; padding-left: 20px; } li { margin-bottom: 5px; }", "sandboxCSS": "", "codePrefix": "/* Target all anchor elements inside nav using the descendant combinator */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "nav a {\n text-decoration: none;\n color: blue;\n}", "validations": [ { "type": "regex", "value": "^nav\\s+a\\s*{", "message": "Use nav a with a space between nav and a", "options": { "caseSensitive": true } }, { "type": "contains", "value": "text-decoration:", "message": "Include the text-decoration property" }, { "type": "property_value", "value": { "property": "text-decoration", "expected": "none" }, "message": "Set text-decoration to none" }, { "type": "contains", "value": "color:", "message": "Include the color property" }, { "type": "property_value", "value": { "property": "color", "expected": "blue" }, "message": "Set color to blue" }, { "type": "regex", "value": "nav\\s+a\\s*{[^}]*}", "message": "Make sure to close your CSS rule with a closing brace }", "options": { "caseSensitive": true } } ] }, { "id": "adjacent-sibling-combinator", "title": "Adjacent (+)", "description": "The adjacent sibling combinator (+) selects an element that immediately follows another element at the same level in the HTML structure. Both elements must share the same parent, and there can be no other elements between them. For example, h1 + p selects paragraph elements that come directly after h1 headings. This combinator is particularly useful for styling elements that have special relationships, like the first paragraph after a heading, or labels that follow form inputs. When styling adjacent siblings, you can use properties like margin-top to adjust spacing and font-style to add emphasis like italics to create visual hierarchy.", "task": "Use the adjacent sibling combinator to target paragraphs that immediately follow h2 headings. Remove their top margin with margin-top: 0 and make them italic.", "previewHTML": "This paragraph directly follows h2 (should be affected).
\nThis paragraph comes after another paragraph (should NOT be affected).
\nThis paragraph also directly follows h2 (should be affected).
\nThis paragraph comes after a div (should NOT be affected).
", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } h2, p, div { margin: 15px 0; padding: 8px; border: 1px dashed #ccc; }", "sandboxCSS": "", "codePrefix": "/* Target paragraphs that immediately follow h2 headings */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "h2 + p {\n margin-top: 0;\n font-style: italic;\n}", "validations": [ { "type": "regex", "value": "^h2\\s*\\+\\s*p\\s*{", "message": "Use h2 + p with the adjacent sibling combinator (+)", "options": { "caseSensitive": true } }, { "type": "contains", "value": "margin-top:", "message": "Include the margin-top property" }, { "type": "property_value", "value": { "property": "margin-top", "expected": "0" }, "message": "Set margin-top to 0" }, { "type": "contains", "value": "font-style:", "message": "Include the font-style property" }, { "type": "property_value", "value": { "property": "font-style", "expected": "italic" }, "message": "Set font-style to italic" }, { "type": "regex", "value": "h2\\s*\\+\\s*p\\s*{[^}]*}", "message": "Make sure to close your CSS rule with a closing brace }", "options": { "caseSensitive": true } } ] }, { "id": "general-sibling-combinator", "title": "Sibling (~)", "description": "The general sibling combinator (~) selects all elements that follow another element at the same level, not just the immediately adjacent one. Unlike the adjacent sibling combinator, there can be other elements between the target elements, as long as they all share the same parent and the selected elements come after the reference element. For example, h2 ~ p selects all paragraph elements that appear after any h2 heading at the same level. When styling general siblings, you can use properties like color to change text color and padding-left to create visual indentation, helping to show the relationship between related content sections.", "task": "Use the general sibling combinator to target all paragraphs that come after the h3 heading (at the same level). Give them a gray color and 20px of left padding.", "previewHTML": "This paragraph comes before h3 (should NOT be affected).
\nFirst paragraph after h3 (should be affected).
\nSecond paragraph after h3 (should also be affected).
\n More content\nThird paragraph after h3 (should also be affected).
\nHover over the button below to see the effect:
\n\nThe button should change colors when you hover over it.
", "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } button { padding: 12px 24px; font-size: 16px; border: 2px solid darkblue; background-color: lightblue; color: darkblue; border-radius: 5px; cursor: pointer; }", "sandboxCSS": "", "codePrefix": "/* Create a hover effect for the button */\n", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "button:hover {\n background-color: darkblue;\n color: white;\n}", "validations": [ { "type": "regex", "value": "^button:hover\\s*{", "message": "Use button:hover to target buttons on hover", "options": { "caseSensitive": true } }, { "type": "contains", "value": "background-color:", "message": "Include the background-color property" }, { "type": "property_value", "value": { "property": "background-color", "expected": "darkblue" }, "message": "Set background-color to darkblue" }, { "type": "contains", "value": "color:", "message": "Include the color property" }, { "type": "property_value", "value": { "property": "color", "expected": "white" }, "message": "Set color to white" }, { "type": "regex", "value": "button:hover\\s*{[^}]*}", "message": "Make sure to close your CSS rule with a closing brace }", "options": { "caseSensitive": true } } ] }, { "id": "first-child-pseudo-class", "title": ":first-child", "description": "The :first-child pseudo-class selects elements that are the first child of their parent element. This is useful for applying special styling to the first item in lists, the first paragraph in articles, or the first element in any container. For example, li:first-child selects the first list item in each list, while p:first-child selects paragraphs that are the first child element of their container. When styling first children, you can use properties like font-weight to make the first item bold and margin-top to adjust spacing, helping create visual hierarchy and improve the layout of your content.", "task": "Use the :first-child pseudo-class to target the first list item in each list. Make it bold and remove its top margin.", "previewHTML": "