Alternative #markup in a block's build function Version: Drupal 8.7.x

I am adding some canvas element to my page, and it gets ignored by Drupal. I can't even see it in the source page of browser.

If I have something like this in my code:

public function build(){
   $content = "&lt;span&gt;Something&lt;/span&gt;&lt;canvas id='12' width='100' height='100'&gt;
               &lt;/canvas&gt;"
   return ['#markup'=&gt;$content]; 
}


View page source will only shows

 &lt;span&gt;Something&lt;/span&gt;


I was thinking that this might be an issue with the #markup. I was wondering if there are any alternative way to work with canvas.
You can use #allowed_tags on the markup.

So put it like that:

  $content = "&lt;span&gt;Something&lt;/span&gt;&lt;canvas id='12' width='100' height='100'&gt;
               &lt;/canvas&gt;"
   return [
     '#markup' =&gt; $content,
     '#allowed_tags' =&gt; [
       'canvas',
       'span'
     ]
   ];


not exactly sure if you need to add the span tag.

But also note that following is suggested as Drupal Best Practice from https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21theme.api.php/group/theme_render/8.7.x:


  #markup: Specifies that the array provides HTML markup directly. Unless 
  the markup is very simple, such as an explanation in a paragraph tag, it
  is normally preferable to use #theme or #type instead, so that the
  theme can customize the markup


And this is the explanation from Drupal regarding #markup and tags:


  Note that the value is passed through
  \Drupal\Component\Utility\Xss::filterAdmin(), which strips known XSS
  vectors while allowing a permissive list of HTML tags that are not XSS
  vectors. (For example,  and  are not allowed.) See
  \Drupal\Component\Utility\Xss::$adminTags for the list of allowed
  tags. If your markup needs any of the tags not in this whitelist, then
  you can implement a theme hook and/or an asset library. Alternatively,
  you can use the key #allowed_tags to alter which tags are filtered.