Bộ chuyển đổi CSS sang JavaScript miễn phí
Chuyển đổi các thuộc tính CSS thành các đối tượng style JavaScript. Biến đổi các thuộc tính kebab-case thành camelCase. Hoàn hảo cho React và styled-components.
background-color: #007bff;
padding: 10px 20px;
border-radius: 4px;
Chuyển đổi thành:
{ backgroundColor: '#007bff', padding: '10px 20px', borderRadius: '4px' }
Cách sử dụng
Công cụ này phân tích các thuộc tính CSS và chuyển đổi chúng thành cú pháp đối tượng JavaScript. Tên thuộc tính ở kebab-case (như background-color) tự động được chuyển đổi thành camelCase (backgroundColor). Các giá trị CSS được giữ nguyên. Bạn có thể nhập các thuộc tính riêng lẻ hoặc một quy tắc CSS đầy đủ với selector.
Phong trào CSS-in-JS, gọn lại
Vì sao bài toán chuyển đổi này tồn tại? Vì năm 2014 một thế hệ lập trình viên frontend quyết định rằng CSS trong các tệp stylesheet riêng đã thất bại ở quy mô. Khoảnh khắc thành lập là bài nói "CSS in JS" của Christopher "Vjeux" Chedeau tại NationJS ngày 15 tháng 11 năm 2014, một kỹ sư Facebook lập luận rằng cascade toàn cục của CSS, thiếu theo dõi phụ thuộc và sự tích lũy mã chết khiến nó là phần tệ nhất của các web app lớn. Bài nói châm ngòi cho phong trào. JSS (Oleg Slobodskoi) phát hành cuối 2014 như thư viện CSS-in-JS đa dụng đầu tiên. CSS Modules đến năm 2015 như cách tiếp cận scope tại thời điểm build. styled-components (Glen Maddern + Max Stoiber) phát hành tháng 10 năm 2016, phổ biến API tagged-template-literal nơi bạn viết CSS trong backtick gắn với định nghĩa thành phần. Emotion (Kye Hohenberger) phát hành ngày 10 tháng 7 năm 2017 với cả API kiểu styled-components và một prop css linh hoạt hơn nhận trực tiếp object JavaScript, đúng định dạng công cụ này tạo ra. Stitches (Modulz/Pedro Duarte) phát hành năm 2020 với API dựa trên variant nhưng ngừng được bảo trì giữa năm 2023 và được lưu trữ chính thức tháng 4 năm 2026.
Quả lắc đã quay về. "Why We're Breaking Up with CSS-in-JS" của Sam Magura ngày 16 tháng 10 năm 2022, do một maintainer Emotion viết, là điểm uốn. Lập luận kỹ thuật: CSS-in-JS lúc runtime làm chậm rõ rệt việc render React (benchmark của chính Magura trên Spot Member Browser đã giảm thời gian render trung vị từ 54,3 ms xuống 27,7 ms sau khi chuyển khỏi Emotion, nhanh khoảng 2×); bundle lớn hơn; chi phí serialize tích lũy. Lập luận kiến trúc: React Server Components (được Next.js 13.4 ổn định ngày 4 tháng 5 năm 2023) không thể dùng React Context, mà phần lớn thư viện CSS-in-JS dựa vào để theming. Làn sóng thay thế: Tailwind CSS (Adam Wathan, ra mắt v4 ngày 22 tháng 1 năm 2025); Vanilla Extract (Mark Dalgleish tại Seek, ngày 26 tháng 3 năm 2021) cho CSS-in-TypeScript thời điểm build; CSS Modules cho tên class scope không có chi phí runtime; và nhóm compile-to-static còn sống được nêu trong chính bài viết của Magura: vanilla-extract, Linaria, Compiled, StyleX và Pigment CSS. Bản thân JSS bị deprecate ngày 14 tháng 5 năm 2024; styled-components chuyển sang chế độ bảo trì ngày 17 tháng 3 năm 2025. CSS-in-JS lúc runtime không còn là mặc định cho dự án React mới năm 2026, nhưng một codebase khổng lồ styled-components và Emotion hiện hữu vẫn tồn tại, và chuyển CSS sang dạng object của các thư viện đó vẫn là thực tế hằng ngày của nhiều đội.
Các bề mặt API của các thư viện chính
Inline style React (prop style) là baseline phổ quát, mọi component React nhận một object style mà khóa là thuộc tính CSS dạng camelCase. Không hỗ trợ pseudo-class (:hover), media query, hay !important; đó là "inline style" theo nghĩa của thuộc tính HTML cũ style="...", chỉ là dùng object JavaScript thay vì chuỗi. Đầu ra của công cụ này nhét trực tiếp vào style={...}. styled-components nhận tagged template literal chứa chuỗi CSS thật: const Button = styled.div`background: red; padding: 10px;`. CSS là CSS thật, kebab-case và mọi thứ, bạn thường không cần bộ chuyển đổi này cho styled-components trừ khi đang di trú từ inline style sang một component styled. Emotion hỗ trợ cả hai API: API styled (template literal như styled-components) và prop css với object JavaScript (camelCase, đúng định dạng công cụ này tạo ra). Cho prop css của Emotion, đầu ra của bộ chuyển đổi này dùng được trực tiếp. JSS dùng định dạng object tương tự với một số tính năng thêm (theming, tự sinh tên class) nhưng cú pháp thuộc tính camelCase cơ bản giống nhau. Binding style của Vue (:style="...") nhận cùng cú pháp object camelCase như inline style của React. Vanilla Extract dùng dạng object có kiểu nghiêm hơn với hàm wrapper style({ ... }) rõ ràng; object camelCase bên trong có cùng hình dạng.
Trường hợp đặc biệt và cạm bẫy
- Ngoại lệ tiền tố vendor
ms. Phần lớn tiền tố vendor được viết hoa sau khi camelCase:-webkit-transform→WebkitTransform,-moz-appearance→MozAppearance,-o-transition→OTransition. Nhưng tiền tố của Microsoft là ngoại lệ:-ms-flex→msFlexvới chữ m thường, vì đó là cách nguồn React DOM định nghĩa. Đây là cạm bẫy CSS-to-JS được Google nhiều nhất. - Thuộc tính không đơn vị. React DOM duy trì một danh sách thuộc tính nơi số trần hợp lệ (
z-index,opacity,line-height,flex-grow,flex-shrink,order,columnsvà một số khác). Cho những cái đó,zIndex: 5là đúng. Cho mọi thứ còn lại, giá trị có chiều đòi đơn vị dạng chuỗi:width: '100px', không phảiwidth: 100(mà React sẽ xử lý là'100px'theo mặc định âm thầm, tiện nhưng mất mát nếu bạn muốn%hayvh). - calc(), var() và thuộc tính tùy biến CSS. Các cái này hoạt động dưới dạng giá trị chuỗi:
width: 'calc(100% - 20px)',color: 'var(--brand-color)'. Thuộc tính tùy biến (biến CSS) cần dấu nháy quanh--name:'--my-var': 'red'. - !important không hoạt động trong inline style của React. Prop style của React âm thầm bỏ qua chú thích
!important. Nếu bạn phải đè quy tắc có độ đặc hiệu cao hơn, hãy dùng stylesheet thật (CSS Modules, Tailwind, styled-components), inline style không phải công cụ đúng. - Nội dung chuỗi rỗng.
content: ''đòi chú ý đến quoting trong JavaScript:content: "''", một giá trị chuỗi rỗng, nhưng chính giá trị là một literal chuỗi CSS rỗng cần các nháy bao quanh được giữ. - Quy tắc lồng và pseudo-selector. Chuyển đổi CSS-to-JS đơn giản tạo object phẳng, trạng thái hover, media query và style pseudo-element cần cấu trúc riêng của thư viện đích. Prop
csscủa Emotion hỗ trợ object lồng ('&:hover': { background: 'red' }); inline style của React thì không. - Thuộc tính rút gọn.
margin: 10px 20px 10px 20pxgiữ là một chuỗi ở dạng JS:margin: '10px 20px 10px 20px'. React cho phép rút gọn; một số thư viện CSS-in-JS cảnh báo điều đó có thể tương tác bất ngờ với các biến thể longhand.
Trường hợp dùng phổ biến
- Inline style React. Chuyển snippet CSS từ designer hoặc stylesheet sang định dạng object
style={...}cho component không có stylesheet liên kết. - Prop css của Emotion. Di trú từ tệp CSS riêng sang prop css cú pháp object của Emotion, nơi camelCase + dạng JS-object là đầu vào native.
- Animation JavaScript. GSAP, anime.js, Motion One và Framer Motion đều nhận object style làm mục tiêu keyframe. Định dạng camelCase cũng được yêu cầu ở đó.
- Token của design system. Chuyển giá trị thuộc tính tùy biến CSS sang hằng JavaScript để dùng trong các hệ design-token (Style Dictionary, Theo, vân vân) nơi TypeScript hoặc JS là nguồn-sự-thật kinh điển.
- Di trú JSS. Material UI v4 và trước dùng JSS nhiều; chuyển nguyên mẫu CSS sang dạng object JSS là điểm ma sát. Lưu ý Material UI v5+ đã chuyển sang Emotion làm mặc định; đây là trường hợp dùng kiểu legacy hơn.
- Binding style inline Vue.
:style="{...}"trong template Vue dùng cùng định dạng object camelCase như prop style của React; đầu ra của bộ chuyển đổi này cũng dùng được trực tiếp trong template Vue.
Phạm vi trung thực: công cụ này làm gì và không làm gì
Công cụ này chuyển khai báo CSS sang cú pháp object JavaScript với khóa camelCase và giá trị chuỗi đặt nháy đúng. Nó xử lý quy tắc viết hoa tiền tố vendor (kể cả ngoại lệ chữ thường ms). Nó không dịch sang API thư viện cụ thể vượt quá việc tạo object camelCase, bạn vẫn phải biết codebase của mình muốn object nằm trong styled.div`...`, trong cuộc gọi css Emotion, trong prop style React, hay trong binding :style Vue. Lựa chọn phụ thuộc thư viện của bạn, không phải bộ chuyển đổi. Công cụ cũng không xử lý quy tắc lồng và pseudo-selector tự động, cú pháp object lồng của Emotion ('&:hover': {...}) và lồng template-literal của styled-components hoạt động khác nhau và đòi cấu trúc thủ công. Cho di trú đầy đủ một tệp CSS sang thư viện CSS-in-JS, hãy mong đợi việc tái cấu trúc vượt quá chuyển đổi từng-thuộc-tính mà công cụ này cung cấp.
Quyền riêng tư: vì sao chỉ-trong-trình-duyệt quan trọng ở đây
CSS hiếm khi chứa bí mật, nhưng stylesheet độc quyền lại tiết lộ thông tin về phân loại class nội bộ của một site, các token design system, và đôi khi giả định A/B test qua các selector riêng cho thí nghiệm. Công cụ chuyển đổi phía server đòi upload CSS, vốn nằm trong log của họ. Cho style sản phẩm nội bộ, tệp nguồn-sự-thật của design system, hoặc thương hiệu đang xây, chuyển đổi thuần-trình-duyệt giữ mọi thứ cục bộ. Công cụ này thực hiện toàn bộ biến đổi trong trình duyệt, hãy kiểm chứng trong tab Network của DevTools khi bạn bấm Convert, hoặc đặt trang offline (chế độ máy bay) và bộ chuyển đổi vẫn hoạt động.
Câu hỏi thường gặp
Thuộc tính CSS được chuyển sang camelCase thế nào?
Mỗi gạch ngang trong thuộc tính CSS kebab-case bị bỏ và chữ kế tiếp được viết hoa: background-color → backgroundColor, border-radius → borderRadius, margin-top → marginTop. Thuộc tính có tiền tố vendor theo cùng quy tắc với viết hoa: -webkit-transform → WebkitTransform (W hoa), -moz-appearance → MozAppearance. Ngoại lệ nổi tiếng là tiền tố Microsoft: -ms-flex → msFlex với m thường, vì đó là cách React DOM định nghĩa.
Có hoạt động với media query và pseudo-class không?
Object style JavaScript đơn giản (prop style của React, :style của Vue) không hỗ trợ media query hay pseudo-class, đó là khái niệm stylesheet. Các thư viện CSS-in-JS nhận cú pháp object (prop css của Emotion, JSS) hỗ trợ chúng qua object lồng: '&:hover': { background: 'red' }, '@media (min-width: 768px)': { padding: '20px' }. Tài liệu của thư viện đích sẽ chỉ ra cấu trúc lồng chính xác. Công cụ này tạo object phẳng; bạn bọc nó trong cú pháp lồng của thư viện theo cách thủ công.
Vì sao !important không hoạt động trong inline style của React?
Prop style của React âm thầm bỏ qua chú thích !important, chúng không phải phần ngữ pháp của literal object JS và renderer của React không dịch chúng. Nếu bạn phải đè quy tắc có độ đặc hiệu cao hơn, hãy dùng stylesheet thật (CSS Modules, Tailwind, styled-components, CSS thuần). Cơ chế inline-style của React là cho style ngẫu nhiên hoặc động nơi độ đặc hiệu không phải mối quan tâm; !important thuộc về stylesheet.
Tôi có nên dùng CSS-in-JS năm 2026 không?
Cho dự án React mới, mặc định hiện thời là "không, hãy dùng Tailwind, CSS Modules hoặc Vanilla Extract". Bài viết của Sam Magura tháng 10 năm 2022 từ bên trong đội Emotion, kết hợp với việc React Server Components không tương thích Context, đã đẩy hệ sinh thái về phía giải pháp chỉ-build-time. styled-components chuyển sang chế độ bảo trì ngày 17 tháng 3 năm 2025; JSS bị deprecate ngày 14 tháng 5 năm 2024. Cho codebase hiện hữu có đầu tư đáng kể vào styled-components hoặc Emotion, không cần vội di trú, cả hai thư viện vẫn hoạt động, và chi phí runtime là loại điều bạn tối ưu khi nó xuất hiện trong profiling. Cho dự án mới hoàn toàn năm 2026: Tailwind v4 (ra mắt ngày 22 tháng 1 năm 2025) là lựa chọn phổ biến nhất; Vanilla Extract cho dự án muốn TypeScript chặt trên style; CSS Modules cho dự án muốn lớp trừu tượng tối thiểu.
Tôi có thể chuyển token design-system theo cách này không?
Cho snippet lẻ, có. Cho cả design system, thường là hàng chục hoặc hàng trăm token tổ chức theo màu, khoảng cách, kiểu chữ, motion, hãy dùng công cụ chuyên dụng như Style Dictionary hoặc Theo, cả hai nhận một nguồn-sự-thật duy nhất (JSON, YAML hoặc JS) và xuất ra nhiều đích (thuộc tính tùy biến CSS, hằng JS, iOS Asset Catalog, Android XML, vân vân). Lợi ích của công cụ design-token thật là sự nhất quán xuyên các nền tảng; bộ chuyển đổi này dành cho trường hợp bạn có một snippet CSS trong tay và muốn dạng JS ngay.
CSS của tôi có được gửi đi đâu không?
Không. Việc chuyển đổi chạy hoàn toàn trong trình duyệt qua JavaScript. CSS bạn dán không bao giờ đi qua mạng, hãy kiểm chứng trong tab Network của DevTools khi bạn bấm Convert, hoặc đặt trang offline sau khi đã tải xong và xác nhận công cụ vẫn hoạt động. An toàn cho stylesheet độc quyền, tệp nguồn-sự-thật của design system, hoặc bất kỳ CSS nào tiết lộ phân loại class nội bộ bạn không muốn bị sao vào ổ cứng của người lạ.