| HTML Attribute / Syntax | JSX Equivalent | Category | Usage Note |
class="btn" | className="btn" | Attribute | class is a reserved word in JavaScript |
for="email" | htmlFor="email" | Attribute | for is a reserved loop keyword |
tabindex="0" | tabIndex={0} | Attribute | camelCase; numeric value as a number |
readonly | readOnly | Attribute | Boolean attribute, camelCase |
maxlength="20" | maxLength={20} | Attribute | Number in braces for TypeScript |
minlength="3" | minLength={3} | Attribute | Number in braces for TypeScript |
colspan="2" | colSpan={2} | Attribute | Table cell |
rowspan="2" | rowSpan={2} | Attribute | Table cell |
cellpadding="0" | cellPadding="0" | Attribute | Legacy table attribute |
cellspacing="0" | cellSpacing="0" | Attribute | Legacy table attribute |
contenteditable | contentEditable | Attribute | Warns when children exist; add suppressContentEditableWarning |
spellcheck="false" | spellCheck="false" | Attribute | Takes a string or boolean |
autocomplete="off" | autoComplete="off" | Attribute | Form fields |
autofocus | autoFocus | Attribute | Focuses on mount |
autoplay | autoPlay | Attribute | Audio and video |
autocapitalize="none" | autoCapitalize="none" | Attribute | Mobile keyboards |
enctype="multipart/form-data" | encType="multipart/form-data" | Attribute | Form uploads |
formaction="/save" | formAction="/save" | Attribute | Button override; accepts a function in React 19 |
formnovalidate | formNoValidate | Attribute | Submit button override |
novalidate | noValidate | Attribute | Form attribute |
accept-charset="UTF-8" | acceptCharset="UTF-8" | Attribute | Hyphen becomes camelCase |
http-equiv="refresh" | httpEquiv="refresh" | Attribute | Meta tag |
charset="utf-8" | charSet="utf-8" | Attribute | Meta tag |
srcset="a.png 2x" | srcSet="a.png 2x" | Attribute | Responsive images |
srcdoc="..." | srcDoc="..." | Attribute | Iframe inline document |
srclang="en" | srcLang="en" | Attribute | Track element |
usemap="#map" | useMap="#map" | Attribute | Image maps |
datetime="2026-10-27" | dateTime="2026-10-27" | Attribute | time and del elements |
hreflang="en" | hrefLang="en" | Attribute | Links |
crossorigin="anonymous" | crossOrigin="anonymous" | Attribute | Scripts, images, links |
referrerpolicy="no-referrer" | referrerPolicy="no-referrer" | Attribute | Links and images |
allowfullscreen | allowFullScreen | Attribute | Iframes |
playsinline | playsInline | Attribute | Mobile video |
itemprop="name" | itemProp="name" | Attribute | Microdata |
itemscope | itemScope | Attribute | Microdata |
itemtype="https://schema.org/Person" | itemType="https://schema.org/Person" | Attribute | Microdata |
accesskey="s" | accessKey="s" | Attribute | Keyboard shortcut |
inputmode="numeric" | inputMode="numeric" | Attribute | Mobile keyboard hint |
enterkeyhint="go" | enterKeyHint="go" | Attribute | Mobile keyboard hint |
fetchpriority="high" | fetchPriority="high" | Attribute | Images; React 19 or later |
frameborder="0" | frameBorder="0" | Attribute | Iframes |
nomodule | noModule | Attribute | Script element |
<input value="x"> | <input defaultValue="x" /> | Attribute | value alone makes the input controlled and read-only |
<input checked> | <input defaultChecked /> | Attribute | checked alone needs an onChange |
<option selected> | <select defaultValue="b"> | Attribute | React warns on selected; set defaultValue on select |
disabled="" | disabled | Attribute | Empty boolean attributes become bare |
data-id="7" | data-id="7" | Attribute | data-* attributes stay hyphenated |
aria-label="Close" | aria-label="Close" | Attribute | aria-* attributes stay hyphenated |
stroke-width="2" | strokeWidth="2" | Attribute | SVG attributes become camelCase |
fill-rule="evenodd" | fillRule="evenodd" | Attribute | SVG |
clip-path="url(#c)" | clipPath="url(#c)" | Attribute | SVG |
stroke-linecap="round" | strokeLinecap="round" | Attribute | SVG |
stroke-linejoin="round" | strokeLinejoin="round" | Attribute | SVG |
xlink:href="#a" | xlinkHref="#a" | Attribute | Prefer href in modern SVG |
xmlns:xlink="..." | xmlnsXlink="..." | Attribute | SVG root |
xml:lang="en" | xmlLang="en" | Attribute | Namespaced attribute |
viewBox="0 0 24 24" | viewBox="0 0 24 24" | Attribute | Already camelCase, unchanged |
onclick="go()" | onClick={() => go()} | Event Handler | String becomes an arrow function |
ondblclick | onDoubleClick | Event Handler | Name differs from the DOM event |
onchange | onChange | Event Handler | Fires on every keystroke for text inputs in React |
oninput | onInput | Event Handler | Same timing as onChange in React |
onsubmit | onSubmit | Event Handler | Call event.preventDefault() yourself |
onreset | onReset | Event Handler | Form reset |
onfocus | onFocus | Event Handler | Bubbles in React, unlike DOM focus |
onblur | onBlur | Event Handler | Bubbles in React, unlike DOM blur |
onkeydown | onKeyDown | Event Handler | Use event.key |
onkeyup | onKeyUp | Event Handler | Use event.key |
onkeypress | onKeyPress | Event Handler | Deprecated; prefer onKeyDown |
onmousedown | onMouseDown | Event Handler | Mouse |
onmouseup | onMouseUp | Event Handler | Mouse |
onmousemove | onMouseMove | Event Handler | Mouse |
onmouseover | onMouseOver | Event Handler | Bubbles |
onmouseout | onMouseOut | Event Handler | Bubbles |
onmouseenter | onMouseEnter | Event Handler | Does not bubble |
onmouseleave | onMouseLeave | Event Handler | Does not bubble |
oncontextmenu | onContextMenu | Event Handler | Right click |
onscroll | onScroll | Event Handler | Scrollable elements |
onwheel | onWheel | Event Handler | Passive by default |
onload | onLoad | Event Handler | Images, iframes |
onerror | onError | Event Handler | Images, media |
oncopy / oncut / onpaste | onCopy / onCut / onPaste | Event Handler | Clipboard events |
ondrag / ondrop | onDrag / onDrop | Event Handler | Drag and drop; also onDragStart, onDragOver |
ontouchstart | onTouchStart | Event Handler | Touch |
onpointerdown | onPointerDown | Event Handler | Pointer events |
onplay / onpause | onPlay / onPause | Event Handler | Media events |
onanimationend | onAnimationEnd | Event Handler | CSS animations |
ontransitionend | onTransitionEnd | Event Handler | CSS transitions |
style="color:red" | style={{ color: 'red' }} | Style | String becomes an object |
font-size:14px | fontSize: '14px' | Style | Property names become camelCase |
background-color:#fff | backgroundColor: '#fff' | Style | camelCase |
z-index:10 | zIndex: 10 | Style | Unitless numbers stay numbers |
opacity:0.5 | opacity: 0.5 | Style | Unitless number |
-webkit-box-shadow:none | WebkitBoxShadow: 'none' | Style | Vendor prefix gets a capital letter |
-ms-transform:none | msTransform: 'none' | Style | ms prefix is lowercase |
--brand:#06f | '--brand': '#06f' | Style | Custom properties are quoted keys |
background:url(a.png) | background: 'url(a.png)' | Style | Values stay strings |
color:red !important | color: 'red !important' | Style | React ignores !important in inline styles; use a CSS class instead |
<br> | <br /> | Tag / Syntax | Void elements must self-close |
<img src="a.png"> | <img src="a.png" /> | Tag / Syntax | Void element |
<input type="text"> | <input type="text" /> | Tag / Syntax | Void element |
<hr> | <hr /> | Tag / Syntax | Void element |
<meta> / <link> | <meta /> / <link /> | Tag / Syntax | Void elements |
<!-- note --> | {/* note */} | Tag / Syntax | HTML comments are not valid in JSX |
| | Tag / Syntax | Entities are valid in JSX text |
{ or } in text | {'{'} / {'}'} | Tag / Syntax | Braces start expressions in JSX |
two root elements | <>...</> | Tag / Syntax | Wrap siblings in a Fragment |
<script>code</script> | <script>{`code`}</script> | Tag / Syntax | Template literal keeps the text intact |
<style>a{}</style> | <style>{`a{}`}</style> | Tag / Syntax | Braces would break otherwise |
<textarea>text</textarea> | <textarea defaultValue="text" /> | Tag / Syntax | Text children are not supported |
<pre>a b</pre> | <pre>{"a b"}</pre> | Tag / Syntax | Expression keeps whitespace exact |
inline space between tags | {' '} | Tag / Syntax | JSX trims whitespace at line ends |
<a href="#"> | <a href="#"> | Tag / Syntax | Valid, but prefer a button or router Link |