Refactor CSS Using Modern Selectors
In this assignment, you will refactor existing CSS to use modern selectors and nesting. You will replace repetitive selector patterns with :is() and :where(), implement parent-based logic with :has(), use :not() for exclusions, and convert flat CSS to nested CSS. This refactoring will reduce code repetition, improve readability, and demonstrate better specificity management.
Assignment Overview
You are provided with a working HTML page and CSS file that uses older patterns: repetitive selectors, flat (non-nested) structure, and unnecessarily high specificity. Your task is to refactor the CSS using modern techniques while maintaining the exact same visual appearance. The goal is to write cleaner, more maintainable CSS that is easier to understand and modify.
Learning Objectives
-
Identify opportunities to use
:is()to reduce selector repetition -
Apply
:where()to reduce specificity and make styles easier to override -
Use
:has()to implement parent-based styling logic -
Employ
:not()for exclusion patterns - Convert flat CSS to nested CSS for better organization
- Understand the impact of refactoring on specificity and maintainability
Setup Instructions
1. Download Starter Files
Download the starter files from refactoring.zip. Extract the files and you will find:
-
index.html— The HTML structure (do not modify) -
styles-old.css— The CSS to refactor (do not modify, keep for reference) -
styles-new.css— Empty file where you will write your refactored CSS
2. Add to Your Portfolio
Create a new directory in your portfolio for this assignment:
portfolio/
└── unit-1/
└── css-refactoring/
├── index.html
├── styles-old.css
└── styles-new.css
3. Verify Starting Point
Open index.html in your browser. Notice that styles-old.css is commented out and styles-new.css is linked. The page will appear unstyled initially. Your goal is to recreate the exact same appearance using modern CSS techniques in styles-new.css.
Reference the old styles: You can temporarily uncomment styles-old.css to see what the page should look like when properly styled. Make sure to comment it back out when working on your refactored version.
Requirements
Your refactored CSS must meet all of the following requirements. Each requirement demonstrates your understanding of modern selectors and CSS organization.
1. Use CSS Nesting
- Convert all flat selectors to nested CSS where appropriate
- Group related rules under parent selectors
-
Use the
&symbol for pseudo-classes and modifiers
2. Replace Repetitive Selectors with :is()
- Identify patterns where the same properties are applied to multiple selectors
-
Combine these selectors using
:is() - Reduce code duplication significantly
3. Manage Specificity with :where()
-
Use
:where()for base styles that should be easy to override - Demonstrate understanding of zero-specificity benefits
-
Document why you chose
:where()over:is()in specific cases
4. Implement :has() for Conditional Styling
-
Replace class-based conditional styling with
:has()where appropriate - Style parent elements based on their children or siblings
- Eliminate the need for JavaScript-added classes
5. Use :not() for Exclusions
- Simplify rules that exclude certain elements
-
Use modern multiple-selector
:not()syntax where beneficial
6. Maintain Visual Parity
- Your refactored CSS must produce the exact same visual result as the original
- Test thoroughly at different screen sizes
- Verify all interactive states (hover, focus, etc.)
Refactoring Strategy
1. Analyze the Old CSS
Before writing code, review styles-old.css and identify patterns. Look for:
-
Repeated selector lists that could use
:is() -
High specificity selectors that could use
:where() -
Class-based conditional styling that could use
:has() -
Exclusion patterns that could use
:not() - Flat selectors that should be nested
2. Plan Your Structure
Decide how to organize your nested CSS. Group related rules together and plan your nesting hierarchy. Consider which selectors should be at the root level and which should be nested.
3. Refactor Incrementally
Refactor one section at a time. Work on the navigation, then the hero section, then the cards, and so on. Test each section as you complete it to ensure visual parity.
4. Compare and Document
After completing your refactoring, compare your new CSS with the old CSS. Note the improvements in line count, readability, and specificity management.
Example Refactoring Patterns
Here are some patterns you will encounter in the starter CSS and how to approach them:
Pattern 1: Repetitive Selectors
/* Old: repetitive */
.header h1 { }
.header h2 { }
.header h3 { }
.footer h1 { }
.footer h2 { }
.footer h3 { }
/* New: using :is() and nesting */
:is(.header, .footer) {
:is(h1, h2, h3) {
/* styles */
}
}
Pattern 2: High Specificity
/* Old: high specificity from IDs */
#navigation ul li a { }
/* New: using :where() for zero specificity */
:where(#navigation) {
ul {
li {
a { }
}
}
}
Pattern 3: Conditional Classes
/* Old: requires class added by JavaScript */
.card.has-image { }
/* New: pure CSS with :has() */
.card:has(img) { }
Testing Checklist
Before submitting, verify that your refactored CSS meets these criteria:
- Visual appearance matches the original exactly
- All hover and focus states work correctly
- Responsive behavior is maintained at all screen sizes
- Code is more readable and maintainable than the original
- Line count is reduced compared to the original
- Selectors use appropriate specificity levels
- CSS follows consistent nesting and organization patterns
Submission
Once you have completed your refactoring and tested thoroughly, document your work and submit it for evaluation. Complete the form below with your refactoring decisions and analysis, then download the PDF and submit it to Canvas.
Evaluation Criteria
Your refactored CSS will be evaluated on how effectively it demonstrates modern selector usage and improves upon the original code:
- Visual Parity: Does your CSS produce the exact same appearance as the original?
-
Modern Selectors: Have you effectively used
:is(),:where(),:has(), and:not()? - CSS Nesting: Is your CSS properly nested and well-organized?
- Code Quality: Is your CSS more maintainable and readable than the original?
- Specificity Management: Have you appropriately managed specificity?
- Documentation: Have you clearly explained your refactoring decisions?
Tips for Success
- Keep the old CSS handy: Reference it frequently to understand what each rule is doing
- Test incrementally: Refactor one section at a time and test before moving on
- Use browser DevTools: Compare computed styles between old and new to ensure parity
- Look for patterns: The same refactoring techniques often apply in multiple places
- Consider maintenance: Think about how easy it would be to modify your refactored code
- Document as you go: Note your decisions while refactoring, not after
- Review the lesson: Reference the modern selectors lesson when deciding which selector to use