Validating and making accessible a wordpress site

Install Accessibility by UserWay

You can download the plugin here.

Nu Html Checker

First, run the Nu Html Checker for your site. You should have no errors there.

Elementor

				
					add_action( 'elementor/frontend/the_content', function( $content ) {
// element pack carousel widget
$content = str_replace(" bdt-grid>", " >", $content);
$content = str_replace(" bdt-margin>", " >", $content);
$content = str_replace("migration_allowed=\"1\"", "", $content);
$content = str_replace("migrated=\"0\"", "", $content);
$content = str_replace("<i ", "<span ", $content);
$content = str_replace("</i>", "</span>", $content);
return $content;
} );

add_action( 'elementor/widget/render_content', function( $content, $widget ) {
//echo $widget->get_name();
// woocommerce mini cart
if ( 'woocommerce-menu-cart' === $widget->get_name() ) {
$content = str_replace("class=\"elementor-menu-cart__container", "role=\"navigation\" class=\"elementor-menu-cart__container", $content);
$content = str_replace("class=\"elementor-menu-cart__main\" aria-expanded=\"false\"", "class=\"elementor-menu-cart__main\"", $content);
$content = str_replace("id=\"elementor-menu-cart__toggle_button\"", "", $content);
//var_dump($content);
}

// ajax search
if ( 'wp-widget-ajaxsearchprowidget' === $widget->get_name() ) {
$content = str_replace("id=\"x-mark-icon\"", "", $content);
}

// icon
if ( 'icon' === $widget->get_name() ) {
$content = str_replace("<i ", "<span style=\"display:none;\">dummy</span><i ", $content);
}

// jet-mega-menu
if ( 'jet-mega-menu' === $widget->get_name() ) {
$content = str_replace("<i ", "<span style=\"display:none;\">dummy</span><i ", $content);
}

// slides
if ( 'slides' === $widget->get_name() ) {
$content = str_replace("</a>", "<span style=\"display:none;\">dummy</span></a>", $content);
}

// bdt-mailchimp
if ( 'bdt-mailchimp' === $widget->get_name() ) {
	//Clean the line breaks and leave just a space
	$content = preg_replace("/[ \t]+/", " ", preg_replace("/\s*$^\s*/m", "\n", $content));
    $content = preg_replace("/[\n\r]/", "", $content);
    $content = str_replace("</div> <div class=\"bdt-newsletter-btn", "</span><span class=\"bdt-newsletter-btn", $content);
	$content = str_replace("</div> </div> </button>", "</span></span></button>", $content);
	$content = str_replace("<div class=\"bdt-newsletter-btn", "<span class=\"bdt-newsletter-btn", $content);
}

return $content;
}, 10, 2 );
				
			
				
					// remove font-display: swap
function start_wp_head_buffer() {
    ob_start();
}

add_action('wp_head', 'start_wp_head_buffer', 0);

function end_wp_head_buffer() {
    $in = ob_get_clean();
    // remove font-display:swap;
    $in = str_replace('font-display:swap;', '', $in);
    echo $in; // output the result unless you want to remove it
}

add_action('wp_head', 'end_wp_head_buffer', PHP_INT_MAX);
				
			

If you want to replace <i> with <span> to pass accessibility, add this code:

				
					function callback($content) {
	// modify content here, and then return the updated code
	$content = str_replace("<i ", "<span ", $content);
	$content = str_replace("</i>", "</span>", $content);
	
	$content = str_replace("<a class=\"next", "<a title=\"next\" class=\"next", $content);
	
	$content = str_replace("<select name=\"orderby\"", "<select title=\"orderby\" name=\"orderby\"", $content);
	
	$content = str_replace("<select name=\"count\"", "<select title=\"count\" name=\"count\"", $content);
	
	
	$content = str_replace("<a href=\"\" class=\"bdt-navigation-prev", "<a title=\"bdt-navigation-prev\" href=\"\" class=\"bdt-navigation-prev", $content);
	$content = str_replace("<a href=\"\" class=\"bdt-navigation-next", "<a title=\"bdt-navigation-next\" href=\"\" class=\"bdt-navigation-next", $content);

    //Pattern to match only the content of h3
    $pattern = "|(?<=<h3 class=\"wd-entities-title\">)(.*?)(?=<\/h3>)|";
    //Pattern to match the whole h3 including the content
    $pattern = "/<h3 class=\"wd-entities-title\">(.*?)<\/h3>/";
    
    //$content = preg_replace($pattern, "<h4 class=\"wd-entities-title\">$1</h4>",$content);
    $content = preg_replace("/<h5 class=\"widget-title\">(.*?)<\/h5>/", "<div class=\"widget-title\">$1</div>",$content);
	
	return $content;
}

function buffer_start() { ob_start("callback"); }

function buffer_end() { ob_end_flush(); }

add_action('wp_head', 'buffer_start');
add_action('wp_footer', 'buffer_end');
				
			

If you use GDPR cookie consent plugin, just open the Settings > Customize Cookie bar and convert div to span.

Also click Privacy Overview menu button and remove title if you have one (to remove the headings error).

If you use a slick slider, and you get a aria-describedby error in wave, make sure that you show the bullets in slider (only bullets, not arrows). If this does not work, use a similar code to below.

				
					<script>
jQuery( document ).ready(function() {
	jQuery('.ht-products').each(function(){
		jQuery(this).on('init', function(event, slick){
			remove_aria_describedby(jQuery(this));
		});

		jQuery(this).on('afterChange', function(event, slick, currentSlide){
			remove_aria_describedby(jQuery(this));
		});

		jQuery(this).on('beforeChange', function(event, slick, currentSlide){
			remove_aria_describedby(jQuery(this));
		});
		
	});
	
	function remove_aria_describedby(el){
		console.log(el);
		jQuery('.ht-product').each(function () {
				//jQuery(this).removeAttr('aria-describedby');
				if (jQuery(this).attr('aria-describedby') != undefined) { // ignore extra/cloned slides
						jQuery(this).attr('id', jQuery(this).attr('aria-describedby'));
				}
		});
	}
});
</script>
				
			
				
					add_action( 'elementor/widget/render_content', function( $content, $widget ) {

	if ( 'wd_testimonials' === $widget->get_name() || 'wd_infobox' === $widget->get_name()) {
		$content = str_replace("<img ", "<img alt=/"/" ", $content);
	}
	if ( 'wd_blog' === $widget->get_name() ) {
		$content = str_replace("<h3 ", "<div ", $content);
		$content = str_replace("</h3>", "</div>", $content);
	}
	
	if ( 'wd_text_block' === $widget->get_name() ) {
		$style = "style='font-size: 18px; color:#242424; margin-bottom:20px; font-weight:600;'";
		$content = str_replace("<h4 ", "<div " . $style, $content);
		$content = str_replace("<h4>", "<div ".$style.">", $content);
		$content = str_replace("</h4>", "</div>", $content);
	}
	if ( 'wd_infobox' === $widget->get_name() ) {
		$content = str_replace("<h4", "<div" , $content);
		$content = str_replace("</h4>", "</div>", $content);
	}
	if ( 'sidebar' === $widget->get_name() ) {
		$content = str_replace("<h5", "<div" , $content); print_r('sidebar');
		//$content = str_replace("<h4>", "<div>", $content);
		$content = str_replace("</h5>", "</div>", $content);
	}
	

	return $content;
}, 10, 2 );

function callback($content) {
	// modify content here, and then return the updated code
	$content = str_replace("<i ", "<span ", $content);
	$content = str_replace("</i>", "</span>", $content);

	$content = str_replace("<a class=\"next", "<a title=\"next\" class=\"next", $content);

	$content = str_replace("<select name=\"orderby\"", "<select title=\"orderby\" name=\"orderby\"", $content);

	$content = str_replace("<select name=\"count\"", "<select title=\"count\" name=\"count\"", $content);

	
	
	$content = str_replace("<input type=\"text\" name=\"your-name\"", "<input title=\"your-name\" aria-label=\"NAME\" type=\"text\" name=\"your-name\"", $content);
	$content = str_replace("<input type=\"email\" aria-label=\"EMAIL\" name=\"your-email\"", "<input title=\"your-email\" type=\"email\" name=\"your-email\"", $content);
	$content = str_replace("<input type=\"tel\" name=\"tel-767\"", "<input title=\"tel-767\" type=\"tel\" name=\"tel-767\"", $content);
	$content = str_replace("<input type=\"text\" name=\"text-1\"", "<input title=\"text-1\" type=\"text\" name=\"text-1\"", $content);


	$content = str_replace("<textarea name=\"your-message\"", "<textarea title=\"your-message\" name=\"your-message\"", $content);
	$content = str_replace("<textarea name=\"g-recaptcha-response\"", "<textarea title=\"g-recaptcha-response\" name=\"g-recaptcha-response\"", $content);
	
	$content = str_replace("<a href=\"javascript:void(0);\"", "<a title=\"javascript-void\" href=\"javascript:void(0);\"", $content);
	$content = str_replace("<a href=\"#\"", "<a title=\"#\" href=\"#\"", $content);
	$content = str_replace("<a rel=\"noopener", "<a title=\"noopener\" rel=\"noopener", $content);
	$content = str_replace("<a rel=\"nofollow", "<a title=\"nofollow\" rel=\"nofollow", $content);
	
	
	$content = str_replace("<svg version=\"1.1\" id=\"Layer_1\"", "<svg version=\"1.1\"", $content);
	
	

    //Pattern to match only the content of h3
    $pattern = "|(?<=<h3 class=\"wd-entities-title\">)(.*?)(?=<\/h3>)|";
    //Pattern to match the whole h3 including the content
    $pattern = "/<h3 class=\"wd-entities-title\">(.*?)<\/h3>/";

    //$content = preg_replace($pattern, "<h4 class=\"wd-entities-title\">$1</h4>",$content);
    //$content = preg_replace("/<h5 class=\"widget-title\">(.*?)<\/h5>/", "<div class=\"widget-title\">$1</div>",$content);
	
	
	$content = preg_replace($pattern, "<div class=\"wd-entities-title\">$1</div>",$content);
	
	$content = preg_replace("/<h3 class=\"title slider-title\">(.*?)<\/h3>/", "<div class=\"title slider-title\">$1</div>",$content);
	$content = preg_replace("/<h5 class=\"widget-title\">(.*?)<\/h5>/", "<div class=\"widget-title\">$1</div>",$content);
	$content = preg_replace("/<h3 class=\"widget-title\">(.*?)<\/h3>/", "<div class=\"widget-title\">$1</div>",$content);
	
	
	$content = preg_replace("/<h5 class=\"wd-entities-title\">(.*?)<\/h5>/", "<div class=\"wd-entities-title\">$1</div>",$content);

	//$content = preg_replace("/<h3 class=\"wd-entities-title title post-title\">(.*?)<\/h3>/", "<div class=\"wd-entities-title title post-title\">$1</div>",$content);
	return $content;
}

function buffer_start() { ob_start("callback"); }

function buffer_end() { ob_end_flush(); }

add_action('wp_head', 'buffer_start');
add_action('wp_footer', 'buffer_end');
				
			

If you use revolution slider, open wp-content\plugins\revslider\public\revslider-front.class.php and comment this line in 150:

				
					$custom_css = (trim($custom_css) == '') ? '#rs-demo-id {}' : $custom_css;


				
			

If you use porto theme and you have errors in css, go THEME OPTIONS -> SKIN -> CSTOM CSS and check there. Also, inline style errors may be from blocks from template builer. You must remake them with elementor.

Alt images

Make sure that all your images have alt text

Acchecker

Go to acchecker site and run it for your site. Make sure no errors exist.

Wave checker

Add in chrome wave checker and see that no errors exist.