diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,7 @@
+# Changelog for skylighting-format-blaze-html
+
+## 0.1.1
+
+* Export `formatHtml4Block`, which should be used instead of
+  `formatHtmlBlock` if HTML4 compliance is required.
+
diff --git a/skylighting-format-blaze-html.cabal b/skylighting-format-blaze-html.cabal
--- a/skylighting-format-blaze-html.cabal
+++ b/skylighting-format-blaze-html.cabal
@@ -1,5 +1,5 @@
 name:                skylighting-format-blaze-html
-version:             0.1
+version:             0.1.1
 synopsis:            HTML formatter for skylighting syntax highlighting library
 description:         This module allows tokens produced by skylighting-core
                      to be rendered as HTML.
@@ -11,7 +11,7 @@
 copyright:           (C) 2016-2022 John MacFarlane
 category:            Text
 build-type:          Simple
-extra-source-files:  README.md
+extra-source-files:  README.md, changelog.md
 
 cabal-version:       >=1.10
 
diff --git a/src/Skylighting/Format/HTML.hs b/src/Skylighting/Format/HTML.hs
--- a/src/Skylighting/Format/HTML.hs
+++ b/src/Skylighting/Format/HTML.hs
@@ -3,6 +3,7 @@
 module Skylighting.Format.HTML (
       formatHtmlInline
     , formatHtmlBlock
+    , formatHtml4Block
     , styleToCss
     ) where
 
@@ -64,12 +65,23 @@
 -- CSS.  See the documentation for 'formatHtmlInline' for information about how
 -- tokens are encoded.
 formatHtmlBlock :: FormatOptions -> [SourceLine] -> Html
-formatHtmlBlock opts ls =
+formatHtmlBlock = formatHtmlBlockFor Html5
+
+-- | Like 'formatHtmlBlock' but uses only attributes valid in HTML 4
+-- (so, @aria-hidden@ is not used in empty line number spans).
+formatHtml4Block :: FormatOptions -> [SourceLine] -> Html
+formatHtml4Block = formatHtmlBlockFor Html4
+
+data HtmlVersion = Html4 | Html5
+  deriving (Show, Eq)
+
+formatHtmlBlockFor :: HtmlVersion -> FormatOptions -> [SourceLine] -> Html
+formatHtmlBlockFor htmlVersion opts ls =
   H.div ! A.class_ (toValue "sourceCode") $
   H.pre ! A.class_ (toValue $ Text.unwords classes)
         $ wrapCode opts
         $ mconcat . intersperse (toHtml "\n")
-        $ zipWith (sourceLineToHtml opts) [startNum..] ls
+        $ zipWith (sourceLineToHtml htmlVersion opts) [startNum..] ls
   where  classes = Text.pack "sourceCode" :
                    [Text.pack "numberSource" | numberLines opts] ++
                    [x | x <- containerClasses opts
@@ -87,12 +99,12 @@
 
 -- | Each line of source is wrapped in an (inline-block) anchor that makes
 -- subsequent per-line processing (e.g. adding line numnbers) possible.
-sourceLineToHtml :: FormatOptions -> LineNo -> SourceLine -> Html
-sourceLineToHtml opts lno cont =
+sourceLineToHtml :: HtmlVersion -> FormatOptions -> LineNo -> SourceLine -> Html
+sourceLineToHtml htmlVersion opts lno cont =
   H.span ! A.id lineNum
          $ do
            H.a ! A.href lineRef
-               ! (if numberLines opts
+               ! (if numberLines opts || htmlVersion == Html4
                      then mempty
                      else customAttribute (fromString "aria-hidden")
                            (fromString "true")) -- see jgm/pandoc#6352
