Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?


Failed to load latest commit information.
Latest commit message
Commit time
November 10, 2020 08:53
December 14, 2015 16:51
June 30, 2020 14:44
November 10, 2020 07:41
June 30, 2020 14:44
October 7, 2019 14:36
March 23, 2018 16:31
June 30, 2020 14:44
June 30, 2020 14:44

HtmlTags HtmlTags

CI NuGet NuGet Version MyGet CI Version

.NET objects for generating HTML


Install via nuget, for ASP.NET Core:

PM> Install-Package HtmlTags

When should I use HtmlTags?

In general, you should avoid building strings of HTML in your applications. There are plenty of template/view engines that are much more suitable for generating dynamic markup. However, there are some situations that require you to build snippets of HTML from code (e.g., view extensions in HtmlHelper extensions in ASP.NET Core). HtmlTags is the best way to build those snippets.

The HtmlTags advantage

  • Automatic encoding of HTML entities in your attributes and inner text
  • Ensures proper structure (closing tags, etc)
  • Easy to use chaining API with method names modeled after jQuery
  • Compatible with Razor expressions
  • Methods manipulate an internal model, not a string. The HTML string is not generated until ToString() is called.

That last point seems trivial, but it is actually HtmlTag's biggest strength. If your HtmlHelper extensions return an HtmlTag instance, you have the ability to customize the generated tag within your view template. When your HtmlHelpers return a strings (as the helpers included with ASP.NET Core do), you have no chance to customize the tag (without ugly string manipulation).

HtmlHelpers that return strings

Consider the built-in ASP.NET Core TextBox() helper:


It will generate the following HTML:

<input id="FirstName" name="FirstName" type="text" value="" />

What if you wanted to apply a CSS class to that input? Or change the element id? You can do it, but it requires a much more verbose overload:

@Html.TextBox("FirstName", "Lucas", new Dictionary<string, object> {{"id", "first-name"}, {"class", "required"})

HtmlHelpers that return HtmlTags

Now consider an HtmlHelper extension that returns an HtmlTag:

public static class HtmlTagHelpers {
    public static HtmlTag TextBoxTag(this HtmlHelper html, string name) {
        return new HtmlTag("input").Id(name).Attr("name", name)
            .Attr("type", "text").Attr("value", html.ViewData[name]);

You can use it just as easily in your view template:


and it will generate the exact same HTML as above. However, you can also very easily modify the tag produced by the helper:


will generate:

<input id="first-name" name="FirstName" type="text" value="Lucas" class="required" />



Each HtmlTag instance represents a single HTML element, and optionally, a collection of inner elements.

To create an element, pass the element name to the HtmlTag constructor:

new HtmlTag("span")

Calling ToString() on this instance will produce:


There are a number of methods you can use to modify the element:

var tag = new HtmlTag("span");
tag.Text("Hello & Goodbye");
tag.Attr("title", "Greeting");

which will produce:

<span title="Greetings" class="important">Hello &amp; Goodbye</span>

All of the modifying methods return the instance, so they can be chained. The above example can be rewritten as:

new HtmlTag("span").Text("Hello & Goodbye").AddClass("important").Attr("title", "Greetings")

Most methods that set a value also have an overload that returns the value:

var tag = new HtmlTag("span").Attr("title", "My Tooltip");
Console.WriteLine( tag.Attr("title") ); // writes: My Tooltip

Custom Data attributes

There is also built-in support for JSON serializing values of HTML5-style custom data attributes:

<%: Html.TextBoxTag("Birthday")
    .Data("validate", true)
    .Data("validate-type", "date")
    .Data("min-date", new DateTime(1900, 1, 1)) %>

Will render:

<input id="Birthday" name="Birthday" type="text" data-validate="true" data-validate-type="date" data-min-date="&quot;\/Date(-2208967200000)\/&quot;" />

jQuery Metadata support

Or you can serialize an entire settings object in a single value on the server that can be interpreted on the client using something like the jQuery Metadata plugin:

public class EditableOptions {
    public bool MultiLine { get; set; }
    public int MaxLength { get; set; }
    public string InputType { get; set; }

public static HtmlTag Editable(this HtmlHelper html) {
    // EditableOptions hardcoded for this example, but they could be 
    // determined based on different criteria for the input being rendered
    var options = new EditableOptions {
        MultiLine = false,
        MaxLength = 20,
        InputType = "date"

    return new HtmlTag("div").MetaData("editable", options);

Notice we're passing an instance of an object (EditableOptions) as the value of the "editable" metadata. This will render:

<div data-__="{&quot;editable&quot;:{&quot;MultiLine&quot;:false,&quot;MaxLength&quot;:20,&quot;InputType&quot;:&quot;date&quot;}}"></div>

You can then drive logic on the client using this data:

$.metadata.setType('attr', 'data-__'); //once on your page
var o = $("div").metadata();
alert(o.MultiLine); // # false
alert(o.MaxLength); // # 20
alert(o.InputType); // # "date"

More information

More detailed documention is coming. In the meantime, try browsing the unit tests for further examples.