diff --git a/resources/common/common.less b/resources/common/common.less
index 468cbab98..a75cb43db 100644
--- a/resources/common/common.less
+++ b/resources/common/common.less
@@ -15,7 +15,7 @@
@import './components/Indicators.less';
@import './components/SiteNotice.less';
@import './components/Menu.less';
- @import './components/MenuDropdown.less';
+ @import './components/MenuDropdownCheckbox.less';
@import './components/MenuPortal.less';
@import './components/SearchBox.less';
@import './components/SidebarLogo.less';
diff --git a/resources/common/components/MenuDropdown.less b/resources/common/components/MenuDropdown.less
deleted file mode 100644
index 31497e9d0..000000000
--- a/resources/common/components/MenuDropdown.less
+++ /dev/null
@@ -1,130 +0,0 @@
-@import '../variables.less';
-@import 'mediawiki.mixins.less';
-
-/**
- * Targets:
- * - language variants, Actions menus
- * - more menu, user menu
- * - ULS button in sticky header
- */
-.emptyPortlet .vector-menu-heading,
-.vector-menu-dropdown .vector-menu-heading,
-.mw-interlanguage-selector {
- display: flex;
- color: @color-base--subtle;
-
- &:after {
- content: '';
- background: url( images/arrow-down.svg ) 100% 50% no-repeat;
- width: unit( 16 / @font-size-tabs / @font-size-browser, em );
- height: unit( 16 / @font-size-tabs / @font-size-browser, em );
- // Modify the color of the image from the default #202122 to approx. #404244 to match the text.
- opacity: 0.84;
- }
-
- &:hover,
- &:focus {
- color: @color-base;
-
- &:after {
- opacity: 1;
- }
- }
-}
-
-.vector-menu-dropdown {
- direction: ltr;
- float: left;
- cursor: pointer;
- position: relative;
-
- // The menu itself.
- .vector-menu-content {
- background-color: @background-color-base;
- list-style: none;
- line-height: 1.125em;
- // Match the width of the dropdown "heading" (the tab)
- min-width: 100%;
- position: absolute;
- top: 100%;
- left: -@border-width-base;
- margin: 0;
- border: @border-width-base @border-style-base @border-color-base;
- padding: 0;
- box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 );
- text-align: left;
- opacity: 0;
- visibility: hidden;
- transition-property: opacity;
- transition-duration: @transition-duration-base;
- z-index: @z-index-menu;
- }
-
- // Hide and show menu content based off checked status.
- .vector-menu-checkbox:checked ~ .vector-menu-content {
- opacity: 1;
- visibility: visible;
- }
-
- ul {
- // display list style images introduced in typography.less.
- list-style: none;
- }
-
- li {
- padding: 0;
- margin: 0;
- text-align: left;
- line-height: 1em;
-
- a {
- padding: 0.625em;
- color: @color-link;
- display: block;
- white-space: nowrap;
- cursor: pointer;
- }
- }
-
- .selected a,
- .selected a:visited {
- color: @color-link-selected;
- text-decoration: none;
- }
-}
-
-// Invisible checkbox covering the dropdown menu handle
-.vector-menu-checkbox {
- cursor: pointer;
- position: absolute;
- top: 0;
- left: 0;
- z-index: @z-index-menu-checkbox;
- opacity: 0;
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- // Hide the checkbox completely in browsers that don't support :checked
- display: none;
-
- :not( :checked ) > & {
- // When the browser supports :checked, display it
- display: block;
- }
-}
-
-.vector-menu-dropdown-noicon {
- .vector-menu-heading {
- // `padding-top` needs to scale with font-size.
- padding: 1.25em 8px 6px;
- font-weight: normal;
- }
-
- // Add focus state to legacy menu dropdown buttons (i.e. p-variants, p-cactions)
- .vector-menu-checkbox:focus + .vector-menu-heading {
- // Simulate browser focus ring
- outline: dotted 1px; // Firefox style
- outline: auto -webkit-focus-ring-color; // Webkit style
- }
-}
diff --git a/resources/common/components/MenuDropdownCheckbox.less b/resources/common/components/MenuDropdownCheckbox.less
new file mode 100644
index 000000000..71b83571a
--- /dev/null
+++ b/resources/common/components/MenuDropdownCheckbox.less
@@ -0,0 +1,93 @@
+@import '../variables.less';
+
+/**
+ * Common styles responsible for hiding/showing the Vector dropdown.
+ */
+
+/**
+ * Vector Dropdown. Contains the dropdown label, checkbox, and
+ * dropdown content.
+ */
+.vector-menu-dropdown {
+ cursor: pointer;
+ position: relative;
+
+ // Dropdown menu container. Hidden by default until checkbox is checked.
+ .vector-menu-content {
+ position: absolute;
+ top: 100%;
+ left: -@border-width-base;
+ opacity: 0;
+ visibility: hidden;
+ // The menu content should not be narrower than the menu button.
+ min-width: 100%;
+ margin: 0;
+ padding: 0;
+ z-index: @z-index-menu;
+ }
+
+ // Dropdown
element.
+ .vector-menu-content-list {
+ list-style: none;
+ }
+
+ // dropdown list items.
+ .mw-list-item {
+ padding: 0;
+ margin: 0;
+
+ a {
+ // displays all links in a single column.
+ display: block;
+ white-space: nowrap;
+ cursor: pointer;
+ }
+ }
+
+ .selected a,
+ .selected a:visited {
+ color: @color-link-selected;
+ text-decoration: none;
+ }
+}
+
+/**
+ * Invisible checkbox covering the dropdown menu handle.
+ */
+.vector-menu-checkbox {
+ cursor: pointer;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: @z-index-menu-checkbox;
+ opacity: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ // Hide the checkbox completely in browsers that don't support :checked
+ display: none;
+
+ // Hide and show menu content based off checked status.
+ &:checked ~ .vector-menu-content {
+ opacity: 1;
+ visibility: visible;
+ }
+
+ :not( :checked ) > & {
+ // When the browser supports :checked, display it
+ display: block;
+ }
+
+ // flips the chevron so it points up when the dropdown is open.
+ &:checked + .vector-menu-heading:after {
+ transform: scaleY( -1 );
+ }
+
+ // Add focus state to menu dropdown buttons (i.e. #p-variants, #p-cactions)
+ &:focus + .vector-menu-heading {
+ // Simulate browser focus ring
+ outline: dotted 1px; // Firefox style
+ outline: auto -webkit-focus-ring-color; // Webkit style
+ }
+}
diff --git a/resources/common/mixins.less b/resources/common/mixins.less
new file mode 100644
index 000000000..a7af3b7f7
--- /dev/null
+++ b/resources/common/mixins.less
@@ -0,0 +1,11 @@
+/**
+ * Less mixins shared between both legacy and Vector 2022.
+ */
+
+// Defines the arrow beside dropdown headings.
+.mixin-vector-menu-heading-arrow() {
+ content: '';
+ background: url( ../common/images/arrow-down.svg ) 100% 50% no-repeat;
+ width: unit( 16 / @font-size-tabs / @font-size-browser, em );
+ height: unit( 16 / @font-size-tabs / @font-size-browser, em );
+}
diff --git a/resources/skins.vector.styles.legacy/components/MenuDropdown.less b/resources/skins.vector.styles.legacy/components/MenuDropdown.less
index b483818a6..7ab579a90 100644
--- a/resources/skins.vector.styles.legacy/components/MenuDropdown.less
+++ b/resources/skins.vector.styles.legacy/components/MenuDropdown.less
@@ -1,56 +1,81 @@
@import '../../common/variables.less';
@import 'mediawiki.mixins.less';
+@import '../../common/mixins.less';
-// Extends the common MenuDropdown, but allows it to be opened via hover.
+/**
+ * Dropdown menus that only appear in the tab bar in legacy Vector.
+ */
+.vector-menu-dropdown {
+ direction: ltr;
+ float: left;
+ cursor: pointer;
+ position: relative;
+ line-height: 1.125em;
-.vector-menu-dropdown:not( .vector-user-menu ) {
+ // menu label with chevron icon.
+ .vector-menu-heading {
+ display: flex;
+ color: @color-base--subtle;
+ font-size: @font-size-tabs;
+ // Tab separator: Outer end (right in LTR) border of "Actions" menu.
+ background-position: right bottom;
+ margin: 0 -@border-width-base 0 0;
+ // `padding-top` needs to scale with font-size.
+ padding: 1.25em 8px 6px;
+ font-weight: normal;
+
+ &:after {
+ .mixin-vector-menu-heading-arrow();
+ // Modify the color of the image from the default #202122 to approx. #404244 to match the text.
+ opacity: 0.84;
+ }
+
+ &:hover,
+ &:focus {
+ color: @color-base;
+
+ &:after {
+ opacity: 1;
+ }
+ }
+ }
+
+ /**
+ * Dropdown container.
+ */
+ .vector-menu-content {
+ line-height: 1.125em;
+ background-color: @background-color-base;
+ border: @border-width-base @border-style-base @border-color-base;
+ border-top-width: 0;
+ box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 );
+ transition-property: opacity;
+ transition-duration: @transition-duration-base;
+ }
+
+ // Open the dropdown container via hover.
&:hover .vector-menu-content {
opacity: 1;
visibility: visible;
}
-}
-.vector-menu-checkbox {
- &:checked + .vector-menu-heading:after {
- transform: scaleY( -1 );
- }
-}
+ .mw-list-item {
+ text-align: left;
+ line-height: 1em;
-.vector-menu-dropdown {
- line-height: 1.125em;
-
- li {
a:not( .mw-ui-icon ) {
font-size: @font-size-tabs;
}
a {
- // Historic value.
- padding: unit( ( 8.125px / @font-size-browser ), em );
+ padding: 0.625em;
+ color: @color-link;
+ }
+
+ &.selected a,
+ &.selected a:visited {
+ color: @color-link-selected;
+ text-decoration: none;
}
}
-
- .vector-menu-heading {
- background-image: linear-gradient( to bottom, rgba( 167, 215, 249, 0 ) 0, @border-color-content 100% );
- background-repeat: no-repeat;
- // Contain gradient to 1px × 100% size and draw from top to bottom-left or -right corner.
- background-size: @border-width-base 100%;
- background-position: right bottom;
- height: 100%;
- }
-
- .vector-menu-content {
- border-top-width: 0;
- }
-}
-
-.vector-menu-dropdown-noicon .vector-menu-heading {
- font-size: @font-size-tabs;
-}
-
-#mw-head .vector-menu-dropdown .vector-menu-heading {
- // Tab separator: Outer end (right in LTR) border of "Actions" menu.
- background-position: right bottom;
- margin: 0 -@border-width-base 0 0;
- float: left;
}
diff --git a/resources/skins.vector.styles.legacy/components/MenuTabs.less b/resources/skins.vector.styles.legacy/components/MenuTabs.less
index 82acd32fa..f779de6d5 100644
--- a/resources/skins.vector.styles.legacy/components/MenuTabs.less
+++ b/resources/skins.vector.styles.legacy/components/MenuTabs.less
@@ -100,21 +100,3 @@
// Tab separator: Outer end (right in LTR) border of "Actions" menu.
background-position: right bottom;
}
-
-.vector-menu-dropdown-noicon {
- .vector-menu-heading {
- // `padding-top` needs to scale with font-size.
- padding-top: 1.25em;
- padding-left: 8px;
- padding-right: 8px;
- font-size: @font-size-tabs;
- font-weight: normal;
- }
-
- // Add focus state to legacy menu dropdown buttons (i.e. p-variants, p-cactions)
- .vector-menu-checkbox:focus + .vector-menu-heading {
- // Simulate browser focus ring
- outline: dotted 1px; // Firefox style
- outline: auto -webkit-focus-ring-color; // Webkit style
- }
-}
diff --git a/resources/skins.vector.styles/components/MenuDropdown.less b/resources/skins.vector.styles/components/MenuDropdown.less
new file mode 100644
index 000000000..46ef96d4a
--- /dev/null
+++ b/resources/skins.vector.styles/components/MenuDropdown.less
@@ -0,0 +1,57 @@
+@import '../../common/variables.less';
+@import '../../common/mixins.less';
+@import 'mediawiki.mixins.less';
+
+/**
+ * Targets all dropdown labels.
+ * - language variants, Actions menus
+ * - more menu, user menu
+ * - ULS button in sticky header
+ */
+.emptyPortlet .vector-menu-heading,
+.vector-menu-dropdown .vector-menu-heading,
+.mw-interlanguage-selector {
+ display: flex;
+ color: @color-base--subtle;
+
+ &:after {
+ .mixin-vector-menu-heading-arrow();
+ // Modify the color of the image from the default #202122 to approx. #404244 to match the text.
+ opacity: 0.84;
+ }
+
+ &:hover,
+ &:focus {
+ color: @color-base;
+
+ &:after {
+ opacity: 1;
+ }
+ }
+}
+
+/**
+ * Dropdown container
+ */
+.vector-menu-dropdown {
+ .vector-menu-content {
+ background-color: @background-color-base;
+ border: @border-width-base @border-style-base @border-color-base;
+ box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 );
+ transition-property: opacity;
+ transition-duration: @transition-duration-base;
+ line-height: 1.125em;
+ }
+
+ .mw-list-item {
+ a {
+ color: @color-link;
+ }
+
+ &.selected a,
+ &.selected a:visited {
+ color: @color-link-selected;
+ text-decoration: none;
+ }
+ }
+}
diff --git a/resources/skins.vector.styles/components/MenuTabs.less b/resources/skins.vector.styles/components/MenuTabs.less
index 2f44ce18c..30fe2f1e7 100644
--- a/resources/skins.vector.styles/components/MenuTabs.less
+++ b/resources/skins.vector.styles/components/MenuTabs.less
@@ -59,3 +59,10 @@
box-sizing: border-box;
}
}
+
+// Applies only to dropdowns inside the article toolbar.
+.mw-article-toolbar-container .vector-menu-dropdown {
+ .mw-list-item {
+ padding: 0.625em;
+ }
+}
diff --git a/resources/skins.vector.styles/skin.less b/resources/skins.vector.styles/skin.less
index 8308372d1..f7d3f7669 100644
--- a/resources/skins.vector.styles/skin.less
+++ b/resources/skins.vector.styles/skin.less
@@ -18,6 +18,7 @@
@import './components/LanguageButton.less';
@import './components/UserLinks.less';
@import './components/Header.less';
+ @import './components/MenuDropdown.less';
@import './components/MenuTabs.less';
@import './components/StickyHeader.less';
@import './components/TabWatchstarLink.less';
diff --git a/stories/MenuDropdown.stories.js b/stories/MenuDropdown.stories.js
index a7902195d..fa7434f05 100644
--- a/stories/MenuDropdown.stories.js
+++ b/stories/MenuDropdown.stories.js
@@ -1,5 +1,5 @@
import mustache from 'mustache';
-import '../resources/skins.vector.styles/MenuDropdown.less';
+import '../resources/skins.vector.styles/components/MenuDropdown.less';
import { vectorMenuTemplate, moreData, variantsData } from './MenuDropdown.stories.data';
export default {