Borders and rounded corners are the most used, and most neglected, details in document layout. A table without borders is a wall of numbers; a card without rounded corners feels stiff; one wrong border property can shift an entire page. dompdf.js provides full support for the border and radius family: independent per-side borders, solid, dashed, and dotted styles, individual corner radii, and elliptical radii all render according to standard CSS. Because borders are drawn as vector lines in the PDF, they stay crisp at any zoom level and on paper, so thin 1px rules are safe to use without worrying about blurriness. This article starts with the core border properties, covers shorthand versus per-side declarations, explains how border styles behave in PDF output, and walks through every border-radius syntax from fixed values and percentages to elliptical corners. You will see complete code examples for the three scenarios that dominate real documents, tables, cards, and tags, followed by a troubleshooting checklist for the pitfalls that cost developers the most time. After reading, you will be able to add the kind of finish that makes exported PDFs hold up under magnification and print inspection.You will also learn how the box model accounts for border width, how border-collapse changes table rendering, and why transparent borders are a legitimate layout tool rather than a hack. The examples are production-ready, the explanations focus on what the renderer actually does, and the troubleshooting section doubles as a pre-release checklist for any template that uses borders or rounded corners. Whether you are styling a one-page invoice or a hundred-page report, the same rules apply, and the patterns shown here scale from the smallest tag to the largest table without special cases.
A border is defined by three dimensions: width, style, and color, expressed through border-width, border-style, and border-color, or combined in the shorthand border: 1px solid #333. dompdf.js supports the whole system: widths accept px, pt, and em units, colors accept every notation covered in the color guide, and the behavior matches browser CSS, so existing styles carry over unchanged.
Each side can be controlled independently with border-top, border-right, border-bottom, and border-left, which is exactly what you need for a heading with only a bottom rule or a quote block with a left accent line. For finer control you can decompose any side into its width, style, and color components, for example border-top-width: 2px, giving you the same granularity you have in the browser.
Because borders are emitted as vector lines, they remain razor sharp at 200 percent zoom and on printed paper, which is a fundamental difference from bitmap-based PDF pipelines. That means you can safely use hairline borders from 0.5px to 1px for refined details without inflating them for print legibility, keeping the document delicate and professional.
A practical consequence of the box model: by default the border width is included in the element's total size, so width: 200px plus border: 1px means the content area is actually 198px. Templates that mix many bordered elements drift subtly from the design unless every box uses the same sizing rule. Setting box-sizing: border-box on all elements makes widths predictable, border included, and removes an entire class of off-by-a-few-pixels layout bugs before they appear in the PDF.
Borders can also stand in for separators and backgrounds: a light border on the left of a quote block, a bottom border under a section heading, or a border around a callout box all create structure without heavy fills. Because borders render as crisp vector lines, even the thinnest rules stay sharp, so you can use them liberally in templates where bitmap pipelines would force you to choose thicker, uglier lines just to remain legible.
border-style accepts solid, dashed, dotted, double, and the rest of the standard set. Solid is the workhorse for structural borders on tables and cards; dashed suits emphasis zones and fill-in fields; dotted works as a subtle separator; double gives formal documents an elegant underline beneath section titles. All of these render in dompdf.js the same way they do in the browser.
Tables are where borders matter most, and the difference between border-collapse: collapse and separate is essential. collapse merges adjacent cell borders so you never get double-thick lines between cells, which is why it is the default for report templates. separate keeps independent borders and, combined with border-spacing, can create staggered dividers for specialized layouts where uniform grid lines are not the goal.
Transparent borders are a classic layout trick: border: 1px solid transparent reserves border space so content does not shift when a state change swaps the border in. The same technique works in PDF templates, for example reserving a selection border on cards so the layout stays stable across style variants, a small detail that prevents annoying one-pixel jumps in the final document.
Dashed and dotted borders are the right tool for forms and fill-in areas: a dashed underline signals a writable field, a dotted box marks an optional zone, and both render reliably in the PDF. The one caveat is that dash patterns follow the engine's rendering, not the browser's, so a dash rhythm tuned pixel-perfect in Chrome may come out slightly different in the export; design for tolerance and verify once against a real output.
For tables, the collapse versus separate choice also affects spacing: with border-collapse: collapse you lose border-spacing, while separate mode lets you add breathing room between cells. A common report pattern is collapse for the data grid and separate for summary sections, each tuned for its purpose. Whatever you choose, apply it consistently, because mixing the two modes in one table produces unpredictable double lines and gaps that are tedious to hunt down.
border-radius has three writing modes: a single value like border-radius: 8px rounds all four corners equally; two values like 8px 4px apply diagonally; and four values like 10px 20px 30px 40px set top-left, top-right, bottom-right, and bottom-left in clockwise order. The granularity matches the browser exactly, so whatever control you are used to on the web carries into your PDF templates.
Elliptical radius is written as border-radius: 10px 20px, where the horizontal and vertical radii differ, producing pill and stadium shapes. Percentage radius is computed relative to the element's own size, so border-radius: 50% on a square element yields a perfect circle, which is how avatars, badges, and status dots are built in both web and PDF contexts.
The radius clips the element's background and border, so pairing it with a gradient background yields a dimensional card surface, and the background color is correctly cut off at the rounded edge instead of bleeding past it. One rule to remember: a radius larger than half the element size is clamped per the CSS specification, so the rendered result follows the clamped value rather than what you typed.
Rounded corners change the perceived personality of a document: small radii like 4-6px read as crisp and professional, medium radii around 12px read as friendly, and pill shapes read as casual. Pick one radius scale for the template, usually two values, one for cards and one for tags, and stick to it; documents that mix every radius size look unfocused, while a consistent scale makes the layout feel intentional and designed.
Radius interacts with borders and backgrounds in ways worth exploiting: a radius larger than the border width makes the border follow a smooth inner curve, and a radius on a table's outer corners can soften a very boxy report. When you combine radius with a colored header row inside a card, remember that the radius clips only the element that declares it, so the header's corners may poke out unless the header itself is rounded or the card clips with overflow.
The example shows the complete toolkit in one page: a card with a light border and a 12px radius, a pill badge built from a 999px radius, a collapsed table with a dark header, and a two-pixel divider under the section title. Run it as-is to see each element, then adjust the radius values and the border colors to match your brand. Because every style is plain CSS, you can lift the snippets directly into your own templates and extend them with your data without touching the rendering code.
One more detail worth studying is the header row: it uses a dark background with white text and no radius, so its corners stay square against the card's rounded corners. That contrast between the rounded card and the square header is a deliberate, common design choice, and it demonstrates that radius does not have to apply everywhere. If you prefer the header to follow the card's curve, give the header its own radius matching the card, or clip the card with overflow, and compare the two looks.
import { DomPDF } from 'dompdf.js';
const html = `
<style>
.card {
border: 1px solid #d5dbe3;
border-radius: 12px;
padding: 20px;
background-color: #fbfcfe;
}
.badge {
display: inline-block;
border: 1px solid #27ae60;
border-radius: 999px;
padding: 2px 10px;
font-size: 12px;
color: #27ae60;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #b8c2cc;
padding: 8px;
text-align: left;
}
th { background-color: #2c3e50; color: #fff; }
.divider { border-bottom: 2px solid #3498db; }
</style>
<div class='card'>
<h2 class='divider'>Order Details</h2>
<p><span class='badge'>Shipped</span></p>
<table>
<tr><th>Product</th><th>Qty</th><th>Amount</th></tr>
<tr><td>Mechanical keyboard</td><td>1</td><td>$ 399</td></tr>
<tr><td>Mouse pad</td><td>2</td><td>$ 59</td></tr>
</table>
</div>`;
const pdf = new DomPDF({ format: 'A4', margin: '20mm' });
pdf.addPage(html, { format: 'A4' });
pdf.save('borders-demo.pdf');
Table borders are the backbone of reports: a dark header with white text, fine body borders with light alternating rows, and a heavier top border on the totals row creates clear hierarchy. Cards combine borders with radius and a light background to partition content, which suits quotes, product cards, and stat panels. Pill-shaped tags with status colors handle order states and approval progress at a glance.
Dividers are an underrated detail: a 2px solid or double rule under a title, a light 1px rule between blocks, both lighter than full borders. Avoid mixing many different line weights on one page; a consistent line system makes the document look professionally designed and keeps visual noise low, which is exactly the kind of polish clients notice.
Borders also participate in layout: border-bottom creates pseudo-column alignment, transparent borders reserve space, and zero-width borders align baselines. Remember that borders occupy layout space in the box model, so include their width when sizing containers, or content can overflow and push elements to the next page unexpectedly.
Invoices and contracts rely on borders more than any other document type: line-item tables need clear row boundaries, signature areas need visible frames, and terms sections need separation from the commercial terms. A disciplined border system, thin gray for structure, medium for emphasis, and double rules for formal headings, keeps these dense documents scannable and legally readable, and it is worth defining once in the template so every future page inherits the same language.
Print behavior adds two constraints worth knowing. First, thick dark borders on large areas can bleed through on double-sided printing, so keep heavy frames to 1-2px or use light fills with dark thin rules instead. Second, colors that look fine on screen may shift slightly on paper; if the border color is semantically important, such as a red error frame, verify with a proof print rather than assuming the screen is accurate.
Q: Table borders come out double-thick? A: Adjacent cell borders are stacking. Set border-collapse: collapse on the table to merge them; if you genuinely need separate mode, put borders on only one side of each cell to control the visual weight and avoid the double-line effect.
Q: The radius renders as sharp corners in the PDF? A: Check whether the element has explicit width and height, since percentage radii depend on size; an element with unresolved dimensions can degrade to square corners. Fixed-size containers are the most stable target for percentage radius.
Q: The background shows through a transparent border? A: Transparent borders only hide the line, they do not clip the background. If you need the radius to clip the background, declare background-color and border-radius on the same element rather than putting the background on a child.
Q: A 0.5px border disappears when printed? A: Fine borders can be rounded away by some printers. Keep body borders at 1px minimum and emphasis borders at 2px, or substitute a lighter color with a slightly thicker line for the same visual delicacy without the print risk.
A recurring frustration is the one-pixel gap: a border appears to have a hairline crack or a doubled edge where two elements meet. This usually comes from two adjacent elements each carrying a border, or from a parent border plus a child border stacking. Fix it by removing one of the borders, using collapse on tables, or shifting the border onto the container only, and the seam disappears without changing the visual weight.
When debugging border problems, isolate first: render a minimal HTML snippet with only the suspect element and its border, then add complexity back one property at a time. Compare the output to the same snippet rendered in the browser to separate engine behavior from template mistakes. Most border anomalies turn out to be a missing collapse, an unexpected box-sizing default, or a color that is nearly invisible on the chosen background, and each is a thirty-second fix once identified.
下面的按钮用 dompdf.js 在浏览器端实时生成 PDF,无需后端:
这是由 dompdf.js 渲染的示例 PDF 内容。