CSS Positioning and [stacking] contexts
In this content we'll cover the following topics , this is the PT-Br version if you wanna the english version please comment bellow that I'll share here too .
- The types of element positioning: fixed, relative, and absolute
- Building modal dialogs and dropdown menus
- Understanding z-index and stacking contexts
- A new type of positioning: sticky
Vamos examinar uma técnica importante:
a propriedade position
, que você pode usar para construir menus suspensos, diálogos modais e outros efeitos essenciais para aplicações web modernas. Além disso, você aprenderá sobre algo chamado contexto de empilhamento(stacking context), que é uma espécie de efeito colateral oculto da posicionamento. Entender o contexto de empilhamento(stacking context) evitará problemas e, se você algum dia se encontrar em dificuldades com um layout de página, esse conhecimento lhe dará as ferramentas necessárias para voltar aos trilhos.
O valor inicial da propriedade position
é static
. Tudo o que fizemos nos capítulos anteriores foi com posicionamento estático. Quando você altera esse valor para qualquer outro, o elemento é considerado posicionado.
Um elemento com posicionamento estático, ele é não posicionado.
Os métodos de layout que cobrimos anteriorment fazem várias coisas para manipular a forma como o fluxo do documento(document flow)se comporta. O posicionamento é diferente: ele remove elementos completamente do fluxo do documento. Isso permite que você posicione o elemento em outro lugar na tela. Ele pode colocar elementos na frente ou atrás de outros, sobrepondo-os.
Posicionamento Fixo
O posicionamento fixo, embora não seja tão comum quanto alguns outros tipos de posicionamento, é provavelmente o mais simples de entender, então começaremos por aqui.
Aplicar position: fixed
a um elemento permite que você posicione o elemento arbitrariamente dentro da janela de visualização.
Isso é feito com quatro propriedades complementares: top
, right
, bottom
e left
. Os valores que você atribui a essas propriedades especificam a distância que o elemento fixo deve estar de cada borda da janela de visualização do navegador.
Por exemplo, top: 3em
em um elemento fixo significa que sua borda superior estará a 3 em do topo da janela de visualização.
Ao definir esses quatro valores, você também define implicitamente a largura e a altura do elemento. Por exemplo, especificar left: 2em; right: 2em
significa que a borda esquerda do elemento estará a 2 em do lado esquerdo da janela de visualização, e a borda direita estará a 2 em do lado direito; assim, o elemento terá 4 em a menos que a largura total da janela de visualização. Da mesma forma, com top
, bottom
e a altura da janela de visualização.
Vamos contruir uma modal como exemple do posicionamento fixo:
usamos javascript para fazer o evento click ,você pode usar como desafio o truque do input checkbox :
<input type="checkbox" hidden id="checking"/>
<label for="checking">
<button> Open <button>
</label>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Learning about Positioning and stacking Elements</title>
<style>
body{
font-family: Helvetica, Arial, sans-serif;
min-height: 200vh;
margin: 0;
}
button{
padding: 0.5em 0.7em;
border: 1px solid #8d8d8d;
background-color: white;
font-size: 1em;
}
.top-banner{
padding: 1em 0;
background-color: #ffd698;
}
.top-banner-inner{
width: 80%;
max-width: 1000px;
margin: 0 auto;
}
.modal-container{
display: block;
}
.modal-backdrop{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.modal-body{
position: fixed;
top: 3em;
bottom: 3em;
right: 20%;
left: 20%;
padding: 2em 3em;
background-color: white;
overflow: auto;
}
.modal-close{
cursor: pointer;
}
</style>
</head>
<body>
<header class="top-banner">
<div class="top-banner-inner">
<p>Find out what's going on at Wombat Coffee each
month. Sign up for our newsletter:
<button id="open">Sign up</button>
</p>
</div>
</header>
<div class="modal-container" id="modal">
<div class="modal-backdrop"></div>
<div class="modal-body">
<button class="modal-close" id="close">close</button>
<h2>Wombat Newsletter</h2>
<p>Sign up for our monthly newsletter. No spam. We promise!</p>
<form>
<p>
<label for="email">Email address:</label>
<input type="text" name="email"/>
</p>
<p><button type="submit">Submit</button></p>
</form>
</div>
</div>
<script type="text/javascript">
var button = document.getElementById('open'); // botton to open modal
var close = document.getElementById('close'); // bottom to close modal
var modal = document.getElementById('modal'); // display modal
button.addEventListener('click', function (event) {
//when open button clicked = open modal
event.preventDefault();
modal.style.display = 'block';
});
close.addEventListener('click', function (event) {
//when close button click = close modal
event.preventDefault();
modal.style.display = 'none';
});
</script>
</body>
</html>
Neste codigo CSS, você usou o posicionamento fixo duas vezes. Primeiro no `modal-backdrop`, com cada um dos quatro lados definido como 0. Isso faz com que o fundo preencha toda a janela de visualização. passamos uma cor de fundo `rgba(0, 0, 0, 0.5)`. Esta notação de cor especifica valores de vermelho, verde e azul de 0, que resulta em preto. O quarto valor é o canal “alfa”, que especifica sua transparência: um valor de 0 é completamente transparente e 1 é completamente opaco. O valor 0.5 é meio transparente. Isso serve para escurecer todo o conteúdo da página por trás do elemento.
O segundo lugar onde usamos o posicionamento fixo é no `modal-body`. Você posicionou cada um de seus quatro lados dentro da janela de visualização: 3 em das bordas superior e inferior e 20% dos lados esquerdo e direito. também definimos uma cor de fundo branca. Isso faz com que o modal seja uma caixa branca, centralizada na tela. Você pode rolar a página como quiser, mas o fundo e o corpo do modal permanecem no lugar.
Agora carregue a página e você verá um banner amarelo claro na parte superior da tela com um botão. Clique no botão para abrir o modal posicionado. Por causa do posicionamento fixo, o modal permanece no lugar, mesmo quando você rola a página (o valor grande de `min-height` no corpo permite rolar para ilustrar esse comportamento).
Clique no botão de fechar na parte superior do modal para fechá-lo. Este botão está em um local estranho agora, mas voltaremos e o posicionaremos em um momento.
Controlando o tamanho de elementos posicionados
Ao posicionar um elemento, você não é obrigado a especificar valores para todos os quatro lados. Você pode especificar apenas os lados necessários e, em seguida, usar width
e/ou height
para ajudar a determinar seu tamanho.
Você também pode permitir que o elemento seja dimensionado naturalmente. Considere estas declarações:
position: fixed;
top: 1em;
right: 1em;
width: 20%;
Isso fixaria o elemento a 1 em das bordas superior e direita da janela de visualização com uma largura de 20% da largura da janela de visualização. Ao omitir as propriedades bottom
e height
, a altura do elemento será determinada naturalmente por seu conteúdo. Isso pode ser usado, por exemplo, para fixar um menu de navegação na tela. Ele permanecerá no lugar mesmo enquanto o usuário rola o conteúdo da página.
Desafio 1: crie um menu com posicionamento fixo , independente da rolagem ,defina um min-height maior para criar um overflow-y
Como um elemento fixo é removido do fluxo do documento, ele não afeta mais a posição de outros elementos na página. Eles seguirão o fluxo normal do documento como se ele não estivesse lá, o que significa que muitas vezes eles fluirão por trás do elemento fixo, ficando ocultos. Isso geralmente é bom com uma caixa de diálogo modal, pois você quer que ela esteja em primeiro plano até que o usuário a feche.
Com algo persistente, como um menu de navegação lateral, você precisará tomar cuidado para que outros conteúdos não fluam por trás dele. Isso geralmente é mais fácil de fazer adicionando uma margem ao conteúdo. Por exemplo, coloque todo o seu conteúdo em um contêiner com right-margin: 20%
. Essa margem fluirá por trás do elemento fixo e o conteúdo não se sobreporá.
Posicionamento Absoluto
O posicionamento fixo, que acabamos de ver, permite posicionar um elemento em relação à janela de visualização(Viewport). Isso é chamado de seu bloco contêiner(containing block). A declaração left: 2em
, por exemplo, posiciona a borda esquerda de um elemento posicionado a 2 em da borda esquerda do bloco contêiner.
O posicionamento absoluto funciona da mesma maneira, exceto que tem um bloco contêiner(containing block) diferente.
Em vez de sua posição ser baseada na janela de visualização(viewport), sua posição é baseada no elemento ancestral posicionado mais próximo. Assim como em um elemento fixo, as propriedades top
, right
, bottom
e left
posicionam as bordas do elemento dentro de seu bloco contêiner.
Vamos Posicionar Absolutamente o Botão de Fechar
Para ver como isso funciona, vamos reposicionar o botão de fechar para o canto superior direito da sua caixa de diálogo modal.
Para fazer isso, você declarará o posicionamento absoluto para o botão de fechar. Seu elemento pai é o modal-body
, que tem posicionamento fixo, então ele se torna o bloco contêiner para o botão(containing block). Edite os estilos do seu botão para corresponder a requisição acima
.modal-close {
position: absolute;
top: 0.3em;
right: 0.3em;
padding: 0.3em;
cursor: pointer;
}
Esta listagem coloca o botão a 0.3 em do topo e 0.3 em da direita do modal-body. Normalmente, como neste exemplo, o bloco contêiner será o pai do elemento. Nos casos em que o elemento pai não é posicionado, o navegador irá subir na hierarquia do DOM até o avô, bisavô, e assim por diante, até encontrar um elemento posicionado, que será então usado como o bloco contêiner(containing block).
NOTA: Se nenhum dos ancestrais do elemento for posicionado, então o elemento posicionado absolutamente será posicionado com base em algo chamado de bloco contêiner inicial(initial containing-block). Esta é uma área com dimensões iguais ao tamanho da janela de visualização (viewport), ancorada no topo da página.
Posicionando um pseudo-elemento
Nós posicionamos o botão Fechar onde queriamos, mas ele está um tanto espartano. Para um botão Fechar como este, os usuários geralmente esperam ver alguma indicação gráfica, como um x.
Sua primeira tentação pode ser remover a palavra “fechar” do seu markup e substituí-la por um x, mas isso introduziria um problema de acessibilidade: Leitores de tela assistivos leem o texto do botão, então ele deve dar alguma indicação significativa do propósito do botão.
O HTML deve fazer sentido por conta própria antes que o CSS seja aplicado.Em vez disso, você pode usar CSS para esconder a palavra “fechar” e exibir um x. Você conseguirá isso fazendo duas coisas.
- Primeiro, você empurrará o texto do botão para fora do botão e esconderá o overflow.
- Segundo, você usará a propriedade content para adicionar o x ao pseudo-elemento ::after do botão e o posicionamento absoluto para centralizá-lo dentro do botão.
Atualize os estilos do seu botão para corresponder o seguinte
DICA: Em vez da letra x, eu recomendo o caractere unicode para o sinal de multiplicação. É mais simétrico e geralmente mais esteticamente agradável para este propósito. O caractere HTML × renderá como este caractere, mas na propriedade content do CSS, você deve usar o número unicode escapado(unicode scaping): \00D7.
.modal-close {
position: absolute;
top: 0.3em;
right: 0.3em;
padding: 0.3em;
cursor: pointer;
font-size: 2em;
height: 1em;
width: 1em;
text-indent: 10em;
overflow: hidden;
border: 0;
}
Posicionamento Relativo
O posicionamento relativo é provavelmente o tipo de posicionamento menos compreendido. Quando você aplica position: relative
a um elemento pela primeira vez, geralmente não verá nenhuma mudança visível na página. O elemento posicionado relativamente, e todos os elementos ao seu redor na página, permanecerão exatamente onde estavam (embora você possa ver algumas mudanças em relação a quais elementos estão na frente de quais. Vamos abordar isso em breve a propriedade z-index).
As propriedades top
, right
, bottom
e left
, se aplicadas, deslocarão o elemento de sua posição original, mas não mudarão a posição de quaisquer elementos ao redor. Veja a figura abaixo para um exemplo. Ela mostra quatro elementos inline-block
. Apliquei três propriedades adicionais ao segundo elemento: position: relative; top: 1em; left: 2em
. Como você pode ver, isso deslocou o elemento de sua posição inicial, mas os outros elementos não foram afetados. Eles ainda seguem o fluxo normal do documento ao redor da posição inicial do elemento deslocado.
Exemplo:
html code:
<div class="container">
<div class="box">Box 1</div>
<div class="box relative-box">Box 2</div>
<div class="box">Box 3</div>
<div class="box">Box 4</div>
</div>
css code:
.container {
display: inline-block;
}
.box {
display: inline-block;
width: 100px;
height: 100px;
background-color: lightblue;
margin: 10px;
text-align: center;
line-height: 100px;
}
.relative-box {
position: relative;
top: 1em;
left: 2em;
}
Neste exemplo, o segundo box (Box 2
) é deslocado 1em para baixo e 2em para a direita, enquanto os outros boxes permanecem inalterados.
Aplicando top
e left
em Posicionamento Relativo
Aplicar top: 1em
move o elemento para baixo 1 em (afastando-o da borda superior original). E left: 2em
desloca o elemento para a direita 2 em (afastando-o da borda esquerda original). Esses deslocamentos podem fazer com que o elemento se sobreponha aos elementos abaixo ou ao lado dele. No posicionamento, valores negativos também são suportados, então bottom: -1em
deslocaria o elemento para baixo 1 em, assim como top: 1em
faz.
Nota
Ao contrário dos posicionamentos fixo e absoluto, você não pode usar top
, right
, bottom
e left
para alterar o tamanho de um elemento posicionado relativamente. Esses valores apenas deslocarão a posição do elemento para cima ou para baixo, para a esquerda ou para a direita. Você pode usar top
ou bottom
, mas não ambos juntos (o bottom
será ignorado); da mesma forma, você pode usar left
ou right
, mas não ambos (o right
será ignorado).
Uso Comum do Posicionamento Relativo
Usar essas propriedades para ajustar a posição de um elemento relativo pode ser útil para ajustar a posição de um elemento ocasionalmente, mas, na verdade, isso raramente é o motivo pelo qual você usará o posicionamento relativo. Muito mais frequentemente, você usará position: relative
para estabelecer o bloco contêiner para um elemento posicionado absolutamente dentro dele.
Criando um Menu Dropdown
Vamos usar posicionamento relativo e absoluto para criar um menu dropdown. Inicialmente será um simples retângulo, mas quando o usuário passar o mouse sobre ele, ele abrirá uma lista de links como mostrado na figura abaixo
a imagem abaixo mostra a marcação para este menu. Anexe-o ao seu HTML após o fechamento do </div>
do elemento <div class="modal">
. Este código inclui um contêiner que você usará para centralizar o conteúdo e alinhá-lo com o conteúdo do banner. Eu também adicionei um <h1>
abaixo do popup para ilustrar como o popup aparece na frente de outro conteúdo na página.
o html serai o seguinte:
<div class="container">
<nav>
<div class="dropdown">
<div class="dropdown-label">Main Menu</div>
<div class="dropdown-menu">
<ul class="submenu">
<li><a href="/">Home</a></li>
<li><a href="/coffees">Coffees</a></li>
<li><a href="/brewers">Brewers</a></li>
<li><a href="/specials">Specials</a></li>
<li><a href="/about">About us</a></li>
</ul>
</div>
</div>
</nav>
<h1>Something to render here</h1>
</div>
CSS code
.container {
width: 80%;
max-width: 1000px;
margin: 1em auto;
}
.dropdown {
display: inline-block;
position: relative;
}
.dropdown-label {
padding: .5em 1.5em;
border: 1px solid #ccc;
background-color: #eee;
}
.dropdown-menu {
display: none;
position: absolute;
left: 0;
top: 2.1em;
min-width: 100%;
background-color: #eee;
}
.dropdown:hover .dropdown-menu {
display: block;
}
.submenu {
padding-left: 0;
margin: 0;
list-style-type: none;
border: 1px solid #999;
}
.submenu > li + li {
border-top: 1px solid #999;
}
.submenu > li > a {
display: block;
padding: .5em 1.5em;
background-color: #eee;
color: #369;
text-decoration: none;
}
.submenu > li > a:hover {
background-color: #fff;
}
Como você usaria suas habilidades parac contruir este dropdown?
Criando um Triângulo em CSS
Vamos adicionar um toque final no nosso menu dropdown. Ele funciona como está, mas pode não ser imediatamente aparente para o usuário que há mais conteúdo a ser descoberto junto com o rótulo do Menu Principal. Vamos adicionar uma pequena seta para baixo ao rótulo para indicar que há mais a explorar.
Você pode usar um pequeno truque com bordas para desenhar um triângulo que serve como a seta apontando para baixo. Você usará o pseudo-elemento ::after
do rótulo do dropdown para desenhar o triângulo e, em seguida, usará posicionamento absoluto para colocá-lo no lado direito do rótulo.
Observa o que acontence quando você aumenta o valor das bordas
Normalmente, quando você adiciona bordas a um elemento, você as faz finas: geralmente 1 px ou 2 px é suficiente. Mas observe o que acontece quando você faz uma borda muito mais grossa. Vou fazer cada lado da borda com uma cor única para destacar onde uma borda termina e a próxima começa.
Observe o que acontece nos cantos onde as bordas de duas arestas se encontram: elas formam uma borda diagonal. Agora observe o que acontece se você reduzir a altura e a largura do elemento para zero (como na figura abaixo). Todas as bordas se unem no centro.
A borda de cada lado do elemento forma um triângulo. A borda superior aponta para baixo; a borda direita aponta para a esquerda, e assim por diante. Com isso em mente, você pode usar uma borda para criar o triângulo que você precisa e então definir a cor das bordas restantes como transparente. Um elemento com bordas esquerda e direita transparentes e uma borda superior visível parecerá como a figura abaixo — um simples triângulo.
Aplicando Estilos ao Pseudo-elemento ::after do Dropdown-label
Vamos aplicar estilos ao pseudo-elemento dropdown-label::after
para criar um triângulo e posicioná-lo usando posicionamento absoluto. Adicione isso ao seu stylesheet:
aqui vai o codigo alterado:
.dropdown-label {
padding: 0.5em 2em 0.5em 1.5em;
border: 1px solid #ccc;
background-color: #eee;
}
.dropdown-label::after {
content: "";
position: absolute;
right: 1em;
top: 1em;
border: 0.3em solid;
border-color: black transparent transparent;
}
dropdown:hover .dropdown-label::after {
top: 0.7em;
border-color: transparent transparent black;
}
Contextos de empilhamento e z-index
Posicionar elementos é útil, mas é importante conhecer as implicações envolvidas. Quando você remove um elemento do fluxo do documento, você se torna responsável por todas as coisas que o fluxo do documento normalmente faz por você.
Gerenciando Elementos Posicionados
- Limites da Janela de Visualização: Certifique-se de que o elemento não transborde acidentalmente para fora da janela de visualização do navegador, tornando-se invisível para o usuário.
- Visibilidade do Conteúdo: Assegure-se de que o elemento posicionado não cubra inadvertidamente conteúdo importante que precisa estar visível.
Elementos Sobrepostos e Ordem de Empilhamento
Quando vários elementos posicionados se sobrepõem, a ordem de empilhamento se torna crucial. Sem o gerenciamento adequado, você pode descobrir que o elemento “errado” aparece na frente de outro. Por exemplo, considere um cenário onde você criou um menu suspenso e uma caixa de diálogo modal:
- Menu Suspenso: Posicionado usando posicionamento absoluto ou fixo.
- Caixa de Diálogo Modal: Posicionada usando posicionamento fixo para permanecer centralizada na tela.
Cenário de Exemplo
Clique no botão “Sign up” no cabeçalho da página para abrir a caixa de diálogo modal. Se o código do menu suspenso estiver posicionado após a modal no seu HTML, você pode ver o menu suspenso aparecer na frente da modal, como mostrado na figura abaixo.
Entendendo o Processo de Renderização e Ordem de Empilhamento
Para resolver isso, é essencial entender como o navegador determina a ordem de empilhamento. Isso envolve o processo de renderização:
- Árvore de Renderização: À medida que o navegador analisa o HTML para o DOM, ele cria uma árvore de renderização que representa a aparência visual e a posição de cada elemento.
- Ordem de Pintura: O navegador determina a ordem em que os elementos são pintados. Elementos pintados posteriormente aparecem na frente dos pintados anteriormente, caso se sobreponham.
Ordem de Empilhamento Normal
Em circunstâncias normais (sem posicionamento aplicado), a ordem de empilhamento é determinada pela ordem em que os elementos aparecem no HTML. Considere os três elementos no seguinte trecho de código:
<div class="element1">Elemento 1</div>
<div class="element2">Elemento 2</div>
<div class="element3">Elemento 3</div>
Neste caso:
element1
é pintado primeiro.element2
é pintado em seguida e aparece na frente deelement1
se eles se sobrepuserem.element3
é pintado por último e aparece na frente deelement1
eelement2
se eles se sobrepuserem.
Criando um Contexto de Empilhamento
Quando elementos são posicionados, especialmente com valores de z-index
, um novo contexto de empilhamento pode ser criado. Um contexto de empilhamento é um grupo isolado de elementos que são empilhados de acordo com certas regras.
Exemplo: z-index e Contextos de Empilhamento
Vamos explorar como controlar a ordem de empilhamento usando z-index
. Considere o seguinte CSS:
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1000; /* Alto z-index para garantir que fique no topo */
}
.dropdown {
position: absolute;
top: 10px;
left: 10px;
z-index: 500; /* Menor z-index do que a modal */
}
Neste exemplo:
- A modal recebe um
z-index
alto de1000
para garantir que apareça no topo. - O menu suspenso tem um
z-index
mais baixo de500
, fazendo com que ele apareça atrás da modal, se eles se sobrepuserem.
Notas Importantes sobre z-index
- Criando Novos Contextos de Empilhamento: Certas propriedades CSS criam novos contextos de empilhamento. Por exemplo,
position: relative;
,position: absolute;
,position: fixed;
,opacity < 1
,transform
,filter
eperspective
. - Contextos de Empilhamento Aninhados: Contextos de empilhamento podem ser aninhados, e cada contexto é tratado de forma independente. Elementos dentro de um contexto aninhado são empilhados entre si primeiro antes de considerar o contexto de empilhamento do pai.
Resumo
Gerenciar elementos posicionados e sua ordem de empilhamento é crucial para manter uma interface clara e amigável para o usuário. Ao entender como o navegador renderiza e empilha elementos, e ao usar propriedades como z-index
de forma ponderada, você pode controlar quais elementos aparecem na frente dos outros, garantindo que sua página web pareça e funcione conforme o esperado.
Entendendo os Contextos de Empilhamento
Um contexto de empilhamento consiste em um elemento ou um grupo de elementos que são pintados juntos pelo navegador. Um elemento é a raiz do contexto de empilhamento. Quando você adiciona um z-index
a um elemento posicionado, esse elemento se torna a raiz de um novo contexto de empilhamento. Todos os seus elementos descendentes passam a fazer parte desse contexto de empilhamento.
Contextos de Empilhamento vs. Contextos de Formatação de Bloco
Não confunda contextos de empilhamento com contextos de formatação de bloco. São conceitos separados, embora não necessariamente exclusivos entre si:
- Contextos de Empilhamento: Lida com quais elementos estão na frente de outros elementos.
- Contextos de Formatação de Bloco: Lida com o fluxo do documento e se os elementos se sobrepõem ou não.
Importância dos Contextos de Empilhamento
O fato de que todos os elementos de um contexto de empilhamento são pintados juntos tem uma ramificação importante:
- Ordem de Empilhamento Interna: Nenhum elemento fora do contexto de empilhamento pode ser empilhado entre dois elementos dentro desse contexto.
- Exemplo: Se um elemento está empilhado na frente de um contexto de empilhamento, nenhum elemento dentro desse contexto pode ser trazido à frente dele. Da mesma forma, se um elemento está empilhado atrás do contexto de empilhamento, nenhum elemento dentro desse contexto pode ser empilhado atrás desse elemento.
Before any further, take a look at the previous topics covered
https://medium.com/@funnymous43/how-to-properly-use-clip-path-9f9704cdcec1
Find me on github:
if you this content useful you can buy me a coffee:
https://buymeacoffee.com/santoscampj
or either through QR code