{"id":165440,"date":"2014-03-11T14:11:42","date_gmt":"2014-03-11T21:11:42","guid":{"rendered":"http:\/\/css-tricks.com\/?p=165440"},"modified":"2017-04-12T17:49:47","modified_gmt":"2017-04-13T00:49:47","slug":"popping-hidden-overflow","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/popping-hidden-overflow\/","title":{"rendered":"Popping Out of Hidden Overflow"},"content":{"rendered":"

The following is a guest post by Agop Shirinian<\/a>. Agop ran into an interesting scenario where he needed an element to be scrollable in one direction, while allowing the overflow in the other direction. You’d think that’s what overflow-x and overflow-y are for, but it’s not that simple. I’ll let Agop explain.<\/em><\/p>\n

<\/p>\n

So you’re tasked with creating a scrollable menu with submenus that pop out when you hover over a parent menu item.<\/p>\n

Simple!<\/p>\n

Create a list for the menu, add some nested lists for the submenus, position the nested lists based on their parent list items, voil\u00e0!<\/p>\n

See the Pen Scrollable menu with pop out submenus (broken)<\/a> by Agop (@agop<\/a>) on CodePen<\/a>.<\/p>\n

Wait, that’s not right. Oh, of course, we used overflow: auto<\/code> – perhaps if we use overflow-x: visible<\/code>, the horizontal overflow of the submenus will be visible:<\/p>\n

See the Pen Scrollable menu with pop out submenus (broken #2)<\/a> by Agop (@agop<\/a>) on CodePen<\/a>.<\/p>\n

What gives? Why do we still get scrollbars?<\/p>\n

The Problem<\/h3>\n

If we look at the W3C spec<\/a>, we find the following explanation:<\/p>\n

The computed values of \u2018overflow-x\u2019 and \u2018overflow-y\u2019 are the same as their specified values, except that some combinations with \u2018visible\u2019 are not possible: if one is specified as \u2018visible\u2019 and the other is \u2018scroll\u2019 or \u2018auto\u2019, then \u2018visible\u2019 is set to \u2018auto\u2019.<\/p><\/blockquote>\n

Basically, this:<\/p>\n

overflow-x: visible;\r\noverflow-y: auto;<\/code><\/pre>\n

Turns into this:<\/p>\n

overflow-x: auto;\r\noverflow-y: auto;<\/code><\/pre>\n

So we can’t have visible horizontal overflow if the vertical overflow is invisible, and vice versa.<\/p>\n

And if we can’t have visible horizontal overflow, we can’t have our pop out submenus!<\/p>\n

The Solution<\/h3>\n

Interestingly enough, if we omit the position: relative<\/code> from the menu items, the submenus do show up, positioned based on their closest positioned ancestor<\/a>. In this case, they don’t have a positioned ancestor, so they’re positioned relative to <body><\/code>:<\/p>\n

See the Pen Scrollable menu with pop out submenus (step 1)<\/a> by Agop (@agop<\/a>) on CodePen<\/a>.<\/p>\n

Basically, in order for an absolutely positioned element to appear outside of an element with overflow: hidden<\/code>, its closest positioned ancestor must also be an ancestor of the element with overflow: hidden<\/code>.<\/p>\n

Knowing this, we can add a wrapper around the menus to act as the closest positioned ancestor for each submenu. Then, whenever the user hovers over a menu item, we can position the submenu wrappers using a bit of JavaScript:<\/p>\n

See the Pen Scrollable menu with pop out submenus<\/a> by Agop (@agop<\/a>) on CodePen<\/a>.<\/p>\n

And that’s it! Since neither the menus nor the menu items are positioned, the submenus are able to pop out of the hidden\/scrollable overflow. Now we can have as many levels of nested submenus as we want, and we won’t get any undesired clipping.<\/p>\n

Takeaway<\/h3>\n

Unfortunately, this method of showing items that would otherwise be hidden is very obscure.<\/p>\n

It’d be nice if we could specify a clip depth, which would control which ancestor in the hiearchy would be responsible for clipping a particular element:<\/p>\n

.\/* Fair warning: not real code *\/\r\n.submenu {\r\n  \/* only an ancestor 2 levels up can clip this element *\/ \r\n  clip-depth: 2;\r\n}<\/code><\/pre>\n

Or, even better, perhaps we could specify the clipping parent by a CSS selector:<\/p>\n

\/* Fair warning: not real code *\/\r\n.submenu {\r\n  \/* only an ancestor that matches the .panel selector can clip this element *\/\r\n  clip-parent: .panel;\r\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"

The following is a guest post by Agop Shirinian. Agop ran into an interesting scenario where he needed an element to be scrollable in one direction, while allowing the overflow in the other direction. You’d think that’s what overflow-x and overflow-y are for, but it’s not that simple. I’ll let Agop explain.<\/p>\n","protected":false},"author":248398,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[4],"tags":[],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":251715,"url":"https:\/\/css-tricks.com\/squeezy-stretchy-flexbox-nav\/","url_meta":{"origin":165440,"position":0},"title":"Squeezy Stretchy Flexbox Nav","date":"February 20, 2017","format":false,"excerpt":"I saw an interesting take on off-canvas navigation the other day over on The New Tropic. It wasn't the off-canvas part so much. It was how the elements within the nav took up space. They stretched out to take up all the space, when available, but never squished too far.\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/02\/flex-nav.png?fit=486%2C277&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":336401,"url":"https:\/\/css-tricks.com\/in-praise-of-the-unambiguous-click-menu\/","url_meta":{"origin":165440,"position":1},"title":"In Praise of the Unambiguous Click Menu","date":"March 18, 2021","format":false,"excerpt":"I still remember my excitement when I learned how to build a hover-triggered submenu with just CSS. (It was probably after reading this 2003 article from A List Apart.) At the time, it was a true CSS trick. Seriously. Wild times. That went a little something like this:

    \u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/03\/click-menu.gif?fit=1000%2C500&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":326083,"url":"https:\/\/css-tricks.com\/under-engineered-responsive-tables\/","url_meta":{"origin":165440,"position":2},"title":"Under-Engineered Responsive Tables","date":"December 1, 2020","format":false,"excerpt":"I first blogged about responsive data tables in 2011. When responsive web design was first becoming a thing, there were little hurdles like data tables that had to be jumped. The nature of elements are that they have something a minimum width depending on the content they contain and\u2026","rel":"","context":"In "Link"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/07\/table-pattern.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":4459,"url":"https:\/\/css-tricks.com\/long-dropdowns-solution\/","url_meta":{"origin":165440,"position":3},"title":"Solution For Very Long Dropdown Menus","date":"October 21, 2009","format":false,"excerpt":"I like to be confident with post titles, but the reality in this case is a *possible* solution for very long dropdowns. The problem with long dropdowns is that the dropdown itself can go below the \"fold\" of the website. That is, below the visible area of the browser window.\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/csstricks-uploads\/mt-below-fold.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":13246,"url":"https:\/\/css-tricks.com\/mobile-webkit-overflow-scrolling\/","url_meta":{"origin":165440,"position":4},"title":"Mobile WebKit Overflow Scrolling","date":"July 6, 2011","format":false,"excerpt":"Two of the CSS properties most lamented by mobile website developers is fixed positioning and scrolling overflow. These are absent for a reason. Poorly implemented, they might single-handedly render a website unusable on a small screen. (Imagine a giant fixed position header that hides all the content, or being zoomed\u2026","rel":"","context":"In "Link"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":150992,"url":"https:\/\/css-tricks.com\/targetting-menu-elements-submenus-navigation-bar\/","url_meta":{"origin":165440,"position":5},"title":"Targeting Menu Elements with Submenus in a Navigation Bar","date":"September 23, 2013","format":false,"excerpt":"The following is a guest post by Ray Messina. Ray was interested in sharing this technique as a way to pay forward things he's learned from this site in the past, which is awesome. You might be aware of the jQuery .has method, which allows you to select an element\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"featured_media_src_url":null,"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/165440"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/248398"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=165440"}],"version-history":[{"count":4,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/165440\/revisions"}],"predecessor-version":[{"id":165458,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/165440\/revisions\/165458"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=165440"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=165440"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=165440"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}