Skip to content

Instantly share code, notes, and snippets.

@nickname55
Last active April 11, 2026 17:49
Show Gist options
  • Select an option

  • Save nickname55/4da8cfabb06acca643b39f885c2050cd to your computer and use it in GitHub Desktop.

Select an option

Save nickname55/4da8cfabb06acca643b39f885c2050cd to your computer and use it in GitHub Desktop.

AG Grid + Tailwind Preflight: кнопки в cellRenderer теряют border-radius

РЕШЕНО — корневая причина найдена

TL;DR

Кнопки не "квадратные". border-radius работает. Скруглённые углы обрезаются overflow: hidden на AG Grid ячейке.

Цепочка событий

  1. AG Grid ячейка: height: 42px, overflow: hidden
  2. AG Grid row задаёт line-height: 39px (через CSS-переменную --ag-internal-content-line-height)
  3. Tailwind Preflight содержит: button { line-height: inherit }
  4. Для <span>line-height наследуется от родителя по стандарту CSS, Tailwind тут не при чём
  5. Кнопка/спан внутри cellRenderer наследует line-height: 39px
  6. С padding: 5px сверху и снизу, итоговая высота элемента ~49px
  7. Контейнер 42px с overflow: hidden → обрезает ~7px сверху и снизу
  8. border-radius: 8px полностью срезается → элемент выглядит прямоугольным

Визуальное доказательство

Ячейка AG Grid (42px, overflow: hidden)
┌──────────────────────────┐
│  ┌─ - - - - - - - - ┐   │  ← обрезанный верх (border-radius не виден)
│  │      Yes          │   │
│  └─ - - - - - - - - ┘   │  ← обрезанный низ (border-radius не виден)
└──────────────────────────┘

Без overflow: hidden (или с line-height: normal)
    ╭──────────────────╮
    │      Yes         │      ← border-radius виден
    ╰──────────────────╯

Фикс

[class*="ag-theme-"] button,
[class*="ag-theme-"] input,
[class*="ag-theme-"] span {
  line-height: normal;
}

Чья вина?

AG Grid. Архитектура ячейки — overflow: hidden + фиксированная высота + наследуемый line-height — это мина для любого cellRenderer с кастомными элементами (кнопки, бейджи, инпуты с padding и border-radius).

Tailwind Preflight просто обнажает проблему: без него браузер ставит свой line-height на <button>, и элемент влезает в ячейку. С Preflight'овским line-height: inherit — кнопка вырастает и обрезается.

Что AG Grid могли бы сделать лучше:

  • Использовать overflow: clip вместо overflow: hidden (не создаёт scroll context, но позволяет border-radius выходить за границы)
  • Или overflow: visible на ячейках
  • Или не пробрасывать line-height через row внутрь ячейки — ячейка должна изолировать свои стили
  • В их официальном HR demo они сами фиксят .ag-cell { display: flex; align-items: center } — признание того что дефолтное поведение недостаточно

AG Grid — лучший data grid на рынке, альтернатив на таком уровне нет. Но конкретно эта деталь — плохое решение. Grid рассчитан на текстовые данные, cellRenderer с кастомными элементами — advanced use case, и они ожидают что разработчик сам позаботится о размерах.

Как нашли

Бинарная бисекция 53KB index.css: разрезали пополам → тестировали каждую половину → за 7 итераций нашли конкретное правило button { line-height: inherit }. Затем визуальный тест с разными line-height + container с overflow:hidden доказал механизм.

Почему в изолированных тестах не воспроизводилось

В минимальных тестах с Tailwind Preflight + AG Grid кнопки были круглые, потому что:

  • AG Grid CDN версия инжектирует стили после нашего <style> блока
  • Порядок каскада отличался от реального Vite-билда
  • Только полный index.css (53KB) в комбинации с AG Grid JS-инжектированными стилями давал нужный порядок каскада

Окружение

  • AG Grid Community/Enterprise: 35.2.1
  • Tailwind CSS: 3.4.19
  • Svelte 5, Vite 6
<!DOCTYPE html>
<html><head><meta charset="UTF-8">
<style>
.row { display: flex; gap: 20px; margin: 20px; align-items: center; }
.label { width: 250px; font-size: 13px; font-family: monospace; }
</style>
</head><body style="padding:20px;font-family:sans-serif">
<h3>Why does line-height break border-radius?</h3>
<div class="row">
<span class="label">line-height: normal (OK)</span>
<button style="padding:5px 16px;border-radius:8px;border:2px solid #34d399;background:#d1fae5;font-size:13px;line-height:normal">Yes</button>
</div>
<div class="row">
<span class="label">line-height: 20px (OK)</span>
<button style="padding:5px 16px;border-radius:8px;border:2px solid #34d399;background:#d1fae5;font-size:13px;line-height:20px">Yes</button>
</div>
<div class="row">
<span class="label">line-height: 39px (BROKEN?)</span>
<button style="padding:5px 16px;border-radius:8px;border:2px solid #34d399;background:#d1fae5;font-size:13px;line-height:39px">Yes</button>
</div>
<div class="row">
<span class="label">line-height: 60px</span>
<button style="padding:5px 16px;border-radius:8px;border:2px solid #34d399;background:#d1fae5;font-size:13px;line-height:60px">Yes</button>
</div>
<div class="row">
<span class="label">line-height: 100px</span>
<button style="padding:5px 16px;border-radius:8px;border:2px solid #34d399;background:#d1fae5;font-size:13px;line-height:100px">Yes</button>
</div>
<h4>Same but inside a 42px height container (like AG Grid cell):</h4>
<div class="row">
<span class="label">container 42px + lh: normal</span>
<div style="height:42px;overflow:hidden;display:flex;align-items:center">
<button style="padding:5px 16px;border-radius:8px;border:2px solid #34d399;background:#d1fae5;font-size:13px;line-height:normal">Yes</button>
</div>
</div>
<div class="row">
<span class="label">container 42px + lh: 39px</span>
<div style="height:42px;overflow:hidden;display:flex;align-items:center">
<button style="padding:5px 16px;border-radius:8px;border:2px solid #34d399;background:#d1fae5;font-size:13px;line-height:39px">Yes</button>
</div>
</div>
<div class="row">
<span class="label">container 42px + lh: 39px + NO overflow:hidden</span>
<div style="height:42px;display:flex;align-items:center">
<button style="padding:5px 16px;border-radius:8px;border:2px solid #34d399;background:#d1fae5;font-size:13px;line-height:39px">Yes</button>
</div>
</div>
</body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment