Prerequisites
Before you begin:- Install the extension on your MediaWiki instance
- Activate the Citizen skin
- Identify which pages/features of the extension need styling adjustments
- Set up a development environment (see AGENTS.md)
Step 1: Identify Extension ResourceLoader Modules
First, determine which ResourceLoader modules the extension uses for its styling:- Visit a page where the extension is active
- Open browser DevTools and check the
<head>for loaded stylesheets - Look for module names in the format
ext.ExtensionName.* - Check the extension’s
extension.jsonfile underResourceModules
Example
For Extension:Echo, you might find modules like:ext.echo.styles.badgeext.echo.styles.notificationsext.echo.uiext.echo.special
Step 2: Create the SkinStyles Directory
Create a directory for your extension’s skinStyles:extensions/).
Step 3: Create LESS Files
For each ResourceLoader module you want to style, create a corresponding.less file:
.less appended.
File Structure
Start each file with a header comment:Step 4: Write the Styles
Import Citizen Resources
Import Citizen’s variables or mixins as needed:Use CSS Custom Properties
Always prefer CSS custom properties over LESS variables for theming:Common CSS Custom Properties
| Property | Purpose |
|---|---|
--color-surface-0 | Main background color |
--color-surface-1 | Elevated surface (cards, panels) |
--color-surface-2 | Higher elevation (dropdowns, tooltips) |
--color-emphasized | Primary text color |
--color-subtle | Secondary/muted text |
--color-progressive | Accent color (links, primary actions) |
--color-destructive | Error/delete actions |
--border-color-base | Standard border color |
--border-radius-base | Standard border radius |
--space-xs, --space-sm, etc. | Spacing tokens |
--font-family-base | Body text font |
--font-family-monospace | Code font |
resources/tokens-citizen.less in the Citizen repository.
Example: Styling a Button
Step 5: Register in skin.json
Openskin.json and add entries to the ResourceModuleSkinStyles section:
The + Prefix
The + prefix is critical—it tells MediaWiki to append your styles to the extension’s original styles rather than replacing them:
- With
+:extension.css+yourSkinStyles.css(appended) - Without
+: OnlyyourSkinStyles.css(replaced)
+ prefix unless you’re intentionally replacing all extension styles.
Alphabetical Order
Keep entries alphabetically sorted by module name for maintainability. Insert your new entries in the correct alphabetical position.
Step 6: Test Your Changes
Clear Caches
Browser Testing
- Hard refresh your browser (Ctrl+Shift+R / Cmd+Shift+R)
- Test in both light and dark modes (use Citizen’s theme switcher)
- Check responsive behavior (mobile, tablet, desktop viewports)
- Verify all interactive states (hover, active, focus, disabled)
- Open browser console and check for CSS errors or warnings
Test Multiple Scenarios
- Test with the extension enabled and disabled
- Test on different page types (articles, special pages, edit pages)
- Test with other extensions that might interact with yours
- Check for visual conflicts with other skinStyles
Step 7: Run Linters
Before committing, run style checks:Step 8: Document Your Changes
Update the README.md to include the new extension in the supported list:- Extension name with link to MediaWiki.org
- MediaWiki version or git hash you tested against
Step 9: Submit a Pull Request
-
Create a new branch:
-
Commit your changes:
-
Push and create a PR on GitHub:
-
In your PR description:
- List which extension and version you tested
- Include before/after screenshots
- Mention any known issues or limitations
- Link to the extension on MediaWiki.org
Advanced Topics
Handling Multiple Extension Versions
If an extension has breaking UI changes between versions:- Document the tested version in the file header
- Add version-specific overrides if needed
- Note compatibility in PR description
Working with JavaScript-Heavy Extensions
Some extensions dynamically inject HTML/CSS:- Use browser DevTools to inspect the rendered DOM
- Target dynamically-added classes in your LESS
- Use
!importantsparingly and only when necessary to override inline styles - Consider timing issues (elements added after page load)
Responsive Design
Use Citizen’s breakpoint variables:@min-width-breakpoint-tablet@min-width-breakpoint-desktop@max-width-breakpoint-mobile@max-width-breakpoint-tablet
Supporting Third-Party Libraries
If an extension uses a library (Leaflet, DataTables, etc.):-
Create a reusable LESS file in
skinStyles/lib/: -
Register it once in
skin.json: - Multiple extensions can reference the same library skinStyles
Common Patterns
Hide Elements
Fix Z-Index Issues
Style Form Elements
Dark Mode Considerations
If you use CSS custom properties correctly, dark mode support is automatic. However, if you need mode-specific overrides:Troubleshooting
Styles Not Applying
- Clear MediaWiki cache:
php maintenance/run.php update.php --quick - Hard refresh browser (Ctrl+Shift+R)
- Check browser DevTools → Network tab for 404 errors
- Verify
skin.jsonsyntax (JSON must be valid) - Check that module names match exactly
Specificity Issues
If your styles are being overridden:-
Increase specificity by chaining classes:
-
Use
!importantas a last resort:
Extension Styles Not Loading
If the extension itself isn’t loading styles:- Verify the extension is installed and enabled in
LocalSettings.php - Check the extension’s
extension.jsondeclares the module - Run
php maintenance/run.php update.phpto register new modules
Resources
- Citizen GitHub Repository
- MediaWiki ResourceLoader Documentation
- MediaWiki Skin Development
- Citizen Design Tokens
- Existing SkinStyles Examples
Getting Help
- Open an issue on GitHub for bugs
- Ask questions in the discussion forum
- Check existing skinStyles for similar extensions as reference