Element Styling
Introduction
Mimeeq Web Components are built using Shadow DOM, providing encapsulation of styles and functionality. To allow for easier customization and styling of these components, we expose various parts that can be targeted and styled using CSS.
The ::part
pseudo-element selectors enable developers to style individual parts of Mimeeq Web Components without affecting other parts or the surrounding page. By leveraging these selectors effectively, you can achieve consistent and visually appealing designs across your application.
How Shadow DOM and Parts Work
Understanding Shadow DOM
Shadow DOM creates a separate DOM tree for components, encapsulating their styles and behavior. This provides several benefits:
- Style isolation: Styles defined inside the component don't leak out
- DOM structure hiding: The internal structure is hidden, providing a clean API
- Scoped selectors: CSS selectors inside the component only apply to its shadow tree
However, this encapsulation creates a challenge: how do you customize components from the outside? This is where ::part()
comes in.
The ::part() Selector
The ::part()
selector provides a controlled way to customize specific elements within Shadow DOM:
- Components expose specific elements as "parts" using the
part
attribute - External styles can target these parts using the
::part()
pseudo-element - Only the exposed parts can be styled—the rest remains encapsulated
<!-- Inside the component's shadow DOM -->
<button part="submit-button">Submit</button>
<!-- External CSS -->
mmq-component::part(submit-button) {
background-color: blue;
color: white;
}
Shadow Parts vs. CSS Variables
Mimeeq provides two main methods for styling components:
-
CSS Variables (Theme Customization):
- Best for theming (colors, fonts, spacing)
- Provides a consistent look across all components
- Easier to maintain with theme changes
-
Shadow Parts (this guide):
- Best for structural changes to specific components
- Allows targeting individual elements within a component
- Provides more granular control over specific UI elements
For best results, combine both approaches—use CSS variables for theming and parts for specific structural adjustments.
Styling Mimeeq Components with Parts
Entry Point Components
To style Mimeeq components, you'll primarily target these entry point components:
- mmq-variant-ui: Main container for product variants and customizations
- mmq-modular-ui: Used for modular UI elements (headers, buttons, etc.)
- mmq-tabs: Provides tabbed navigation functionality
- mmq-related-products: Displays related products
- mmq-basket: Handles shopping cart functionality
- mmq-dialog: Used for dialog boxes and modals
- mmq-ar-loader: Handles AR experiences
- mmq-mobile-tabs: Mobile-specific tabs interface
- mmq-side-panel: Side panel for options and configurations
- mmq-ar-preview: Offers augmented reality preview capabilities.
Commonly Styled UI Components
These components are frequently targeted for styling:
- mmq-button: Button component
- mmq-tooltip: Tooltip component
- mmq-loader: Loading indicator component
- mmq-quick-icon-button: Icon button component
- mmq-dialog-header: Header for dialog components
- mmq-dialog-content: Content area for dialog components
- mmq-dialog-footer: Footer for dialog components
Practical Examples
Example 1: Custom Button Styling
To create buttons with rounded corners, custom colors, and uppercase text:
/* Target the finish button in multiple components */
.mmq-variant-ui::part(finish-btn),
.mmq-mobile-tabs::part(finish-btn) {
border: 1px solid var(--mmq-accent-main);
border-radius: 50px;
text-transform: uppercase;
background: transparent;
color: var(--mmq-accent-main);
flex: unset;
width: auto;
padding: 12px 24px;
font-weight: 600;
transition: all 0.2s ease;
}
/* Add hover effect */
.mmq-variant-ui::part(finish-btn):hover,
.mmq-mobile-tabs::part(finish-btn):hover {
background: var(--mmq-accent-main);
color: white;
}
Example 2: Custom Side Panel Group Styling
To customize option groups in the side panel:
/* Style group headers */
.mmq-variant-ui::part(side-panel-group-header) {
background-color: #f5f5f5;
padding: 12px 16px;
border-left: 3px solid var(--mmq-accent-main);
}
/* Style expanded group items */
.mmq-variant-ui::part(side-panel-group-item-button-expanded) {
font-weight: 700;
text-decoration: underline;
text-underline-offset: 4px;
}
/* Style the content container */
.mmq-variant-ui::part(side-panel-group-content) {
padding: 8px 16px 16px;
background-color: #fafafa;
}
Example 3: Custom Dialog Styling
To create dialogs with rounded corners and custom header:
/* Style dialog header */
.mmq-dialog::part(dialog-header) {
background-color: var(--mmq-accent-main);
color: white;
border-radius: 12px 12px 0 0;
}
/* Style dialog content */
.mmq-dialog::part(dialog-content) {
padding: 24px;
background-color: #f9f9f9;
}
/* Style dialog footer */
.mmq-dialog::part(dialog-footer) {
background-color: #f0f0f0;
padding: 16px 24px;
border-radius: 0 0 12px 12px;
}
/* Style close button */
.mmq-dialog-header::part(close-button) {
color: white;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 50%;
}
Example 4: Customizing Basket Appearance
To reposition the basket button and style it:
/* Position the basket button on the left instead of right */
:root {
--mmq-basket-button-radius: 0px 4px 4px 0;
--mmq-basket-button-position-right: initial;
--mmq-basket-button-position-left: 0;
}
/* Style the basket button */
.mmq-basket::part(button) {
background-color: var(--mmq-accent-main);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
/* Style the counter badge */
.mmq-basket::part(counter) {
background-color: white;
color: var(--mmq-accent-main);
font-weight: bold;
}
/* Adjust the panel position */
.mmq-basket::part(panel) {
--mmq-basket-panel-position-right: unset;
--mmq-basket-panel-position-left: 0;
}
Example 5: Mobile Tabs Customization
To enhance the mobile tabs interface:
/* Style the tab buttons */
.mmq-mobile-tabs::part(tab) {
padding: 12px 16px;
border-bottom: 2px solid transparent;
transition: all 0.2s ease;
}
/* Style active tab */
.mmq-mobile-tabs::part(tab-active) {
border-bottom: 2px solid var(--mmq-accent-main);
font-weight: 700;
}
/* Style tab content wrapper */
.mmq-mobile-tabs::part(content-wrapper) {
padding: 16px;
background-color: #fafafa;
}
Component Part Reference
Below are the key components and their available parts for styling. This is not an exhaustive list, but covers the most commonly styled parts.
For full list of available parts and extensive list of components go to:
- Component Styling Reference - list of main components with their parts and css-variables listed
- Components Reference - full list of all available components
mmq-variant-ui
Part | Description |
---|---|
wrapper | Main container for the entire UI |
canvas-container | Container for the 3D canvas |
side-panel | Container for configuration options |
side-panel-header | Header of the side panel |
side-panel-content | Content area of the side panel |
side-panel-footer | Footer of the side panel |
side-panel-group | Group container in the side panel |
side-panel-group-header | Header for a group in the side panel |
side-panel-group-content | Content for a group in the side panel |
side-panel-group-item-button | Button for a group item |
side-panel-group-item-button-expanded | Expanded state for a group item button |
finish-btn | The finish/add to cart button |
summary-box-price | Price display in summary box |
price-value-field | Price display element on mobile |
price-container | Container for price on mobile |
mmq-basket
Part | Description |
---|---|
button | The floating basket button |
counter | The item counter badge |
icon | The icon within the button |
panel | The sliding panel for basket contents |
backdrop | The overlay behind the panel |
mmq-dialog-header
Part | Description |
---|---|
title | The dialog title text |
close-button | The close button |
close-icon | The icon within the close button |
mmq-mobile-tabs
Part | Description |
---|---|
list | Container for tab buttons |
tab | Individual tab button |
tab-active | Currently active tab |
content-wrapper | Container for tab content |
footer | Footer with actions |
finish-btn | Finish/cart button in footer |
summary-box-price | Price display element |
Best Practices
Ensure Specificity
When styling parts, be specific about which component the part belongs to:
/* Good: Specifically targets the button in mmq-basket */
.mmq-basket::part(button) {
background-color: red;
}
/* Bad: Could conflict with other components that have a button part */
::part(button) {
background-color: red;
}
Combine with CSS Variables
For the most maintainable code, use CSS variables for values that might change:
/* Define theme variables at root */
:root {
--my-brand-color: #ff5722;
--my-border-radius: 8px;
}
/* Use variables when styling parts */
.mmq-variant-ui::part(finish-btn) {
background-color: var(--my-brand-color);
border-radius: var(--my-border-radius);
}
Test Across Browsers
Shadow DOM and the ::part()
selector have good support in modern browsers but test your styling in all required browsers.
Fallback for Older Browsers
Consider providing fallbacks for browsers that don't support shadow parts:
/* Fallback using CSS variables for older browsers */
:root {
--mmq-finish-btn-background: blue;
}
/* Modern browsers will use this */
.mmq-variant-ui::part(finish-btn) {
background-color: blue;
}
Handling CSS Resets
When using global CSS resets in your application, you need to be careful not to break Mimeeq components. Here are two approaches:
Method 1: Using the .hydrated Class
Mimeeq automatically adds the .hydrated
class to custom elements once loaded:
/* Reset styles for standard elements only */
*:not(.hydrated),
*:not(.hydrated)::before,
*:not(.hydrated)::after {
margin: 0;
box-sizing: inherit;
}
Method 2: Using Attribute Selectors
Target only standard HTML elements for your reset:
/* Reset styles for built-in elements only */
:where(*:not(:defined)):not(:is(*-*)),
:where(*:not(:defined)):not(:is(*-*))::before,
:where(*:not(:defined)):not(:is(*-*))::after {
margin: 0;
box-sizing: inherit;
}
Further Resources
- Theme Customization - Learn how to use CSS variables for theming
- Configurator Customization - See practical examples
- MDN Web Docs: ::part - Learn more about the part selector
- MDN Web Docs: Shadow DOM - Understand Shadow DOM fundamentals