Largura da div 100% menos quantidade fixa de pixels


316

Como posso alcançar a seguinte estrutura sem usar tabelas ou JavaScript? As bordas brancas representam bordas de divs e não são relevantes para a pergunta.

Estrutura 1

O tamanho da área no meio vai variar, mas ele terá valores exatos de pixels e toda a estrutura deve ser dimensionada de acordo com esses valores. Para simplificá-lo, eu precisaria de uma maneira de definir a largura "100% - n px" para as divs superior-média e inferior-média.

Eu apreciaria uma solução limpa entre navegadores, mas, caso isso não seja possível, os hacks CSS o farão.

Aqui está um bônus. Outra estrutura com a qual tenho lutado e acabo usando tabelas ou JavaScript. É um pouco diferente, mas apresenta novos problemas. Eu tenho usado principalmente no sistema de janelas baseado em jQuery, mas gostaria de manter o layout fora do script e controlar apenas o tamanho de um elemento (o do meio).

Estrutura 2


Para o segundo elemento, você está dizendo que quer a altura do elemento muito do meio para ser corrigido, mas os outros elementos próxima para ser dinâmico
Casebash

Respostas:


78

Você pode usar elementos aninhados e preenchimento para obter uma borda esquerda e direita na barra de ferramentas. A largura padrão de um divelemento é auto, o que significa que ele usa a largura disponível. Você pode adicionar preenchimento ao elemento e ele ainda permanece dentro da largura disponível.

Aqui está um exemplo que você pode usar para colocar imagens como cantos arredondados esquerdo e direito e uma imagem central que se repete entre eles.

O HTML:

<div class="Header">
   <div>
      <div>This is the dynamic center area</div>
   </div>
</div>

O CSS:

.Header {
   background: url(left.gif) no-repeat;
   padding-left: 30px;
}
.Header div {
   background: url(right.gif) top right no-repeat;
   padding-right: 30px;
}
.Header div div {
   background: url(center.gif) repeat-x;
   padding: 0;
   height: 30px;
}

Obrigado por isso. Eu tive que ajustar um pouco para a minha situação. A primeira div aninhada precisava de uma margem direita em vez de preenchimento, e a div central também precisava da mesma margem direita.
Max

3
Ótima solução. apenas uma coisinha -> isso funciona porque ".Header div div" substitui ".Header div" . Deve ser ".Header> div" e ".Header> div> div" . De fato, ".Header Div" significa qualquer criança div ou sub div criança enquanto ".Header> div" meios únicos filhos diretos de .Header
Charles Hetier

@CharlesHETIER: Sim, isso também funciona e é mais fácil de usar, pois você não precisa substituir todas as configurações da regra menos específica. A resposta foi escrita quando o suporte ao >operador ainda não era bom o suficiente para ser confiável.
Guffa

1
Isso está desatualizado, veja a resposta abaixo sobre a função calc em css.
María Arias de Reyna Domínguez

2
@delawen: Você tem que esperar um pouco antes de ficar desatualizado. Não há suporte para o calcIE 8 ou as versões atuais do Anroid Browser ou Opera. caniuse.com/#search=calc
Guffa

760

Nova maneira que acabei de me deparar com: csscalc() :

.calculated-width {
    width: -webkit-calc(100% - 100px);
    width:    -moz-calc(100% - 100px);
    width:         calc(100% - 100px);
}​

Origem: largura do css 100% menos 100px


86
A melhor resposta em 2013 IMHO. A resposta aceita está desatualizada.
Danubian Sailor

7
Já era hora de alguém tropeçar nisso. Eu terminei com hacks agora que sei disso. 0 @ lechlukasz
preahkumpii

47
Após 10 anos de luta com CSS, esta resposta merece +20000! Ainda não posso acreditar nos meus olhos ...
skobaljic

8
Tudo o que posso dizer sobre isso é ... youtube.com/…
Jazz

5
Mais compatível? -> $ ('# yourEl'). css ('width', '100%'). css ('width', '- = 100px'); (jQuery)
sboy031 18/12/2013

7

Embora a resposta de Guffa funcione em muitas situações, em alguns casos você pode não querer que os pedaços de preenchimento esquerdo e / ou direito sejam os pais da divisão central. Nesses casos, você pode usar um contexto de formatação de bloco no centro e flutuar os divs de preenchimento para a esquerda e para a direita. Aqui está o código

O HTML:

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
    <div class="center"></div>
</div>

O CSS:

.container {
    width: 100px;
    height: 20px;
}

.left, .right {
    width: 20px;
    height: 100%;
    float: left;
    background: black;   
}

.right {
    float: right;
}

.center {
    overflow: auto;
    height: 100%;
    background: blue;
}

Eu sinto que essa hierarquia de elementos é mais natural quando comparada às divs aninhadas e aninhadas e representa melhor o que está na página. Por esse motivo, bordas, preenchimento e margem podem ser aplicados normalmente a todos os elementos (ou seja: essa 'naturalidade' vai além do estilo e tem ramificações).

Observe que isso funciona apenas em divs e outros elementos que compartilham sua propriedade 'preencher 100% da largura por padrão'. Entradas, tabelas e possivelmente outras exigirão que você as envolva em uma div de contêiner e adicione um pouco mais de css para restaurar essa qualidade. Se você tiver a sorte de estar nessa situação, entre em contato comigo e eu desenterrarei o css.

jsfiddle aqui: jsfiddle.net/RgdeQ

Aproveitar!


6

Você pode usar o layout do Flexbox . Você precisa definir flex: 1o elemento que precisa ter largura ou altura dinâmica flex-direction: row and columnrespectivamente.

Largura dinâmica:

HTML

<div class="container">
  <div class="fixed-width">
    1
  </div>
  <div class="flexible-width">
    2
  </div>
  <div class="fixed-width">
    3
  </div>
</div>

CSS

.container {
  display: flex;
}
.fixed-width {
  width: 200px; /* Fixed width or flex-basis: 200px */
}
.flexible-width {
  flex: 1; /* Stretch to occupy remaining width i.e. flex-grow: 1 and flex-shrink: 1*/
}

Resultado:


Altura dinâmica:

HTML

<div class="container">
  <div class="fixed-height">
    1
  </div>
  <div class="flexible-height">
    2
  </div>
  <div class="fixed-height">
    3
  </div>
</div>

CSS

.container {
  display: flex;
}
.fixed-height {
  height: 200px; /* Fixed height or flex-basis: 200px */
}
.flexible-height {
  flex: 1; /* Stretch to occupy remaining height i.e. flex-grow: 1 and flex-shrink: 1*/
}

Resultado:


3

A maneira usual de fazer isso é como descrito por Guffa, elementos aninhados. É um pouco triste ter que adicionar marcações extras para obter os ganchos necessários para isso, mas na prática uma div de wrapper aqui ou ali não vai machucar ninguém.

Se você precisar fazê-lo sem elementos extras (por exemplo, quando não tiver controle da marcação da página), poderá usar o tamanho da caixa , que possui um suporte ao navegador bastante decente, mas não completo ou simples. É provavelmente mais divertido do que ter que confiar em scripts.


3

Talvez eu esteja sendo burro, mas a mesa não é a solução óbvia aqui?

<div class="parent">
    <div class="fixed">
    <div class="stretchToFit">
</div>

.parent{ display: table; width 100%; }
.fixed { display: table-cell; width: 150px; }
.stretchToFit{ display: table-cell; vertical-align: top}

Outra maneira que eu descobri no chrome é ainda mais simples, mas o homem é um hack!

.fixed{ 
   float: left
}
.stretchToFit{
   display: table-cell;
   width: 1%;
}

Isso por si só deve preencher o restante da linha horizontalmente, como as células da tabela. No entanto, você obtém alguns problemas estranhos, ultrapassando 100% de seu pai, definindo a largura como um valor percentual corrige isso.


2

Podemos conseguir isso usando a caixa flexível com muita facilidade.

Se tivermos três elementos como Header, MiddleContainer e Footer. E queremos dar uma altura fixa ao cabeçalho e rodapé. então podemos escrever assim:

Para React / RN (os padrões são 'display' como flex e 'flexDirection' como coluna), no web css, teremos que especificar o contêiner do corpo ou o contêiner que os contém como display: 'flex', flex-direction: 'column' como abaixo:

    container-containing-these-elements: {
     display: flex,
     flex-direction: column
    }
    header: {
     height: 40,
    },
    middle-container: {
     flex: 1, // this will take the rest of the space available.
    },
    footer: {
     height: 100,
    }

1

e se sua div de empacotamento fosse 100% e você usasse o preenchimento para uma quantidade de pixels, se o # do preenchimento precisar ser dinâmico, você poderá facilmente usar o jQuery para modificar o valor do preenchimento quando os eventos forem disparados.


1

Eu tive um problema semelhante em que queria um banner na parte superior da tela que tivesse uma imagem à esquerda e uma imagem repetida à direita na borda da tela. Acabei resolvendo assim:

CSS:

.banner_left {
position: absolute;
top: 0px;
left: 0px;
width: 131px;
height: 150px;
background-image: url("left_image.jpg");
background-repeat: no-repeat;
}

.banner_right {
position: absolute;
top: 0px;
left: 131px;
right: 0px;
height: 150px;
background-image: url("right_repeating_image.jpg");
background-repeat: repeat-x;
background-position: top left;
}

A chave era a etiqueta certa. Basicamente, estou especificando que quero que repita de 131px da esquerda para 0px da direita.


0

Em alguns contextos, você pode aproveitar as configurações de margem para especificar efetivamente "100% de largura menos N pixels". Veja a resposta aceita para esta pergunta .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.