Skip to content

useSortedAttributes (HTML)

.vscode/settings.json
{
"editor.codeActionsOnSave": {
"source.action.useSortedAttributes.biome": "explicit",
"source.fixAll.biome": "explicit"
}
}
biome.json
{
"assist": {
"actions": {
"source": {
"useSortedAttributes": "on"
}
}
}
}

Enforce attribute sorting in HTML elements.

This rule checks if HTML attributes, along with Astro, Svelte, and Vue directives, are sorted in a consistent way. The sort order is:

  • Regular HTML attributes, sorted alphabetically according to the sortOrder option
  • Astro directives, sorted alphabetically according to sortOrder
  • Svelte directives, sorted according to eslint-plugin-svelte’s sort-attributes rule
  • Vue directives, sorted according to the Vue.js Style Guide

If two attributes belong to the same category, they will be sorted alphabetically according to sortOrder.

This rule will not consider spread props or the Vue v-bind="object" syntax as sortable. Instead, it will sort each group of consecutive sortable attributes within the element, leaving any spread props or v-bind="object" attributes in place. This prevents breaking the override of certain props using spread props or v-bind="object".

<input type="text" id="name" name="name" />
code-block.html:1:1 assist/source/useSortedAttributes  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The attributes are not sorted.

> 1 │ <input type="text" id="name" name="name" />
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

Safe fix: Sort the HTML attributes.

1 - <input·type="text"·id="name"·name="name"·/>
1+ <input·id="name"·name="name"·type="text"·/>
2 2

<textarea id="mytextarea" name="textarea" rows="5" cols="20" data-1="" data-11="" data-12="" data-2="">Hello, world!</textarea>
code-block.html:1:1 assist/source/useSortedAttributes  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The attributes are not sorted.

> 1 │ <textarea id="mytextarea" name="textarea" rows="5" cols="20" data-1="" data-11="" data-12="" data-2="">Hello, world!</textarea>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

Safe fix: Sort the HTML attributes.

1 - <textarea·id="mytextarea"·name="textarea"·rows="5"·cols="20"·data-1=""·data-11=""·data-12=""·data-2="">Hello,·world!</textarea>
1+ <textarea·cols="20"·data-1=""·data-2=""·data-11=""·data-12=""·id="mytextarea"·name="textarea"·rows="5"·>Hello,·world!</textarea>
2 2

<svg slot="fallback" class="generic-avatar" transition:name="avatar">...</svg>
code-block.astro:1:3 assist/source/useSortedAttributes  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The attributes are not sorted.

> 1 │ <svg slot="fallback" class="generic-avatar" transition:name="avatar">...</svg>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

Safe fix: Sort the HTML attributes.

1 - ··<svg·slot="fallback"·class="generic-avatar"·transition:name="avatar">...</svg>
1+ ··<svg·class="generic-avatar"·slot="fallback"·transition:name="avatar">...</svg>
2 2

<input type="range" bind:value={b} min="0" max="10" />
code-block.svelte:1:4 assist/source/useSortedAttributes  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The attributes are not sorted.

> 1 │ <input type="range" bind:value={b} min="0" max="10" />
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

Safe fix: Sort the HTML attributes.

1 - ··<input·type="range"·bind:value={b}·min="0"·max="10"·/>
1+ ··<input·max="10"·min="0"·type="range"·bind:value={b}·/>
2 2

<div bind:value2={a} bind:value1={a} {...props} style:color="red">...</div>
code-block.svelte:1:4 assist/source/useSortedAttributes  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The attributes are not sorted.

> 1 │ <div bind:value2={a} bind:value1={a} {...props} style:color="red">...</div>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

Safe fix: Sort the HTML attributes.

1 - ··<div·bind:value2={a}·bind:value1={a}·{...props}·style:color="red">...</div>
1+ ··<div·bind:value1={a}·bind:value2={a}·{...props}·style:color="red">...</div>
2 2

<input @input="onInput" :value="text" placeholder="Type here">
code-block.vue:1:4 assist/source/useSortedAttributes  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The attributes are not sorted.

> 1 │ <input @input="onInput" :value="text" placeholder="Type here">
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

Safe fix: Sort the HTML attributes.

1 - ··<input·@input="onInput"·:value="text"·placeholder="Type·here">
1+ ··<input·placeholder="Type·here"·:value="text"·@input="onInput"·>
2 2

<input id="name" name="name" type="text" />
<textarea cols="20" data-1="" data-2="" data-11="" data-12="" id="mytextarea" name="textarea" rows="5">Hello, world!</textarea>
<svg class="generic-avatar" slot="fallback" transition:name="avatar">...</svg>
<input max="10" min="0" type="range" bind:value={b} />
<div bind:value1={a} bind:value2={a} {...props} style:color="red">...</div>
<input placeholder="Type here" :value="text" @input="onInput" >

The following options are available

The sort ordering to enforce. Values:

  • "[natural](https://en.wikipedia.org/wiki/Natural_sort_order)"
  • "[lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order)"

Default: "natural"

biome.json
{
"assist": {
"actions": {
"source": {
"useSortedAttributes": {
"level": "on",
"options": {
"sortOrder": "lexicographic"
}
}
}
}
}
}
<textarea id="mytextarea" name="textarea" rows="5" cols="20" data-1="" data-2="" data-11="" data-12="">Hello, world!</textarea>
code-block.html:1:1 assist/source/useSortedAttributes  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The attributes are not sorted.

> 1 │ <textarea id="mytextarea" name="textarea" rows="5" cols="20" data-1="" data-2="" data-11="" data-12="">Hello, world!</textarea>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

Safe fix: Sort the HTML attributes.

1 - <textarea·id="mytextarea"·name="textarea"·rows="5"·cols="20"·data-1=""·data-2=""·data-11=""·data-12="">Hello,·world!</textarea>
1+ <textarea·cols="20"·data-1=""·data-11=""·data-12=""·data-2=""·id="mytextarea"·name="textarea"·rows="5"·>Hello,·world!</textarea>
2 2