diff --git a/CHANGELOG.md b/CHANGELOG.md
index f914019c..770e8bde 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
## 3.12.1 under development
- New #260: Add `$attributes` parameter to `Html::li()` method (@gauravkumar2525)
+- Chg #234: Remove tag attributes sorting (@FrankiFixx)
- Enh #261: Enhance `RadioList::addRadioWrapClass()` method for cleaner class addition (@vjik)
## 3.12.0 December 13, 2025
diff --git a/src/Html.php b/src/Html.php
index 90866126..1d1c3238 100644
--- a/src/Html.php
+++ b/src/Html.php
@@ -99,45 +99,6 @@
*/
final class Html
{
- /**
- * The preferred order of attributes in a tag. This mainly affects the order of the attributes that are
- * rendered by {@see renderTagAttributes()}.
- */
- private const ATTRIBUTE_ORDER = [
- 'type',
- 'id',
- 'class',
- 'name',
- 'value',
-
- 'href',
- 'loading',
- 'src',
- 'srcset',
- 'form',
- 'action',
- 'method',
-
- 'selected',
- 'checked',
- 'readonly',
- 'disabled',
- 'multiple',
-
- 'size',
- 'maxlength',
- 'minlength',
- 'width',
- 'height',
- 'rows',
- 'cols',
-
- 'alt',
- 'title',
- 'rel',
- 'media',
- ];
-
/**
* List of tag attributes that should be specially handled when their values are of array type.
* In particular, if the value of the `data` attribute is `['name' => 'xyz', 'age' => 13]`, two attributes will be
@@ -1674,16 +1635,6 @@ public static function address(string|Stringable $content = '', array $attribute
*/
public static function renderTagAttributes(array $attributes): string
{
- if (count($attributes) > 1) {
- $sorted = [];
- foreach (self::ATTRIBUTE_ORDER as $name) {
- if (isset($attributes[$name])) {
- $sorted[$name] = $attributes[$name];
- }
- }
- $attributes = array_merge($sorted, $attributes);
- }
-
$html = '';
/**
* @var string $name
diff --git a/tests/HtmlTest.php b/tests/HtmlTest.php
index ad94d1d3..1da7e8f8 100644
--- a/tests/HtmlTest.php
+++ b/tests/HtmlTest.php
@@ -135,7 +135,7 @@ public function testMeta(): void
{
$this->assertSame('', Html::meta()->render());
$this->assertSame(
- '',
+ '',
Html::meta(['name' => 'keywords', 'content' => 'yii', 'id' => 'main'])->render(),
);
}
@@ -154,15 +154,15 @@ public function testLink(): void
public function testCssFile(): void
{
$this->assertSame(
- '',
+ '',
Html::cssFile('http://example.com')->render(),
);
$this->assertSame(
- '',
+ '',
Html::cssFile('')->render(),
);
$this->assertSame(
- '',
+ '',
Html::cssFile('http://example.com', ['id' => 'main'])->render(),
);
}
@@ -178,7 +178,7 @@ public function testJavaScriptFile(): void
Html::javaScriptFile('')->render(),
);
$this->assertSame(
- '',
+ '',
Html::javaScriptFile('http://example.com', ['id' => 'main'])->render(),
);
}
@@ -206,7 +206,7 @@ public function testMailto(): void
Html::mailto('contact me', 'info@example.com')->render(),
);
$this->assertSame(
- 'contact me',
+ 'contact me',
Html::mailto('contact me', 'info@example.com', ['id' => 'contact'])->render(),
);
}
@@ -385,15 +385,15 @@ public function testTextInput(): void
public function testColorInput(): void
{
$this->assertSame('', Html::color()->render());
- $this->assertSame('', Html::color('')->render());
- $this->assertSame('', Html::color(null, '')->render());
- $this->assertSame('', Html::color('test')->render());
+ $this->assertSame('', Html::color('')->render());
+ $this->assertSame('', Html::color(null, '')->render());
+ $this->assertSame('', Html::color('test')->render());
$this->assertSame(
- '',
+ '',
Html::color('test', '#ff0000')->render(),
);
$this->assertSame(
- '',
+ '',
Html::color('test', '#ff0000', ['required' => true])->render(),
);
}
@@ -409,7 +409,7 @@ public function testHiddenInput(): void
Html::hiddenInput('test', '43')->render(),
);
$this->assertSame(
- '',
+ '',
Html::hiddenInput('test', '43', ['id' => 'ABC'])->render(),
);
}
@@ -433,15 +433,15 @@ public function testPasswordInput(): void
public function testFile(): void
{
$this->assertSame('', Html::file()->render());
- $this->assertSame('', Html::file('')->render());
- $this->assertSame('', Html::file(null, '')->render());
- $this->assertSame('', Html::file('test')->render());
+ $this->assertSame('', Html::file('')->render());
+ $this->assertSame('', Html::file(null, '')->render());
+ $this->assertSame('', Html::file('test')->render());
$this->assertSame(
- '',
+ '',
Html::file('test', '43')->render(),
);
$this->assertSame(
- '',
+ '',
Html::file('test', '43', ['class' => 'photo'])->render(),
);
}
@@ -449,15 +449,15 @@ public function testFile(): void
public function testRadio(): void
{
$this->assertSame('', Html::radio()->render());
- $this->assertSame('', Html::radio('')->render());
- $this->assertSame('', Html::radio(null, '')->render());
- $this->assertSame('', Html::radio('test')->render());
+ $this->assertSame('', Html::radio('')->render());
+ $this->assertSame('', Html::radio(null, '')->render());
+ $this->assertSame('', Html::radio('test')->render());
$this->assertSame(
- '',
+ '',
Html::radio('test', '43')->render(),
);
$this->assertSame(
- '',
+ '',
Html::radio('test', '43', ['readonly' => true])->render(),
);
}
@@ -465,15 +465,15 @@ public function testRadio(): void
public function testCheckbox(): void
{
$this->assertSame('', Html::checkbox()->render());
- $this->assertSame('', Html::checkbox('')->render());
- $this->assertSame('', Html::checkbox(null, '')->render());
- $this->assertSame('', Html::checkbox('test')->render());
+ $this->assertSame('', Html::checkbox('')->render());
+ $this->assertSame('', Html::checkbox(null, '')->render());
+ $this->assertSame('', Html::checkbox('test')->render());
$this->assertSame(
- '',
+ '',
Html::checkbox('test', '43')->render(),
);
$this->assertSame(
- '',
+ '',
Html::checkbox('test', '43', ['readonly' => true])->render(),
);
}
@@ -481,15 +481,15 @@ public function testCheckbox(): void
public function testRange(): void
{
$this->assertSame('', Html::range()->render());
- $this->assertSame('', Html::range('')->render());
- $this->assertSame('', Html::range(null, '')->render());
- $this->assertSame('', Html::range('test')->render());
+ $this->assertSame('', Html::range('')->render());
+ $this->assertSame('', Html::range(null, '')->render());
+ $this->assertSame('', Html::range('test')->render());
$this->assertSame(
- '',
+ '',
Html::range('test', '43')->render(),
);
$this->assertSame(
- '',
+ '',
Html::range('test', '43', ['readonly' => true])->render(),
);
}
@@ -532,9 +532,9 @@ public function testCheckboxList(): void
$this->assertSame(
'' . "\n"
. '
' . "\n"
- . '' . "\n"
- . '' . "\n"
- . '' . "\n"
+ . '' . "\n"
+ . '' . "\n"
+ . '' . "\n"
. '
',
Html::checkboxList('test')
->items([1 => 'One', 2 => 'Two', 5 => 'Five'])
@@ -550,9 +550,9 @@ public function testRadioList(): void
$this->assertSame(
'' . "\n"
. '' . "\n"
- . '' . "\n"
- . '' . "\n"
- . '' . "\n"
+ . '' . "\n"
+ . '' . "\n"
+ . '' . "\n"
. '
',
Html::radioList('test')
->items([1 => 'One', 2 => 'Two', 5 => 'Five'])
@@ -706,7 +706,7 @@ public function testLi(): void
$this->assertSame('Hello', Html::li(Html::span('Hello'))->render());
$this->assertSame(
- 'Content',
+ 'Content',
Html::li('Content', ['class' => 'item', 'id' => 'item-1'])->render(),
);
$this->assertSame('', Html::li(attributes: ['class' => 'empty'])->render());
@@ -857,7 +857,7 @@ public static function dataRenderTagAttributes(): array
[' class="first second"', ['class' => ['first', 'second']]],
['', ['class' => []]],
[' style="width: 100px; height: 200px;"', ['style' => ['width' => '100px', 'height' => '200px']]],
- [' name="position" value="42"', ['value' => 42, 'name' => 'position']],
+ [' value="42" name="position"', ['value' => 42, 'name' => 'position']],
[
' id="x" class="a b" data-a="1" data-b="2" style="width: 100px;" any=\'[1,2]\'',
[
diff --git a/tests/Tag/Base/BooleanInputTagTest.php b/tests/Tag/Base/BooleanInputTagTest.php
index aaa1780c..59bf58fa 100644
--- a/tests/Tag/Base/BooleanInputTagTest.php
+++ b/tests/Tag/Base/BooleanInputTagTest.php
@@ -12,7 +12,7 @@ final class BooleanInputTagTest extends TestCase
{
public function testChecked(): void
{
- $this->assertSame('', (string) TestBooleanInputTag::tag()->checked());
+ $this->assertSame('', (string) TestBooleanInputTag::tag()->checked());
$this->assertSame('', (string) TestBooleanInputTag::tag()->checked(false));
$this->assertSame('', (string) TestBooleanInputTag::tag()
->checked(true)
@@ -64,7 +64,7 @@ public function testLabel(string $expected, ?string $label, array $attributes):
public function testLabelNoWrap(): void
{
$this->assertSame(
- ' ',
+ ' ',
(string) TestBooleanInputTag::tag()
->id('ID')
->label('Voronezh', wrap: false),
@@ -74,7 +74,7 @@ public function testLabelNoWrap(): void
public function testLabelWithId(): void
{
$this->assertSame(
- '',
+ '',
TestBooleanInputTag::tag()
->id('Test')
->label('One')
@@ -85,7 +85,7 @@ public function testLabelWithId(): void
public function testSideLabel(): void
{
$this->assertMatchesRegularExpression(
- '~ ~',
+ '~ ~',
TestBooleanInputTag::tag()
->sideLabel('One')
->render(),
@@ -95,7 +95,7 @@ public function testSideLabel(): void
public function testSideLabelEmpty(): void
{
$this->assertMatchesRegularExpression(
- '~ ~',
+ '~ ~',
TestBooleanInputTag::tag()
->sideLabel('')
->render(),
@@ -115,7 +115,7 @@ public function testSideLabelNull(): void
public function testSideLabelWithId(): void
{
$this->assertSame(
- ' ',
+ ' ',
TestBooleanInputTag::tag()
->id('Test')
->sideLabel('One')
@@ -126,7 +126,7 @@ public function testSideLabelWithId(): void
public function testSideLabelWithAttributes(): void
{
$this->assertMatchesRegularExpression(
- '~ ~',
+ '~ ~',
TestBooleanInputTag::tag()
->sideLabel('One', ['class' => 'red'])
->render(),
@@ -136,7 +136,7 @@ public function testSideLabelWithAttributes(): void
public function testSideLabelId(): void
{
$this->assertSame(
- ' ',
+ ' ',
TestBooleanInputTag::tag()
->sideLabel('One')
->id('count')
@@ -160,15 +160,15 @@ public static function dataUncheckValue(): array
return [
['', null, null],
['', null, 7],
- ['', 'color', null],
- ['', 'color[]', null],
+ ['', 'color', null],
+ ['', 'color[]', null],
[
- '',
+ '',
'color',
7,
],
[
- '',
+ '',
'color[]',
7,
],
@@ -191,7 +191,7 @@ public function testUncheckValueDisabled(): void
{
$this->assertSame(
''
- . '',
+ . '',
TestBooleanInputTag::tag()
->name('color')
->uncheckValue(7)
@@ -204,7 +204,7 @@ public function testUncheckValueForm(): void
{
$this->assertSame(
''
- . '',
+ . '',
TestBooleanInputTag::tag()
->name('color')
->uncheckValue(7)
@@ -217,7 +217,7 @@ public function testUncheckValueWithLabel(): void
{
$this->assertSame(
''
- . '',
+ . '',
TestBooleanInputTag::tag()
->name('color')
->uncheckValue(7)
diff --git a/tests/Tag/Base/MediaTagTest.php b/tests/Tag/Base/MediaTagTest.php
index 22e7f669..f78a2a0a 100644
--- a/tests/Tag/Base/MediaTagTest.php
+++ b/tests/Tag/Base/MediaTagTest.php
@@ -169,9 +169,9 @@ public function testWrongTrackDefault(): void
$this->assertSame(
'' . "\n"
- . '',
$tag->render(),
);
diff --git a/tests/Tag/Base/TagTest.php b/tests/Tag/Base/TagTest.php
index cd7e33e2..752af442 100644
--- a/tests/Tag/Base/TagTest.php
+++ b/tests/Tag/Base/TagTest.php
@@ -28,7 +28,7 @@ public static function dataAttributes(): array
['', ['class' => ['first', 'second']]],
['', ['class' => []]],
['', ['style' => ['width' => '100px', 'height' => '200px']]],
- ['', ['value' => 42, 'name' => 'position']],
+ ['', ['value' => 42, 'name' => 'position']],
[
'',
[
@@ -93,7 +93,7 @@ public function testReplaceAttributes(): void
public function testUnionAttributes(): void
{
$this->assertSame(
- '',
+ '',
TestTag::tag()
->class('red')
->unionAttributes(['class' => 'green', 'id' => 'color'])
diff --git a/tests/Tag/ColgroupTest.php b/tests/Tag/ColgroupTest.php
index 00242d9a..b843fe6f 100644
--- a/tests/Tag/ColgroupTest.php
+++ b/tests/Tag/ColgroupTest.php
@@ -16,8 +16,8 @@ public function testBase(): void
$this->assertSame(
'' . "\n"
. '' . "\n"
- . '' . "\n"
- . '' . "\n"
+ . '' . "\n"
+ . '' . "\n"
. '',
Colgroup::tag()
->columns(
diff --git a/tests/Tag/FormTest.php b/tests/Tag/FormTest.php
index 2db79d06..d1e2adde 100644
--- a/tests/Tag/FormTest.php
+++ b/tests/Tag/FormTest.php
@@ -18,7 +18,7 @@ public function testBase(): void
$tag = Form::tag();
$this->assertSame(
- '',
@@ -36,7 +36,7 @@ public function testBase(): void
public function testGet(): void
{
$this->assertSame(
- '',
+ '',
Form::tag()
->get('https://example.com/send')
->render(),
@@ -56,7 +56,7 @@ public function testGetWithoutUrl(): void
public function testPost(): void
{
$this->assertSame(
- '',
+ '',
Form::tag()
->post('https://example.com/send')
->render(),
diff --git a/tests/Tag/Input/CheckboxTest.php b/tests/Tag/Input/CheckboxTest.php
index abedeebb..8951beae 100644
--- a/tests/Tag/Input/CheckboxTest.php
+++ b/tests/Tag/Input/CheckboxTest.php
@@ -12,7 +12,7 @@ final class CheckboxTest extends TestCase
public function testBase(): void
{
$this->assertSame(
- '',
+ '',
Checkbox::tag()
->name('number')
->value(42)
diff --git a/tests/Tag/Input/ColorTest.php b/tests/Tag/Input/ColorTest.php
index 576299ff..b30d761d 100644
--- a/tests/Tag/Input/ColorTest.php
+++ b/tests/Tag/Input/ColorTest.php
@@ -12,7 +12,7 @@ final class ColorTest extends TestCase
public function testBase(): void
{
$this->assertSame(
- '',
+ '',
Color::tag()
->name('color')
->value('#ff0000')
diff --git a/tests/Tag/Input/FileTest.php b/tests/Tag/Input/FileTest.php
index 8a861031..068205a6 100644
--- a/tests/Tag/Input/FileTest.php
+++ b/tests/Tag/Input/FileTest.php
@@ -13,7 +13,7 @@ final class FileTest extends TestCase
public function testBase(): void
{
$this->assertSame(
- '',
+ '',
File::tag()
->name('avatar')
->render(),
@@ -25,15 +25,15 @@ public static function dataUncheckValue(): array
return [
['', null, null],
['', null, 7],
- ['', 'avatar', null],
- ['', 'avatar[]', null],
+ ['', 'avatar', null],
+ ['', 'avatar[]', null],
[
- '',
+ '',
'avatar',
7,
],
[
- '',
+ '',
'avatar[]',
7,
],
@@ -56,7 +56,7 @@ public function testUncheckValueDisabled(): void
{
$this->assertSame(
''
- . '',
+ . '',
File::tag()
->name('avatar')
->uncheckValue(7)
@@ -69,7 +69,7 @@ public function testUncheckValueForm(): void
{
$this->assertSame(
''
- . '',
+ . '',
File::tag()
->name('avatar')
->uncheckValue(7)
@@ -89,8 +89,8 @@ public function testUncheckInputAttributes(): void
->render();
$this->assertSame(
- ''
- . '',
+ ''
+ . '',
$result,
);
}
@@ -106,8 +106,8 @@ public function testReplaceUncheckInputAttributes(): void
->render();
$this->assertSame(
- ''
- . '',
+ ''
+ . '',
$result,
);
}
@@ -116,11 +116,11 @@ public static function dataAccept(): array
{
return [
[
- '',
+ '',
null,
],
[
- '',
+ '',
'.doc,.docx',
],
];
@@ -142,11 +142,11 @@ public static function dataMultiple(): array
{
return [
[
- '',
+ '',
true,
],
[
- '',
+ '',
false,
],
];
@@ -167,7 +167,7 @@ public function testMultiple(string $expected, ?bool $multiple): void
public function testMultipleDefault(): void
{
$this->assertSame(
- '',
+ '',
File::tag()
->name('avatar')
->multiple()
diff --git a/tests/Tag/Input/RadioTest.php b/tests/Tag/Input/RadioTest.php
index 134660c8..0598ee2d 100644
--- a/tests/Tag/Input/RadioTest.php
+++ b/tests/Tag/Input/RadioTest.php
@@ -12,7 +12,7 @@ final class RadioTest extends TestCase
public function testBase(): void
{
$this->assertSame(
- '',
+ '',
Radio::tag()
->name('number')
->value(42)
diff --git a/tests/Tag/Input/RangeTest.php b/tests/Tag/Input/RangeTest.php
index 1a05ec01..249fbcc6 100644
--- a/tests/Tag/Input/RangeTest.php
+++ b/tests/Tag/Input/RangeTest.php
@@ -21,7 +21,7 @@ public function testBase(): void
->step(10);
$this->assertSame(
- '',
+ '',
$tag->render(),
);
}
@@ -30,11 +30,11 @@ public static function dataMin(): array
{
return [
['', null],
- ['', ''],
- ['', '2.5'],
- ['', 10],
- ['', 42.7],
- ['', new StringableObject('99')],
+ ['', ''],
+ ['', '2.5'],
+ ['', 10],
+ ['', 42.7],
+ ['', new StringableObject('99')],
];
}
@@ -50,11 +50,11 @@ public static function dataMax(): array
{
return [
['', null],
- ['', ''],
- ['', '2.5'],
- ['', 10],
- ['', 42.7],
- ['', new StringableObject('99')],
+ ['', ''],
+ ['', '2.5'],
+ ['', 10],
+ ['', 42.7],
+ ['', new StringableObject('99')],
];
}
@@ -70,11 +70,11 @@ public static function dataStep(): array
{
return [
['', null],
- ['', ''],
- ['', '2.5'],
- ['', 10],
- ['', 42.7],
- ['', new StringableObject('99')],
+ ['', ''],
+ ['', '2.5'],
+ ['', 10],
+ ['', 42.7],
+ ['', new StringableObject('99')],
];
}
@@ -90,7 +90,7 @@ public static function dataList(): array
{
return [
['', null],
- ['', 'DataList'],
+ ['', 'DataList'],
];
}
@@ -124,7 +124,7 @@ public function testAddOutputAttributes(): void
$this->assertSame(
''
- . "\n" . '-',
+ . "\n" . '-',
$tag->render(),
);
}
@@ -181,7 +181,7 @@ public function testOutputWithCustomAttributes(): void
$this->assertMatchesRegularExpression(
'~rangeOutput\d*)\"\)\.innerHTML=this\.value">'
- . "\n" . '-~',
+ . "\n" . '-~',
$tag->render(),
);
}
@@ -193,7 +193,7 @@ public function testOutputWithValue(): void
->value(10);
$this->assertMatchesRegularExpression(
- '~rangeOutput\d*)\"\)\.innerHTML=this\.value">'
. "\n" . '10~',
$tag->render(),
diff --git a/tests/Tag/InputTest.php b/tests/Tag/InputTest.php
index a7056eaf..af283308 100644
--- a/tests/Tag/InputTest.php
+++ b/tests/Tag/InputTest.php
@@ -48,7 +48,7 @@ public function testPassword(): void
public function testFile(): void
{
$this->assertSame(
- '',
+ '',
(string) Input::file('photo', 'c:\\path\\'),
);
}
@@ -56,7 +56,7 @@ public function testFile(): void
public function testCheckbox(): void
{
$this->assertSame(
- '',
+ '',
(string) Input::checkbox('subscribe')->checked(),
);
}
@@ -64,7 +64,7 @@ public function testCheckbox(): void
public function testRadio(): void
{
$this->assertSame(
- '',
+ '',
(string) Input::radio('count', 'one'),
);
}
@@ -72,7 +72,7 @@ public function testRadio(): void
public function testRange(): void
{
$this->assertSame(
- '',
+ '',
(string) Input::range('count', 10),
);
}
@@ -80,7 +80,7 @@ public function testRange(): void
public function testColor(): void
{
$this->assertSame(
- '',
+ '',
(string) Input::color('color', '#ff0000'),
);
}
diff --git a/tests/Tag/LinkTest.php b/tests/Tag/LinkTest.php
index 627eae64..edd45638 100644
--- a/tests/Tag/LinkTest.php
+++ b/tests/Tag/LinkTest.php
@@ -13,7 +13,7 @@ final class LinkTest extends TestCase
public function testBase(): void
{
$this->assertSame(
- '',
+ '',
(string) Link::tag()
->url('/rss')
->type('application/rss+xml')
@@ -25,7 +25,7 @@ public function testBase(): void
public function testToCssFile(): void
{
$this->assertSame(
- '',
+ '',
(string) Link::toCssFile('main.css'),
);
}
@@ -119,8 +119,8 @@ public function testAs(string $expected, ?string $as): void
public static function dataPreload(): array
{
return [
- ['', '/main.css'],
- ['', '/main.css', 'style'],
+ ['', '/main.css'],
+ ['', '/main.css', 'style'],
];
}
diff --git a/tests/Tag/PictureTest.php b/tests/Tag/PictureTest.php
index f052013c..f0019941 100644
--- a/tests/Tag/PictureTest.php
+++ b/tests/Tag/PictureTest.php
@@ -31,8 +31,8 @@ public function testBase(): void
$this->assertSame(
'' . "\n"
- . '' . "\n"
- . '' . "\n"
+ . '' . "\n"
+ . '' . "\n"
. '
' . "\n"
. '',
$picture->render(),
diff --git a/tests/Tag/SelectTest.php b/tests/Tag/SelectTest.php
index 9b4d0a40..eb30355c 100644
--- a/tests/Tag/SelectTest.php
+++ b/tests/Tag/SelectTest.php
@@ -35,15 +35,15 @@ public static function dataNameForMultiple(): array
{
return [
['', null],
- ['', ''],
+ ['', ''],
[
'' . "\n"
- . '',
+ . '',
'age',
],
[
'' . "\n"
- . '',
+ . '',
'place[]',
],
];
@@ -362,7 +362,7 @@ public function testOptionsAndGroupsAttributes(): void
$this->assertStringContainsStringIgnoringLineEndings(
<<
-
+