Como fazer a largura do CSS para preencher o pai?

88

Tenho certeza de que esse problema foi perguntado antes, mas não consigo encontrar a resposta.

Eu tenho a seguinte marcação:

<div id="foo">
    <div id="bar">
        here be dragons
    </div>
</div>

Meu desejo é fazer com que foo tenha largura de 600px( width: 600px;) e que bar tenha os seguintes comportamentos:

padding-left: 2px;
padding-right: 2px;
margin-left: 2px;
margin-right: 2px;
outerWidth: 100%;

Em outras palavras, em vez de definir a largura da barra 592pxcomo, gostaria de definir a largura externa da barra para 100%que ela seja calculada 592px. A importância aqui é que eu posso alterar a largura de foo para 800pxe a barra irá calcular quando renderizada, em vez de eu ter que fazer a matemática para todas essas instâncias manualmente.

Isso é possível em CSS puro?

Um pouco mais divertido com isso:

  • E se #barfor uma mesa?
  • E se #barfor uma área de texto?
  • E se #barfor uma entrada?

  • E se #foofor uma célula de tabela ( td)? (Isso muda o problema ou o problema é idêntico?)


Até agora table#bar, input#barfoi discutido. Eu não vi uma boa solução para textarea # bar. Eu acho que uma textarea sem borda / margem / preenchimento com uma divquebra pode funcionar com o divestilo para funcionar como bordas para o textarea.

Dmitriy Likhten
fonte

Respostas:

39

EDITAR :

Todos esses três elementos diferentes têm regras de renderização diferentes.

Então, para:

table#barvocê precisa definir a largura para 100%, caso contrário, ela será apenas tão larga quanto determina que precisa ser. No entanto, se a largura total das linhas da tabela for maior do que a largura bardela se expandirá para a largura necessária. SE eu me lembrar, você pode neutralizar isso configurando, display: block !important;embora já faça algum tempo desde que eu tive que consertar isso. (tenho certeza que alguém vai me corrigir se eu estiver errado).

textarea#bari Beleive é um elemento de nível de bloco, portanto, seguirá as mesmas regras que o div. A única ressalva aqui é que textareater um atributos colse rowsque são medidos em colunas de caracteres. Se for especificado no elemento, ele substituirá a largura especificada pelo css.

input#baré um elemento embutido, portanto, por padrão, você não pode atribuir largura a ele. No entanto, o semelhante ao textareado colsatributo, que tem um sizeatributo no elemento que pode determinar a largura. Dito isso, você sempre pode especificar uma largura usando display: block;em seu css para isso. Em seguida, ele seguirá as mesmas regras de renderização do div.

td#fooserá processado como um table-cellque contém alguma loucura. O ponto principal aqui é que, para seus propósitos, ele funcionará exatamente como div#foo, na medida em que restringe a largura de seu conteúdo. O único problema aqui será um possível texto não encapsulável em algum lugar da coluna, o que faria com que ele ignorasse sua configuração de largura. Além disso, todas as células da coluna terão a largura da célula mais larga.


Esse é o comportamento padrão do elemento de nível de bloco - ou seja, se a largura for auto(o padrão), será 100% da largura interna do elemento que o contém. então, em essência:

#foo {width: 800px;}
#bar {padding-left: 2px; padding-right: 2px; margin-left: 2px; margin-right: 2px;}

lhe dará exatamente o que você deseja.

filho pródigo
fonte
Ei, obrigado. Também se divertindo com as mesas decidindo sangrar de qualquer maneira. Presumo que as tabelas tenham o mesmo comportamento que os divs.
Dmitriy Likhten
@Dimitry: Não, eles têm regras especiais que os tornam mais semelhantes do inline-blockque blockelementos. Observe, porém, que eu disse mais como não é o mesmo que :-) O que você provavelmente está experimentando é que, a menos que definido de outra forma, eles geralmente se expandem para acomodar todas as colunas, o que pode ser realmente irritante se alguns dos cabeçalhos / células contiverem um texto longo que não pode ser encapsulado.
prodigitalson
Obrigado por ajudar :) Deixe-me atualizar um pouco a pergunta para dar uma visão geral muito mais completa dos problemas e, esperançosamente, todas as soluções alternativas podem ser listadas em uma seção.
Dmitriy Likhten
Tenho experimentado com a div # foo table # bar e definir a largura: 100% na tabela # bar irá realmente expandir a tabela, mas as bordas / margens da tabela irão sangrar por div # foo. Definir a tabela para exibir: bloco não é bom, pois confunde outros aspectos da renderização da tabela, como o manuseio da largura da linha. textarea # bar não se expandirá quando a largura for configurada para automático ou não configurada.
Dmitriy Likhten
1
pois textarea#barvocê deve ser capaz de definir isso display: blockcom poucos efeitos adversos. Quanto à tabela, eu sei que usei algum tipo de solução / mitigação para isso no passado, mas não me lembro o que era no momento. No entanto, direi que geralmente não defino "margens" em uma mesa, mas envolvo-a em uma div com preenchimento / margens ... isso pode ser o próprio #foo ou outro div usado apenas para aplicar esse tipo de espaçamento. Além disso, você pode fazer para neutralizar o problema da borda para aplicar as bordas apenas à primeira / última célula em uma linha / as células na primeira / última linha
prodigitalson
28

quase lá, basta mudar outerWidth: 100%;para width: auto;(outerWidth não é uma propriedade CSS)

como alternativa, aplique os seguintes estilos à barra:

width: auto;
display: block;
Rowan
fonte
4
Isso não funcionará se ele estiver definindo uma margem de preenchimento, barporque o será adicionado aos 100% tornando-o efetivamente barmais largo do que seu pai foo.
prodigitalson
sim, respondi essa muito rápido; P
Rowan
Espere um segundo. Então, se eu definir a propriedade de largura para qualquer coisa, ela irá sangrar? largura: automático não é a solução, em vez de não definir a largura é?
Dmitriy Likhten
2
sim, está certo. Qualquer elemento que tenha display:block;(também conhecido como elemento de nível de bloco) adotará esse comportamento. um elemento DIV tem width:auto;e display:block;definida por padrão.
Rowan
Postagem antiga, mas ele não poderia simplesmente usar box-sizing: border-box para permitir que o preenchimento ficasse dentro da largura do elemento.
CHBresser
16

Use os estilos

left: 0px;

ou e

right: 0px;

ou e

top: 0px;

ou e

bottom: 0px;

Eu acho que na maioria dos casos isso fará o trabalho

Tigsar
fonte
4

Portanto, após a pesquisa, o seguinte é descoberto:

Para uma div#barconfiguração display:block; width: auto;causa o equivalente aouterWidth:100%;

Para um, table#barvocê precisa envolvê-lo em um div com as regras declaradas abaixo. Portanto, sua estrutura se torna:

<div id="foo">
 <div id="barWrap" style="border....">
  <table id="bar" style="width: 100%; border: 0; padding: 0; margin: 0;">

Desta forma, a tabela ocupa o div pai 100% e #barWrapé usada para adicionar bordas / margens / preenchimento à #bartabela. Observe que você precisará definir o fundo de tudo em #barWrape fazer com que #baro fundo seja transparente ou igual a #barWrap.

Pois textarea#bare input#barvocê precisa fazer a mesma coisa que table#bar, o lado negativo é que, ao remover as bordas, você interrompe a renderização nativa do widget da área de entrada / texto e as #barWrapbordas de parecerão um pouco diferentes de tudo o mais, então você provavelmente terá que estilize todas as suas entradas desta forma.

Dmitriy Likhten
fonte