Создадим простой быстрореагирующий аккордеон, который при раскрытии будет перемещаться к верхней области просмотра. Также будет добавлено несколько переходов CSS3 для стрелки. Гибкость заключается в том, что ширина аккордеона будет подстраиваться под размеры экрана.

Разметка HTML

Cтруктура html будет состоять из контейнера с ID и class "st-accordion" и неупорядоченного списка. У элементов списка будет ссылка, служащая заголовком пункта аккордеона и блок с контентом, который изначально скрыт. Блок SPAN с классом "st-arrow" будет стрелкой в правой части, которая появляется при наведении на название пункта:

<div id="st-accordion" class="st-accordion">
    <ul>
        <li>
            <a href="#">Название пункта<span class="st-arrow">Открыть или Закрыть</span></a>
            <div class="st-content">
                <p>Контент</p>
            </div>
        </li>
        <li>
              ...
        </li>
    </ul>
</div>

CSS

В начале стилизуем основной контейнер, дав ему ширину в 100%, так как хотим, чтобы он подстраивался под ширинув внешнего контейнера. Если внешнего контейнера у вас нет, то используйте значение в процентах, которое вам больше подходит. В нашем примере у внешнего контейнера максимальная ширина 800px, а ширина 90%. У "st-accordion" будет минимальная ширина 270px:

.st-accordion{
    width:100%;
    min-width:270px;
    margin: 0 auto;
}


Предположим, хотя в примере он и используется, у нас есть некоторый стиль reset.css, который сбрасывает значения padding и margin из списков UL и т.д., тогда мы определяем стиль для каждого элемента списка. Установим начальную высоту 100px, в основном она будет высотой элемента ссылки, а переполнение - overflow - будет скрыто, т.е. контент мы не увидим. При открытии элемента, мы анимируем его высоту, чтобы показать контент. Границы border позволяет нам создать разделение между пунктами аккордеона:

.st-accordion ul li{
    height: 100px;
    border-bottom: 1px solid #c7deef;
    border-top:1px solid #fff;
    overflow: hidden;
}

У первого пункта не будет верхней границы:

.st-accordion ul li:first-child{
    border-top:none;
}

Для ссылок добавим цветной переход при наведении мышки. Высота строки - line-height - должна быть такой же, как и начальная высота элемента списка:

.st-accordion ul li > a{
    font-family: Verdana,Georgia, serif;
    text-shadow: 1px 1px 1px #fff;
    font-size: 46px;
    display: block;
    position: relative;
    line-height: 100px;
    outline:none;
    -webkit-transition:  color 0.2s ease-in-out;
    -moz-transition:  color 0.2s ease-in-out;
    -o-transition:  color 0.2s ease-in-out;
    -ms-transition:  color 0.2s ease-in-out;
    transition:  color 0.2s ease-in-out;
}
.st-accordion ul li > a:hover{
    color: #1693eb;
}

SPAN для стрелки будет раположен абсолютно, мы также скроем его, поместив за пределами элемента ссылки с прозрачностью 0. С помощью переходов стрелка будет появляться справой стороны:

.st-accordion ul li > a span{
    background: transparent url(../images/down.png) no-repeat center center;
    text-indent:-9000px;
    width: 26px;
    height: 14px;
    position: absolute;
    top: 50%;
    right: -26px;
    margin-top: -7px;
    opacity:0;
    -webkit-transition:  all 0.2s ease-in-out;
    -moz-transition:  all 0.2s ease-in-out;
    -o-transition:  all 0.2s ease-in-out;
    -ms-transition:  all 0.2s ease-in-out;
    transition:  all 0.2s ease-in-out;
}
.st-accordion ul li > a:hover span{
    opacity:1;
    right: 10px;
}

Когда мы раскроем пункт аккордеона, то назначим для него класс st-open и ссылка останется с цветом, какой был при наведении. SPAN будет повернут на 180 градусов:

.st-accordion ul li.st-open > a{
    color: #1693eb;
}
.st-accordion ul li.st-open > a span{
    -webkit-transform:rotate(180deg);
    -moz-transform:rotate(180deg);
    transform:rotate(180deg);
    right:10px;
    opacity:1;
}

Это стиль контента и его элементов:

.st-content{
    padding: 5px 0px 30px 0px;
}
.st-content p{
    font-size:  16px;
    font-family:  Georgia, serif;
    font-style: italic;
    line-height:  28px;
    padding: 0px 4px 15px 4px; 
}
.st-content img{
    border-right:1px solid #fff;
    border-bottom:1px solid #fff;
}

С помощью media запроса, удостоверимся, что размер шрифта заголовка будет меньше:

@media screen and (max-width: 320px){
    .st-accordion ul li > a{
        font-size:36px;
    }
}

javascript

Подключаем jQuery библиотеку и плагин easing и плагин accordion, о котором ниже чуть подробнее.

Самые важные части плагина accordion.

Начнем с настроек по умолчанию:

$.Accordion.defaults         = {
    // Открыт или Закрыт пункт. -1 означает, что все пункты свернуты по умолчанию.
    open            : -1,
    // если установлено true, то только один элемент может быть раскрыт, другой, если был открыт, свернется.
    oneOpenedItem    : false,
    // сокрость анимации открытия / закрытия
    speed            : 600,
    // название используемой анимации открытия / закрытия
    easing            : 'easeInOutExpo',
    // сокрость анимации прокрутки
    scrollSpeed        : 900,
    // анимация при прокрутке
    scrollEasing    : 'easeInOutExpo'
};

Инициализируем плагин вызывая функцию _init:

_init                 : function( options ) {
    
    this.options         = $.extend( true, {}, $.Accordion.defaults, options );
    
    // проверка опций
    this._validate();
    
    // current is the index of the opened item
    this.current        = this.options.open;
    
    // скрыть содержимое
    this.$items.find('div.st-content').hide();
    
    // сохранить оригинальную высоту и значение top каждого пункта
    this._saveDimValues();
    
    // если мы хотим, пункт открыт по умолчанию...
    if( this.current != -1 )
        this._toggleItem( this.$items.eq( this.current ) );
    
    // инициализируем события
    this._initEvents();
    
},

Функция _saveDimValues сохраняет исходную высоту и значение top элемента так, чтобы мы знали до куда должны прокрутить при открытии элмента.
Если мы установили по умолчанию элемент открытым, то вызывается функция _toggleItem. Затем инициализируем событие.
Функция _toggleItem заботится о двух случаях, когда мы кликаем по пунктам, то есть при открытии и закрытии элементов. И затем прокручиваем окно до положения при котором элемент по которому кликаем, останется вверху за счет функции _scroll:

_toggleItem            : function( $item ) {
    
    var $content = $item.find('div.st-content');
    
    ( $item.hasClass( 'st-open' ) ) 
            
        ? ( this.current = -1, $content.stop(true, true).fadeOut( this.options.speed ), $item.removeClass( 'st-open' ).stop().animate({
            height    : $item.data( 'originalHeight' )
        }, this.options.speed, this.options.easing ) )
        
        : ( this.current = $item.index(), $content.stop(true, true).fadeIn( this.options.speed ), $item.addClass( 'st-open' ).stop().animate({
            height    : $item.data( 'originalHeight' ) + $content.outerHeight( true )
        }, this.options.speed, this.options.easing ), this._scroll( this ) )

},

В функции _initevents мы инициализируем два события, нажатие на пункт и изменение размеров окна. Когда мы кликаем по элементу мы или открываем или закрываем его, вызывая функцию _toggleItem и если мы установили опцию oneOpenedItem в значение true, то мы закрываем сначала любой открытый элемент прежде, чем открыть текущий.
Когда окно изменено, мы должны сбросить исходные значения элемента и высоту контента. И затем элемент прокручивается к верху:

_initEvents            : function() {
    
    var instance    = this;
    
    // открыть / закрыть пункт
    this.$items.find('a:first').bind('click.accordion', function( event ) {
        
        var $item            = $(this).parent();
        
        // закрыть открытый пункт, если oneOpenedItem - true
        if( instance.options.oneOpenedItem && instance._isOpened() && instance.current!== $item.index() ) {
            
            instance._toggleItem( instance.$items.eq( instance.current ) );
        
        }
        
        // открыть / закрыть пункт
        instance._toggleItem( $item );
        
        return false;
    
    });
    
    $(window).bind('smartresize.accordion', function( event ) {
        
        // сбросить исходные значения
        instance._saveDimValues();
    
        // сбросить высоту контента любого элемента, который в настоящий момент открыт
        instance.$el.find('li.st-open').each( function() {
            
            var $this    = $(this);
            $this.css( 'height', $this.data( 'originalHeight' ) + $this.find('div.st-content').outerHeight( true ) );
        
        });
        
        // прокуртка до текушего
        if( instance._isOpened() )
        instance._scroll();
        
    });
    
},

Это наиболее важные функции для данного аккордеона.

СКАЧАТЬСкачек: 1135
56,2 Kb
Кто скачал?

ДЕМОПосмотреть
пример