PostCSS and Modern CSS Features
In this assignment, you will set up a PostCSS build process for your portfolio and implement responsive components using container queries and feature detection with @supports. This assignment brings together the build tooling concepts and modern CSS features you have learned, applying them to create a maintainable, production-ready CSS architecture.
You will work with provided starter files that include the basic structure, HTML scaffold, and configuration files. Your task is to complete the CSS implementation by adding container queries and @supports feature detection, then integrate the build process into your portfolio workflow.
Assignment Overview
You are provided with a complete project structure including HTML, PostCSS configuration, and organized CSS files following CUBE CSS principles. The CSS files are partially complete with TODO comments indicating where you need to add container queries and @supports checks. Your task is to complete the implementation and ensure the PostCSS build process works correctly.
Learning Objectives
- Set up and run a PostCSS build process with multiple plugins
- Organize CSS using CUBE CSS architecture principles
- Implement container queries for component-based responsive design
-
Use
@supportsto provide progressive enhancement with sensible fallbacks - Work with modern CSS features while maintaining browser compatibility
Setup Instructions
1. Download Starter Files
Download the starter files and extract the contents. You will find:
-
index.html— Complete HTML structure (do not modify unless needed for testing) -
package.json— npm configuration with build scripts already set up -
postcss.config.js— PostCSS configuration with all plugins configured -
.browserslistrc— Browser support targets for autoprefixer -
css/— Directory with organized CSS files following CUBE CSS structure
2. Add to Your Portfolio
Copy the starter files into your portfolio repository:
portfolio/
└── unit-2/
└── postcss-practice/
├── css/
│ ├── base/
│ ├── components/
│ ├── layout/
│ ├── utilities/
│ └── main.css
├── index.html
├── package.json
├── postcss.config.js
└── .browserslistrc
3. Install Dependencies
Navigate to the postcss-practice directory in your terminal and install the required packages:
cd portfolio/unit-2/postcss-practice
npm install
This command reads the package.json file and installs all the PostCSS plugins and dependencies needed for the build process. The installation may take a minute or two depending on your internet connection.
4. Review the File Structure
Before starting implementation, familiarize yourself with how the CSS is organized:
- base/: Variables, colors, fonts, and foundational styles that everything else builds upon
- components/: Reusable UI components like cards, buttons, and navigation
- layout/: Page structure and major layout patterns like grids and containers
- utilities/: Single-purpose helper classes for common styling needs
- main.css: The entry point that imports all other files in the correct order
Open css/components/card.css and read through the TODO comments. This is where you will implement the container queries and @supports checks.
Requirements
Your implementation must meet all of the following requirements. Each requirement demonstrates your understanding of PostCSS, container queries, and progressive enhancement.
1. PostCSS Build Process
-
Successfully run the PostCSS build process using
npm run build -
Verify that
css/main.min.cssis generated with all files combined - Verify that the output CSS is minimized (whitespace removed, shortened property names where possible)
2. Container Query Implementation
-
Set up the
.card-containerclass with proper container properties - Implement a container query that changes the card layout when the container reaches 400px width
- Cards should switch from vertical (stacked) to horizontal (side-by-side) layout at the breakpoint
- Images should maintain appropriate sizing and not distort
3. Progressive Enhancement with @supports
-
Wrap your container query implementation in an
@supportscheck - Ensure base card styles work as a fallback for browsers without container query support
-
Implement at least one additional
@supportscheck for another modern CSS feature (CSS nesting,color-mix(), or subgrid) - Provide appropriate fallback styles for each modern feature you use
4. CSS Organization
- Maintain the CUBE CSS file structure (do not reorganize the directories)
- Keep component styles in the components directory
-
Use the provided custom properties from
base/variables.css - Do not modify the base files unless instructed to do so
5. Testing and Verification
-
Test with both
css/main.cssandcss/main.min.cssto verify the build works - Verify container queries work by resizing the browser window
- Test in at least one browser to confirm the layout responds correctly
- Verify that the fallback styles work (you can temporarily disable container queries in DevTools to test)
Implementation Steps
1. Set Up the Card Container
Open css/components/card.css and find the first TODO comment. Add the container properties to .card-container:
.card-container {
container-type: inline-size;
container-name: card;
}
This establishes the container that child elements can query. The inline-size value means the container tracks its width, and naming it card allows us to be explicit about which container we are querying.
2. Add Container Query for Wide Cards
Add a container query that changes the card layout when the container is at least 400px wide:
@container card (min-width: 400px) {
.card {
flex-direction: row;
align-items: flex-start;
}
.card-image {
width: 200px;
flex-shrink: 0;
}
}
This changes the card from a vertical stack to a horizontal layout with the image on the left side. The flex-shrink: 0 prevents the image from getting smaller than 200px.
3. Wrap Container Query in @supports
Now wrap your container setup and query in an @supports check to ensure browsers without container query support use the base styles:
@supports (container-type: inline-size) {
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
flex-direction: row;
align-items: flex-start;
}
.card-image {
width: 200px;
flex-shrink: 0;
}
}
}
This ensures that browsers without container query support simply use the base card styles (vertical layout) without errors. The cards will still work, just without the container-based responsive behavior.
4. Add Another Modern CSS Feature
Choose one of the following options and implement it with an @supports fallback. This demonstrates your understanding of progressive enhancement for different CSS features.
Use native CSS nesting to organize hover states inside the .card selector:
/* Fallback: separate hover rule */
.card:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
/* Enhanced: nested hover rule */
@supports (selector(&)) {
.card {
&:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
}
}
Use color-mix() to create a dynamic hover background color:
/* Fallback: static background color */
.card:hover {
background-color: #f0f0f0;
}
/* Enhanced: dynamic color mixing */
@supports (background: color-mix(in oklch, red, blue)) {
.card:hover {
background-color: color-mix(in oklch, var(--bg-clr) 95%, var(--link-clr) 5%);
}
}
If you modify the layout to use a grid of cards, use subgrid to align content across cards:
/* Base grid layout */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: var(--spacing-med);
}
.card {
display: grid;
grid-template-rows: auto 1fr auto;
gap: var(--spacing-sm);
}
/* Enhanced: subgrid alignment */
@supports (grid-template-rows: subgrid) {
.card {
grid-template-rows: subgrid;
grid-row: span 3;
}
}
5. Build and Test
Run the PostCSS build process:
npm run build
Open index.html in your browser. The page should now show three cards that respond to their container size. Resize the browser window to verify the container queries work correctly.
During development, you can use the watch command to automatically rebuild when you save changes:
npm run watch
Press Ctrl+C in the terminal to stop the watch process when you are done.
6. Verify the Build Output
Open css/main.min.css and verify that:
- All your CSS files have been combined into one file
- The CSS is minimized (no extra whitespace, shortened where possible)
-
Font URLs have been rewritten from
../fonts/to./fonts/
Understanding the Conditional CSS Loading
The HTML file includes JavaScript that conditionally loads either main.min.css (processed) or main.css (source) depending on which file exists. This is a convenience for this assignment to make testing easier.
(async () => {
const link = document.createElement('link');
link.rel = 'stylesheet';
try {
const res = await fetch('/css/main.min.css', { method: 'HEAD' });
link.href = res.ok ? '/css/main.min.css' : '/css/main.css';
} catch {
link.href = '/css/main.css';
}
document.head.appendChild(link);
})();
This is non-standard practice. In production, you would typically only deploy the processed files and use a standard <link> tag in your HTML. We are using this approach for convenience in this assignment so you can easily test both the source and processed CSS files without manually changing the HTML.
Testing Checklist
Before submitting, verify that your implementation meets these criteria:
- PostCSS build completes without errors
-
css/main.min.cssis generated and contains combined, minimized CSS - Cards display correctly in both vertical and horizontal layouts
- Container queries trigger at the correct breakpoint (400px)
- Base styles work as fallback when container queries are not supported
- Your chosen modern CSS feature works correctly
- Fallback styles are provided for the modern CSS feature
-
The page works when loading either
main.cssormain.min.css - Images scale appropriately and do not distort
Submission
Once you have completed your implementation and tested thoroughly, document your work and submit it for evaluation. Complete the form below with your implementation details, then download the PDF and submit it to Canvas.
Portfolio Link:
Which feature(s) did you implement with @supports?
Evaluation Criteria
Your implementation will be evaluated on how effectively it demonstrates PostCSS configuration, container queries, and progressive enhancement:
- Build Process: Does PostCSS successfully process your CSS files? Is the output minimized?
- Container Queries: Are container queries implemented correctly? Do cards respond to their container size rather than the viewport?
-
Progressive Enhancement: Are
@supportschecks used appropriately? Do fallback styles work correctly? - CSS Organization: Is the CSS properly organized following CUBE CSS principles? Are custom properties used appropriately?
- Code Quality: Is your CSS clean and well-structured? Are there any syntax errors or console warnings?
- Testing: Does the implementation work correctly in the browser? Have you verified both the source and processed CSS files?
Tips for Success
-
Read through all the TODO comments in
css/components/card.cssbefore starting - Test your container queries by resizing the browser window slowly and watching when the layout changes
-
Use browser DevTools to inspect the generated
main.min.cssand verify the build process worked - If the build fails, read the error messages carefully as they usually indicate exactly what went wrong
-
Use
npm run watchduring development to automatically rebuild on save -
Test your fallback styles by temporarily removing the
@supportschecks to see the base styles - Remember that container queries query the container size, not the viewport, so cards in narrow containers will stay vertical even on wide screens