Title: wp_kses_attr
Published: April 25, 2014
Last modified: May 20, 2026

---

# wp_kses_attr( string $element, string $attr, array[]|string $allowed_html, string[] $allowed_protocols ): string

## In this article

 * [Description](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#wp--skip-link--target)

Removes all attributes, if none are allowed for this element.

## 󠀁[Description](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#description)󠁿

If some are allowed it calls `wp_kses_hair()` to split them further, and then it
builds up new HTML code from the data that `wp_kses_hair()` returns. It also removes`
<` and `>` characters, if there are any left. One more thing it does is to check
if the tag has a closing XHTML slash, and if it does, it puts one in the returned
code as well.

An array of allowed values can be defined for attributes. If the attribute value
doesn’t fall into the list, the attribute will be removed from the tag.

Attributes can be marked as required. If a required attribute is not present, KSES
will remove all attributes from the tag. As KSES doesn’t match opening and closing
tags, it’s not possible to safely remove the tag itself, the safest fallback is 
to strip all attributes from the tag, instead.

## 󠀁[Parameters](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#parameters)󠁿

 `$element`stringrequired

HTML element/tag.

`$attr`stringrequired

HTML attributes from HTML element to closing HTML element tag.

`$allowed_html`array[]|stringrequired

An array of allowed HTML elements and attributes, or a context name such as `'post'`.
See [wp_kses_allowed_html()](https://developer.wordpress.org/reference/functions/wp_kses_allowed_html/)
for the list of accepted context names.

`$allowed_protocols`string[]required

Array of allowed URL protocols.

## 󠀁[Return](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#return)󠁿

 string Sanitized HTML element.

## 󠀁[Source](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#source)󠁿

    ```php
    function wp_kses_attr( $element, $attr, $allowed_html, $allowed_protocols ) {
    	if ( ! is_array( $allowed_html ) ) {
    		$allowed_html = wp_kses_allowed_html( $allowed_html );
    	}

    	// Is there a closing XHTML slash at the end of the attributes?
    	$xhtml_slash = '';
    	if ( preg_match( '%\s*/\s*$%', $attr ) ) {
    		$xhtml_slash = ' /';
    	}

    	// Are any attributes allowed at all for this element?
    	$element_low = strtolower( $element );
    	if ( empty( $allowed_html[ $element_low ] ) || true === $allowed_html[ $element_low ] ) {
    		return "<$element$xhtml_slash>";
    	}

    	// Split it.
    	$attrarr = wp_kses_hair( $attr, $allowed_protocols );

    	// Check if there are attributes that are required.
    	$required_attrs = array_filter(
    		$allowed_html[ $element_low ],
    		static function ( $required_attr_limits ) {
    			return isset( $required_attr_limits['required'] ) && true === $required_attr_limits['required'];
    		}
    	);

    	/*
    	 * If a required attribute check fails, we can return nothing for a self-closing tag,
    	 * but for a non-self-closing tag the best option is to return the element with attributes,
    	 * as KSES doesn't handle matching the relevant closing tag.
    	 */
    	$stripped_tag = '';
    	if ( empty( $xhtml_slash ) ) {
    		$stripped_tag = "<$element>";
    	}

    	// Go through $attrarr, and save the allowed attributes for this element in $attr2.
    	$attr2 = '';
    	foreach ( $attrarr as $arreach ) {
    		// Check if this attribute is required.
    		$required = isset( $required_attrs[ strtolower( $arreach['name'] ) ] );

    		if ( wp_kses_attr_check( $arreach['name'], $arreach['value'], $arreach['whole'], $arreach['vless'], $element, $allowed_html ) ) {
    			$attr2 .= ' ' . $arreach['whole'];

    			// If this was a required attribute, we can mark it as found.
    			if ( $required ) {
    				unset( $required_attrs[ strtolower( $arreach['name'] ) ] );
    			}
    		} elseif ( $required ) {
    			// This attribute was required, but didn't pass the check. The entire tag is not allowed.
    			return $stripped_tag;
    		}
    	}

    	// If some required attributes weren't set, the entire tag is not allowed.
    	if ( ! empty( $required_attrs ) ) {
    		return $stripped_tag;
    	}

    	// Remove any "<" or ">" characters.
    	$attr2 = preg_replace( '/[<>]/', '', $attr2 );

    	return "<$element$attr2$xhtml_slash>";
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/kses.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.0/src/wp-includes/kses.php#L1437)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.0/src/wp-includes/kses.php#L1437-L1503)

## 󠀁[Related](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#related)󠁿

| Uses | Description | 
| [wp_kses_attr_check()](https://developer.wordpress.org/reference/functions/wp_kses_attr_check/)`wp-includes/kses.php` |

Determines whether an attribute is allowed.

  | 
| [wp_kses_hair()](https://developer.wordpress.org/reference/functions/wp_kses_hair/)`wp-includes/kses.php` |

Given a string of HTML attributes and values, parse into a structured attribute list.

  | 
| [wp_kses_allowed_html()](https://developer.wordpress.org/reference/functions/wp_kses_allowed_html/)`wp-includes/kses.php` |

Returns an array of allowed HTML tags and attributes for a given context.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/functions/wp_kses_attr/?output_format=md#changelog)󠁿

| Version | Description | 
| [5.9.0](https://developer.wordpress.org/reference/since/5.9.0/) | Added support for an array of allowed values for attributes.
 Added support for required attributes. | 
| [1.0.0](https://developer.wordpress.org/reference/since/1.0.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_kses_attr%2F)
before being able to contribute a note or feedback.