Open demo

CSS code

HTML
<article class="job">
  <div class="head">
    <span class="logo" aria-hidden="true">M</span>
    <div><h2><a href="#">Senior Front-End Engineer</a></h2><p>Meridian · Series B, 140 people</p></div>
    <button class="save" type="button" aria-label="Save Senior Front-End Engineer"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 4h12v16l-6-4-6 4z"/></svg></button>
  </div>
  <ul class="tags" aria-label="Job details"><li>Remote (UK)</li><li>Full-time</li><li>TypeScript</li><li>Design systems</li></ul>
  <p class="pay">£78,000 – £95,000 <small>per year + equity</small></p>
  <p class="desc">Own the component library used by every product surface. You will work with two
    designers and set the standard for accessibility across the platform.</p>
  <div class="foot"><span>Posted 3 days ago · 24 applicants</span><button class="apply" type="button">Apply<span class="sr-only"> for Senior Front-End Engineer</span></button></div>
</article>
CSS
/* Job listing card. The job title is a stretched link (its ::after covers the card), so the whole
   card opens the posting; Save and Apply are lifted above that layer with position + z-index. */
.job{position:relative;width:400px;max-width:100%;padding:20px;display:flex;flex-direction:column;gap:14px;
  background:#fff;border:1px solid #e9ecf1;border-radius:16px;transition:box-shadow .18s,transform .18s}
.job:hover{transform:translateY(-4px);box-shadow:0 18px 36px -16px rgba(16,24,40,.16)}
.job svg{display:block}
.job .head{display:flex;gap:14px;align-items:flex-start}
.job .logo{width:46px;height:46px;flex-shrink:0;border-radius:12px;display:grid;place-items:center;
  font-weight:800;color:#fff;background:linear-gradient(140deg,#0ea5e9,#2563eb)}
.job h2{font-size:1.03rem;letter-spacing:-.01em}
.job h2 a{color:inherit;text-decoration:none}
.job h2 a::after{content:"";position:absolute;inset:0}
.job h2 a:focus-visible{outline:2px solid transparent}
.job:has(h2 a:focus-visible){outline:2px solid #4f46e5;outline-offset:3px}
@supports not selector(:has(*)){.job h2 a:focus-visible{outline-color:#4f46e5;outline-offset:2px}}
.job .head p{font-size:.85rem;color:#667085;margin-top:3px}
.job button{position:relative;z-index:1}
.job button:focus-visible{outline:2px solid #4f46e5;outline-offset:2px}
.job .save{margin-left:auto;width:32px;height:32px;border:1px solid #e4e7ec;background:#fff;border-radius:9px;
  cursor:pointer;color:#667085;display:grid;place-items:center;flex-shrink:0}
.job .save:hover{color:#4f46e5;border-color:#c7d2fe}
.job .save svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2}
.job .tags{display:flex;flex-wrap:wrap;gap:7px;list-style:none}
.job .tags li{font-size:.76rem;font-weight:600;color:#344054;background:#f2f4f7;padding:5px 10px;border-radius:7px}
.job .pay{font-size:1.02rem;font-weight:800;letter-spacing:-.02em}
.job .pay small{font-size:.78rem;font-weight:500;color:#667085}
.job .desc{font-size:.86rem;color:#667085;line-height:1.6}
.job .foot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:14px;border-top:1px solid #f0f2f6}
.job .foot span{font-size:.79rem;color:#667085}
.job .apply{border:0;background:#101828;color:#fff;font:inherit;font-size:.85rem;font-weight:700;
  padding:9px 18px;border-radius:9px;cursor:pointer}
.job .apply:hover{background:#344054}
@media (prefers-reduced-motion:reduce){.job{transition:none}.job:hover{transform:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<article class="card job">
  <div class="card-body d-flex flex-column">
    <div class="d-flex align-items-start gap-3">
      <span class="logo" aria-hidden="true">M</span>
      <div><h2 class="card-title"><a href="#" class="stretched-link">Senior Front-End Engineer</a></h2><p class="co mb-0">Meridian · Series B, 140 people</p></div>
      <button class="btn save ms-auto" type="button" aria-label="Save Senior Front-End Engineer"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 4h12v16l-6-4-6 4z"/></svg></button>
    </div>
    <ul class="tags list-unstyled d-flex flex-wrap m-0" aria-label="Job details"><li class="badge">Remote (UK)</li><li class="badge">Full-time</li><li class="badge">TypeScript</li><li class="badge">Design systems</li></ul>
    <p class="pay mb-0">£78,000 – £95,000 <small>per year + equity</small></p>
    <p class="desc card-text mb-0">Own the component library used by every product surface. You will work with two
      designers and set the standard for accessibility across the platform.</p>
    <div class="foot d-flex align-items-center justify-content-between gap-3"><span>Posted 3 days ago · 24 applicants</span><button class="btn apply" type="button">Apply<span class="visually-hidden"> for Senior Front-End Engineer</span></button></div>
  </div>
</article>
CSS
/* Bootstrap .card + .stretched-link + .badge + .btn. The title's stretched link makes the whole card
   open the posting; Save and Apply are lifted above the link's ::after layer. */
.job{--bs-card-border-color:#e9ecf1;--bs-card-border-radius:16px;--bs-card-spacer-y:20px;--bs-card-spacer-x:20px;
  width:400px;max-width:100%;transition:box-shadow .18s,transform .18s}
.job:hover{transform:translateY(-4px);box-shadow:0 18px 36px -16px rgba(16,24,40,.16)}
.job .card-body{gap:14px}
.job .logo{width:46px;height:46px;flex-shrink:0;border-radius:12px;display:grid;place-items:center;
  font-weight:800;color:#fff;background:linear-gradient(140deg,#0ea5e9,#2563eb)}
.job .card-title{font-size:1.03rem;font-weight:700;line-height:normal;letter-spacing:-.01em;margin:0}
.job .card-title a{color:inherit;text-decoration:none}
.job .stretched-link:focus-visible{outline:2px solid transparent}
.job:has(.stretched-link:focus-visible){outline:2px solid #4f46e5;outline-offset:3px}
@supports not selector(:has(*)){.job .stretched-link:focus-visible{outline-color:#4f46e5;outline-offset:2px}}
.job .co{font-size:.85rem;color:#667085;margin-top:3px}
.job .btn{position:relative;z-index:2;--bs-btn-focus-box-shadow:0 0 0 2px #fff,0 0 0 4px #4f46e5}
.job .save{--bs-btn-padding-x:0;--bs-btn-padding-y:0;--bs-btn-border-radius:9px;--bs-btn-color:#667085;
  --bs-btn-bg:#fff;--bs-btn-border-color:#e4e7ec;--bs-btn-hover-color:#4f46e5;--bs-btn-hover-bg:#fff;
  --bs-btn-hover-border-color:#c7d2fe;--bs-btn-active-color:#4f46e5;--bs-btn-active-bg:#eef2ff;
  --bs-btn-active-border-color:#c7d2fe;width:32px;height:32px;display:grid;place-items:center;flex-shrink:0}
.job .save svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2}
.job .tags{gap:7px}
.job .tags .badge{--bs-badge-font-size:.76rem;--bs-badge-font-weight:600;--bs-badge-color:#344054;
  --bs-badge-padding-x:10px;--bs-badge-padding-y:5px;--bs-badge-border-radius:7px;background:#f2f4f7;line-height:normal}
.job .pay{font-size:1.02rem;font-weight:800;letter-spacing:-.02em}
.job .pay small{font-size:.78rem;font-weight:500;color:#667085}
.job .desc{font-size:.86rem;color:#667085;line-height:1.6}
.job .foot{padding-top:14px;border-top:1px solid #f0f2f6}
.job .foot span{font-size:.79rem;color:#667085}
.job .apply{--bs-btn-color:#fff;--bs-btn-bg:#101828;--bs-btn-border-color:#101828;--bs-btn-hover-color:#fff;
  --bs-btn-hover-bg:#344054;--bs-btn-hover-border-color:#344054;--bs-btn-active-bg:#1d2939;
  --bs-btn-active-border-color:#1d2939;--bs-btn-font-size:.85rem;--bs-btn-font-weight:700;
  --bs-btn-padding-y:8px;--bs-btn-padding-x:17px;--bs-btn-border-radius:9px;--bs-btn-line-height:normal}
@media (prefers-reduced-motion:reduce){.job,.job .btn{transition:none}.job:hover{transform:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<article class="relative flex w-[400px] max-w-full flex-col gap-3.5 rounded-2xl border border-[#e9ecf1] bg-white p-5 transition-[box-shadow,translate] duration-[180ms] hover:-translate-y-1 hover:shadow-[0_18px_36px_-16px_rgba(16,24,40,.16)] has-[h2_a:focus-visible]:outline-2 has-[h2_a:focus-visible]:outline-offset-[3px] has-[h2_a:focus-visible]:outline-[#4f46e5] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
  <div class="flex items-start gap-3.5">
    <span class="grid size-[46px] shrink-0 place-items-center rounded-xl bg-[linear-gradient(140deg,#0ea5e9,#2563eb)] font-extrabold text-white" aria-hidden="true">M</span>
    <div><h2 class="text-[1.03rem] font-bold tracking-[-.01em]"><a href="#" class="after:absolute after:inset-0 focus-visible:outline-2 focus-visible:outline-transparent">Senior Front-End Engineer</a></h2><p class="mt-[3px] text-[.85rem] text-[#667085]">Meridian · Series B, 140 people</p></div>
    <button class="relative z-10 ml-auto grid size-8 shrink-0 cursor-pointer place-items-center rounded-[9px] border border-[#e4e7ec] bg-white text-[#667085] hover:border-[#c7d2fe] hover:text-[#4f46e5] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#4f46e5]" type="button" aria-label="Save Senior Front-End Engineer"><svg class="block size-[15px] fill-none stroke-current stroke-2" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 4h12v16l-6-4-6 4z"/></svg></button>
  </div>
  <ul class="flex flex-wrap gap-[7px] [&>li]:rounded-[7px] [&>li]:bg-[#f2f4f7] [&>li]:px-2.5 [&>li]:py-[5px] [&>li]:text-[.76rem] [&>li]:font-semibold [&>li]:text-[#344054]" aria-label="Job details"><li>Remote (UK)</li><li>Full-time</li><li>TypeScript</li><li>Design systems</li></ul>
  <p class="text-[1.02rem] font-extrabold tracking-[-.02em]">£78,000 – £95,000 <small class="text-[.78rem] font-medium text-[#667085]">per year + equity</small></p>
  <p class="text-[.86rem] leading-[1.6] text-[#667085]">Own the component library used by every product surface. You will work with two
    designers and set the standard for accessibility across the platform.</p>
  <div class="flex items-center justify-between gap-3 border-t border-[#f0f2f6] pt-3.5"><span class="text-[.79rem] text-[#667085]">Posted 3 days ago · 24 applicants</span><button class="relative z-10 cursor-pointer rounded-[9px] bg-[#101828] px-[18px] py-[9px] text-[.85rem] font-bold text-white hover:bg-[#344054] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#4f46e5]" type="button">Apply<span class="sr-only"> for Senior Front-End Engineer</span></button></div>
</article>

About this set

A job board card for one opening: a company logo tile, the job title and company line, a Save bookmark button, a row of tags for location, contract, stack and focus, the salary band with its terms, a two-line description, and a footer with the posting age, applicant count and an Apply button. The job title is a stretched link, so the whole card opens the full posting, and Save and Apply are lifted above the link layer so they remain their own targets. Both buttons carry the job title in their accessible names (Save Senior Front-End Engineer, Apply for Senior Front-End Engineer), which matters when a page lists dozens of cards with identical button text. The tags are a real list with an accessible name. Use the card in job boards, careers pages and internal hiring tools; for a grid, drop several into a CSS grid or a Bootstrap .row-cols-md-2. The Bootstrap version uses .card, .stretched-link, .badge for the tags and .btn for both buttons; the Tailwind version draws the card focus ring with has-[h2_a:focus-visible].

What’s included

  • Whole card opens the posting through a stretched title link
  • Save and Apply stay separate targets above the link
  • Button names include the job title
  • Tags marked up as a labelled list
  • Hover lift removed under reduced motion

Accessibility

The job title is an h2 containing the card's only link. The Save button is labelled Save Senior Front-End Engineer and Apply has visually hidden text naming the job; the logo and icon are aria-hidden. The card link draws a 2px indigo ring around the card on keyboard focus and the buttons get their own ring. Grey text was darkened to reach 4.5:1, and the hover lift is disabled under prefers-reduced-motion.

Customise it

The logo gradient is on .logo, the Apply colour is #101828 (--bs-btn-bg in Bootstrap, bg-[#101828] in Tailwind) and the tag chips use #f2f4f7 with #344054 text. Card width is the 400px on .job.