Always use when escaping HTML attributes (especially form values) such as alt, value, title, etc. To escape the value of a translation use esc_attr__() instead; to escape, translate and echo, use esc_attr_e().

When escaping the values of attributes that accept URIs (like href and src), it is important to pass the value through esc_url(). If you only use esc_attr(), the code may still be vulnerable to XSS. (Note also, that when using esc_url(), you don’t need to also use esc_attr().)

I’m not sure if esc_attr() is what you should use if you’re echoing out the value for a form input that is allowed to contain HTML entities because they get lost. ie, you may start with a string containing HTML entities (eg &), and find them disappearing (turning into &).

It’s easiest to explain with an example:

1. You have a value in the database that is Want to do a "br" tag? Do this: &lt;br&gt;';

2. You output that value in a page inside a form input’s value with code like this

<input type="text" value="<?php echo esc_attr($value);?>">

That will produce HTML like

<input value="Want to do a &quot;br&quot; tag? Do this: &lt;br&gt;">

3. When that is displayed by the browser, it will DECODE the HTML entities, showing the user Want to do a "br" tag? Do this: <br>.
4. When that form is submitted back to the server, the browser will send the value the USER SAW, namely Want to do a "br" tag? Do this: <br>.
5. If your database code saves the user's input as it was received, it will save it as Want to do a "br" tag? Do this: <br>

Notice we lost the HTML entities? We started with Want to do a "br" tag? Do this: &lt;br&gt;'; but ended up with Want to do a "br" tag? Do this: <br>. OUPS.

In order to fix that, esc_attr() should have DOUBLE-encoded the HTML entities; ie produced HTML like this:

<input value="Want to do a &quot;br&quot; tag? Do this: &amp;lt;br&amp;gt;">

Notice the <br> tag has been double-encoded. That will mean the value Want to do a "br" tag? Do this: &lt;br&gt; will be displayed to the user, and thus get submitted, and saved down the road.

So what function should you use for inputs that are allowed to have HTML entities? esc_textarea().