tabler-icons

Activity, over time

Daily observations from the public event archive.

Attention

Daily stars & forks

Loading attention chart

Star accumulation

Cumulative stars

Loading star accumulation chart

Pull requests

Daily opens & merges

Loading pull requests chart

Conversations

Daily issues & comments

Loading conversations chart

Community

Daily accounts & reviews

Loading community chart

Releases

Daily releases

Loading releases chart

Mentions

6posts · 30d
Nov 40 posts
  1. DEV · · @svgicons

    Keep Dynamic Icon Groups from Breaking Your List Layout --- title: "Keep Dynamic Icon Groups from Breaking Your List Layout" published: true tags: react, css, webdev, frontend --- A list looks tidy when every row starts with one icon. Then one item gets three icons, another gets five, and the labels stop lining up. The tempting fix is to adjust the gap. That works for one row and breaks another. The gap was consistent already; the space before it was changing. Give every row the same leading slot, then put a limit on what can occupy it. In this React example, that means a shared CSS Grid column, a bounded icon stack, and an explicit rule for overflow. !Animated illustration of icon group alignment before and after using a fixed-width slot Why the labels drift Suppose a row contains an icon group followed by its label: <li className="source-row"> <IconGroup members={item.members} /> <div className="row-content">{item.label}</div> </li> With a content-sized group in a flex row, the label follows the group's width. One badge takes less space than three overlapping badges. Even with identical icon sizes and gaps, the labels start at different positions. That is reasonable flex behavior. It becomes a problem when the design expects a common label column across independent rows. A concrete instance appears in Magpie issue #2498: model rows have a single provider icon, while routing groups have stacked icons. The issue describes reserving a common leading width. This tutorial uses that reported problem as a starting point, with an independent teaching implementation. Define the stack policy before choosing the width A fixed column alone does not stop its children from overflowing. Decide how many positions the component can display first. For this example: | Number of sources | Visible content | | --- | --- | | 0 | Empty slot, with the label still aligned | | 1–3 | All source icons | | 4 or more | First two icons and a counter for the remaining sources | Five sources therefore render as two icons and +3. The counter occupies the third position; it is not appended as a fourth item. Use 28px badges, with each overlapping badge starting 16px after the previous one. Three positions occupy: 28 + (3 - 1) × 16 = 60px A 64px slot leaves 4px of spare space. With a 16px root font size, those dimensions are 1.75rem, 1rem, and 4rem. Choose a width from the actual badge geometry and overflow policy. A 3rem slot, for example, would be too small for this particular stack. Build the React component The example uses three Tabler SVGs retrieved through the SVGicons catalogue: - Folder - Bell - File Settings They are by Paweł Kuna and distributed under the MIT licence. Keep the copyright and licence notice with redistributed assets. Save them in your application's public directory so they are available at /icons/folder.svg, /icons/bell.svg, and /icons/file-settings.svg. The layout does not require a particular icon library. Using local image files keeps SVG markup out of the component's layout logic. function IconGroup({ members }) { const visible = members.length > 3 ? members.slice(0, 2) : members; const hidden = members.length - visible.length; return ( <span className="icon-slot" aria-hidden="true"> <span className="icon-stack"> {visible.map((member, index) => ( <span className="badge" key={member.id} style={{ '--index': index }} > <img src={member.src} alt="" width="18" height="18" /> </span> ))} {hidden > 0 && ( <span className="badge count" style={{ '--index': 2 }}> {hidden > 99 ? '99+' : `+${hidden}`} </span> )} </span> </span> ); } function SourceList({ items }) { return ( <ul className="source-list"> {items.map((item) => ( <li className="source-row" key={item.id}> <IconGroup members={item.members} /> <div className="row-content"> <span className="row-label">{item.label}</span> <span className="sr-only"> {item.members.length ? `. Sources: ${item.members.map((m) => m.name).join(', ')}` : '. No connected sources'} </span> </div> </li> ))} </ul> ); } Each member needs a stable, unique id, a readable name, and a trusted local src. For example: const files = { id: 'files', name: 'Files', src: '/icons/folder.svg', }; const alerts = { id: 'alerts', name: 'Alerts', src: '/icons/bell.svg', }; const config = { id: 'config', name: 'Configuration', src: '/icons/file-settings.svg', }; const archive = { id: 'archive', name: 'Archive', src: '/icons/folder.svg', }; const monitoring = { id: 'monitoring', name: 'Monitoring', src: '/icons/bell.svg', }; const items = [ { id: 'documents', label: 'Documents', members: [files], }, { id: 'activity', label: 'Project activity', members: [files, alerts], }, { id: 'overview', label: 'Workspace overview', members: [files, alerts, config], }, { id: 'operations', label: 'Operations across all connected workspaces', members: [files, alerts, config, archive, monitoring], }, { id: 'empty', label: 'No connected sources yet', members: [], }, ]; export default function App() { return <SourceList items={items} />; } The source names are exposed once as text. The overlapping images and counter are hidden from assistive technology, avoiding a second announcement of the same source information. This approach suits a static list. If users need to inspect or select individual sources, provide a visible details view with equivalent keyboard access. A tiny overlapped badge should not be the only way to reach an action. Localize the source sentence and counter formatting for your product. Reserve the column and contain the stack Apply these styles: * { box-sizing: border-box; } .source-list { --badge-size: 1.75rem; --stack-step: 1rem; --icon-slot: 4rem; list-style: none; margin: 0; padding: 0; } .source-row { display: grid; grid-template-columns: var(--icon-slot) minmax(0, 1fr); column-gap: .75rem; align-items: start; padding-block: 1rem; border-block-start: 1px solid #e3e8f1; } .icon-slot { min-inline-size: 0; inline-size: var(--icon-slot); } .icon-stack { display: block; position: relative; block-size: var(--badge-size); } .badge { position: absolute; inset-inline-start: calc(var(--index) * var(--stack-step)); inset-block-start: 0; inline-size: var(--badge-size); block-size: var(--badge-size); display: grid; place-items: center; background: #dce8ff; border: 2px solid white; border-radius: 50%; } .badge:nth-child(2) { background: #dcf5ec; } .badge:nth-child(3) { background: #efe3ff; } .badge img { display: block; inline-size: 1.125rem; block-size: 1.125rem; } .count { font-size: .625rem; font-weight: 800; color: #17233b; } .row-content { min-inline-size: 0; } .row-label { display: block; overflow-wrap: anywhere; } .sr-only { position: absolute; inline-size: 1px; block-size: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; } There are two separate constraints here: - The shared --icon-slot keeps the label position consistent across rows. - The component's three-position limit keeps the stack within that slot. An empty group keeps its wrapper, so zero icons does not become another alignment exception. The absolutely positioned badges need an explicit stack height because they do not contribute to their parent's normal flow height. Later badges paint over earlier ones in this simple stack. The label track uses minmax(0, 1fr) so its minimum track size does not default to a content-based minimum. min-inline-size: 0 lets the content wrapper shrink, while overflow-wrap: anywhere allows long unbroken identifiers to wrap. These choices address different parts of overflow handling. Replacing the icon column alone will not fix every long-text case. See MDN's references for grid track sizing and minimum widths. If labels must stay on one line, use a deliberate truncation design instead. Make the full text available through an accessible details interaction; do not rely only on a mouse tooltip. Keep the same rule on narrow screens and in RTL As the container narrows, the fixed slot stays put and the text wraps in the remaining track. Top alignment keeps a multi-line label beside the top of its icon stack. If a compact design needs a smaller slot, change its geometry for the entire list. For example, 24px badges with a 12px step occupy 48px across three positions: .source-list.compact { --badge-size: 1.5rem; --stack-step: .75rem; --icon-slot: 3rem; } Never make this choice independently for each row, or the common column disappears again. Check that the counter remains readable in the smaller badges. For right-to-left layout, place dir="rtl" on the list or an ancestor. Grid's inline direction places the leading column on the right. inset-inline-start moves the badge stack from that same side. <div dir="rtl"> <SourceList items={items} /> </div> Use real translated labels when reviewing the result. Changing direction on English text checks the layout rule, but does not verify Arabic or Hebrew typography, punctuation, or mixed-direction identifiers. Test the relationship that matters A screenshot can catch an obvious regression. A geometry assertion can also express the actual requirement: every label container has the same leading edge. Here is a Playwright test for a page containing one .source-list. Serve the component on the / route and configure Playwright's baseURL to point to your development server. import { test, expect } from '@playwright/test'; for (const width of [420, 1100]) { for (const direction of ['ltr', 'rtl']) { test(`label alignment: ${width}px ${direction}`, async ({ page }) => { await page.setViewportSize({ width, height: 1000, }); await page.goto('/'); await page.locator('.source-list').evaluate((list, dir) => { list.dir = dir; }, direction); const edges = await page.locator('.row-content').evaluateAll( (nodes, dir) => nodes.map((node) => { const rect = node.getBoundingClientRect(); return dir === 'rtl' ? rect.right : rect.left; }), direction ); expect(edges.length).toBeGreaterThan(1); expect( Math.max(...edges) - Math.min(...edges) ).toBeLessThan(1); }); } } Also check that every badge stays within its slot, images have loaded, and the document has no horizontal overflow. A component can keep its labels aligned while its icons still collide with them. Use fixtures with: - Zero, one, two, three and five sources. - A very large source count. - A multi-line label. - A long unbroken identifier. - Larger text. - Both LTR and RTL directions. Check keyboard navigation if the rows contain links or buttons. Keep screenshot baselines only after reviewing the initial renders, and rerun the checks in your supported browser engines. The useful invariant is simple: source count may change the content of the icon slot, but it must not change where the label begins. Once that rule is explicit, new data has much less room to rearrange the list.

  2. YouTube · · YouTube description · Alex Hitt

    Tabler Icons GitHub Explained: Build State-Driven React Interfaces with SVG tabler-icons by tabler: tabler/tabler-icons Tabler Icons documentation: tabler.io See how a fictional garden-monitoring card uses Tabler Icons inside a React interface. This overview explains why inline SVG keeps icon paths under DOM and CSS control, how currentColor follows a parent element, and how size and stroke values shape a consistent 24×24 grid. It also covers the @tabler/icons-react package, local node_modules usage, icon discovery and imports, the outline-versus-filled distinction, and a Chromium sizing limitation when CSS variables are passed directly into SVG dimensions. The final section connects package-manager usage with MIT-license attribution for production distribution. TimeStamps: 0:00 Fictional dashboard and the 24×24 icon grid 0:30 Why inline SVGs can inherit interface styles 0:48 React prerequisites and local package setup 1:42 Finding icons and importing the React component 2:33 currentColor inheritance in the dashboard DOM 3:01 Size and stroke tuning on a 24×24 grid 3:36 Chromium’s CSS-variable sizing limitation 4:13 Outline versus filled icons for irrigation state 5:03 Boolean state drives color and variant changes 5:27 MIT licensing and package-manager attribution 6:18 Deploying customizable vectors with legal attribution 🌧️ Fictional irrigation dashboard with a stateful droplet icon 🎨 currentColor, size, stroke, and 24×24 SVG geometry ⚙️ React components, outline/filled variants, and CSS sizing 📄 MIT licensing and attribution considerations Tabler Icons suits React developers who want a large, consistent SVG set that can follow component state without a new image for every color or variant. Keep the 24×24 grid in mind, use a controlled wrapper when CSS variables misbehave in Chromium, and retain MIT attribution when packaging or copying assets. #TablerIcons #React #SVG [de-DE] YNAS ynp_ca7261cfc4f01b90 Cinematic Privater automatisierter Staging-Upload. Paketidentität: ynp_ca7261cfc4f01b90; Ausgabe: cinematic. [es-US] YNAS ynp_ca7261cfc4f01b90 cinematográfico Carga de entorno de prueba de automatización privada. Identidad del paquete: ynp_ca7261cfc4f01b90; salida: cinematográfica. [fr-FR] YNAS ynp_ca7261cfc4f01b90 cinématique Téléchargement de la zone de test d'automatisation privée. Identifiant du package : ynp_ca7261cfc4f01b90 ; sortie : cinématique. [hi] YNAS ynp_ca7261cfc4f01b90 सिनेमैटिक निजी स्वचालन स्टेजिंग अपलोड। पैकेज पहचान: ynp_ca7261cfc4f01b90; आउटपुट: सिनेमाई। [id] Sinematik YNAS ynp_ca7261cfc4f01b90 Unggahan staging otomatisasi pribadi. Identitas paket: ynp_ca7261cfc4f01b90; output: sinematik. [it] YNAS ynp_ca7261cfc4f01b90 cinematografico Caricamento di automazione privata. Identità del pacchetto: ynp_ca7261cfc4f01b90; output: cinematografico. [pt-BR] YNAS ynp_ca7261cfc4f01b90 cinematográfico Upload de teste de automação privada. Identidade do pacote: ynp_ca7261cfc4f01b90; saída: cinemática.

    1 like · 60 views
  3. Bluesky · · @lea-linux.org

    tabler/tabler-icons Pour vos beaux projets opensource, de zolies zicones tout beaux

    20 likes · 5 reposts
  4. 做网页、排 PPT、做海报,最烦的就是找图标:免费的就几百个还风格不一,好看的要收费,网上搜来的图又怕侵权。 Tabler Icons 是 Tabler 团队开源的一套图标库(MIT):6238 个图标(5184 个线性 + 1054 个填充),全部免费、全部可商用。 2.2 万 star。 tabler/tabler-icons t.co

    28 views
  5. X · · @geekbb

    Tabler Icons 是 tabler 组织维护的图标集,提供 6238 个 MIT 许可的 24x24 SVG 图标,以及 React、Vue、Svelte、Angular 等十余个框架的现成组件包。 tabler/tabler-icons t.co

    10 likes · 5 reposts · 2,024 views
  6. Reddit · · r/BestGitHubRepos · u/company_url_finder

    Tabler Icons: A set of 6238 free, MIT-licensed, high-quality SVG icons for your web projects (22k stars) What it does All text below is quoted directly from the project README. >A set of 6238 free, MIT-licensed, high-quality SVG icons for your web projects. Each icon is designed on a 24x24 grid with a 2px stroke. Preview: - Outline version (5184 icons) - Filled version (1054 icons) Packages: >Tabler Icons is distributed as a set of official packages, one for each format and framework. All packages are published to npm from this repository and share the same version number. - @tabler/icons: Raw SVG files (outline and filled) with icon metadata - @tabler/icons-sprite: SVG sprite with all icons - @tabler/icons-webfont: Icon font with CSS and SCSS files - @tabler/icons-react: React components - @tabler/icons-react-native: React Native components - @tabler/icons-preact: Preact components - @tabler/icons-vue: Vue 3 components - @tabler/icons-svelte: Svelte 4 components - @tabler/icons-svelte-runes: Svelte 5 components (runes) - @tabler/icons-solidjs: SolidJS components - @tabler/icons-astro: Astro components - @tabler/icons-angular: Angular component and icon providers - @tabler/icons-png: PNG files - @tabler/icons-pdf: PDF files - @tabler/icons-eps: EPS files >Install the SVG package with your package manager of choice: npm install @tabler/icons Repository tabler/tabler-icons Repository stats |Metric|Value| |:-|:-| |Stars|21,918| |Forks|1,218| |Last release|v3.49.0 (2026-10-05)| |Languages|JavaScript 57.2%, TypeScript 30.3%, CSS 4.5%| |Contributors|103| |AI contributor accounts (Claude / Codex / Cursor / Copilot)|Claude: 1, Cursor: 1, Copilot: 4| |AI co-authored commits|Claude: 1, Cursor: 1, Copilot: 3| Main contributor |Field|Value| |:-|:-| |Name|Paweł Kuna| |GitHub|@codecalm| |Commits to this repo|1,831 (top contributor)| |Bio|Freelancer, Web Application Developer. Big fan of @codepen. Father of tabler.io| |Company|Tabler @tabler| |Location|Bielsko-Biala, Poland| |Website|tabler.io| |X / Twitter|@codecalm| |Followers|1,038| |Public repos|42| |On GitHub since|2011-12-23|

    95 points · 1 comment

Latest stargazers

The last 10 distinct accounts we observed this year.

Most active participants

PR, issue, comment & review events in the past year.

Packages

15
PackageVersionDownloads · 30dTrend · 30d
v3.9.0
≥6.6M
v3.49.0
≥5.3K
v3.49.0
≥1.9K
v3.9.0
≥592
v3.9.0
≥509
v3.9.0
≥4.1K
v3.9.0
≥5.3K
v3.9.0
≥5.8M
v3.9.0
≥235.5K
v3.9.0
≥6.1K
v3.9.0
≥2.8K
v3.9.0
≥43.9K
v3.49.0
≥18.1K
v3.9.0
≥107.9K
v3.9.0
≥132K

README badges

Embed a badge in your README or website.

  • tabler/tabler-icons reached #1 in daily stars on gitwal · Mar 19, 2020
  • tabler/tabler-icons reached #2 in weekly stars on gitwal · Week of Mar 16, 2020
Live mentions · last 30 days
tabler/tabler-icons mentions in the last 30 days