Unlike example blocks, source code and fixed-width blocks don't support the attr_html keyword. Contrast these outputs: #+begin_src emacs-lisp :results value replace :wrap src html (require 'org) (require 'ox-html) (org-export-string-as "#+attr_html: :class foo ,#+begin_src sh :exports code pwd ,#+end_src" 'html t) #+end_src #+RESULTS: #+begin_src html
pwd
#+end_src #+begin_src emacs-lisp :results value replace :wrap src html (require 'org) (require 'ox-html) (org-export-string-as "#+attr_html: :class foo ,#+RESULTS: : blah" 'html t) #+end_src #+RESULTS: #+begin_src html
blah
#+end_src With the output for example blocks: #+begin_src emacs-lisp :results value replace :wrap src html (require 'org) (require 'ox-html) (org-export-string-as "#+attr_html: :class foo ,#+begin_example hello world! ,#+end_example" 'html t) #+end_src #+RESULTS: #+begin_src html
hello world!
#+end_src The attached patches are a straight-forward copy-paste of relevant code from org-html-example-block. It may be better to refactor this logic and ensure that it is applied on all relevant AST nodes (others are probably affected as well).