Como construir barras laterais colapsáveis com Bootstrap e jQuery

Neste tutorial vamos usar o sistema de grelha do Bootstrap 3 e algum CSS e jQuery para construir três soluções distintas:

Esta abordagem funciona tanto para contentores fixos como fluidos.

Barra lateral esquerda colapsável

O Bootstrap 3 tem um sistema de grelha responsivo com 12 colunas. A nossa barra lateral vai ocupar 3 colunas e as restantes 9 serão usadas para o conteúdo.

É importante tomar nota disto porque irá influenciar a nossa implementação. Devem adaptar a vossa solução para o tamanho desejado.

<div class="container">
    <div class="row" id="row-main">
        <div class="col-md-3" id="sidebar">
            ...
        </div>
        <div class="col-md-9" id="content">
            ...
        </div>
    </div>
</div>

Quando uma barra lateral for colapsada acontecerá o seguinte:

  • A barra lateral será escondida
  • O contentor do conteúdo irá ocupar o espaço deixado livre pela barra lateral

No nosso caso, o contentor do conteúdo passará de 9 colunas para 12.

Outro aspecto a ter em conta é como irá ser escondida a barra lateral. Vamos implementar isto de duas formas:

  • Para ecrãs maiores iremos usar uma margem negativa à esquerda (da mesma largura da barra lateral) para que possamos animar a transição
  • Para ecrãs mais pequenos, como cada coluna é quebrada para a sua própria linha, vamos simplesmente esconder a barra lateral quando colapsada
.collapsed {
    display: none; /* hide it for small displays */
}
@media (min-width: 992px) {
    .collapsed {
        display: block;
        margin-left: -25%; /* same width as sidebar */
    }
}

Reparem no breakpoint da media query. Estamos a usar um breakpoint de min-width apropriado para colunas de tamanho médio (.col-md-). Têm de adaptar esta parte se estiverem a usar colunas de tamanho diferente.

Como estamos a atribuir uma margem negativa à esquerda, a barra lateral será empurrada para fora do contentor. Precisamos de escondê-la. Fazemos isso ao definir o overflow na linha principal.

#row-main {
    overflow-x: hidden; /* necessary to hide collapsed sidebar */
}

Agora a única coisa que falta fazer é tratar da animação.

#content {
    -webkit-transition: width 0.3s ease;
    -moz-transition: width 0.3s ease;
    -o-transition: width 0.3s ease;
    transition: width 0.3s ease;
}
#sidebar {
    -webkit-transition: margin 0.3s ease;
    -moz-transition: margin 0.3s ease;
    -o-transition: margin 0.3s ease;
    transition: margin 0.3s ease;
}

E quando queremos alternar o estado da barra lateral apenas trocamos as classes CSS apropriadas:

$("#sidebar").toggleClass("collapsed");
$("#content").toggleClass("col-md-12 col-md-9");

Barra lateral direita colapsável

Como devem imaginar, ter a barra lateral do lado direito não requer uma solução muito diferente.

O HTML apenas necessita de um pequeno ajuste – a barra lateral irá aparecer depois do contentor do conteúdo.

<div class="container">
    <div class="row" id="row-main">
        <div class="col-md-9" id="content">
            ...
        </div>
        <div class="col-md-3" id="sidebar">
            ...
        </div>
    </div>
</div>

A única outra coisa que muda na solução é que a margem irá ser aplicada à direita:

@media (min-width: 992px) {
    .collapsed {
        display: block;
        margin-right: -25%; /* same width as sidebar */
    }
}

O resto irá permanecer igual.

Barras laterais colapsáveis em ambos os lados

Ter barras laterais em ambos os lados torna a solução um bocadinho mais complicada.

A estrutura HTML irá agora incluir duas barras laterais.

<div class="container">
    <div class="row" id="row-main">
        <div class="col-md-3 sidebar" id="sidebar-left">
            ...
        </div>
        <div class="col-md-6" id="content">
            ...
        </div>
        <div class="col-md-3 sidebar" id="sidebar-right">
            ...
        </div>
    </div>
</div>

Adaptamos o CSS para ter em conta os diferentes estados colapsados.

@media (min-width: 992px) {
    .collapsed {
        display: block;
    }
    #sidebar-left.collapsed {
        margin-left: -25%; /* same width as sidebar */
    }
    #sidebar-right.collapsed {
        margin-right: -25%; /* same width as sidebar */
    }
}

Como ambas as barras laterais partilham agora uma classe comum, também precisamos de actualizar o código da transição.

.sidebar {
    -webkit-transition: margin 0.3s ease;
    -moz-transition: margin 0.3s ease;
    -o-transition: margin 0.3s ease;
    transition: margin 0.3s ease;
}

Do lado do Javascript as coisas ficam um bocado mais complicadas, porque agora temos de considerar 3 larguras diferentes para o contentor do conteúdo.

Para colapsar ou expandir uma barra lateral temos de:

  • Alternar a classe collapsed na barra lateral
  • Encontrar o número de barras laterais expandidas
  • Determinar a classe apropriada para o conteúdo de acordo com o número de barras laterais expandidas
  • Aplicar a classe correcta ao contentor do conteúdo

O contentor do conteúdo irá alternar entre 6, 9, ou 12 colunas, já que cada barra lateral ocupa exactamente 3 colunas.

function toggleSidebar(side) {
    if (side !== "left" && side !== "right") {
        return false;
    }
    var left = $("#sidebar-left"),
        right = $("#sidebar-right"),
        content = $("#content"),
        openSidebarsCount = 0,
        contentClass = "";
    
    // toggle sidebar
    if (side === "left") {
        left.toggleClass("collapsed");
    } else if (side === "right") {
        right.toggleClass("collapsed");
    }
    
    // determine number of open sidebars
    if (!left.hasClass("collapsed")) {
        openSidebarsCount += 1;
    }
    
    if (!right.hasClass("collapsed")) {
        openSidebarsCount += 1;
    }
    
    // determine appropriate content class
    if (openSidebarsCount === 0) {
        contentClass = "col-md-12";
    } else if (openSidebarsCount === 1) {
        contentClass = "col-md-9";
    } else {
        contentClass = "col-md-6";
    }
    
    // apply class to content
    content.removeClass("col-md-12 col-md-9 col-md-6")
        .addClass(contentClass);
}

Podemos alternar o estado de uma barra lateral chamando a função acima com o parâmetro apropriado.

toggleSidebar("left");

Conclusão

Com Bootstrap 3, jQuery e alguma magia CSS construímos uma barra lateral colapsável com conteúdo expansível.

Podem encontrar o código fonte no GitHub ou nos 3 exemplos:

Artigos relacionados