diff --git a/branca/element.py b/branca/element.py
index 853ca16..504e7cc 100644
--- a/branca/element.py
+++ b/branca/element.py
@@ -328,7 +328,8 @@ class Figure(Element):
A percentage defining the aspect ratio of the Figure.
It will be ignored if height is not None.
title : str, default None
- Figure title.
+ Figure title. Also used as the ``title`` attribute (accessible
+ name) of the iframe when the Figure is displayed in a notebook.
figsize : tuple of two int, default None
If you're a matplotlib addict, you can overwrite width and
height. Values will be converted into pixels in using 60 dpi.
@@ -412,24 +413,37 @@ def render(self, **kwargs) -> str:
def _repr_html_(self, **kwargs) -> str:
"""Displays the Figure in a Jupyter notebook."""
html = escape(self.render(**kwargs))
+ # Give the iframe an accessible name when a title is set, so it is
+ # not flagged by "frames must have an accessible name" audits.
+ title_attr = f' title="{escape(self.title)}"' if self.title else ""
if self.height is None:
iframe = (
'
'
'
' # noqa
'Make this Notebook Trusted to load map: File -> Trust Notebook' # noqa
- '"
"
"
- ).format(html=html, width=self.width, ratio=self.ratio)
+ ).format(
+ html=html,
+ width=self.width,
+ ratio=self.ratio,
+ title_attr=title_attr,
+ )
else:
iframe = (
- '"
- ).format(html=html, width=self.width, height=self.height)
+ ).format(
+ html=html,
+ width=self.width,
+ height=self.height,
+ title_attr=title_attr,
+ )
return iframe
def add_subplot(self, x: int, y: int, n: int, margin: float = 0.05) -> "Div":
@@ -640,6 +654,10 @@ class IFrame(Element):
height. Values will be converted into pixels in using 60 dpi.
For example figsize=(10, 5) will result in
width="600px", height="300px".
+ title : str, default None
+ Value for the iframe's ``title`` attribute, used as the frame's
+ accessible name. Set it to satisfy accessibility audits that
+ require every frame to have an accessible name.
"""
def __init__(
@@ -649,10 +667,12 @@ def __init__(
height: Optional[str] = None,
ratio: str = "60%",
figsize: Optional[Tuple[int, int]] = None,
+ title: Optional[str] = None,
):
super().__init__()
self._name = "IFrame"
+ self.title = title
self.width = width
self.height = height
self.ratio = ratio
@@ -671,21 +691,32 @@ def render(self, **kwargs) -> str:
html = "data:text/html;charset=utf-8;base64," + base64.b64encode(
html.encode("utf8"),
).decode("utf8")
+ title_attr = f' title="{escape(self.title)}"' if self.title else ""
if self.height is None:
iframe = (
'"
- ).format(html=html, width=self.width, ratio=self.ratio)
+ ).format(
+ html=html,
+ width=self.width,
+ ratio=self.ratio,
+ title_attr=title_attr,
+ )
else:
iframe = (
- ''
- ).format(html=html, width=self.width, height=self.height)
+ ).format(
+ html=html,
+ width=self.width,
+ height=self.height,
+ title_attr=title_attr,
+ )
return iframe
diff --git a/tests/test_element.py b/tests/test_element.py
new file mode 100644
index 0000000..934703a
--- /dev/null
+++ b/tests/test_element.py
@@ -0,0 +1,76 @@
+"""
+Tests for branca.element
+------------------------
+"""
+
+from html.parser import HTMLParser
+
+import branca.element as elem
+
+
+class _IframeAttrs(HTMLParser):
+ """Collect the attributes of every