diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst
index 17d8c79994dbe..895c21e79886f 100644
--- a/doc/source/whatsnew/v1.3.0.rst
+++ b/doc/source/whatsnew/v1.3.0.rst
@@ -448,7 +448,7 @@ Other
- :meth:`Index.where` behavior now mirrors :meth:`Index.putmask` behavior, i.e. ``index.where(mask, other)`` matches ``index.putmask(~mask, other)`` (:issue:`39412`)
- Bug in :func:`pandas.testing.assert_series_equal`, :func:`pandas.testing.assert_frame_equal`, :func:`pandas.testing.assert_index_equal` and :func:`pandas.testing.assert_extension_array_equal` incorrectly raising when an attribute has an unrecognized NA type (:issue:`39461`)
- Bug in :class:`Styler` where ``subset`` arg in methods raised an error for some valid multiindex slices (:issue:`33562`)
--
+- :class:`Styler` rendered HTML output minor alterations to support w3 good code standard (:issue:`39626`)
-
.. ---------------------------------------------------------------------------
diff --git a/pandas/io/formats/templates/html.tpl b/pandas/io/formats/templates/html.tpl
index 97bfda9af089d..b315c57a65cdf 100644
--- a/pandas/io/formats/templates/html.tpl
+++ b/pandas/io/formats/templates/html.tpl
@@ -1,70 +1,70 @@
{# Update the template_structure.html document too #}
{%- block before_style -%}{%- endblock before_style -%}
{% block style %}
-
-{%- endblock style %}
-{%- block before_table %}{% endblock before_table %}
-{%- block table %}
-
-{%- block caption %}
-{%- if caption -%}
- {{caption}}
-{%- endif -%}
-{%- endblock caption %}
-{%- block thead %}
-
- {%- block before_head_rows %}{% endblock %}
- {%- for r in head %}
- {%- block head_tr scoped %}
+{% endblock style %}
+{% block before_table %}{% endblock before_table %}
+{% block table %}
+
+{% block caption %}
+{% if caption %}
+ {{caption}}
+{% endif %}
+{% endblock caption %}
+{% block thead %}
+
+{% block before_head_rows %}{% endblock %}
+{% for r in head %}
+{% block head_tr scoped %}
- {%- for c in r %}
- {%- if c.is_visible != False %}
- <{{ c.type }} class="{{c.class}}" {{ c.attributes|join(" ") }}>{{c.value}}{{ c.type }}>
- {%- endif %}
- {%- endfor %}
+{% for c in r %}
+{% if c.is_visible != False %}
+ <{{c.type}} class="{{c.class}}" {{c.attributes|join(" ")}}>{{c.value}}{{c.type}}>
+{% endif %}
+{% endfor %}
- {%- endblock head_tr %}
- {%- endfor %}
- {%- block after_head_rows %}{% endblock %}
-
-{%- endblock thead %}
-{%- block tbody %}
-
- {% block before_rows %}{% endblock before_rows %}
- {% for r in body %}
- {% block tr scoped %}
+{% endblock head_tr %}
+{% endfor %}
+{% block after_head_rows %}{% endblock %}
+
+{% endblock thead %}
+{% block tbody %}
+
+{% block before_rows %}{% endblock before_rows %}
+{% for r in body %}
+{% block tr scoped %}
- {% for c in r %}
- {% if c.is_visible != False %}
- <{{ c.type }} {% if c.id is defined -%} id="T_{{ uuid }}{{ c.id }}" {%- endif %} class="{{ c.class }}" {{ c.attributes|join(" ") }}>{{ c.display_value }}{{ c.type }}>
- {% endif %}
- {%- endfor %}
+{% for c in r %}
+{% if c.is_visible != False %}
+ <{{c.type}} {% if c.id is defined -%} id="T_{{uuid}}{{c.id}}" {%- endif %} class="{{c.class}}" {{c.attributes|join(" ")}}>{{c.display_value}}{{c.type}}>
+{% endif %}
+{% endfor %}
- {% endblock tr %}
- {%- endfor %}
- {%- block after_rows %}{%- endblock after_rows %}
-
-{%- endblock tbody %}
+{% endblock tr %}
+{% endfor %}
+{% block after_rows %}{% endblock after_rows %}
+
+{% endblock tbody %}
-{%- endblock table %}
-{%- block after_table %}{% endblock after_table %}
+{% endblock table %}
+{% block after_table %}{% endblock after_table %}
diff --git a/pandas/tests/io/formats/test_style.py b/pandas/tests/io/formats/test_style.py
index d2c5b5b9d0b2c..0bd0c5bd87761 100644
--- a/pandas/tests/io/formats/test_style.py
+++ b/pandas/tests/io/formats/test_style.py
@@ -140,8 +140,8 @@ def test_multiple_render(self):
s = Styler(self.df, uuid_len=0).applymap(lambda x: "color: red;", subset=["A"])
s.render() # do 2 renders to ensure css styles not duplicated
assert (
- '" in s.render()
+ '" in s.render()
)
def test_render_empty_dfs(self):
@@ -1794,11 +1794,11 @@ def test_column_and_row_styling(self):
df = DataFrame(data=[[0, 1], [1, 2]], columns=["A", "B"])
s = Styler(df, uuid_len=0)
s = s.set_table_styles({"A": [{"selector": "", "props": [("color", "blue")]}]})
- assert "#T__ .col0 {\n color: blue;\n }" in s.render()
+ assert "#T__ .col0 {\n color: blue;\n}" in s.render()
s = s.set_table_styles(
{0: [{"selector": "", "props": [("color", "blue")]}]}, axis=1
)
- assert "#T__ .row0 {\n color: blue;\n }" in s.render()
+ assert "#T__ .row0 {\n color: blue;\n}" in s.render()
def test_colspan_w3(self):
# GH 36223
@@ -1855,12 +1855,12 @@ def test_tooltip_render(self, ttips):
s = Styler(df, uuid_len=0).set_tooltips(ttips).render()
# test tooltip table level class
- assert "#T__ .pd-t {\n visibility: hidden;\n" in s
+ assert "#T__ .pd-t {\n visibility: hidden;\n" in s
# test 'Min' tooltip added
assert (
- "#T__ #T__row0_col0:hover .pd-t {\n visibility: visible;\n } "
- + ' #T__ #T__row0_col0 .pd-t::after {\n content: "Min";\n }'
+ "#T__ #T__row0_col0:hover .pd-t {\n visibility: visible;\n}\n"
+ + '#T__ #T__row0_col0 .pd-t::after {\n content: "Min";\n}'
in s
)
assert (
@@ -1871,8 +1871,8 @@ def test_tooltip_render(self, ttips):
# test 'Max' tooltip added
assert (
- "#T__ #T__row0_col1:hover .pd-t {\n visibility: visible;\n } "
- + ' #T__ #T__row0_col1 .pd-t::after {\n content: "Max";\n }'
+ "#T__ #T__row0_col1:hover .pd-t {\n visibility: visible;\n}\n"
+ + '#T__ #T__row0_col1 .pd-t::after {\n content: "Max";\n}'
in s
)
assert (
@@ -1892,16 +1892,16 @@ def test_tooltip_reindex(self):
index=[0, 2],
)
s = Styler(df, uuid_len=0).set_tooltips(DataFrame(ttips)).render()
- assert '#T__ #T__row0_col0 .pd-t::after {\n content: "Mi";\n }' in s
- assert '#T__ #T__row0_col2 .pd-t::after {\n content: "Ma";\n }' in s
- assert '#T__ #T__row2_col0 .pd-t::after {\n content: "Mu";\n }' in s
- assert '#T__ #T__row2_col2 .pd-t::after {\n content: "Mo";\n }' in s
+ assert '#T__ #T__row0_col0 .pd-t::after {\n content: "Mi";\n}' in s
+ assert '#T__ #T__row0_col2 .pd-t::after {\n content: "Ma";\n}' in s
+ assert '#T__ #T__row2_col0 .pd-t::after {\n content: "Mu";\n}' in s
+ assert '#T__ #T__row2_col2 .pd-t::after {\n content: "Mo";\n}' in s
def test_tooltip_ignored(self):
# GH 21266
df = DataFrame(data=[[0, 1], [2, 3]])
s = Styler(df).set_tooltips_class("pd-t").render() # no set_tooltips()
- assert '' in s
+ assert '' in s
assert '' not in s
def test_tooltip_class(self):
@@ -1913,11 +1913,8 @@ def test_tooltip_class(self):
.set_tooltips_class(name="other-class", properties=[("color", "green")])
.render()
)
- assert "#T__ .other-class {\n color: green;\n" in s
- assert (
- '#T__ #T__row0_col0 .other-class::after {\n content: "tooltip";\n'
- in s
- )
+ assert "#T__ .other-class {\n color: green;\n" in s
+ assert '#T__ #T__row0_col0 .other-class::after {\n content: "tooltip";\n' in s
# GH 39563
s = (
@@ -1926,10 +1923,50 @@ def test_tooltip_class(self):
.set_tooltips_class(name="other-class", properties="color:green;color:red;")
.render()
)
- assert (
- "#T__ .other-class {\n color: green;\n color: red;\n "
- in s
+ assert "#T__ .other-class {\n color: green;\n color: red;\n}" in s
+
+ def test_w3_html_format(self):
+ s = (
+ Styler(
+ DataFrame([[2.61], [2.69]], index=["a", "b"], columns=["A"]),
+ uuid_len=0,
+ )
+ .set_table_styles([{"selector": "th", "props": "att2:v2;"}])
+ .applymap(lambda x: "att1:v1;")
+ .set_table_attributes('class="my-cls1" style="attr3:v3;"')
+ .set_td_classes(DataFrame(["my-cls2"], index=["a"], columns=["A"]))
+ .format("{:.1f}")
+ .set_caption("A comprehensive test")
)
+ expected = """
+
+ A comprehensive test
+
+
+ |
+ A |
+
+
+
+
+ a |
+ 2.6 |
+
+
+ b |
+ 2.7 |
+
+
+
+"""
+ assert expected == s.render()
@td.skip_if_no_mpl