咨询:如何用SCSS多Mixin创建DRY风格多页面主题卡片
Let’s break down a scalable, maintainable solution that lets you reuse card components across pages while applying page-specific themes—all while simplifying your HTML to just the .card class.
Step 1: Centralize Theme Configuration
First, use a SCSS map to store all your page themes. This makes it trivial to add/modify themes later without hunting through code:
// Define all page themes (add/remove as needed) $themes: ( page1: hsl(193, 99%, 47%), // Blue theme page2: hsl(270, 100%, 60%), // Purple theme page3: hsl(10, 100%, 60%) // Red theme ); // Shared global variables (cleaned up for brevity) $buffer: 1.5em 0; $padding: 1em; $pull-left-offset: -16px; $pull-right-offset: -15px; $shadow-base: 8.5px 7.5px 0 0;
Step 2: Refactor Mixins for Reusability
Simplify your mixins to eliminate repetition and make them more flexible:
// Box-shadow mixin: handles direction and hover state with minimal repetition @mixin box-shadow($color, $direction: 'right', $hover: false) { // Flip horizontal shadow based on direction $horizontal-shadow: if($direction == 'right', $shadow-base, -nth($shadow-base, 1) nth($shadow-base, 2) nth($shadow-base, 3) nth($shadow-base, 4)); @if $hover { &:hover { box-shadow: $horizontal-shadow $color; } } @else { box-shadow: $horizontal-shadow $color; } } // Card pull mixin: handles left/right positioning @mixin card-pull($direction: 'left') { left: if($direction == 'left', $pull-left-offset, auto); right: if($direction == 'right', $pull-right-offset, auto); }
Note: We removed the redundant background-color mixin—you can directly set background-color using variables instead of wrapping it in a mixin.
Step 3: Build Reusable Base Card Styles
Define all shared card properties once in a base .card class. This ensures consistency across all cards:
.card { margin: $buffer; padding: $padding; @include card-pull('left'); // Default pull direction (override with modifiers if needed) // Add other shared styles here (e.g., border-radius, transition, etc.) }
Step 4: Generate Page-Specific Theme Styles
Use a loop to generate theme-scoped styles for each page. We’ll scope themes to a body class so styles only apply to the current page:
// Generate theme-specific card styles for each page @each $theme-name, $theme-color in $themes { body.theme-#{$theme-name} { .card { background-color: $theme-color; @include box-shadow($theme-color, 'right', false); // Optional: Add hover state if needed // &:hover { // @include box-shadow($theme-color, 'right', true); // } } } }
Step 5: Simplify Your HTML
Now, all you need to do is add a theme class to the <body> of each page, and use the .card class on your elements. No more redundant classes!
Page 1 (Blue Theme)
<body class="theme-page1"> <div class="container-fluid"> <div class="row col-md-5 col-sm-11 col-xs-11 card"> <h1>Page 1 Title</h1> </div> </div> </body>
Page 2 (Purple Theme)
<body class="theme-page2"> <div class="container-fluid"> <div class="row col-md-5 col-sm-11 col-xs-11 card"> <h1>Page 2 Title</h1> </div> </div> </body>
Key Benefits of This Approach
- Scalable Themes: Add new pages/themes by just updating the
$themesmap. - DRY Code: No repeated styles or HTML classes—shared logic lives in mixins/base styles.
- Clean HTML: Your markup stays focused on layout (Bootstrap classes) and component identity (
.card), not styling details. - Maintainable: Changes to card styles only need to be made in one place, not across every page.
Optional: Add Modifier Classes for Edge Cases
If you need variations of the card (e.g., right-aligned, left shadow), add modifier classes:
// Right-pulled card .card--pull-right { @include card-pull('right'); } // Left-shadow card .card--shadow-left { @include box-shadow($theme-color, 'left', false); }
Use them in HTML like:
<div class="row col-md-5 col-sm-11 col-xs-11 card card--pull-right"> <h1>Right-Pulled Card</h1> </div>
内容的提问来源于stack exchange,提问作者xtianpoop

