CSS Basics
Master CSS styling fundamentals to create professional-looking PDF documents.
Learning Objectives
By the end of this article, you’ll be able to:
- Apply CSS styles using inline, embedded, and external methods
- Understand CSS selectors and specificity
- Use common CSS properties for PDFs
- Create reusable style classes
- Understand which CSS properties work in PDFs
Three Ways to Apply CSS
1. Inline Styles
Apply styles directly to elements using the style attribute:
<h1 style="color: #2563eb; font-size: 24pt;">Title</h1>
<p style="margin: 10pt 0; line-height: 1.6;">Paragraph text.</p>
Pros:
- Highest specificity
- Quick for testing
- Element-specific styling
Cons:
- Hard to maintain
- Not reusable
- Mixes content and presentation
When to use: Dynamic styling with data binding
<div style="color: {{model.themeColor}};">
Dynamic color based on data
</div>
2. Embedded Styles
Use <style> tag in the <head> section:
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>Document</title>
<style>
body {
font-family: Helvetica, sans-serif;
font-size: 11pt;
margin: 40pt;
}
h1 {
color: #2563eb;
font-size: 24pt;
}
p {
line-height: 1.6;
margin-bottom: 10pt;
}
</style>
</head>
<body>
<h1>Title</h1>
<p>Content</p>
</body>
</html>
Pros:
- Reusable within document
- Clean HTML markup
- Easy to maintain
Cons:
- Not shared across documents
- Increases file size if duplicated
When to use: Single-file templates
3. External Stylesheets
Link to external CSS files:
<head>
<link rel="stylesheet" href="./styles/common.css" />
<link rel="stylesheet" href="./styles/invoice.css" />
</head>
common.css:
body {
font-family: Helvetica, sans-serif;
font-size: 11pt;
margin: 40pt;
}
h1 {
color: #2563eb;
font-size: 24pt;
margin-bottom: 20pt;
}
Pros:
- Shared across multiple templates
- Easier to maintain
- Cacheable (with proper configuration)
- Separation of concerns
Cons:
- Additional file to manage
- Path resolution required
When to use: Production applications with multiple templates
CSS Selectors
Element Selectors
Target all elements of a type:
p {
margin: 10pt 0;
}
h1 {
font-size: 24pt;
}
table {
width: 100%;
}
Class Selectors
Target elements with specific classes:
<style>
.highlight {
background-color: #fef3c7;
padding: 10pt;
}
.error {
color: #dc2626;
font-weight: bold;
}
</style>
<p class="highlight">This is highlighted.</p>
<p class="error">This is an error message.</p>
ID Selectors
Target a specific element by ID:
<style>
#header {
background-color: #2563eb;
color: white;
padding: 20pt;
}
</style>
<div id="header">
<h1>Document Header</h1>
</div>
Multiple Classes
Apply multiple classes to an element:
<style>
.box {
border: 1pt solid #ccc;
padding: 15pt;
}
.warning {
border-color: #f59e0b;
background-color: #fef3c7;
}
.large {
font-size: 14pt;
}
</style>
<div class="box warning large">
This has multiple styles applied.
</div>
Descendant Selectors
Target nested elements:
/* All paragraphs inside .content */
.content p {
line-height: 1.8;
}
/* All links inside table cells */
table td a {
color: #2563eb;
text-decoration: none;
}
Child Selectors
Target direct children only:
/* Direct children only */
.menu > li {
font-weight: bold;
}
/* Nested items won't be affected */
.menu li li {
font-weight: normal;
}
Attribute Selectors
Target elements by attribute:
/* Links with href */
a[href] {
color: #2563eb;
}
/* Images with alt text */
img[alt] {
border: 1pt solid #ccc;
}
/* Inputs of type text */
input[type="text"] {
border: 1pt solid #999;
}
Pseudo-classes
Special selectors for states:
/* First child */
li:first-child {
font-weight: bold;
}
/* Last child */
li:last-child {
margin-bottom: 0;
}
/* Nth child (odd/even rows) */
tr:nth-child(odd) {
background-color: #f9fafb;
}
tr:nth-child(even) {
background-color: white;
}
/* Specific nth child */
li:nth-child(3) {
color: red;
}
Specificity and Cascade
CSS specificity determines which styles apply when there are conflicts:
Specificity Order (Highest to Lowest)
- Inline styles -
style="..."(1,0,0,0) - ID selectors -
#header(0,1,0,0) - Class, attribute, pseudo-class -
.highlight,[type],:first-child(0,0,1,0) - Element selectors -
p,div(0,0,0,1)
Examples
/* Specificity: 0,0,0,1 */
p {
color: black;
}
/* Specificity: 0,0,1,0 - WINS */
.highlight {
color: blue;
}
/* Specificity: 0,1,0,0 - WINS */
#special {
color: red;
}
<p>Black text</p>
<p class="highlight">Blue text</p>
<p id="special">Red text</p>
<p style="color: green;">Green text (inline always wins)</p>
Increasing Specificity
/* Low specificity */
p {
color: black;
}
/* Higher specificity */
div p {
color: blue;
}
/* Even higher */
.content div p {
color: red;
}
/* Highest (without inline) */
#main .content div p {
color: green;
}
Common CSS Properties for PDFs
Text Styling
p {
/* Font */
font-family: Helvetica, Arial, sans-serif;
font-size: 11pt;
font-weight: bold; /* or normal, 100-900 */
font-style: italic; /* or normal */
/* Color */
color: #333;
/* Spacing */
line-height: 1.6;
letter-spacing: 0.5pt;
word-spacing: 1pt;
/* Alignment */
text-align: left; /* or right, center, justify */
text-indent: 20pt;
/* Decoration */
text-decoration: underline; /* or none, line-through */
text-transform: uppercase; /* or lowercase, capitalize */
}
Box Model
.box {
/* Dimensions */
width: 400pt;
height: 200pt;
/* Padding (inside) */
padding: 15pt;
padding-top: 10pt;
padding-right: 20pt;
padding-bottom: 10pt;
padding-left: 20pt;
/* Border */
border: 1pt solid #ccc;
border-top: 2pt solid #2563eb;
border-radius: 5pt;
/* Margin (outside) */
margin: 20pt;
margin-top: 10pt;
margin-bottom: 20pt;
}
Colors and Backgrounds
.element {
/* Text color */
color: #2563eb; /* Hex */
color: rgb(37, 99, 235); /* RGB */
color: rgba(37, 99, 235, 0.5); /* RGBA with transparency */
/* Background */
background-color: #eff6ff;
background-image: url('./images/bg.png');
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
Display and Visibility
.element {
/* Display type */
display: block; /* Block-level */
display: inline; /* Inline */
display: inline-block; /* Inline with dimensions */
display: none; /* Hidden */
/* Visibility */
visibility: visible; /* Visible */
visibility: hidden; /* Hidden but takes space */
}
Positioning
.element {
position: static; /* Default flow */
position: relative; /* Relative to normal position */
position: absolute; /* Absolute positioning */
position: fixed; /* Fixed on page */
top: 10pt;
right: 20pt;
bottom: 10pt;
left: 20pt;
z-index: 10; /* Stacking order */
}
Practical Example: Styled Document
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>Professional Document</title>
<style>
/* Base styles */
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 11pt;
margin: 40pt;
color: #333;
line-height: 1.6;
}
/* Typography hierarchy */
h1 {
color: #1e40af;
font-size: 28pt;
font-weight: bold;
border-bottom: 3pt solid #1e40af;
padding-bottom: 10pt;
margin-bottom: 20pt;
}
h2 {
color: #2563eb;
font-size: 20pt;
font-weight: bold;
margin-top: 30pt;
margin-bottom: 15pt;
}
h3 {
color: #3b82f6;
font-size: 16pt;
font-weight: 600;
margin-top: 20pt;
margin-bottom: 10pt;
}
/* Paragraphs */
p {
margin-bottom: 10pt;
}
/* Reusable components */
.info-box {
border: 1pt solid #2563eb;
border-left: 4pt solid #2563eb;
background-color: #eff6ff;
padding: 15pt;
margin: 20pt 0;
}
.warning-box {
border: 1pt solid #f59e0b;
border-left: 4pt solid #f59e0b;
background-color: #fef3c7;
padding: 15pt;
margin: 20pt 0;
}
.highlight {
background-color: #fef08a;
padding: 2pt 4pt;
}
/* Lists */
ul, ol {
margin: 10pt 0;
padding-left: 30pt;
}
li {
margin-bottom: 5pt;
}
/* Tables */
table {
width: 100%;
border-collapse: collapse;
margin: 20pt 0;
}
thead {
background-color: #2563eb;
color: white;
}
th {
padding: 10pt;
text-align: left;
font-weight: bold;
}
td {
padding: 8pt;
border-bottom: 1pt solid #e5e7eb;
}
tbody tr:nth-child(even) {
background-color: #f9fafb;
}
/* Footer */
.footer {
position: fixed;
bottom: 20pt;
left: 40pt;
right: 40pt;
text-align: center;
font-size: 9pt;
color: #666;
border-top: 1pt solid #ccc;
padding-top: 10pt;
}
</style>
</head>
<body>
<h1>Professional Document</h1>
<div class="info-box">
<strong>Info:</strong> This document demonstrates CSS styling best practices.
</div>
<h2>Introduction</h2>
<p>
This is a paragraph with <span class="highlight">highlighted text</span>.
The document uses consistent spacing, colors, and typography.
</p>
<h2>Features</h2>
<ul>
<li>Consistent typography hierarchy</li>
<li>Reusable style classes</li>
<li>Professional color scheme</li>
<li>Proper spacing and alignment</li>
</ul>
<div class="warning-box">
<strong>Warning:</strong> Always test your styles in actual PDF output.
</div>
<h2>Data Table</h2>
<table>
<thead>
<tr>
<th>Item</th>
<th>Description</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Item 1</td>
<td>First item description</td>
<td>$100</td>
</tr>
<tr>
<td>Item 2</td>
<td>Second item description</td>
<td>$200</td>
</tr>
<tr>
<td>Item 3</td>
<td>Third item description</td>
<td>$300</td>
</tr>
</tbody>
</table>
<div class="footer">
Page <page-number /> of <page-count /> | Professional Document | Generated with Scryber.Core
</div>
</body>
</html>
CSS Properties NOT Supported
These CSS properties don’t work in Scryber (PDF limitations):
Layout
display: flex- Use tables insteaddisplay: grid- Use tables insteadfloat- Use positioning or tables
Animation/Interaction
transition- PDFs are staticanimation- PDFs are statictransform- Limited support (rotation only):hover,:active- No interaction in PDFs
Advanced Features
box-shadow- Not supportedtext-shadow- Not supportedclip-path- Not supportedfilter- Not supported
Try It Yourself
Exercise 1: Three Styling Methods
Create the same styled paragraph using:
- Inline styles
- Embedded
<style>tag - External CSS file
Compare which feels most maintainable.
Exercise 2: Specificity Test
Create CSS rules with different specificity levels:
p { color: black; }
.highlight { color: blue; }
#special { color: red; }
Apply them to paragraphs and observe which wins.
Exercise 3: Reusable Component Library
Create a small library of reusable classes:
.box-info,.box-warning,.box-error.btn-primary,.btn-secondary.text-small,.text-large
Use them in a document.
Common Pitfalls
❌ Using Browser-Specific CSS
.container {
display: flex; /* Won't work */
}
✅ Solution: Use supported properties
.container {
display: table;
width: 100%;
}
❌ Forgetting Units
p {
margin: 10; /* Missing unit */
}
✅ Solution: Always specify units
p {
margin: 10pt;
}
❌ Overly Specific Selectors
body div.content div.section div.subsection p.text {
color: black;
}
✅ Solution: Keep selectors simple
.subsection p {
color: black;
}
Next Steps
Now that you understand CSS basics:
- Pages & Sections - Structure multi-page documents
- Styling & Appearance - Deep dive into styling
- CSS Property Reference - All supported properties
Continue learning → Pages & Sections