codeat3/inlinestyle
InlineStyle converts embedded/external CSS into inline style attributes on HTML elements—ideal for HTML emails where clients ignore stylesheets. Load HTML from a file or string, extract/apply stylesheets (with optional base URL), then get the modified HTML.
Installation:
composer require codeat3/inlinestyle
Add the service provider to config/app.php:
Codeat3\Inlinestyle\InlinestyleServiceProvider::class,
First Use Case:
Inline CSS from a <style> block in a Blade template:
@inlineStyle('<style>body { color: red; }</style>')
<div>Hello, world!</div>
Outputs:
<div style="color: red;">Hello, world!</div>
Alternative: Process HTML Strings:
use Codeat3\Inlinestyle\InlineStyle;
$html = '<style>p { margin: 0; }</style><p>Test</p>';
$processor = new InlineStyle($html);
$processor->applyStylesheet($processor->extractStylesheets());
echo $processor->getHTML();
Blade Integration:
@inlineStyle() for embedded CSS:
@inlineStyle(file_get_contents('css/email-template.css'))
@inlineStyle('<style>body { font-family: Arial; }</style>')
@inlineStyle('<style>a { color: blue; }</style>')
Dynamic Email Templates:
public function build()
{
$html = view('emails.welcome')->render();
$processor = new InlineStyle($html);
$processor->applyStylesheet($processor->extractStylesheets());
return $this->markdown('emails.welcome')
->with(['html' => $processor->getHTML()]);
}
External Stylesheets:
$html = file_get_contents('https://example.com');
$processor = new InlineStyle($html);
$processor->applyStylesheet($processor->extractStylesheets(null, 'https://example.com'));
Livewire/Alpine.js Integration:
public function mount()
{
$this->html = '<style>div { transition: all 0.3s; }</style><div>Hover me</div>';
}
Service Provider Bootstrapping:
// InlinestyleServiceProvider.php
public function boot()
{
Blade::directive('inlineStyle', function ($expression) {
return "<?php echo (new \\Codeat3\\Inlinestyle\\InlineStyle($expression))->applyStylesheet((new \\Codeat3\\Inlinestyle\\InlineStyle($expression))->extractStylesheets())->getHTML(); ?>";
});
}
Cached Inlining:
$cachedKey = 'inline_css_' . md5($html);
return Cache::remember($cachedKey, 60, function () use ($html) {
$processor = new InlineStyle($html);
return $processor->applyStylesheet($processor->extractStylesheets())->getHTML();
});
Queue Jobs for Heavy Processing:
InlineCssJob::dispatch($html)->onConnection('database');
CSS Specificity Conflicts:
/* External CSS */
.button { background: red; }
/* Inlined CSS */
<button style="background: blue !important;">Click</button>
!important sparingly or audit CSS cascades.Malformed HTML:
try {
$processor = new InlineStyle($html);
} catch (\Exception $e) {
Log::error("Invalid HTML: " . $e->getMessage());
return back()->withError('Template error');
}
Base URL Resolution:
// Wrong: Relative path without base URL
$processor->extractStylesheets(null, 'https://example.com');
// Right: Absolute URL
$processor->extractStylesheets(null, 'https://example.com/assets/css');
Performance:
php -dmemory_limit=256M artisan your:command
Inspect Processed HTML:
file_put_contents('debug.html', $processor->getHTML());
Check Extracted Stylesheets:
$stylesheets = $processor->extractStylesheets();
dd($stylesheets); // Debug extracted CSS
Symfony Dependency Conflicts:
composer why symfony/dom
composer require symfony/dom:^6.4
Custom Style Processing:
applyStylesheet method to filter styles:
class CustomInlineStyle extends \Codeat3\Inlinestyle\InlineStyle
{
public function applyStylesheet($stylesheets)
{
$filtered = array_filter($stylesheets, fn($css) => strpos($css, '.hidden') === false);
return parent::applyStylesheet($filtered);
}
}
Blade Directive Extensions:
Blade::directive('inlineStyleFile', function ($expression) {
return "<?php echo (new \\Codeat3\\Inlinestyle\\InlineStyle(file_get_contents($expression)))->applyStylesheet((new \\Codeat3\\Inlinestyle\\InlineStyle(file_get_contents($expression)))->extractStylesheets())->getHTML(); ?>";
});
Usage:
@inlineStyleFile('css/email.css')
Whitelist Tags/Attributes:
<script>):
$processor = new InlineStyle($html);
$processor->setAllowedTags(['div', 'p', 'a']); // Whitelist
$processor->applyStylesheet($processor->extractStylesheets());
No Built-in Config:
// config/inlinestyle.php
return [
'allowed_tags' => ['div', 'p', 'a', 'span'],
'debug' => env('INLINE_STYLE_DEBUG', false),
];
Symfony 7+ Compatibility:
composer.json pins Symfony components to avoid conflicts:
"require": {
"symfony/dom": "^6.4",
"symfony/css-selector": "^6.4"
}
Pair with Tailwind:
@apply in inlined CSS for utility-first workflows:
@inlineStyle('<style>@import "tailwind.css"; .btn { @apply px-4 py-2 bg-blue-500; }</style>')
<button class="btn">Click</button>
Email-Specific Optimizations:
$emailHtml = view('emails.welcome')->render();
$processor = new InlineStyle($emailHtml);
$processor->applyStylesheet($processor->extractStylesheets());
$processor->setAllowedTags(['table', 'td', 'tr', 'a']); // Email-safe tags
Livewire Dynamic Styles:
public $color = 'red';
public function mount()
{
$this->html = '<style>div { color: ' . $this->color . '; }</style><div>Dynamic</div>';
}
public function updateColor($color)
{
$this->color = $color;
$this->html = '<style>div { color: ' . $this->color . '; }</style>' . $this->html;
}
How can I help you explore Laravel packages today?