HTML and CSS Good First Issues

Leonid Bugaev
|
(Updated August 31, 2026)
|
7 min read
html css beginners good-first-issue contributing

The first HTML or CSS pull request that merges is one element: a missing label, a contrast fail, an empty alt, a focus ring outline: none deleted. It is not a site-wide a11y rewrite, a design-token migration, or a bundler you added because the static file felt too small.

Generic hunting: how to find good first issues. Multi-language picking: best open source projects for beginners. Merge checks: how to pick an issue that will get merged. This URL is the HTML filter. CSS-heavy tickets have a sibling hub.

Open the HTML hub

HTML hub

Labeled good-first and help-wanted issues on active GitHub repos whose language is HTML. On 2026-08-31: about 1,863 labeled issues at 10+ stars. Snapshot. It moves.

Writing CSS more than markup? The sibling CSS hub is the filter for that. On 2026-08-31: about 426 labeled issues at 10+ stars. Separate feed. This post still points at HTML first — open CSS when the ticket is a stylesheet, not a page.

Not writing HTML or CSS? The homepage is the language switch.

Read the body. Skip stale, claimed, and repos that have not merged lately. I am not listing famous projects. A leftover label on a well-known name is still leftover. The feed is the hub, ticket by ticket.

a11y: one element, not the site

The first HTML evening that actually lands is usually one accessibility hole the issue named.

Shapes that merge:

Done is that element. It is not:

One control. One image. One ring. Match the markup they already use. If they wrap the input in <label>, wrap it. Do not switch to aria-label to look modern unless the issue said so.

A labeled ticket that says “audit the site” is a program, not issue one. Leave it.

Docs sites: a typo or a broken example page

Static docs are HTML. A heading typo, a broken example page, a class the screenshot still shows, a docs/ file whose layout collapsed on the named viewport — that is a real first PR.

Typical tickets:

Done means the named page looks like the issue described, in the preview they already have. Done is not a new docs theme, a Docusaurus or VitePress plugin, or a second getting-started path you invented.

If CONTRIBUTING.md names a docs script or “open index.html”, that is the loop. Ship the page. Do not restyle the rest of docs/ while you are there.

A docs-only HTML/CSS merge counts. An unasked redesign of the guide does not.

Component libraries: the leaf, not the tokens

A labeled ticket in a component library is not automatically first-timer sized. The badge is the same string. The file is not.

Leaf: one component’s markup or stylesheet. A missing aria-* on the date-picker trigger. A hover state on a chip. Padding on a badge. You open one file. You verify in Storybook or the static preview they already run.

Not a leaf: the design-token system, the theme contract, the CSS custom-property tree every component imports, the Sass or Less map that generates the palette. Touching tokens is a product change. Reviewers bounce a “while I was here” token rename.

Prefer the leaf for issue one. After a merge in that library, issue two can be tokens. Not before.

I am not listing famous component libraries. Filter the HTML hub — or the CSS hub if the ticket is a stylesheet — and judge the file, not the brand.

No-build first PRs

Prefer tickets you can verify in a static file or the project’s existing preview. Open index.html. Open the Storybook they already documented. Run the docs script CONTRIBUTING names.

Do not introduce a bundler. Do not add Vite, webpack, Parcel, or a Tailwind build “so you can iterate faster.” That PR is infrastructure. It reviews as policy and stalls the contrast fix.

If the repo has no preview and the ticket is “please add a build,” that is not issue one unless you already live in that toolchain. Pick a static file.

If the only way to see the change is a pipeline you cannot run, pick another ticket. Debugging someone else’s first-time docs build is two projects.

A green existing preview on the default branch is the gate. The markup change comes after.

CSS-in-JS core and design-system internals wait

Styled-components, Emotion, other CSS-in-JS runtimes, the theme provider, the token pipeline, the “create a new primitive” tickets — those look labeled and are still issue two. Implicit contracts. Reviewers who will bounce a plausible patch.

Issue one is a leaf: one element’s a11y, one docs page, one component stylesheet, verified without a new bundler.

Framework CSS-in-JS core waits. After a merge in that repo, you can go inward.

Ship one ticket

  1. Filter on the HTML hub. Writing CSS more than HTML? Use the CSS hub. Drop stale and claimed. Confirm recent merges. Prefer a static file or an existing preview.
  2. Read CONTRIBUTING.md for how they preview HTML/CSS. Get default branch rendering before you edit.
  3. Comment on one issue.
  4. Diff stays on the ticket. One element, one page, one leaf component. No bundler. No token system. Fixes #123. Say how you verified (opened the static file, ran their docs preview). Stay for review.

Git: first pull request guide. Week-1: how to contribute to open source.

FAQ

Is a missing label, contrast fail, alt, or focus ring a real first PR?

Yes. One element the issue named. A site-wide a11y rewrite, a new lint plugin, or an “audit everything” ticket is not issue one. Do the control, not the program.

Is a docs HTML/CSS typo or a broken example page a real first PR?

Yes. Docs sites are HTML. A heading, a broken example, a drifted stylesheet path on one page is a real merge. A volunteer theme or a new docs generator is not. Do the ticket.

Can my first issue be in the design-token system or a CSS-in-JS runtime?

No. Leaf component markup or style. Not tokens, not the theme provider, not CSS-in-JS core. Those files have implicit contracts. After a merge in that library, issue two can move inward.

Should I add Vite, webpack, or Tailwind so I can preview the change?

No. Verify in a static file or the project’s existing preview. Introducing a bundler is infrastructure. It stalls the a11y fix. If you cannot see the page without a pipeline you cannot run, pick another ticket.

Where do I find live HTML and CSS good first issues?

On the HTML hub first. CSS-heavy work: the CSS hub. Filter, skip stale and claimed threads. Read CONTRIBUTING for the preview command. Other languages: the homepage.

Start here

Open the HTML hub. Pick one unclaimed ticket that is one a11y element, a docs-page HTML/CSS fix, or a leaf component — not tokens, not a bundler, not CSS-in-JS core. Writing CSS more than markup? The CSS hub is the sibling filter. Comment once, keep the diff on that job, and stay for review. Not writing HTML or CSS tonight? The homepage is the language switch.

Back to all articles Find projects that need your help