Existe uma maneira de aumentar a largura de um DIV filho maior que o DIV pai usando CSS?

229

Existe uma maneira de ter um DIV filho dentro de um DIV de contêiner pai que seja mais largo que seu pai. O DIV filho precisa ter a mesma largura da janela de exibição do navegador.

Veja o exemplo abaixo: insira a descrição da imagem aqui

O DIV filho deve permanecer como filho do div principal. Eu sei que posso definir margens negativas arbitrárias na div filho para torná-la mais ampla, mas não consigo descobrir como torná-la essencialmente 100% de largura do navegador.

Eu sei que posso fazer isso:

.child-div{
    margin-left: -100px;
    margin-right: -100px;
}

Mas preciso que o filho tenha a mesma largura do navegador, que é dinâmico.

Atualizar

Obrigado por suas respostas, parece que a resposta mais próxima até agora é tornar a posição DIV filho: absoluta e defina as propriedades esquerda e direita como 0.

O próximo problema que tenho é que o pai tem a posição: relativa, o que significa que as propriedades esquerda e direita ainda são relativas à div pai e não ao navegador, veja o exemplo aqui: jsfiddle.net/v2Tja/2

Não consigo remover a posição relativa dos pais sem estragar tudo o resto.

Camsoft
fonte
Seus requisitos realmente não fazem sentido. O "div filho" deve permanecer como filho do div pai, e ainda assim o div pai tem position: relative? Para que você precisa position: relative? Acho que estou perguntando: o que você está tentando fazer?
thirtydot
@Camsoft Você viu meu comentário na minha resposta? Que funciona para mim, verifique também o meu site edocuments.co.uk que faz o que você está tentando fazer de uma maneira diferente
Blowsie
1
@Camsoft além disso, realmente deve haver nenhuma necessidade para qualquer jquery / js em sua solução
Blowsie

Respostas:

112

Use posicionamento absoluto

.child-div {
    position:absolute;
    left:0;
    right:0;
}
Blowsie
fonte
14
Ok, próxima pergunta, que se o pai ou outro ancestral tem posição de layout ou seja: relative, consulte: jsfiddle.net/v2Tja/2
Camsoft
que tal outro div pai ser position: static e outro div dentro com position: relative? jsfiddle.net/blowsie/v2Tja/3
Blowsie
10
existe uma maneira de fazer isso, com a altura do .child-div automática e ainda ter o posicionamento correto abaixo?
Philippe Gilbert
2
e não definir a div pai para "overflow: hidden" ^^
chris
@Blowsie que tal position:fixed . por que não funciona corretamente?
Mostafa Ghadimi
227

Aqui está uma solução genérica que mantém o elemento filho no fluxo do documento:

.child {
  width: 100vw;
  position: relative;
  left: calc(-50vw + 50%);
}

Definimos o widthelemento filho para preencher toda a largura da janela de visualização e, em seguida, fazemos com que ela atenda à borda da tela movendo-a para leftuma distância de metade da janela de visualização, menos 50% da largura do elemento pai.

Demo:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  overflow-x: hidden;
}

.parent {
  max-width: 400px;
  margin: 0 auto;
  padding: 1rem;
  position: relative;
  background-color: darkgrey;
}

.child {
  width: 100vw;
  position: relative;
  left: calc(-50vw + 50%);

  height: 100px;
  border: 3px solid red;
  background-color: lightgrey;
}
<div class="parent">
  Pre
  <div class="child">Child</div>
  Post
</div>

O suporte do navegador para vw e calc () geralmente pode ser visto como IE9 e mais recente.

Nota: Isso pressupõe que o modelo da caixa está definido como border-box. Sem border-box, você também teria que subtrair bordas e bordas, tornando essa solução uma bagunça.

Nota: Recomenda-se ocultar o estouro horizontal do seu contêiner de rolagem, pois determinados navegadores podem optar por exibir uma barra de rolagem horizontal, apesar de não haver estouro.

Nils Kaspersson
fonte
4
O que você sabe, ele realmente funciona no IE9. 1 Nice
CatShoes
13
Era exatamente isso que eu estava procurando, muito obrigado mutch. IMO, esta é uma resposta melhor do que a aceita, uma vez que esta não interrompe o fluxo de documentos
Rémi
18
vw não é bom. Se você tiver uma barra de rolagem vertical, 100vw fornecerá uma barra de rolagem horizontal.
Ensolarado
2
Parece que isso funciona apenas um nível abaixo. Existe uma maneira de funcionar, independentemente de quantos elementos pai um elemento filho possui?
Mythofechelon
3
Esta é a resposta certa para agrupar um elemento filho mais amplo em um position: relativepai!
Hanfei Sun
14

Eu procurei em toda parte por uma solução para esse problema por um longo tempo. Idealmente, queremos ter o filho maior que o pai, mas sem conhecer antecipadamente as restrições do pai.

E finalmente encontrei uma resposta genérica brilhante aqui . Copiando textualmente:

A idéia aqui é: empurre o contêiner para o centro exato da janela do navegador com a esquerda: 50% ;, em seguida, puxe-o de volta para a borda esquerda com margem -50vw negativa.

.child-div {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
}
dangom
fonte
1
Descobri que, se quiser que, digamos, 90% da largura da janela de visualização, posso usar a acima, mas defina a largura como 90vw. Além disso, parece que margin-rightnão tem efeito em nenhum caso.
Jason Dufair 31/10
tive que alterar os valores de margem esquerda e direita porque meu invólucro tem 80% da largura da janela de visualização. Então, no meu caso, tinha que ter margem esquerda: -10vw e margem direita: -10vw e funcionou perfeitamente! obrigado!
Timotheus Triebl
1
Esta foi uma resposta brilhante! Obrigado.
cullanrocks
7

Com base na sugestão original da sua sugestão (definindo margens negativas), tentei criar um método semelhante usando unidades de porcentagem para a largura dinâmica do navegador:

HTML

<div class="grandparent">
    <div class="parent">
        <div class="child">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolore neque repellat ipsum natus magni soluta explicabo architecto, molestias laboriosam rerum. Tempore eos labore temporibus alias necessitatibus illum enim, est harum perspiciatis, sit, totam earum corrupti placeat architecto aut minus dignissimos mollitia asperiores sint ea. Libero hic laudantium, ipsam nostrum earum distinctio. Cum expedita, ratione, accusamus dicta similique distinctio est dolore assumenda soluta dolorem quisquam ex possimus aliquid provident quo? Enim tempora quo cupiditate eveniet aperiam.</p>
        </div>
    </div>
</div>

CSS:

.child-div{
   margin: 0 -100%;
   padding: 0 -100%;
}

.parent {
    width: 60%;
    background-color: red;
    margin: 0 auto;
    padding: 50px;
    position:relative;
}

.grandparent {
        overflow-x:hidden;
        background-color: blue;
        width: 100%;
        position:relative;
    }

As margens negativas deixarão o conteúdo fluir da DIV principal. Portanto, defini padding: 0 100%;o botão para empurrar o conteúdo de volta aos limites originais do Chlid DIV.

As margens negativas também farão com que a largura total do .child-div se expanda para fora da janela de exibição do navegador, resultando em uma rolagem horizontal. Portanto, precisamos cortar a largura da extrusão aplicando um overflow-x: hiddena um DIV dos avós (que é o pai da divisão dos pais):

Aqui está o JSfiddle

Já experimentei o de Nils Kaspersson left: calc(-50vw + 50%); funcionou perfeitamente no Chrome e no FF (ainda não tenho certeza sobre o IE) até descobrir que os navegadores Safari não o fazem corretamente. Espero que eles tenham resolvido isso assim que eu realmente gosto desse método simples.

Isso também pode resolver o problema em que o elemento Parent DIV deve ser position:relative

As 2 desvantagens deste método de solução alternativa são:

  • Exigir marcação extra (ou seja, um elemento de avô (assim como o bom e velho método de alinhamento vertical da tabela, não é ...)
  • As margens esquerda e direita do Child DIV nunca serão exibidas, simplesmente porque estão fora da janela de exibição do navegador.

Informe-me se houver algum problema com esse método;). Espero que ajude.

Austeróide
fonte
4

O Flexbox pode ser usado para tornar um filho mais amplo que seu pai, com três linhas de CSS.

Só da criança display, margin-lefte widthnecessidade de ser definido. margin-leftdepende da criança width. A fórmula é:

margin-left: calc(-.5 * var(--child-width) + 50%);

As variáveis ​​CSS podem ser usadas para evitar o cálculo manual da margem esquerda.

Demo # 1: Cálculo manual

.parent {
  background-color: aqua;
  height: 50vh;
  margin-left: auto;
  margin-right: auto;
  width: 50vw;
}

.child {
  background-color: pink;
  display: flex;
}

.wide {
  margin-left: calc(-37.5vw + 50%);
  width: 75vw;
}

.full {
  margin-left: calc(-50vw + 50%);
  width: 100vw;
}
<div class="parent">
  <div>
    parent
  </div>
  <div class="child wide">
    75vw
  </div>
  <div class="child full">
    100vw
  </div>
</div>

Demo # 2: Usando variáveis ​​CSS

.parent {
  background-color: aqua;
  height: 50vh;
  margin-left: auto;
  margin-right: auto;
  width: 50vw;
}

.child {
  background-color: pink;
  display: flex;
  margin-left: calc(-.5 * var(--child-width) + 50%);
  width: var(--child-width);
}

.wide {
  --child-width: 75vw;
}

.full {
  --child-width: 100vw;
}
<div class="parent">
  <div>
    parent
  </div>
  <div class="child wide">
    75vw
  </div>
  <div class="child full">
    100vw
  </div>
</div>

Markus
fonte
3

Eu usei isso:

HTML

<div class="container">
 <div class="parent">
  <div class="child">
   <div class="inner-container"></div>
  </div>
 </div>
</div>

CSS

.container {
  overflow-x: hidden;
}

.child {
  position: relative;
  width: 200%;
  left: -50%;
}

.inner-container{
  max-width: 1179px;
  margin:0 auto;
}
hsuastegui
fonte
1

você pode tentar a posição: absoluto. e dê largura e altura, em cima: 'eixo y a partir de cima' e à esquerda: 'eixo x'

Khurram Ijaz
fonte
1

Eu tive uma questão semelhante. O conteúdo do elemento filho deveria permanecer no elemento pai enquanto o plano de fundo tinha que estender a largura total da janela de exibição.

Resolvi esse problema criando o elemento filho position: relativee adicionando um pseudo elemento ( :before) a ele position: absolute; top: 0; bottom: 0; width: 4000px; left: -1000px;. O pseudo elemento fica atrás do filho real como um pseudo elemento de fundo. Isso funciona em todos os navegadores (mesmo IE8 + e Safari 6+ - não tem a possibilidade de testar versões mais antigas).

Violino de exemplo pequeno: http://jsfiddle.net/vccv39j9/

Seika85
fonte
Isso parece funcionar, mas faz com que o navegador mostre uma barra de rolagem horizontal, pois a largura é de 4000px. Qual é a solução alternativa para manter o pseudo elemento dentro da largura da janela de exibição?
Aaron Hudon
É claro que você deve definir o corpo ou a divisão de quebra de página como overflow-x: hidden.
Seika85
1

Adicionando à solução de Nils Kaspersson, também estou resolvendo a largura da barra de rolagem vertical. Estou usando 16pxcomo exemplo, que é subtraído da largura da porta de exibição. Isso evitará que a barra de rolagem horizontal apareça.

width: calc(100vw - 16px);
left: calc(-1 * (((100vw - 16px) - 100%) / 2));
Zona A
fonte
1
Eu acredito 16pxque o que você precisa subtrair porque está causando a barra de rolagem horizontal é a margem / preenchimento padrão do navegador, em vez de subtraí-lo, basta usar isso, html, body{ margin:0; padding:0 }assim você não precisará fazer cálculos extras para o16px
Mi-Creativity
É quando o conteúdo da página é maior e fica abaixo da dobra e a barra de rolagem aparece automaticamente. Obviamente, quando o conteúdo está dentro da dobra, isso não é necessário. Eu adiciono o 16px à fórmula somente quando sei que o conteúdo da página será longo e a barra de rolagem realmente aparecerá.
Uma zona-
Eu acho que não vai funcionar no celular. mobile não tem barra de rolagem.
hjchin
1

Supondo que o pai tenha uma largura fixa, por exemplo, #page { width: 1000px; }e esteja centralizado #page { margin: auto; }, você deseja que o filho caiba na largura da janela de exibição do navegador que você pode simplesmente fazer:

#page {
    margin: auto;
    width: 1000px;
}

.fullwidth {
    margin-left: calc(500px - 50vw); /* 500px is half of the parent's 1000px */
    width: 100vw;
}
Nabil Kadimi
fonte
1

Para tornar o div filho tão amplo quanto o conteúdo, tente o seguinte:

.child{
    position:absolute;
    left:0;
    overflow:visible;
    white-space:nowrap;
}
Toki
fonte
0
.parent {
    margin:0 auto;
    width:700px;
    border:2px solid red;
}
.child {
    position:absolute;
    width:100%;
    border:2px solid blue;
    left:0;
    top:200px;
}
Sam
fonte
Inteligente, mas não parece funcionar (com extensões incorporadas a li's, pelo menos).
Ruffin
0

Eu sei que isso é antigo, mas para quem vem a isso como resposta, você faria assim:

Estouro oculto em um elemento que contém o elemento pai, como o corpo.

Dê ao seu elemento filho uma largura muito maior que a sua página e posicione-o na esquerda absoluta em -100%.

Aqui está um exemplo:

body {
  overflow:hidden;
}

.parent{
  width: 960px;
  background-color: red;
  margin: 0 auto;
  position: relative;    
}

.child {
  height: 200px;
  position: absolute;
  left: -100%;
  width:9999999px;
}

Também aqui está um JS Fiddle: http://jsfiddle.net/v2Tja/288/

Tom Chinery
fonte
0

Então a solução será a seguinte.

HTML

<div class="parent">
    <div class="child"></div>
</div>

CSS

.parent{
        width: 960px;
        margin: auto;
        height: 100vh
    }
    .child{
        position: absolute;
        width: 100vw
    }
Himavan
fonte
Embora esse código possa responder à pergunta, fornecer um contexto adicional sobre como e / ou por que resolve o problema melhoraria o valor a longo prazo da resposta.
R Balasubramanian
0

Eu tentei algumas de suas soluções. Este :

margin: 0px -100%;
padding: 0 100%;

é de longe o melhor, já que não precisamos de css extra para telas menores. Eu criei um codePen para mostrar os resultados: usei uma div pai com uma imagem de plano de fundo e uma div div infantil com conteúdo interno.

https://codepen.io/yuyazz/pen/BaoqBBq

blogob
fonte