diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index d07ef6db4c6b0..096541423c6c1 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1080,7 +1080,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
                 cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.as_ref().unwrap()));
             write!(
                 w,
-                "<div id=\"{id}\" class=\"variant small-section-header\">\
+                "<h3 id=\"{id}\" class=\"variant small-section-header\">\
                     <a href=\"#{id}\" class=\"anchor field\"></a>\
                     <code>{name}",
                 id = id,
@@ -1093,9 +1093,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
             }
             w.write_str("</code>");
             render_stability_since(w, variant, it, cx.tcx());
-            w.write_str("</div>");
-            document(w, cx, variant, Some(it), HeadingOffset::H3);
-            document_non_exhaustive(w, variant);
+            w.write_str("</h3>");
 
             use crate::clean::Variant;
             if let Some((extra, fields)) = match *variant.kind {
@@ -1109,12 +1107,8 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
                     variant.name.as_ref().unwrap()
                 ));
                 write!(w, "<div class=\"sub-variant\" id=\"{id}\">", id = variant_id);
-                write!(
-                    w,
-                    "<h3>{extra}Fields of <b>{name}</b></h3><div>",
-                    extra = extra,
-                    name = variant.name.as_ref().unwrap(),
-                );
+                write!(w, "<h4>{extra}Fields</h4>", extra = extra,);
+                document_non_exhaustive(w, variant);
                 for field in fields {
                     match *field.kind {
                         clean::StrippedItem(box clean::StructFieldItem(_)) => {}
@@ -1126,7 +1120,8 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
                             ));
                             write!(
                                 w,
-                                "<span id=\"{id}\" class=\"variant small-section-header\">\
+                                "<div class=\"sub-variant-field\">\
+                                 <span id=\"{id}\" class=\"variant small-section-header\">\
                                     <a href=\"#{id}\" class=\"anchor field\"></a>\
                                     <code>{f}:&nbsp;{t}</code>\
                                 </span>",
@@ -1134,13 +1129,16 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
                                 f = field.name.as_ref().unwrap(),
                                 t = ty.print(cx)
                             );
-                            document(w, cx, field, Some(variant), HeadingOffset::H4);
+                            document(w, cx, field, Some(variant), HeadingOffset::H5);
+                            write!(w, "</div>");
                         }
                         _ => unreachable!(),
                     }
                 }
-                w.write_str("</div></div>");
+                w.write_str("</div>");
             }
+
+            document(w, cx, variant, Some(it), HeadingOffset::H4);
         }
     }
     let def_id = it.def_id.expect_def_id();
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 93cbc0debb945..968e40ec4cb0b 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1101,25 +1101,28 @@ a.test-arrow:hover{
 	margin-right: 5px;
 }
 
-.sub-variant, .sub-variant > h3 {
-	margin-top: 0px !important;
-	padding-top: 1px;
+h3.variant {
+	font-weight: 600;
+	font-size: 1.1em;
+	margin-bottom: 10px;
+	border-bottom: none;
 }
 
-#main .sub-variant > h3 {
-	font-size: 15px;
-	margin-left: 25px;
-	margin-bottom: 5px;
+.sub-variant h4 {
+	font-size: 1em;
+	font-weight: 400;
+	border-bottom: none;
+	margin-top: 0;
+	margin-bottom: 0;
 }
 
-.sub-variant > div {
-	margin-left: 20px;
-	margin-bottom: 10px;
+.sub-variant {
+	margin-left: 24px;
+	margin-bottom: 40px;
 }
 
-.sub-variant > div > span {
-	display: block;
-	position: relative;
+.sub-variant > .sub-variant-field {
+	margin-left: 24px;
 }
 
 .toggle-label {
diff --git a/src/test/rustdoc-gui/headings.goml b/src/test/rustdoc-gui/headings.goml
index 35d772170f6f9..3b5cfeb68af61 100644
--- a/src/test/rustdoc-gui/headings.goml
+++ b/src/test/rustdoc-gui/headings.goml
@@ -1,4 +1,4 @@
-// This test check that headers (a) have the correct heading level, (b) are the right size,
+// This test checks that headers (a) have the correct heading level, (b) are the right size,
 // and (c) have the correct underlining (or absence of underlining).
 // The sizes may change as design changes, but try to make sure a lower header is never bigger than
 // its parent headers. Also make sure lower headers don't have underlines when their parents lack
@@ -67,25 +67,25 @@ assert-css: ("h4#top-doc-prose-sub-sub-heading", {"border-bottom-width": "1px"})
 assert-css: ("h2#variants", {"font-size": "22.4px"})
 assert-css: ("h2#variants", {"border-bottom-width": "1px"})
 
-assert-css: ("h3#none-prose-title", {"font-size": "20.8px"})
-assert-css: ("h3#none-prose-title", {"border-bottom-width": "0px"})
-assert-css: ("h4#none-prose-sub-heading", {"font-size": "16px"})
-assert-css: ("h4#none-prose-sub-heading", {"border-bottom-width": "0px"})
-
-assert-css: ("h3#wrapped-prose-title", {"font-size": "20.8px"})
-assert-css: ("h3#wrapped-prose-title", {"border-bottom-width": "0px"})
-assert-css: ("h4#wrapped-prose-sub-heading", {"font-size": "16px"})
-assert-css: ("h4#wrapped-prose-sub-heading", {"border-bottom-width": "0px"})
-
-assert-css: ("h4#wrapped0-prose-title", {"font-size": "16px"})
-assert-css: ("h4#wrapped0-prose-title", {"border-bottom-width": "0px"})
-assert-css: ("h5#wrapped0-prose-sub-heading", {"font-size": "16px"})
-assert-css: ("h5#wrapped0-prose-sub-heading", {"border-bottom-width": "0px"})
-
-assert-css: ("h4#structy-prose-title", {"font-size": "16px"})
-assert-css: ("h4#structy-prose-title", {"border-bottom-width": "0px"})
-assert-css: ("h5#structy-prose-sub-heading", {"font-size": "16px"})
-assert-css: ("h5#structy-prose-sub-heading", {"border-bottom-width": "0px"})
+assert-css: ("h4#none-prose-title", {"font-size": "16px"})
+assert-css: ("h4#none-prose-title", {"border-bottom-width": "0px"})
+assert-css: ("h5#none-prose-sub-heading", {"font-size": "16px"})
+assert-css: ("h5#none-prose-sub-heading", {"border-bottom-width": "0px"})
+
+assert-css: ("h4#wrapped-prose-title", {"font-size": "16px"})
+assert-css: ("h4#wrapped-prose-title", {"border-bottom-width": "0px"})
+assert-css: ("h5#wrapped-prose-sub-heading", {"font-size": "16px"})
+assert-css: ("h5#wrapped-prose-sub-heading", {"border-bottom-width": "0px"})
+
+assert-css: ("h5#wrapped0-prose-title", {"font-size": "16px"})
+assert-css: ("h5#wrapped0-prose-title", {"border-bottom-width": "0px"})
+assert-css: ("h6#wrapped0-prose-sub-heading", {"font-size": "15.2px"})
+assert-css: ("h6#wrapped0-prose-sub-heading", {"border-bottom-width": "0px"})
+
+assert-css: ("h5#structy-prose-title", {"font-size": "16px"})
+assert-css: ("h5#structy-prose-title", {"border-bottom-width": "0px"})
+assert-css: ("h6#structy-prose-sub-heading", {"font-size": "15.2px"})
+assert-css: ("h6#structy-prose-sub-heading", {"border-bottom-width": "0px"})
 
 assert-css: ("h2#implementations", {"font-size": "22.4px"})
 assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
diff --git a/src/test/rustdoc/enum-headings.rs b/src/test/rustdoc/enum-headings.rs
new file mode 100644
index 0000000000000..2e5c34391c4af
--- /dev/null
+++ b/src/test/rustdoc/enum-headings.rs
@@ -0,0 +1,40 @@
+#![crate_name = "foo"]
+// @has foo/enum.Token.html
+/// A token!
+/// # First
+/// Some following text...
+// @has - '//h2[@id="first"]' "First"
+pub enum Token {
+    /// A declaration!
+    /// # Variant-First
+    /// Some following text...
+    // @has - '//h4[@id="variant-first"]' "Variant-First"
+    Declaration {
+        /// A version!
+        /// # Variant-Field-First
+        /// Some following text...
+        // @has - '//h5[@id="variant-field-first"]' "Variant-Field-First"
+        version: String,
+    },
+    /// A Zoople!
+    /// # Variant-First
+    Zoople(
+        // @has - '//h5[@id="variant-tuple-field-first"]' "Variant-Tuple-Field-First"
+        /// Zoople's first variant!
+        /// # Variant-Tuple-Field-First
+        /// Some following text...
+        usize,
+    ),
+    /// Unfinished business!
+    /// # Non-Exhaustive-First
+    /// Some following text...
+    // @has - '//h4[@id="non-exhaustive-first"]' "Non-Exhaustive-First"
+    #[non_exhaustive]
+    Unfinished {
+        /// This is x.
+        /// # X-First
+        /// Some following text...
+        // @has - '//h5[@id="x-first"]' "X-First"
+        x: usize,
+    },
+}
diff --git a/src/test/rustdoc/tuple-struct-fields-doc.rs b/src/test/rustdoc/tuple-struct-fields-doc.rs
index f3d8e39ea2d26..139c5b4391ab7 100644
--- a/src/test/rustdoc/tuple-struct-fields-doc.rs
+++ b/src/test/rustdoc/tuple-struct-fields-doc.rs
@@ -20,10 +20,10 @@ pub struct Foo(
 
 // @has foo/enum.Bar.html
 // @has - '//pre[@class="rust enum"]' 'BarVariant(String),'
-// @matches - '//*[@id="variant.BarVariant.fields"]/h3' '^Tuple Fields of BarVariant$'
+// @matches - '//*[@id="variant.BarVariant.fields"]/h4' '^Tuple Fields$'
 // @has - '//*[@id="variant.BarVariant.field.0"]' '0: String'
 // @has - '//*[@id="variant.BarVariant.fields"]//*[@class="docblock"]' 'Hello docs'
-// @matches - '//*[@id="variant.FooVariant.fields"]/h3' '^Fields of FooVariant$'
+// @matches - '//*[@id="variant.FooVariant.fields"]/h4' '^Fields$'
 pub enum Bar {
     BarVariant(
         /// Hello docs