Container for document metadata where style elements typically reside. Learn more →
<style> ElementThe <style> element contains CSS style information for a document or document fragment. It allows you to embed CSS directly into HTML, defining how elements should be displayed in the browser. While typically placed in the <head> section, <style> elements can appear anywhere in your document.
<style> /* CSS rules go here */ selector { property: value; }</style>The content inside <style> tags should be valid CSS. The styles apply to the document or shadow DOM tree containing the element.
| Attribute | Description | Values |
|---|---|---|
media | Specifies which media/device the styles are optimized for | Media query (e.g., screen, print, (max-width: 600px)) |
type | MIME type of the style sheet (deprecated) | text/css (default, can be omitted) |
nonce | Cryptographic nonce for Content Security Policy | Base64-encoded string |
blocking | Indicates rendering should block on fetching critical subresources | render |
This element supports all global attributes, including id, class, and title.
Embed CSS directly in your HTML for small projects or single-page applications:
Use the media attribute to apply styles only for specific devices or conditions:
Inline critical above-the-fold styles to improve initial render performance:
Use <style> within document fragments or web components for scoped styling:
Implement dark mode using the prefers-color-scheme media query:
Create responsive layouts with media query-based styles:
Understanding when to use <style> versus <link> is crucial for performance and maintainability:
Use inline <style> when: Critical above-the-fold CSS (improves First Contentful Paint), small amounts of CSS (under 10KB), page-specific styles not reused elsewhere, implementing critical rendering path optimization, working with component-based architectures where scoping is important, or creating single-page applications or standalone HTML files.
Use external <link> when: Styles are shared across multiple pages (better caching), total CSS exceeds 14KB (HTTP/2 packet size), you want to leverage browser caching, managing large stylesheets that benefit from separation, working in teams where CSS and HTML are maintained separately, or you need to support style sheet switching or alternate stylesheets.
Best practice for production: Inline critical CSS for above-the-fold content in a <style> tag, then load the rest via <link rel="stylesheet"> with appropriate loading strategies. This combines the benefits of both approaches for optimal performance.
Styles in <style> tags are render-blocking, meaning the browser must parse and apply them before rendering content. This is both a strength and a consideration:
Advantages of inline styles: No network request required (faster than external files for small CSS), guaranteed to be available immediately, perfect for critical rendering path optimization, and eliminates FOUC (Flash of Unstyled Content) for initial content. Inline styles reduce Total Blocking Time and improve First Contentful Paint metrics.
Potential issues: Cannot be cached across page loads (unlike external stylesheets), increases HTML file size, may delay HTML parsing if styles are large, and can bloat the HTML document if overused. Each page load re-downloads the same styles, wasting bandwidth for returning visitors.
The optimal approach for most production websites:
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Optimized Page</title>
<!-- Step 1: Inline critical CSS (above-the-fold) --> <style> /* Critical styles for immediate render */ body { margin: 0; font-family: system-ui; } .header { background: #333; color: white; padding: 1rem; } .hero { min-height: 500px; background: #f0f0f0; } </style>
<!-- Step 2: Preload non-critical CSS --> <link rel="preload" href="/styles/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="/styles/main.css"></noscript>
<!-- Step 3: Preconnect to external resources --> <link rel="preconnect" href="https://fonts.googleapis.com"> </head> <body> <!-- Content renders immediately with critical styles --> </body></html>Keep inline <style> blocks appropriately sized:
Modern web applications use Content Security Policy to prevent XSS attacks. The nonce attribute allows inline styles while maintaining security:
When implementing Content Security Policy with inline styles:
nonce attribute exactly'unsafe-inline' in production; use nonces or hashes instead<!-- Example with hash-based CSP --><!-- CSP header: style-src 'sha256-xyz123abc456...' --><style> body { margin: 0; }</style>Inline styles can be vectors for CSS injection attacks if user content is unsafely inserted:
<!-- DANGEROUS: Never do this --><style> .user-color { /* User input: <%= user_input %> */ color: <%= user_input %>; }</style>Risk: An attacker could inject malicious CSS to steal data or manipulate the page appearance for phishing attacks.
<!-- SAFE: Sanitize and validate user input --><style> .user-color { /* Validated hex color only */ color: <?= htmlspecialchars($validated_color) ?>; }</style>Protection: Always validate and sanitize user input. For colors, use allowlists or strict regex validation. Never trust user input directly in CSS.
Respect user preferences for high contrast mode:
Respect user preferences for reduced motion to avoid triggering vestibular disorders:
Ensure your styles support browser zoom and user font size preferences:
/* Good: Use relative units */body { font-size: 1rem; /* Respects user preferences */ line-height: 1.5;}
h1 { font-size: 2em; /* Scales with body font */}
/* Avoid: Fixed sizes that don't scale */body { font-size: 16px; /* Ignores user preferences */}Ensure sufficient color contrast for readability:
/* Good: WCAG AA compliant (4.5:1 contrast ratio) */.text { color: #333333; background-color: #ffffff;}
/* Poor: Insufficient contrast */.text { color: #cccccc; background-color: #ffffff;}| Browser | Version | Notes |
|---|---|---|
| Chrome | 1+ | Full support including media queries |
| Firefox | 1+ | Full support including media queries |
| Safari | 1+ | Full support including media queries |
| Edge | 12+ | Full support including media queries |
| IE | 3+ | Basic support; IE9+ for media queries |
| Feature | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
Basic <style> | 1+ | 1+ | 1+ | 12+ |
media attribute | 1+ | 1+ | 3+ | 12+ |
| Media queries | 4+ | 3.5+ | 4+ | 12+ |
nonce attribute | 45+ | 31+ | 10+ | 79+ |
blocking attribute | 105+ | 105+ | 17+ | 105+ |
Container for document metadata where style elements typically reside. Learn more →
Links to external stylesheets, an alternative to inline styles. Learn more →
Embeds or references JavaScript code, similar to how style embeds CSS. Learn more →
<!DOCTYPE html><html> <body> <h1>My Page</h1> <!-- Wrong: Styles should be in head --> <style> h1 { color: blue; } </style> <p>Content here...</p> </body></html>Issue: While technically valid HTML, placing styles in the body can cause Flash of Unstyled Content and poor rendering performance. The browser must reflow and repaint content.
<!DOCTYPE html><html> <head> <style> h1 { color: blue; } </style> </head> <body> <h1>My Page</h1> <p>Content here...</p> </body></html>Better: Place styles in the <head> section so they’re parsed before content is rendered, preventing visual flickering.
<style type="text/css"> body { margin: 0; }</style>Outdated: The type attribute is no longer needed in HTML5. CSS is the default and only style language.
<style> body { margin: 0; }</style>Modern: Omit the type attribute in HTML5. It’s implied and unnecessary.
<!-- Poor: Too much inline CSS --><style> /* Thousands of lines of CSS... */</style>
<!-- Better: Split into critical and non-critical --><style> /* Only critical above-the-fold CSS here (< 10KB) */</style><link rel="stylesheet" href="/main.css"><!-- Incomplete: No fallback for older browsers --><style media="(prefers-color-scheme: dark)"> body { background: black; color: white; }</style>
<!-- Complete: Provide default and progressive enhancement --><style> /* Default light mode */ body { background: white; color: black; }
/* Enhanced dark mode */ @media (prefers-color-scheme: dark) { body { background: black; color: white; } }</style>