Skip to content

Custom Styling

EasyPdf captures the DOM as-is, so any CSS that renders in the browser will appear in the PDF. You can use inline styles, CSS classes, Tailwind, or injected stylesheets — whatever your project already uses.

Inline Styles

tsx
import { useEasyPdf } from "@easypdf/react";

const InlineStyleExample = () => {
  const { pdfRef, downloadPDF, isLoading } = useEasyPdf();

  return (
    <div>
      <button onClick={() => downloadPDF(pdfRef)} disabled={isLoading}>
        {isLoading ? "Generating..." : "Download PDF"}
      </button>

      <div ref={pdfRef}>
        <h1 style={{ fontSize: "28px", color: "#1a1a2e", textAlign: "center", marginBottom: "24px" }}>
          Document Title
        </h1>
        <div style={{ backgroundColor: "#f8f9fa", borderRadius: "8px", padding: "20px", margin: "16px 0" }}>
          <p style={{ color: "#333", lineHeight: "1.6" }}>
            Section content with custom inline styles.
          </p>
        </div>
      </div>
    </div>
  );
};

CSS Classes via <style> Tag

Inject a <style> tag directly inside the ref container:

tsx
const CSSClassExample = () => {
  const { pdfRef, downloadPDF, isLoading } = useEasyPdf();

  return (
    <div>
      <button onClick={() => downloadPDF(pdfRef)} disabled={isLoading}>
        {isLoading ? "Generating..." : "Download PDF"}
      </button>

      <div ref={pdfRef}>
        <style>{`
          .doc-title {
            font-size: 26px;
            color: #2c3e50;
            text-align: center;
            border-bottom: 2px solid #3498db;
            padding-bottom: 12px;
            margin-bottom: 24px;
          }
          .section {
            background: #f8f9fa;
            border-radius: 8px;
            padding: 20px;
            margin: 16px 0;
          }
          .table-styled {
            width: 100%;
            border-collapse: collapse;
          }
          .table-styled th, .table-styled td {
            border: 1px solid #ddd;
            padding: 8px 12px;
            text-align: left;
          }
          .table-styled th {
            background: #f0f0f0;
            font-weight: bold;
          }
        `}</style>

        <h1 className="doc-title">Styled Document</h1>

        <div className="section">
          <h2>Summary</h2>
          <p>Content in a styled section.</p>
        </div>

        <table className="table-styled">
          <thead>
            <tr><th>Item</th><th>Value</th></tr>
          </thead>
          <tbody>
            <tr><td>Alpha</td><td>100</td></tr>
            <tr><td>Beta</td><td>200</td></tr>
          </tbody>
        </table>
      </div>
    </div>
  );
};

Global Custom CSS via Config

Use styles.customCSS to inject a stylesheet into the off-screen container. Works for both visual and programmatic modes:

tsx
const { pdfRef, downloadPDF } = useEasyPdf({
  styles: {
    backgroundColor: "#ffffff",
    defaultFontSize: 13,
    defaultFontFamily: "Arial, sans-serif",
    defaultTextColor: "#333333",
    customCSS: `
      h1 { font-size: 28px; color: #1a1a2e; }
      h2 { font-size: 20px; color: #2c3e50; margin-top: 24px; }
      .highlight { background: #fff3cd; padding: 2px 6px; border-radius: 3px; }
      .info-box { border-left: 4px solid #3498db; padding: 12px 16px; background: #f0f8ff; }
    `,
  },
});

Tailwind CSS

If your project uses Tailwind, classes work automatically in the PDF since EasyPdf captures the live DOM with all applied styles:

tsx
const TailwindExample = () => {
  const { pdfRef, downloadPDF, isLoading } = useEasyPdf();

  return (
    <div>
      <button onClick={() => downloadPDF(pdfRef)} disabled={isLoading}>
        {isLoading ? "Generating..." : "Download PDF"}
      </button>

      <div ref={pdfRef} className="max-w-2xl mx-auto p-8 font-sans">
        <h1 className="text-3xl font-bold text-gray-800 mb-6">Report Title</h1>

        <div className="grid grid-cols-2 gap-6 mb-8">
          <div className="bg-white p-6 rounded-lg shadow">
            <h3 className="text-lg font-semibold mb-2">Metric A</h3>
            <p className="text-3xl font-bold text-blue-600">1,240</p>
          </div>
          <div className="bg-white p-6 rounded-lg shadow">
            <h3 className="text-lg font-semibold mb-2">Metric B</h3>
            <p className="text-3xl font-bold text-green-600">98%</p>
          </div>
        </div>

        <div className="bg-gray-50 p-6 rounded-lg">
          <h2 className="text-xl font-semibold mb-3">Details</h2>
          <p className="text-gray-700 leading-relaxed">
            Full details of the report...
          </p>
        </div>
      </div>
    </div>
  );
};

Reusable Styled Components

Since EasyPdf captures whatever React renders, you can use any component library or hand-rolled components:

tsx
const Badge = ({ color, children }: { color: string; children: React.ReactNode }) => (
  <span style={{
    display: "inline-block",
    padding: "2px 10px",
    borderRadius: "12px",
    backgroundColor: color,
    color: "#fff",
    fontSize: "12px",
    fontWeight: "bold",
  }}>
    {children}
  </span>
);

const ReportExample = () => {
  const { pdfRef, downloadPDF } = useEasyPdf();

  return (
    <div>
      <button onClick={() => downloadPDF(pdfRef)}>Download</button>
      <div ref={pdfRef} style={{ padding: "32px", fontFamily: "Arial, sans-serif" }}>
        <h1>Status Report</h1>
        <p>Project Alpha: <Badge color="#22c55e">On Track</Badge></p>
        <p>Project Beta: <Badge color="#ef4444">At Risk</Badge></p>
        <p>Project Gamma: <Badge color="#f59e0b">Delayed</Badge></p>
      </div>
    </div>
  );
};

Preventing Page Breaks

Add the no-break CSS class to keep an element on one page:

tsx
<div className="no-break">
  <table>
    <thead><tr><th>Column</th></tr></thead>
    <tbody><tr><td>Data</td></tr></tbody>
  </table>
</div>

The following elements are automatically treated as unbreakable: <table>, <figure>, <img>, <pre>, <code>, <ul>, <ol>.

Best Practices

  • Use px units for font sizes and spacing — they render predictably at the capture scale
  • Test your PDF at scale: 2 (default) — this doubles resolution so thin borders and small text remain sharp
  • Use container.style.width to pin content width when you need a consistent layout regardless of window size

Released under the MIT License.