Repository: pandas-dev/pandas

Issue:
Columns Index Name with to_html(index_names=False) is displayed.
#### Code Sample

```python
df = pd.DataFrame(np.zeros((2, 2), dtype=int))
df.columns.name = 'columns.name'
df.to_html(index_names=False)
```

#### Output

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th>columns.name</th>
      <th>0</th>
      <th>1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <th>1</th>
      <td>0</td>
      <td>0</td>
    </tr>
  </tbody>
</table>

#### Problem description

from the docs:

index_names : bool, optional
Prints the names of the indexes, default True

The problem occurs with both standard and MultiIndex columns index. The expected behavior is observed on the (row) Index, if it has names they are not displayed.

#### Expected Output

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>0</th>
      <th>1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <th>1</th>
      <td>0</td>
      <td>0</td>
    </tr>
  </tbody>
</table>

#### Output of ``pd.show_versions()``

<details>

[paste the output of ``pd.show_versions()`` here below this line]

</details>



Discussion:

Resolving patch:
diff --git a/pandas/io/formats/html.py b/pandas/io/formats/html.py
--- a/pandas/io/formats/html.py
+++ b/pandas/io/formats/html.py
@@ -43,6 +43,35 @@ def __init__(self, formatter, classes=None, notebook=False, border=None,
         self.table_id = table_id
         self.render_links = render_links
 
+    @property
+    def show_col_idx_names(self):
+        # see gh-22579
+        # Column misalignment also occurs for
+        # a standard index when the columns index is named.
+        # Determine if ANY column names need to be displayed
+        # since if the row index is not displayed a column of
+        # blank cells need to be included before the DataFrame values.
+        # TODO: refactor to add show_col_idx_names property to
+        # DataFrameFormatter
+        return all((self.fmt.has_column_names,
+                    self.fmt.show_index_names,
+                    self.fmt.header))
+
+    @property
+    def row_levels(self):
+        if self.fmt.index:
+            # showing (row) index
+            return self.frame.index.nlevels
+        elif self.show_col_idx_names:
+            # see gh-22579
+            # Column misalignment also occurs for
+            # a standard index when the columns index is named.
+            # If the row index is not displayed a column of
+            # blank cells need to be included before the DataFrame values.
+            return 1
+        # not showing (row) index
+        return 0
+
     @property
     def is_truncated(self):
         return self.fmt.is_truncated
@@ -201,7 +230,7 @@ def write_result(self, buf):
 
     def _write_header(self, indent):
         truncate_h = self.fmt.truncate_h
-        row_levels = self.frame.index.nlevels
+
         if not self.fmt.header:
             # write nothing
             return indent
@@ -267,12 +296,26 @@ def _write_header(self, indent):
                         values = (values[:ins_col] + [u('...')] +
                                   values[ins_col:])
 
-                name = self.columns.names[lnum]
-                row = [''] * (row_levels - 1) + ['' if name is None else
-                                                 pprint_thing(name)]
-
-                if row == [""] and self.fmt.index is False:
-                    row = []
+                # see gh-22579
+                # Column Offset Bug with to_html(index=False) with
+                # MultiIndex Columns and Index.
+                # Initially fill row with blank cells before column names.
+                # TODO: Refactor to remove code duplication with code
+                # block below for standard columns index.
+                row = [''] * (self.row_levels - 1)
+                if self.fmt.index or self.show_col_idx_names:
+                    # see gh-22747
+                    # If to_html(index_names=False) do not show columns
+                    # index names.
+                    # TODO: Refactor to use _get_column_name_list from
+                    # DataFrameFormatter class and create a
+                    # _get_formatted_column_labels function for code
+                    # parity with DataFrameFormatter class.
+                    if self.fmt.show_index_names:
+                        name = self.columns.names[lnum]
+                        row.append(pprint_thing(name or ''))
+                    else:
+                        row.append('')
 
                 tags = {}
                 j = len(row)
@@ -287,18 +330,28 @@ def _write_header(self, indent):
                 self.write_tr(row, indent, self.indent_delta, tags=tags,
                               header=True)
         else:
-            if self.fmt.index:
-                row = [''] * (self.frame.index.nlevels - 1)
-                row.append(self.columns.name or '')
-            else:
-                row = []
+            # see gh-22579
+            # Column misalignment also occurs for
+            # a standard index when the columns index is named.
+            # Initially fill row with blank cells before column names.
+            # TODO: Refactor to remove code duplication with code block
+            # above for columns MultiIndex.
+            row = [''] * (self.row_levels - 1)
+            if self.fmt.index or self.show_col_idx_names:
+                # see gh-22747
+                # If to_html(index_names=False) do not show columns
+                # index names.
+                # TODO: Refactor to use _get_column_name_list from
+                # DataFrameFormatter class.
+                if self.fmt.show_index_names:
+                    row.append(self.columns.name or '')
+                else:
+                    row.append('')
             row.extend(self.columns)
             align = self.fmt.justify
 
             if truncate_h:
-                if not self.fmt.index:
-                    row_levels = 0
-                ins_col = row_levels + self.fmt.tr_col_num
+                ins_col = self.row_levels + self.fmt.tr_col_num
                 row.insert(ins_col, '...')
 
             self.write_tr(row, indent, self.indent_delta, header=True,
@@ -346,9 +399,6 @@ def _write_regular_rows(self, fmt_values, indent):
                 index_values = self.fmt.tr_frame.index.map(fmt)
             else:
                 index_values = self.fmt.tr_frame.index.format()
-            row_levels = 1
-        else:
-            row_levels = 0
 
         row = []
         for i in range(nrows):
@@ -356,18 +406,24 @@ def _write_regular_rows(self, fmt_values, indent):
             if truncate_v and i == (self.fmt.tr_row_num):
                 str_sep_row = ['...'] * len(row)
                 self.write_tr(str_sep_row, indent, self.indent_delta,
-                              tags=None, nindex_levels=row_levels)
+                              tags=None, nindex_levels=self.row_levels)
 
             row = []
             if self.fmt.index:
                 row.append(index_values[i])
+            # see gh-22579
+            # Column misalignment also occurs for
+            # a standard index when the columns index is named.
+            # Add blank cell before data cells.
+            elif self.show_col_idx_names:
+                row.append('')
             row.extend(fmt_values[j][i] for j in range(self.ncols))
 
             if truncate_h:
-                dot_col_ix = self.fmt.tr_col_num + row_levels
+                dot_col_ix = self.fmt.tr_col_num + self.row_levels
                 row.insert(dot_col_ix, '...')
             self.write_tr(row, indent, self.indent_delta, tags=None,
-                          nindex_levels=row_levels)
+                          nindex_levels=self.row_levels)
 
     def _write_hierarchical_rows(self, fmt_values, indent):
         template = 'rowspan="{span}" valign="top"'
@@ -376,6 +432,8 @@ def _write_hierarchical_rows(self, fmt_values, indent):
         truncate_v = self.fmt.truncate_v
         frame = self.fmt.tr_frame
         nrows = len(frame)
+        # TODO: after gh-22887 fixed, refactor to use class property
+        # in place of row_levels
         row_levels = self.frame.index.nlevels
 
         idx_values = frame.index.format(sparsify=False, adjoin=False,


Test patch:
diff --git a/pandas/tests/io/formats/data/datetime64_hourformatter.html b/pandas/tests/io/formats/data/html/datetime64_hourformatter.html
similarity index 100%
rename from pandas/tests/io/formats/data/datetime64_hourformatter.html
rename to pandas/tests/io/formats/data/html/datetime64_hourformatter.html
diff --git a/pandas/tests/io/formats/data/datetime64_monthformatter.html b/pandas/tests/io/formats/data/html/datetime64_monthformatter.html
similarity index 100%
rename from pandas/tests/io/formats/data/datetime64_monthformatter.html
rename to pandas/tests/io/formats/data/html/datetime64_monthformatter.html
diff --git a/pandas/tests/io/formats/data/escape_disabled.html b/pandas/tests/io/formats/data/html/escape_disabled.html
similarity index 100%
rename from pandas/tests/io/formats/data/escape_disabled.html
rename to pandas/tests/io/formats/data/html/escape_disabled.html
diff --git a/pandas/tests/io/formats/data/escaped.html b/pandas/tests/io/formats/data/html/escaped.html
similarity index 100%
rename from pandas/tests/io/formats/data/escaped.html
rename to pandas/tests/io/formats/data/html/escaped.html
diff --git a/pandas/tests/io/formats/data/gh12031_expected_output.html b/pandas/tests/io/formats/data/html/gh12031_expected_output.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh12031_expected_output.html
rename to pandas/tests/io/formats/data/html/gh12031_expected_output.html
diff --git a/pandas/tests/io/formats/data/gh14882_expected_output_1.html b/pandas/tests/io/formats/data/html/gh14882_expected_output_1.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh14882_expected_output_1.html
rename to pandas/tests/io/formats/data/html/gh14882_expected_output_1.html
diff --git a/pandas/tests/io/formats/data/gh14882_expected_output_2.html b/pandas/tests/io/formats/data/html/gh14882_expected_output_2.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh14882_expected_output_2.html
rename to pandas/tests/io/formats/data/html/gh14882_expected_output_2.html
diff --git a/pandas/tests/io/formats/data/gh14998_expected_output.html b/pandas/tests/io/formats/data/html/gh14998_expected_output.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh14998_expected_output.html
rename to pandas/tests/io/formats/data/html/gh14998_expected_output.html
diff --git a/pandas/tests/io/formats/data/gh15019_expected_output.html b/pandas/tests/io/formats/data/html/gh15019_expected_output.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh15019_expected_output.html
rename to pandas/tests/io/formats/data/html/gh15019_expected_output.html
diff --git a/pandas/tests/io/formats/data/gh21625_expected_output.html b/pandas/tests/io/formats/data/html/gh21625_expected_output.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh21625_expected_output.html
rename to pandas/tests/io/formats/data/html/gh21625_expected_output.html
diff --git a/pandas/tests/io/formats/data/gh22270_expected_output.html b/pandas/tests/io/formats/data/html/gh22270_expected_output.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh22270_expected_output.html
rename to pandas/tests/io/formats/data/html/gh22270_expected_output.html
diff --git a/pandas/tests/io/formats/data/html/gh22579_expected_output.html b/pandas/tests/io/formats/data/html/gh22579_expected_output.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/gh22579_expected_output.html
@@ -0,0 +1,76 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th colspan="2" halign="left">a</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th>c</th>
+      <th>d</th>
+      <th>c</th>
+      <th>d</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>0</td>
+      <td>10</td>
+      <td>10</td>
+      <td>10</td>
+    </tr>
+    <tr>
+      <td>1</td>
+      <td>11</td>
+      <td>11</td>
+      <td>11</td>
+    </tr>
+    <tr>
+      <td>2</td>
+      <td>12</td>
+      <td>12</td>
+      <td>12</td>
+    </tr>
+    <tr>
+      <td>3</td>
+      <td>13</td>
+      <td>13</td>
+      <td>13</td>
+    </tr>
+    <tr>
+      <td>4</td>
+      <td>14</td>
+      <td>14</td>
+      <td>14</td>
+    </tr>
+    <tr>
+      <td>5</td>
+      <td>15</td>
+      <td>15</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <td>6</td>
+      <td>16</td>
+      <td>16</td>
+      <td>16</td>
+    </tr>
+    <tr>
+      <td>7</td>
+      <td>17</td>
+      <td>17</td>
+      <td>17</td>
+    </tr>
+    <tr>
+      <td>8</td>
+      <td>18</td>
+      <td>18</td>
+      <td>18</td>
+    </tr>
+    <tr>
+      <td>9</td>
+      <td>19</td>
+      <td>19</td>
+      <td>19</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/gh22783_expected_output.html b/pandas/tests/io/formats/data/html/gh22783_expected_output.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh22783_expected_output.html
rename to pandas/tests/io/formats/data/html/gh22783_expected_output.html
diff --git a/pandas/tests/io/formats/data/html/gh22783_named_columns_index.html b/pandas/tests/io/formats/data/html/gh22783_named_columns_index.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/gh22783_named_columns_index.html
@@ -0,0 +1,30 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>3</th>
+      <th>4</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th></th>
+      <td>1.764052</td>
+      <td>0.400157</td>
+      <td>...</td>
+      <td>2.240893</td>
+      <td>1.867558</td>
+    </tr>
+    <tr>
+      <th></th>
+      <td>-0.977278</td>
+      <td>0.950088</td>
+      <td>...</td>
+      <td>-0.103219</td>
+      <td>0.410599</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/gh6131_expected_output.html b/pandas/tests/io/formats/data/html/gh6131_expected_output.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh6131_expected_output.html
rename to pandas/tests/io/formats/data/html/gh6131_expected_output.html
diff --git a/pandas/tests/io/formats/data/gh8452_expected_output.html b/pandas/tests/io/formats/data/html/gh8452_expected_output.html
similarity index 100%
rename from pandas/tests/io/formats/data/gh8452_expected_output.html
rename to pandas/tests/io/formats/data/html/gh8452_expected_output.html
diff --git a/pandas/tests/io/formats/data/index_1.html b/pandas/tests/io/formats/data/html/index_1.html
similarity index 100%
rename from pandas/tests/io/formats/data/index_1.html
rename to pandas/tests/io/formats/data/html/index_1.html
diff --git a/pandas/tests/io/formats/data/index_2.html b/pandas/tests/io/formats/data/html/index_2.html
similarity index 100%
rename from pandas/tests/io/formats/data/index_2.html
rename to pandas/tests/io/formats/data/html/index_2.html
diff --git a/pandas/tests/io/formats/data/index_3.html b/pandas/tests/io/formats/data/html/index_3.html
similarity index 100%
rename from pandas/tests/io/formats/data/index_3.html
rename to pandas/tests/io/formats/data/html/index_3.html
diff --git a/pandas/tests/io/formats/data/index_4.html b/pandas/tests/io/formats/data/html/index_4.html
similarity index 100%
rename from pandas/tests/io/formats/data/index_4.html
rename to pandas/tests/io/formats/data/html/index_4.html
diff --git a/pandas/tests/io/formats/data/index_5.html b/pandas/tests/io/formats/data/html/index_5.html
similarity index 100%
rename from pandas/tests/io/formats/data/index_5.html
rename to pandas/tests/io/formats/data/html/index_5.html
diff --git a/pandas/tests/io/formats/data/index_formatter.html b/pandas/tests/io/formats/data/html/index_formatter.html
similarity index 100%
rename from pandas/tests/io/formats/data/index_formatter.html
rename to pandas/tests/io/formats/data/html/index_formatter.html
diff --git a/pandas/tests/io/formats/data/html/index_named_multi_columns_named_multi.html b/pandas/tests/io/formats/data/html/index_named_multi_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_named_multi_columns_named_multi.html
@@ -0,0 +1,34 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th>columns.name.0</th>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th>columns.name.1</th>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+    <tr>
+      <th>index.name.0</th>
+      <th>index.name.1</th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th>b</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>c</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_named_multi_columns_named_standard.html b/pandas/tests/io/formats/data/html/index_named_multi_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_named_multi_columns_named_standard.html
@@ -0,0 +1,29 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+    </tr>
+    <tr>
+      <th>index.name.0</th>
+      <th>index.name.1</th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th>b</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>c</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_named_multi_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/index_named_multi_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_named_multi_columns_unnamed_multi.html
@@ -0,0 +1,34 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th></th>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+    <tr>
+      <th>index.name.0</th>
+      <th>index.name.1</th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th>b</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>c</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_named_multi_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/index_named_multi_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_named_multi_columns_unnamed_standard.html
@@ -0,0 +1,29 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th></th>
+      <th>0</th>
+      <th>1</th>
+    </tr>
+    <tr>
+      <th>index.name.0</th>
+      <th>index.name.1</th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th>b</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>c</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_named_standard_columns_named_multi.html b/pandas/tests/io/formats/data/html/index_named_standard_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_named_standard_columns_named_multi.html
@@ -0,0 +1,30 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th>columns.name.0</th>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th>columns.name.1</th>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+    <tr>
+      <th>index.name</th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_named_standard_columns_named_standard.html b/pandas/tests/io/formats/data/html/index_named_standard_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_named_standard_columns_named_standard.html
@@ -0,0 +1,26 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+    </tr>
+    <tr>
+      <th>index.name</th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_named_standard_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/index_named_standard_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_named_standard_columns_unnamed_multi.html
@@ -0,0 +1,30 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+    <tr>
+      <th>index.name</th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_named_standard_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/index_named_standard_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_named_standard_columns_unnamed_standard.html
@@ -0,0 +1,26 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th>0</th>
+      <th>1</th>
+    </tr>
+    <tr>
+      <th>index.name</th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_none_columns_named_multi.html b/pandas/tests/io/formats/data/html/index_none_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_none_columns_named_multi.html
@@ -0,0 +1,25 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th>columns.name.0</th>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th>columns.name.1</th>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th></th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th></th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_none_columns_named_standard.html b/pandas/tests/io/formats/data/html/index_none_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_none_columns_named_standard.html
@@ -0,0 +1,21 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th></th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th></th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_none_columns_none.html b/pandas/tests/io/formats/data/html/index_none_columns_none.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_none_columns_none.html
@@ -0,0 +1,12 @@
+<table border="1" class="dataframe">
+  <tbody>
+    <tr>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_none_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/index_none_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_none_columns_unnamed_multi.html
@@ -0,0 +1,21 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_none_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/index_none_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_none_columns_unnamed_standard.html
@@ -0,0 +1,18 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th>0</th>
+      <th>1</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_named_multi.html b/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_named_multi.html
@@ -0,0 +1,28 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th>columns.name.0</th>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th>columns.name.1</th>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th>b</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>c</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_named_standard.html b/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_named_standard.html
@@ -0,0 +1,23 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th>b</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>c</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_unnamed_multi.html
@@ -0,0 +1,28 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th></th>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th>b</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>c</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_unnamed_multi_columns_unnamed_standard.html
@@ -0,0 +1,23 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th></th>
+      <th>0</th>
+      <th>1</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th>b</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>c</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_named_multi.html b/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_named_multi.html
@@ -0,0 +1,25 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th>columns.name.0</th>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th>columns.name.1</th>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_named_standard.html b/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_named_standard.html
@@ -0,0 +1,21 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_unnamed_multi.html
@@ -0,0 +1,25 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th colspan="2" halign="left">a</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th>b</th>
+      <th>c</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/index_unnamed_standard_columns_unnamed_standard.html
@@ -0,0 +1,21 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th>0</th>
+      <th>1</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>0</td>
+      <td>0</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/justify.html b/pandas/tests/io/formats/data/html/justify.html
similarity index 100%
rename from pandas/tests/io/formats/data/justify.html
rename to pandas/tests/io/formats/data/html/justify.html
diff --git a/pandas/tests/io/formats/data/multiindex_1.html b/pandas/tests/io/formats/data/html/multiindex_1.html
similarity index 100%
rename from pandas/tests/io/formats/data/multiindex_1.html
rename to pandas/tests/io/formats/data/html/multiindex_1.html
diff --git a/pandas/tests/io/formats/data/multiindex_2.html b/pandas/tests/io/formats/data/html/multiindex_2.html
similarity index 100%
rename from pandas/tests/io/formats/data/multiindex_2.html
rename to pandas/tests/io/formats/data/html/multiindex_2.html
diff --git a/pandas/tests/io/formats/data/multiindex_sparsify_1.html b/pandas/tests/io/formats/data/html/multiindex_sparsify_1.html
similarity index 100%
rename from pandas/tests/io/formats/data/multiindex_sparsify_1.html
rename to pandas/tests/io/formats/data/html/multiindex_sparsify_1.html
diff --git a/pandas/tests/io/formats/data/multiindex_sparsify_2.html b/pandas/tests/io/formats/data/html/multiindex_sparsify_2.html
similarity index 100%
rename from pandas/tests/io/formats/data/multiindex_sparsify_2.html
rename to pandas/tests/io/formats/data/html/multiindex_sparsify_2.html
diff --git a/pandas/tests/io/formats/data/multiindex_sparsify_false_multi_sparse_1.html b/pandas/tests/io/formats/data/html/multiindex_sparsify_false_multi_sparse_1.html
similarity index 100%
rename from pandas/tests/io/formats/data/multiindex_sparsify_false_multi_sparse_1.html
rename to pandas/tests/io/formats/data/html/multiindex_sparsify_false_multi_sparse_1.html
diff --git a/pandas/tests/io/formats/data/multiindex_sparsify_false_multi_sparse_2.html b/pandas/tests/io/formats/data/html/multiindex_sparsify_false_multi_sparse_2.html
similarity index 100%
rename from pandas/tests/io/formats/data/multiindex_sparsify_false_multi_sparse_2.html
rename to pandas/tests/io/formats/data/html/multiindex_sparsify_false_multi_sparse_2.html
diff --git a/pandas/tests/io/formats/data/render_links_false.html b/pandas/tests/io/formats/data/html/render_links_false.html
similarity index 100%
rename from pandas/tests/io/formats/data/render_links_false.html
rename to pandas/tests/io/formats/data/html/render_links_false.html
diff --git a/pandas/tests/io/formats/data/render_links_true.html b/pandas/tests/io/formats/data/html/render_links_true.html
similarity index 100%
rename from pandas/tests/io/formats/data/render_links_true.html
rename to pandas/tests/io/formats/data/html/render_links_true.html
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_named_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_named_multi.html
@@ -0,0 +1,88 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th></th>
+      <th>foo</th>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th>baz</th>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+    <tr>
+      <th>foo</th>
+      <th></th>
+      <th>baz</th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th rowspan="2" valign="top">c</th>
+      <th>e</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th rowspan="2" valign="top">b</th>
+      <th rowspan="2" valign="top">d</th>
+      <th>e</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_named_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_named_standard.html
@@ -0,0 +1,72 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th></th>
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+    <tr>
+      <th>foo</th>
+      <th></th>
+      <th>baz</th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th rowspan="2" valign="top">c</th>
+      <th>e</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th rowspan="2" valign="top">b</th>
+      <th rowspan="2" valign="top">d</th>
+      <th>e</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_unnamed_multi.html
@@ -0,0 +1,88 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+    <tr>
+      <th>foo</th>
+      <th></th>
+      <th>baz</th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th rowspan="2" valign="top">c</th>
+      <th>e</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th rowspan="2" valign="top">b</th>
+      <th rowspan="2" valign="top">d</th>
+      <th>e</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_named_multi_columns_unnamed_standard.html
@@ -0,0 +1,72 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th></th>
+      <th></th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+    <tr>
+      <th>foo</th>
+      <th></th>
+      <th>baz</th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th rowspan="2" valign="top">c</th>
+      <th>e</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th rowspan="2" valign="top">b</th>
+      <th rowspan="2" valign="top">d</th>
+      <th>e</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_named_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_named_multi.html
@@ -0,0 +1,74 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th>foo</th>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th>baz</th>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+    <tr>
+      <th>index.name</th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th>6</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>7</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_named_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_named_standard.html
@@ -0,0 +1,62 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+    <tr>
+      <th>index.name</th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th>6</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>7</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_unnamed_multi.html
@@ -0,0 +1,74 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+    <tr>
+      <th>index.name</th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th>6</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>7</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_named_standard_columns_unnamed_standard.html
@@ -0,0 +1,62 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+    <tr>
+      <th>index.name</th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th>6</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>7</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_named_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_named_multi.html
@@ -0,0 +1,66 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th>foo</th>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th>baz</th>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th></th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th></th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th></th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th></th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_named_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_named_standard.html
@@ -0,0 +1,54 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th></th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th></th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th></th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th></th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_none.html b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_none.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_none.html
@@ -0,0 +1,39 @@
+<table border="1" class="dataframe">
+  <tbody>
+    <tr>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_unnamed_multi.html
@@ -0,0 +1,58 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_none_columns_unnamed_standard.html
@@ -0,0 +1,48 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_named_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_named_multi.html
@@ -0,0 +1,78 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th></th>
+      <th>foo</th>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th>baz</th>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th rowspan="2" valign="top">c</th>
+      <th>e</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th rowspan="2" valign="top">b</th>
+      <th rowspan="2" valign="top">d</th>
+      <th>e</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_named_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_named_standard.html
@@ -0,0 +1,62 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th></th>
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th rowspan="2" valign="top">c</th>
+      <th>e</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th rowspan="2" valign="top">b</th>
+      <th rowspan="2" valign="top">d</th>
+      <th>e</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_none.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_none.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_none.html
@@ -0,0 +1,50 @@
+<table border="1" class="dataframe">
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th rowspan="2" valign="top">c</th>
+      <th>e</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th rowspan="2" valign="top">b</th>
+      <th rowspan="2" valign="top">d</th>
+      <th>e</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_unnamed_multi.html
@@ -0,0 +1,78 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th></th>
+      <th></th>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th rowspan="2" valign="top">c</th>
+      <th>e</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th rowspan="2" valign="top">b</th>
+      <th rowspan="2" valign="top">d</th>
+      <th>e</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_multi_columns_unnamed_standard.html
@@ -0,0 +1,62 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th></th>
+      <th></th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th rowspan="2" valign="top">a</th>
+      <th rowspan="2" valign="top">c</th>
+      <th>e</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th rowspan="2" valign="top">b</th>
+      <th rowspan="2" valign="top">d</th>
+      <th>e</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>f</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_named_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_named_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_named_multi.html
@@ -0,0 +1,66 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th>foo</th>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th>baz</th>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th>6</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>7</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_named_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_named_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_named_standard.html
@@ -0,0 +1,54 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th>columns.name</th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th>6</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>7</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_none.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_none.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_none.html
@@ -0,0 +1,44 @@
+<table border="1" class="dataframe">
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th>6</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>7</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_unnamed_multi.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_unnamed_multi.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_unnamed_multi.html
@@ -0,0 +1,66 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr>
+      <th></th>
+      <th colspan="2" halign="left">a</th>
+      <th>...</th>
+      <th colspan="2" halign="left">b</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th colspan="2" halign="left">c</th>
+      <th>...</th>
+      <th colspan="2" halign="left">d</th>
+    </tr>
+    <tr>
+      <th></th>
+      <th>e</th>
+      <th>f</th>
+      <th>...</th>
+      <th>e</th>
+      <th>f</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th>6</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>7</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_unnamed_standard.html b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_unnamed_standard.html
new file mode 100644
--- /dev/null
+++ b/pandas/tests/io/formats/data/html/trunc_df_index_unnamed_standard_columns_unnamed_standard.html
@@ -0,0 +1,54 @@
+<table border="1" class="dataframe">
+  <thead>
+    <tr style="text-align: right;">
+      <th></th>
+      <th>0</th>
+      <th>1</th>
+      <th>...</th>
+      <th>6</th>
+      <th>7</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>0</th>
+      <td>0</td>
+      <td>1</td>
+      <td>...</td>
+      <td>6</td>
+      <td>7</td>
+    </tr>
+    <tr>
+      <th>1</th>
+      <td>8</td>
+      <td>9</td>
+      <td>...</td>
+      <td>14</td>
+      <td>15</td>
+    </tr>
+    <tr>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
+    <tr>
+      <th>6</th>
+      <td>48</td>
+      <td>49</td>
+      <td>...</td>
+      <td>54</td>
+      <td>55</td>
+    </tr>
+    <tr>
+      <th>7</th>
+      <td>56</td>
+      <td>57</td>
+      <td>...</td>
+      <td>62</td>
+      <td>63</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/pandas/tests/io/formats/data/truncate.html b/pandas/tests/io/formats/data/html/truncate.html
similarity index 100%
rename from pandas/tests/io/formats/data/truncate.html
rename to pandas/tests/io/formats/data/html/truncate.html
diff --git a/pandas/tests/io/formats/data/truncate_multi_index.html b/pandas/tests/io/formats/data/html/truncate_multi_index.html
similarity index 100%
rename from pandas/tests/io/formats/data/truncate_multi_index.html
rename to pandas/tests/io/formats/data/html/truncate_multi_index.html
diff --git a/pandas/tests/io/formats/data/truncate_multi_index_sparse_off.html b/pandas/tests/io/formats/data/html/truncate_multi_index_sparse_off.html
similarity index 100%
rename from pandas/tests/io/formats/data/truncate_multi_index_sparse_off.html
rename to pandas/tests/io/formats/data/html/truncate_multi_index_sparse_off.html
diff --git a/pandas/tests/io/formats/data/unicode_1.html b/pandas/tests/io/formats/data/html/unicode_1.html
similarity index 100%
rename from pandas/tests/io/formats/data/unicode_1.html
rename to pandas/tests/io/formats/data/html/unicode_1.html
diff --git a/pandas/tests/io/formats/data/unicode_2.html b/pandas/tests/io/formats/data/html/unicode_2.html
similarity index 100%
rename from pandas/tests/io/formats/data/unicode_2.html
rename to pandas/tests/io/formats/data/html/unicode_2.html
diff --git a/pandas/tests/io/formats/data/with_classes.html b/pandas/tests/io/formats/data/html/with_classes.html
similarity index 100%
rename from pandas/tests/io/formats/data/with_classes.html
rename to pandas/tests/io/formats/data/html/with_classes.html
diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py
--- a/pandas/tests/io/formats/test_to_html.py
+++ b/pandas/tests/io/formats/test_to_html.py
@@ -29,7 +29,7 @@ def expected_html(datapath, name):
     str : contents of HTML file.
     """
     filename = '.'.join([name, 'html'])
-    filepath = datapath('io', 'formats', 'data', filename)
+    filepath = datapath('io', 'formats', 'data', 'html', filename)
     with open(filepath, encoding='utf-8') as f:
         html = f.read()
     return html.rstrip()
@@ -415,6 +415,96 @@ def test_to_html_multiindex_max_cols(self, datapath):
         expected = expected_html(datapath, 'gh6131_expected_output')
         assert result == expected
 
+    def test_to_html_multi_indexes_index_false(self, datapath):
+        # GH 22579
+        df = DataFrame({'a': range(10), 'b': range(10, 20), 'c': range(10, 20),
+                        'd': range(10, 20)})
+        df.columns = MultiIndex.from_product([['a', 'b'], ['c', 'd']])
+        df.index = MultiIndex.from_product([['a', 'b'],
+                                            ['c', 'd', 'e', 'f', 'g']])
+        result = df.to_html(index=False)
+        expected = expected_html(datapath, 'gh22579_expected_output')
+        assert result == expected
+
+    @pytest.mark.parametrize('index_names', [True, False])
+    @pytest.mark.parametrize('index', [True, False])
+    @pytest.mark.parametrize('column_index, column_type', [
+        (Index([0, 1]), 'unnamed_standard'),
+        (Index([0, 1], name='columns.name'), 'named_standard'),
+        (MultiIndex.from_product([['a'], ['b', 'c']]), 'unnamed_multi'),
+        (MultiIndex.from_product(
+            [['a'], ['b', 'c']], names=['columns.name.0',
+                                        'columns.name.1']), 'named_multi')
+    ])
+    @pytest.mark.parametrize('row_index, row_type', [
+        (Index([0, 1]), 'unnamed_standard'),
+        (Index([0, 1], name='index.name'), 'named_standard'),
+        (MultiIndex.from_product([['a'], ['b', 'c']]), 'unnamed_multi'),
+        (MultiIndex.from_product(
+            [['a'], ['b', 'c']], names=['index.name.0',
+                                        'index.name.1']), 'named_multi')
+    ])
+    def test_to_html_basic_alignment(
+            self, datapath, row_index, row_type, column_index, column_type,
+            index, index_names):
+        # GH 22747, GH 22579
+        df = DataFrame(np.zeros((2, 2), dtype=int),
+                       index=row_index, columns=column_index)
+        result = df.to_html(index=index, index_names=index_names)
+
+        if not index:
+            row_type = 'none'
+        elif not index_names and row_type.startswith('named'):
+            row_type = 'un' + row_type
+
+        if not index_names and column_type.startswith('named'):
+            column_type = 'un' + column_type
+
+        filename = 'index_' + row_type + '_columns_' + column_type
+        expected = expected_html(datapath, filename)
+        assert result == expected
+
+    @pytest.mark.parametrize('index_names', [True, False])
+    @pytest.mark.parametrize('index', [True, False])
+    @pytest.mark.parametrize('column_index, column_type', [
+        (Index(np.arange(8)), 'unnamed_standard'),
+        (Index(np.arange(8), name='columns.name'), 'named_standard'),
+        (MultiIndex.from_product(
+            [['a', 'b'], ['c', 'd'], ['e', 'f']]), 'unnamed_multi'),
+        (MultiIndex.from_product(
+            [['a', 'b'], ['c', 'd'], ['e', 'f']], names=['foo', None, 'baz']),
+            'named_multi')
+    ])
+    @pytest.mark.parametrize('row_index, row_type', [
+        (Index(np.arange(8)), 'unnamed_standard'),
+        (Index(np.arange(8), name='index.name'), 'named_standard'),
+        (MultiIndex.from_product(
+            [['a', 'b'], ['c', 'd'], ['e', 'f']]), 'unnamed_multi'),
+        (MultiIndex.from_product(
+            [['a', 'b'], ['c', 'd'], ['e', 'f']], names=['foo', None, 'baz']),
+            'named_multi')
+    ])
+    def test_to_html_alignment_with_truncation(
+            self, datapath, row_index, row_type, column_index, column_type,
+            index, index_names):
+        # GH 22747, GH 22579
+        df = DataFrame(np.arange(64).reshape(8, 8),
+                       index=row_index, columns=column_index)
+        result = df.to_html(max_rows=4, max_cols=4,
+                            index=index, index_names=index_names)
+
+        if not index:
+            row_type = 'none'
+        elif not index_names and row_type.startswith('named'):
+            row_type = 'un' + row_type
+
+        if not index_names and column_type.startswith('named'):
+            column_type = 'un' + column_type
+
+        filename = 'trunc_df_index_' + row_type + '_columns_' + column_type
+        expected = expected_html(datapath, filename)
+        assert result == expected
+
     @pytest.mark.parametrize('index', [False, 0])
     def test_to_html_truncation_index_false_max_rows(self, datapath, index):
         # GH 15019
@@ -429,13 +519,20 @@ def test_to_html_truncation_index_false_max_rows(self, datapath, index):
         assert result == expected
 
     @pytest.mark.parametrize('index', [False, 0])
-    def test_to_html_truncation_index_false_max_cols(self, datapath, index):
+    @pytest.mark.parametrize('col_index_named, expected_output', [
+        (False, 'gh22783_expected_output'),
+        (True, 'gh22783_named_columns_index')
+    ])
+    def test_to_html_truncation_index_false_max_cols(
+            self, datapath, index, col_index_named, expected_output):
         # GH 22783
         data = [[1.764052, 0.400157, 0.978738, 2.240893, 1.867558],
                 [-0.977278, 0.950088, -0.151357, -0.103219, 0.410599]]
         df = DataFrame(data)
+        if col_index_named:
+            df.columns.rename('columns.name', inplace=True)
         result = df.to_html(max_cols=4, index=index)
-        expected = expected_html(datapath, 'gh22783_expected_output')
+        expected = expected_html(datapath, expected_output)
         assert result == expected
 
     def test_to_html_notebook_has_style(self):