WordPress.org

Make WordPress Core

Changeset 38853


Ignore:
Timestamp:
10/21/16 06:36:57 (5 months ago)
Author:
westonruter
Message:

Customize: Add sticky headers for panels and sections.

Includes autoprefixing of CSS.

Props delawski, celloexpressions.
See #35186.
Fixes #34343.

Location:
trunk/src/wp-admin
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/customize-controls.css

    r38829 r38853  
    5656#customize-controls .customize-info.section-meta { 
    5757    margin-bottom: 15px; 
     58} 
     59 
     60#customize-controls .customize-info.is-in-view, 
     61#customize-controls .customize-section-title.is-in-view { 
     62    position: absolute; 
     63    z-index: 9; 
     64    width: 100%; 
     65    -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .1); 
     66    box-shadow: 0 1px 0 rgba(0, 0, 0, .1); 
     67} 
     68 
     69#customize-controls .customize-section-title.is-in-view { 
     70    margin-top: 0; 
     71} 
     72 
     73#customize-controls .customize-info.is-in-view + .accordion-section { 
     74    margin-top: 15px; 
     75} 
     76 
     77#customize-controls .customize-info.is-sticky, 
     78#customize-controls .customize-section-title.is-sticky { 
     79    position: fixed; 
     80    top: 46px; 
    5881} 
    5982 
     
    324347#customize-theme-controls .customize-pane-child.accordion-section-content { 
    325348    padding: 12px; 
     349} 
     350 
     351#customize-theme-controls .customize-pane-child.menu li { 
     352    position: static; 
    326353} 
    327354 
     
    410437    float: left; 
    411438    width: 48px; 
    412     height: 70px; 
     439    height: 71px; 
    413440    padding: 0 24px 0 0; 
    414441    margin: 0; 
     
    424451 
    425452.customize-section-back { 
    426     height: 73px; 
     453    height: 74px; 
    427454} 
    428455 
     
    485512 
    486513.wp-full-overlay-sidebar .wp-full-overlay-header { 
     514    background-color: #eee; 
    487515    -webkit-transition: padding ease-in-out .18s; 
    488516    transition: padding ease-in-out .18s; 
     
    10891117    top: 0; 
    10901118    left: 0; 
     1119    -webkit-transition: .18s left ease-in-out; 
    10911120    transition: .18s left ease-in-out; 
    10921121    margin: 0 0 0 300px; 
    10931122    padding:25px; 
    10941123    overflow-y: scroll; 
     1124    width: -webkit-calc(100% - 350px); 
    10951125    width: calc(100% - 350px); 
     1126    height: -webkit-calc(100% - 50px); 
    10961127    height: calc(100% - 50px); 
    10971128    background: #eee; 
     
    11051136    position: relative; 
    11061137    top: 0; 
     1138    -webkit-transition: .18s top ease-in-out; 
    11071139    transition: .18s top ease-in-out; 
    11081140} 
     
    11111143#customize-footer-actions .collapse-sidebar { 
    11121144    bottom: 0; 
     1145    -webkit-transition: .18s bottom ease-in-out; 
    11131146    transition: .18s bottom ease-in-out; 
    11141147} 
     
    11471180 
    11481181/* Adds a delay before fading in to avoid it "jumping" */ 
     1182@-webkit-keyframes themes-fade-in { 
     1183    0% { 
     1184        opacity: 0; 
     1185    } 
     1186    50% { 
     1187        opacity: 0; 
     1188    } 
     1189    100% { 
     1190        opacity: 1; 
     1191    } 
     1192} 
    11491193@keyframes themes-fade-in { 
    11501194    0% { 
     
    11601204 
    11611205.control-panel-themes .customize-themes-full-container.animate { 
     1206    -webkit-animation: .6s themes-fade-in 1; 
    11621207    animation: .6s themes-fade-in 1; 
    11631208} 
    11641209 
    11651210.in-themes-panel:not(.animating) .control-panel-themes .filter-themes-count { 
     1211    -webkit-animation: .6s themes-fade-in 1; 
    11661212    animation: .6s themes-fade-in 1; 
    11671213} 
     
    12061252 
    12071253    .control-panel-themes .filter-themes-count { 
     1254        width: -webkit-calc(100% - 93px); 
    12081255        width: calc(100% - 93px); 
    12091256    } 
     
    12371284 
    12381285    .control-panel-themes .customize-themes-full-container { 
     1286        width: -webkit-calc(100% - 50px); 
    12391287        width: calc(100% - 50px); 
    12401288        margin: 0; 
    12411289        top: 46px; 
     1290        height: -webkit-calc(100% - 96px); 
    12421291        height: calc(100% - 96px); 
    12431292        z-index: 1; 
     
    12741323    width: 100%; 
    12751324    background: #fff; 
     1325    -webkit-box-shadow: none; 
    12761326    box-shadow: none; 
    12771327    outline: none; 
     
    13051355    content: "\f147"; 
    13061356    font: 16px/1 dashicons; 
     1357    -webkit-box-sizing: border-box; 
     1358    -moz-box-sizing: border-box; 
    13071359    box-sizing: border-box; 
    13081360    width: 20px; 
    13091361    height: 20px; 
    13101362    padding: 3px 3px 1px 1px; /* Re-align the icon to the smaller grid */ 
     1363    -webkit-border-radius: 100%; 
    13111364    border-radius: 100%; 
    13121365    position: absolute; 
     
    13771430    border: none; 
    13781431    padding: 0; 
     1432    -webkit-box-shadow: none; 
    13791433    box-shadow: none; 
    13801434} 
     
    14071461    border-bottom-color: #0073aa; /* Color change for focus style should be acceptable because border-bottom is barely visible previously. */ 
    14081462    outline: none; 
     1463    -webkit-box-shadow: none; 
    14091464    box-shadow: none; 
    14101465} 
     
    14261481    margin: 0; 
    14271482    padding: 12px 10px 12px 34px; 
     1483    width: -webkit-calc(100% - 46px); 
    14281484    width: calc(100% - 46px); 
    14291485    line-height: 16px; 
     
    14541510    width: 20px; 
    14551511    height: 20px; 
     1512    left: -webkit-calc(50% - 10px); 
    14561513    left: calc(50% - 10px); 
    14571514    float: none; 
     
    14891546 
    14901547.customize-control.customize-control-theme { /* override most properties on .customize-control */ 
     1548    -webkit-box-sizing: border-box; 
     1549    -moz-box-sizing: border-box; 
    14911550    box-sizing: border-box; 
    14921551    width: 18.4%; 
  • trunk/src/wp-admin/css/customize-nav-menus.css

    r38709 r38853  
    6666} 
    6767 
     68.wp-customizer .menu-item-handle:hover { 
     69    z-index: 8; 
     70} 
     71 
    6872.customize-control-nav_menu_item.has-notifications .menu-item-handle { 
    6973    border-left: 4px solid #00a0d2; 
     
    7377    max-width: 100%; 
    7478    overflow: hidden; 
     79    z-index: 8; 
    7580    padding: 10px; 
    7681    background: #eee; 
  • trunk/src/wp-admin/js/customize-controls.js

    r38829 r38853  
    10051005                        content.addClass( 'open' ); 
    10061006                        overlay.addClass( 'section-open' ); 
     1007                        api.state( 'expandedSection' ).set( section ); 
    10071008                    }, this ); 
    10081009                } 
     
    10431044                content.removeClass( 'open' ); 
    10441045                overlay.removeClass( 'section-open' ); 
     1046                if ( section === api.state( 'expandedSection' ).get() ) { 
     1047                    api.state( 'expandedSection' ).set( false ); 
     1048                } 
    10451049 
    10461050            } else { 
     
    19962000                overlay.addClass( 'in-sub-panel' ); 
    19972001                accordionSection.addClass( 'current-panel' ); 
     2002                api.state( 'expandedPanel' ).set( panel ); 
    19982003 
    19992004            } else if ( ! expanded && accordionSection.hasClass( 'current-panel' ) ) { 
     
    20122017                overlay.removeClass( 'in-sub-panel' ); 
    20132018                accordionSection.removeClass( 'current-panel' ); 
     2019                if ( panel === api.state( 'expandedPanel' ).get() ) { 
     2020                    api.state( 'expandedPanel' ).set( false ); 
     2021                } 
    20142022            } 
    20152023        }, 
     
    49694977                processing = state.create( 'processing' ), 
    49704978                paneVisible = state.create( 'paneVisible' ), 
     4979                expandedPanel = state.create( 'expandedPanel' ), 
     4980                expandedSection = state.create( 'expandedSection' ), 
    49714981                changesetStatus = state.create( 'changesetStatus' ), 
    49724982                previewerAlive = state.create( 'previewerAlive' ), 
     
    50045014            processing( 0 ); 
    50055015            paneVisible( true ); 
     5016            expandedPanel( false ); 
     5017            expandedSection( false ); 
    50065018            previewerAlive( true ); 
    50075019            changesetStatus( api.settings.changeset.status ); 
     
    51575169        }); 
    51585170 
     5171        /* 
     5172         * Sticky header feature. 
     5173         */ 
     5174        (function initStickyHeaders() { 
     5175            var parentContainer = $( '.wp-full-overlay-sidebar-content' ), 
     5176                changeContainer, getHeaderHeight, releaseStickyHeader, resetStickyHeader, positionStickyHeader, 
     5177                activeHeader, lastScrollTop; 
     5178 
     5179            // Determine which panel or section is currently expanded. 
     5180            changeContainer = function( container ) { 
     5181                var newInstance = container, 
     5182                    expandedSection = api.state( 'expandedSection' ).get(), 
     5183                    expandedPanel = api.state( 'expandedPanel' ).get(), 
     5184                    headerElement; 
     5185 
     5186                // Release previously active header element. 
     5187                if ( activeHeader && activeHeader.element ) { 
     5188                    releaseStickyHeader( activeHeader.element ); 
     5189                } 
     5190 
     5191                if ( ! newInstance ) { 
     5192                    if ( ! expandedSection && expandedPanel && expandedPanel.contentContainer ) { 
     5193                        newInstance = expandedPanel; 
     5194                    } else if ( ! expandedPanel && expandedSection && expandedSection.contentContainer ) { 
     5195                        newInstance = expandedSection; 
     5196                    } else { 
     5197                        activeHeader = false; 
     5198                        return; 
     5199                    } 
     5200                } 
     5201 
     5202                headerElement = newInstance.contentContainer.find( '.customize-section-title, .panel-meta' ).first(); 
     5203                if ( headerElement.length ) { 
     5204                    activeHeader = { 
     5205                        instance: newInstance, 
     5206                        element:  headerElement, 
     5207                        parent:   headerElement.closest( '.customize-pane-child' ), 
     5208                        height:   getHeaderHeight( headerElement ) 
     5209                    }; 
     5210                    if ( expandedSection ) { 
     5211                        resetStickyHeader( activeHeader.element, activeHeader.parent ); 
     5212                    } 
     5213                } else { 
     5214                    activeHeader = false; 
     5215                } 
     5216            }; 
     5217            api.state( 'expandedSection' ).bind( changeContainer ); 
     5218            api.state( 'expandedPanel' ).bind( changeContainer ); 
     5219 
     5220            // Throttled scroll event handler. 
     5221            parentContainer.on( 'scroll', _.throttle( function() { 
     5222                if ( ! activeHeader ) { 
     5223                    return; 
     5224                } 
     5225 
     5226                var scrollTop = parentContainer.scrollTop(), 
     5227                    isScrollingUp = ( lastScrollTop ) ? scrollTop <= lastScrollTop : true; 
     5228 
     5229                lastScrollTop = scrollTop; 
     5230                positionStickyHeader( activeHeader, scrollTop, isScrollingUp ); 
     5231            }, 8 ) ); 
     5232 
     5233            // Release header element if it is sticky. 
     5234            releaseStickyHeader = function( headerElement ) { 
     5235                if ( ! headerElement.hasClass( 'is-sticky' ) ) { 
     5236                    return; 
     5237                } 
     5238                headerElement 
     5239                    .removeClass( 'is-sticky' ) 
     5240                    .addClass( 'maybe-sticky is-in-view' ) 
     5241                    .css( 'top', parentContainer.scrollTop() + 'px' ); 
     5242            }; 
     5243 
     5244            // Reset position of the sticky header. 
     5245            resetStickyHeader = function( headerElement, headerParent ) { 
     5246                headerElement 
     5247                    .removeClass( 'maybe-sticky is-in-view' ) 
     5248                    .css( { 
     5249                        width: '', 
     5250                        top: '' 
     5251                    } ); 
     5252                headerParent.css( 'padding-top', '' ); 
     5253            }; 
     5254 
     5255            // Get header height. 
     5256            getHeaderHeight = function( headerElement ) { 
     5257                var height = headerElement.data( 'height' ); 
     5258                if ( ! height ) { 
     5259                    height = headerElement.outerHeight(); 
     5260                    headerElement.data( 'height', height ); 
     5261                } 
     5262                return height; 
     5263            }; 
     5264 
     5265            // Reposition header on throttled `scroll` event. 
     5266            positionStickyHeader = function( header, scrollTop, isScrollingUp ) { 
     5267                var headerElement = header.element, 
     5268                    headerParent = header.parent, 
     5269                    headerHeight = header.height, 
     5270                    headerTop = parseInt( headerElement.css( 'top' ), 10 ), 
     5271                    maybeSticky = headerElement.hasClass( 'maybe-sticky' ), 
     5272                    isSticky = headerElement.hasClass( 'is-sticky' ), 
     5273                    isInView = headerElement.hasClass( 'is-in-view' ); 
     5274 
     5275                // When scrolling down, gradually hide sticky header. 
     5276                if ( ! isScrollingUp ) { 
     5277                    if ( isSticky ) { 
     5278                        headerTop = scrollTop; 
     5279                        headerElement 
     5280                            .removeClass( 'is-sticky' ) 
     5281                            .css( { 
     5282                                top:   headerTop + 'px', 
     5283                                width: '' 
     5284                            } ); 
     5285                    } 
     5286                    if ( isInView && scrollTop > headerTop + headerHeight ) { 
     5287                        headerElement.removeClass( 'is-in-view' ); 
     5288                        headerParent.css( 'padding-top', '' ); 
     5289                    } 
     5290                    return; 
     5291                } 
     5292 
     5293                // Scrolling up. 
     5294                if ( ! maybeSticky && scrollTop >= headerHeight ) { 
     5295                    maybeSticky = true; 
     5296                    headerElement.addClass( 'maybe-sticky' ); 
     5297                } else if ( 0 === scrollTop ) { 
     5298                    // Reset header in base position. 
     5299                    headerElement 
     5300                        .removeClass( 'maybe-sticky is-in-view is-sticky' ) 
     5301                        .css( { 
     5302                            top:   '', 
     5303                            width: '' 
     5304                        } ); 
     5305                    headerParent.css( 'padding-top', '' ); 
     5306                    return; 
     5307                } 
     5308 
     5309                if ( isInView && ! isSticky ) { 
     5310                    // Header is in the view but is not yet sticky. 
     5311                    if ( headerTop >= scrollTop ) { 
     5312                        // Header is fully visible. 
     5313                        headerElement 
     5314                            .addClass( 'is-sticky' ) 
     5315                            .css( { 
     5316                                top:   '', 
     5317                                width: headerParent.outerWidth() + 'px' 
     5318                            } ); 
     5319                    } 
     5320                } else if ( maybeSticky && ! isInView ) { 
     5321                    // Header is out of the view. 
     5322                    headerElement 
     5323                        .addClass( 'is-in-view' ) 
     5324                        .css( 'top', ( scrollTop - headerHeight ) + 'px' ); 
     5325                    headerParent.css( 'padding-top', headerHeight + 'px' ); 
     5326                } 
     5327            }; 
     5328        }()); 
     5329 
    51595330        // Previewed device bindings. 
    51605331        api.previewedDevice = new api.Value(); 
Note: See TracChangeset for help on using the changeset viewer.