Skip to content

Add injectStyles, so Dropzone can supply its own CSS - #2363

Open
enyo wants to merge 1 commit into
plain-cssfrom
inject-css
Open

Add injectStyles, so Dropzone can supply its own CSS#2363
enyo wants to merge 1 commit into
plain-cssfrom
inject-css

Conversation

@enyo

@enyo enyo commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Stacked on #2362. Setting injectStyles makes Dropzone insert dropzone.css into the document itself — no <link> to remember, no path to keep in step with the package.

new Dropzone("#my-form", { url: "/file/post", injectStyles: true });

The CSS is carried as a string rather than imported for its side effect, so nothing reaches the document unless the option asks for it.

Two decisions worth reviewing

It is prepended to <head>, not appended. Appending would place it after a stylesheet the page already links, so turning the option on would quietly override styling that used to work. Prepending means your rules keep winning on equal specificity, with no !important. There is a test for the ordering, because it is the kind of thing a later refactor silently reverses.

It runs before the fallback check, since the fallback form is styled by the same stylesheet.

The cost, stated plainly

injectStyles defaults to false, and this is why: the stylesheet travels inside the JavaScript bundle whether or not the option is switched on, because a runtime condition cannot be tree-shaken.

before after
dropzone-min.js 37,755 B 42,668 B
gzipped 11,767 B 13,066 B

That is +1.3 kB gzipped, about 11%, paid by everyone. Anyone importing the CSS through a bundler should keep doing that — it stays the smaller option, and the docs say so. This is for the people who would otherwise ship no stylesheet at all.

If that cost turns out to bother you, the alternative is a separate entry point (dropzone/with-styles) that only its importers pay for — but that is an import, not an option, which is not what you asked for.

Tests

7 unit tests and 2 end-to-end. The end-to-end ones matter more than usual: the page they load links no stylesheet at all, and the assertion is a computed min-height of 150px. That proves the CSS survived bundling into the standalone file and is actually applying — not merely that a <style> element appeared.

259 unit tests and 5 end-to-end specs pass overall. The docs are updated in both places: a row in the options table, and a section under Installation → CSS that includes the size tradeoff.

A fix that belongs to #2362

While building this I found #2362's CI failing on format:check for src/dropzone.css. Cause: oxfmt runs with --ignore-path .gitignore, and the stale src/.gitignore I deleted in that pull request had been hiding the file from the formatter as well as from git. Fixed on that branch, not this one, and this branch was rebased onto it.

@github-actions

github-actions Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 79.51% 885 / 1113
🔵 Statements 79.79% 932 / 1168
🔵 Functions 92.89% 196 / 211
🔵 Branches 76.52% 515 / 673
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/dropzone/src/dropzone.ts 77.44% 74.95% 92.63% 77.04% 188, 198, 223, 229-232, 289, 316, 359-360, 419, 527, 549, 568-569, 676, 699-702, 739-741, 771-774, 797, 941, 969, 998, 1002, 1074-1075, 1105, 1115-1117, 1134-1135, 1141-1174, 1288, 1346, 1395-1396, 1523, 1547-1548, 1602, 1636, 1656-1687, 1695, 1709-1713, 1724, 1737-1742, 1755-1756, 1760-1761, 1779-1780, 1858-1873, 1918, 1934, 1968, 2121-2123, 2158, 2168, 2201-2235, 2242-2343, 2352-2355
packages/dropzone/src/options.ts 89.91% 76% 92.68% 89.83% 456, 478-481, 493-494, 557, 675, 716, 742, 759
packages/dropzone/src/types.d.ts 0% 0% 0% 0%
Generated in workflow #105 for commit 03797a8 by the Vitest Coverage Report Action

Setting injectStyles makes Dropzone insert dist/dropzone.css into the
document itself, so there is no link tag to remember and no path to keep in
step with the package. The stylesheet is carried as a string rather than
imported for its side effect, so nothing reaches the document unless the
option asks for it.

It is inserted once per page however many dropzones exist, and prepended to
head rather than appended. Appending would put it after a stylesheet the page
already links, so switching the option on would quietly override styling that
used to work. Prepending means page rules keep winning on equal specificity,
with no need for !important.

It runs before the fallback check, because the fallback form is styled by the
same stylesheet.

Defaults to false, and this is the tradeoff worth stating plainly: the CSS
travels inside the JavaScript bundle whether or not the option is on, because
a runtime condition cannot be tree-shaken. That is 4.9 kB minified, 1.3 kB
gzipped, on a bundle that was 11.8 kB gzipped. Anyone importing the CSS
through a bundler should keep doing that; this is for the people who would
otherwise ship no stylesheet at all.

The end-to-end test loads a page with no stylesheet link whatsoever and
asserts a computed min-height of 150px, so it proves the CSS survived
bundling into the standalone file rather than merely that a style element
appeared.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant