Posição fixa mas relativa ao contêiner

Estou tentando consertar um div para que ele fique sempre no topo da canvas, usando:

 position: fixed; top: 0px; right: 0px; 

No entanto, o div está dentro de um contêiner centralizado. Quando uso position:fixed ele fixa o div relação à janela do navegador, por exemplo, contra o lado direito do navegador. Em vez disso, deve ser fixado em relação ao contêiner.

Eu sei que position:absolute pode ser usado para fixar um elemento relativo ao div , mas quando você rola a página, o elemento desaparece e não fica no topo como na position:fixed .

Existe um truque ou solução para conseguir isso?

    Resposta curta: não. (Agora é possível com a transformação CSS. Veja a edição abaixo)

    Resposta longa: O problema com o uso de posicionamento “fixo” é que ele retira o elemento do stream . assim, não pode ser reposicionado em relação a seu pai porque é como se não tivesse um. Se, no entanto, o contêiner tiver uma largura fixa e conhecida, você poderá usar algo como:

     #fixedContainer { position: fixed; width: 600px; height: 200px; left: 50%; top: 0%; margin-left: -300px; /*half the width*/ } 

    http://jsfiddle.net/HFjU6/1/

    Editar (03/2015):

    Esta é uma informação desatualizada. Agora é possível centralizar o conteúdo de um tamanho dynamic (horizontal e verticalmente) com a ajuda da mágica da transformação CSS3. O mesmo princípio se aplica, mas em vez de usar margem para compensar seu contêiner, você pode usar o translateX(-50%) . Isso não funciona com o truque de margem acima, porque você não sabe quanto compensá-lo, a menos que a largura seja fixa e você não possa usar valores relativos (como 50% ) porque ele será relativo ao pai e não ao elemento é aplicado a. transform se comporta de maneira diferente. Seus valores são relativos ao elemento ao qual eles são aplicados. Assim, 50% para transform significa metade da largura do elemento, enquanto 50% para margem é metade da largura do pai. Esta é uma solução IE9 +

    Usando código semelhante ao exemplo acima, recriou o mesmo cenário usando largura e altura completamente dinâmicas:

     .fixedContainer { background-color:#ddd; position: fixed; padding: 2em; left: 50%; top: 0%; transform: translateX(-50%); } 

    Se você quer que ele seja centralizado, você pode fazer isso também:

     .fixedContainer { background-color:#ddd; position: fixed; padding: 2em; left: 50%; top: 50%; transform: translate(-50%, -50%); } 

    Demos:

    jsFiddle: centralizado apenas horizontalmente
    jsFiddle: Centralizado horizontalmente e verticalmente
    O crédito original vai para o usuário aaronk6 por apontar para mim nesta resposta

    Na verdade, isso é possível e a resposta aceita trata apenas da centralização, o que é bastante simples. Além disso, você realmente não precisa usar JavaScript.

    Isso permitirá que você lide com qualquer cenário:

    Configure tudo como se você quisesse posicionar: absolute dentro de uma posição: container relativo, e então crie uma nova posição fixa div dentro da div com position: absolute , mas não defina suas propriedades top e left. Ele será então corrigido onde você quiser, em relação ao contêiner.

    Por exemplo:

     /* Main site body */ .wrapper { width: 940px; margin: 0 auto; position: relative; /* Ensure absolute positioned child elements are relative to this*/ } /* Absolute positioned wrapper for the element you want to fix position */ .fixed-wrapper { width: 220px; position: absolute; top: 0; left: -240px; /* Move this out to the left of the site body, leaving a 20px gutter */ } /* The element you want to fix the position of */ .fixed { width: 220px; position: fixed; /* Do not set top / left! */ } 
     
    Content in here will be fixed position, but 240px to the left of the site body.

    Sim, de acordo com as especificações, há um caminho.

    Embora eu concorde que a Graeme Blackwood deve ser a resposta aceita, porque praticamente resolve o problema, deve-se notar que um elemento fixo pode ser posicionado relativamente ao seu recipiente.

    Eu notei por acaso que, ao aplicar

     -webkit-transform: translateZ(0); 

    para o corpo, fez uma criança fixa em relação a ela (em vez da janela de visualização). Então, meus elementos fixos left e top propriedades top agora são relativas ao contêiner.

    Então eu fiz algumas pesquisas, e descobri que a questão já foi abordada por Eric Meyer e mesmo que pareça um “truque”, acontece que isso é parte das especificações:

    Para elementos cujo layout é governado pelo modelo de checkbox CSS, qualquer valor diferente de none para a transformação resulta na criação de um contexto de empilhamento e de um bloco de contenção. O object atua como um bloco de contenção para descendentes posicionados fixos.

    http://www.w3.org/TR/css3-transforms/

    Portanto, se você aplicar qualquer transformação a um elemento pai, ele se tornará o bloco de contenção.

    Mas…

    O problema é que a implementação parece buggy / creative, porque os elementos também param de se comportar como fixos (mesmo que esse bit não pareça ser parte da especificação).

    O mesmo comportamento será encontrado no Safari, Chrome e Firefox, mas não no IE11 (onde o elemento fixo ainda permanecerá fixo).

    Outra coisa interessante (não documentada) é que quando um elemento fixo está contido dentro de um elemento transformado, enquanto suas propriedades top e left serão relacionadas ao contêiner, respeitando a propriedade de box-sizing , seu contexto de rolagem se estenderá ao longo da borda do elemento. elemento, como se o box-sizing estivesse definido como border-box . Para algum criativo lá fora, isso poderia se tornar um brinquedo 🙂

    TESTE

    A resposta é sim, contanto que você não defina para a left: 0 ou right: 0 depois de definir a posição div como fixa.

    http://jsfiddle.net/T2PL5/85/

    Verifica a div da barra lateral. É fixo, mas relacionado ao pai, não ao ponto de vista da janela.

     body { background: #ccc; } .wrapper { margin: 0 auto; height: 1400px; width: 650px; background: green; } .sidebar { background-color: #ddd; float: left; width: 300px; height: 100px; position: fixed; } .main { float: right; background-color: yellow; width: 300px; height: 1400px; } 
    wrapper
    main

    Eu criei este plugin jQuery para resolver um problema semelhante que eu estava tendo onde eu tinha um contêiner centralizado (dados tabulares), e eu queria que o header para corrigir o topo da página quando a lista foi rolada, mas eu queria que ele ancorado os dados tabulares para que fiquem onde quer que eu coloque o container (centralizado, à esquerda, à direita) e também permitam que ele se mova para a esquerda e direita com a página quando rolada horizontalmente.

    Aqui está o link para este plugin jQuery que pode resolver este problema:

    https://github.com/bigspotteddog/ScrollToFixed

    A descrição deste plugin é a seguinte:

    Este plugin é usado para fixar elementos no topo da página, se o elemento tiver rolado para fora da vista, verticalmente; no entanto, ele permite que o elemento continue se movendo para a esquerda ou para a direita com a rolagem horizontal.

    Dada uma opção marginTop, o elemento deixará de se mover verticalmente para cima uma vez que a rolagem vertical tenha atingido a posição desejada; mas, o elemento ainda se moverá horizontalmente à medida que a página for rolada para a esquerda ou para a direita. Depois que a página tiver sido rolada de volta para baixo, passando pela posição desejada, o elemento será restaurado para sua posição original na página.

    Este plugin foi testado no Firefox 3/4, Google Chrome 10/11, Safari 5 e Internet Explorer 8/9.

    Uso para o seu caso particular:

       $(document).ready(function() { $('#mydiv').scrollToFixed(); }); 

    Basta tirar os estilos superior e esquerdo da posição fixa div. Aqui está um exemplo

     
    content

    O #content div será colocado onde quer que o div pai esteja, mas será fixado lá.

    Você tem position: sticky que é uma nova maneira de posicionar elementos e é conceitualmente similar à position: fixed . A diferença é que um elemento com position: sticky se comporta como position: relative em seu pai, até que um determinado limite de offset seja atingido na viewport.

    No Chrome 56 (atualmente beta em dezembro de 2016, estável em janeiro de 2017) posição: pegajosa agora está de volta.

    https://developers.google.com/web/updates/2016/12/position-sticky

    Mais detalhes estão em Stick seus desembarques! position: terras pegajosas no WebKit .

    Eu tive que fazer isso com um anúncio que meu cliente queria ficar fora da área de conteúdo. Eu simplesmente fiz o seguinte e funcionou como um encanto!

     

    Dois elementos HTML e CSS puro (navegadores modernos)

    Veja este exemplo do jsFiddle. Redimensione e veja como os elementos fixos até se movem com os elementos flutuantes em que estão. Use a barra de rolagem mais interna para ver como o pergaminho funcionaria em um site (elementos fixos permanecendo fixos).

    Como muitos aqui afirmaram, uma chave não está definindo nenhuma configuração posicional no elemento fixed (nenhum valor top , right , bottom ou left ).

    Em vez disso, colocamos todos os elementos fixos (observe como a última checkbox tem quatro deles) primeiro na checkbox em que devem ser posicionados, assim:

     
    Test
    Some other content in.

    Em seguida, usamos margin-top e margin-left para “movê-los” em relação ao seu contêiner, algo como esse CSS faz:

     .fixed { position: fixed; margin-top: 200px; /* Push/pull it up/down */ margin-left: 200px; /* Push/pull it right/left */ } 

    Observe que, como fixed elementos fixed ignoram todos os outros elementos de layout, o contêiner final em nosso violino pode ter vários elementos fixed e ainda ter todos esses elementos relacionados ao canto superior esquerdo. Mas isso só é verdade se todos eles forem colocados em primeiro lugar no contêiner, pois esse violino de comparação mostra que, se dispersos no conteúdo do contêiner, o posicionamento não é confiável .

    Se o wrapper é estático , relativo ou absoluto no posicionamento, isso não importa.

    Você pode usar position: sticky property.

    Aqui está um exemplo do CODEPEN demonstrando o uso e também como ele difere da position: fixed .

    Como se comporta é explicado abaixo:

    1. Um elemento com posição adesiva é posicionado com base na posição de rolagem do usuário. Basicamente, ele age como position: relative até que um elemento seja rolado além de um offset específico, e nesse caso ele se transforma em position: fixed. Quando ele é rolado de volta, ele volta para sua posição anterior (relativa).

    2. Ele afeta o stream de outros elementos na página, ou seja, ocupa um espaço específico na página (assim como a position: relative ).

    3. Se estiver definido dentro de algum contêiner, ele é posicionado em relação a esse contêiner. Se o contêiner tiver algum estouro (rolagem), dependendo do deslocamento de rolagem, ele ficará na posição: fixo.

    Então, se você quiser alcançar a funcionalidade fixa, mas dentro de um contêiner, use o adesivo.

    Você pode tentar meu plugin jQuery, FixTo .

    Uso:

     $('#mydiv').fixTo('#centeredContainer'); 

    Outra solução estranha para alcançar uma posição fixa relativa é converter seu contêiner em um iframe. Dessa forma, seu elemento fixo pode ser corrigido na porta de visualização do contêiner e não na página inteira.

    Com CSS puro, você não consegue fazer isso; pelo menos eu não tenho. No entanto, você pode fazê-lo com jQuery de forma muito simples. Vou explicar meu problema e, com uma pequena mudança, você pode usá-lo.

    Então, para começar, eu queria que meu elemento tivesse um topo fixo (da parte superior da janela) e um componente à esquerda para herdar do elemento pai (porque o elemento pai está centrado). Para definir o componente esquerdo, basta colocar seu elemento no pai e definir position:relative para o elemento pai.

    Então você precisa saber quanto do topo seu elemento é quando a barra de rolagem está no topo (y zero rolado); há duas opções novamente. Primeiro é que é estático (algum número) ou você tem que lê-lo a partir do elemento pai.

    No meu caso, são 150 pixels da parte superior estática. Então, quando você vê 150, é quanto é o elemento do topo quando não rolamos.

    CSS

     #parent-element{position:relative;} #promo{position:absolute;} 

    jQuery

     $(document).ready(function() { //This check window scroll bar location on start wtop=parseInt($(window).scrollTop()); $("#promo").css('top',150+wtop+'px'); }); $(window).scroll(function () { //This is when the window is scrolling wtop=parseInt($(window).scrollTop()); $("#promo").css('top',150+wtop+'px'); }); 

    Isso é fácil (conforme o HTML abaixo)

    O truque é NÃO usar top ou left no elemento (div) com “position: fixed;”. Se estes não forem especificados, o elemento “conteúdo fixo” aparecerá RELATIVE para o elemento incluído (o div com “position: relative;”) INSTEAD OF relativo à janela do navegador !!!

     
    lots of Text To Be Scrolled vertically... bhah! blah! blah!

    Acima permiti-me localizar um botão “X” de fechamento no topo de um monte de texto em um div com rolagem vertical. O “X” fica no lugar (não se move com texto rolado e ainda se move para a esquerda ou para a direita com o contêiner div contido quando o usuário redimensiona a largura da janela do navegador! Assim, ele é “fixo” verticalmente, mas posicionado em relação a o elemento envolvente horizontalmente!

    Antes de eu começar este trabalho, o “X” rolou para cima e para fora da vista quando eu rolei o conteúdo do texto para baixo.

    Desculpas por não fornecer minha function hideDiv () do javascript, mas isso tornaria desnecessariamente esse post mais longo. Eu optei por mantê-lo o mais curto possível.

    Eu criei um jsfiddle para demonstrar como isso funciona usando transformar.

    HTML

     
    Content
    X
    Side bar

    CSS

     body { margin: 0; } .left { width: 77%; background: teal; height: 2000px; } .right { width: 23%; background: yellow; height: 100vh; position: fixed; right: 0; top: 0; } .fixedContainer { background-color:#ddd; position: fixed; padding: 2em; //right: 0; top: 0%; transform: translateX(-100px); } 

    jQuery

     $('.fixedContainer').on('click', function() { $('.right').animate({'width': '0px'}); $('.left').animate({'width': '100%'}); }); 

    https://jsfiddle.net/bx6ktwnn/1/

    Eu tenho o mesmo problema, um dos membros da nossa equipe me dá uma solução. Para permitir a posição de correção div e relativa a outras div, nossa solução é usar um contêiner pai para agrupar a div correção e div de rolagem.

     

    css

     .container { position: relative; flex:1; display:flex; } .fix { prosition:absolute; } 

    Eu fiz algo assim por algum tempo atrás. Eu era bem novo em JavaScript, então tenho certeza que você pode fazer melhor, mas aqui está um ponto de partida:

     function fixxedtext() { if (navigator.appName.indexOf("Microsoft") != -1) { if (document.body.offsetWidth > 960) { var width = document.body.offsetWidth - 960; width = width / 2; document.getElementById("side").style.marginRight = width + "px"; } if (document.body.offsetWidth < 960) { var width = 960 - document.body.offsetWidth; document.getElementById("side").style.marginRight = "-" + width + "px"; } } else { if (window.innerWidth > 960) { var width = window.innerWidth - 960; width = width / 2; document.getElementById("side").style.marginRight = width + "px"; } if (window.innerWidth < 960) { var width = 960 - window.innerWidth; document.getElementById("side").style.marginRight = "-" + width + "px"; } } window.setTimeout("fixxedtext()", 2500) } 

    Você precisará definir sua largura e, em seguida, obtém a largura da janela e altera a margem a cada poucos segundos. Eu sei que é pesado, mas funciona.

    É possível se você usar JavaScript. Neste caso, o plugin do jQuery Sticky-Kit :

    Meu projeto é .NET ASP Core 2 MVC Angular 4 modelo com Bootstrap 4. Adicionando “sticky-top” no componente principal do aplicativo html (ou seja, app.component.html) na primeira linha trabalhada, como segue:

     

    Verifique isso: