Skip to content
tezvyn:

Angular Custom Attribute Directives

Source: angular.devMediumHow cards are made

Angular Custom Attribute Directives

An Angular attribute directive changes the appearance or behavior of an existing DOM element without adding a new one, applied as a plain HTML attribute so reusable behavior like hover effects or validation can be attached declaratively across many templates.

Why it exists

Angular templates often need to attach the same DOM behavior, a hover highlight, a tooltip, an autofocus, a permission based style, to many different unrelated elements across an app. Writing that logic imperatively inside every component that needs it duplicates code and couples unrelated components to DOM manipulation details. Attribute directives exist to package that behavior once and attach it declaratively wherever it is needed.

The mental model

Think of an attribute directive as a clip on accessory for an existing element, like a smart plug clipped onto an ordinary lamp. It does not replace the lamp or add a second one; it just changes how the existing lamp behaves, listening for a signal and reaching into the lamp to change its state. The element underneath is unchanged in kind, only in behavior.

How it works

A directive is created with the Directive decorator and an attribute style selector in square brackets, such as appHighlight, which matches an attribute rather than a tag name. Inside, ElementRef gives access to the host DOM node, though direct manipulation through nativeElement is discouraged in favor of Renderer2, which manipulates the DOM through Angular's abstraction so the same code stays safe under server side rendering and avoids bypassing sanitization. HostListener binds a method to a DOM event fired on the host element, such as mouseenter or mouseleave. HostBinding binds a directive property directly to a host element property or attribute, such as class or an aria attribute, keeping it in sync automatically through change detection. The directive is then applied to any element just by adding its attribute, optionally passing configuration through an Input bound to that same attribute name.

When it matters

This matters whenever the same interactive or visual behavior needs to apply across many unrelated components without duplicating logic or wrapping each one in an extra component. Typical real cases are hover highlights, tooltips, permission based styling, and custom form validators. The common footgun is forgetting to declare the directive in its module, or import it into a standalone component, in which case Angular does not error, it simply treats the attribute as an unrecognized plain HTML attribute and does nothing.

A concrete example

A team builds an appTooltip directive that listens for mouseenter and mouseleave through HostListener, creating and positioning a tooltip element through Renderer2. They then apply it across dozens of unrelated buttons and icons just by writing an appTooltip attribute with a message, such as on a save button, without any of those components needing to know tooltip rendering logic exists.

Interview question

A developer adds the appHighlight attribute to a div in a template, but nothing happens and no error is logged. What is the most likely cause?

  • a.The directive is not declared or imported anywhere the template can see itCorrect
  • b.Attribute directives require a structural directive like ngIf on the same element to activate
  • c.HostListener cannot bind to mouse events inside a custom directive
  • d.Angular blocks custom attributes on div elements for security reasons
Why?

When a directive is not declared in its module or imported into a standalone component, Angular has no way to recognize the attribute and simply renders it as a plain, inert HTML attribute rather than throwing an error; the other options describe restrictions that do not exist in Angular.

Just read this? Test yourself on what you have been reading.

Read the original → angular.dev

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on angular — each one lists the topics its interview covers.

See open roles