Restore email scoped label styles
What does this MR do and why?
Closes Restore email scoped label styles (#627685 - closed); the css_parser upgrade (!250166 (merged)) fixed a parsing bug.. which meant our scoped labels started to look weird.
Fix them:
- Use a CSS border to draw their borders; Gmail drops box-shadows entirely, so using a plain border is reliable.
- But then they look too bloated, since it's 2px extra on all sides. Drop that same amount from the padding, but only in emails.
Screenshots or screen recordings
Comment in question in the web:
| Before | border only |
After (border with padding compensation) |
|---|---|---|
![]() |
![]() |
![]() |
How to set up and validate locally
-
To see this in Gmail, you need to drop something like this in your
config/initializers/smtp_settings.rb:if Rails.env.development? ActionMailer::Base.delivery_method = :smtp ActionMailer::Base.smtp_settings = { address: 'YOUR_SMTP_SERVER', port: 587, user_name: 'YOUR_USERNAME', password: 'YOUR_PASSWORD', authentication: :plain, enable_starttls_auto: true } redirect_all_mail = Class.new do def self.delivering_email(message) message.to = ['YOU+gdk-dest@gitlab.com'] message.from = ['YOUR_EMAIL_ADDRESS'] message.cc = nil message.bcc = nil end end ActionMailer::Base.register_interceptor(redirect_all_mail) endRestart GDK after dropping that in.
If not, you can test against LetterOpener (
/rails/letter_opener), but I've been using Gmail for highest-fidelity, since our reports have been coming internally. -
With master checked out, write a note that includes a few scoped labels (like mine). They're an EE-only feature.
-
Drop this into a file called
scripts/frontend/_tmp.mjs:import { compileAllStyles } from './lib/compile_css.mjs'; await compileAllStyles({ filter: (p) => p.includes('/mailers/'), style: 'compressed' });Then, run
node scripts/frontend/_tmp.mjs. This precompiles your styles, ready for Premailer, the same way it's done for prod. -
Then, open a Rails console, and issue:
ViteRuby.env['VITE_ENABLED'] = 'false' Notify.note_issue_email(User.find_by_username('root').id, Note.last.id).deliver_nowThe first line is to disable Vite in your console session, in case it's on. Premailer doesn't jive with Vite and you won't get any working stylesheet styles in your emails at all like that, only inline ones.
The second line triggers the email for the last-created note.
-
Wait for your email or refresh LetterOpener. It should look like "Before".
-
Check out this branch. Re-do steps 3 through 5.
-
It should look like "After".
-
Tell me your favourite Panthera. The reproduction steps aren't complete until you've done this.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.



