Estilize o elemento de entrada para preencher a largura restante de seu contêiner


197

Digamos que eu tenho um trecho de html como este:

<div style="width:300px;">
    <label for="MyInput">label text</label>
    <input type="text" id="MyInput" />
</div>

Este não é o meu código exato, mas o importante é que há um rótulo e uma entrada de texto na mesma linha em um contêiner de largura fixa. Como posso estilizar a entrada para preencher a largura restante do contêiner sem embrulhar e sem saber o tamanho do rótulo?


Eu sei que a pergunta foi há muito tempo, mas vou adicionar uma boa solução que, obviamente, não está desatualizada.
— danijar

Respostas:


138

por mais que todo mundo odeie tabelas para layout, elas ajudam com coisas como essa, usando tags de tabela explícitas ou usando display: table-cell

<div style="width:300px; display:table">
    <label for="MyInput" style="display:table-cell; width:1px">label&nbsp;text</label>
    <input type="text" id="MyInput" style="display:table-cell; width:100%" />
</div>

Isso funcionaria com o IE6? Caso contrário, eu possa ter para realmente definir uma pequena mesa para este :(
— Joel Coehoorn

não tenho certeza, eu diria que fazer um teste rápido para ver o que eles fazem, mas não têm fácil acesso a IE
— cobbal

Tudo bem: isso me apontou para algo que funciona.
— Joel Coehoorn

42
Gostaria de compartilhar Joel?
— John

10
Concordado, você deve compartilhar sua solução real com o resto de nós e marcar isso como a resposta - como é, isso é meio irritante.
— BrainSlugs83

155

Aqui está uma solução simples e limpa sem usar JavaScript ou hacks de layout de tabela. É semelhante a esta resposta: Insira a largura automática do texto preenchendo 100% com outros elementos flutuantes

É importante agrupar o campo de entrada com uma extensão que seja display:block. A próxima coisa é que o botão tem que vir primeiro e o campo de entrada depois.

Em seguida, você pode flutuar o botão para a direita e o campo de entrada preenche o espaço restante.

form {
    width: 500px;
    overflow: hidden;
    background-color: yellow;
}
input {
    width: 100%;
}
span {
    display: block;
    overflow: hidden;
    padding-right:10px;
}
button {
    float: right;
}
<form method="post">
     <button>Search</button>
     <span><input type="text" title="Search" /></span>
</form>

Um violino simples: http://jsfiddle.net/v7YTT/90/

Atualização 1: se o seu site é direcionado apenas a navegadores modernos, sugiro o uso de caixas flexíveis . Aqui você pode ver o suporte atual .

Atualização 2: isso funciona mesmo com vários botões ou outros elementos que compartilham o máximo com o campo de entrada. Aqui está um exemplo .


Porém, isso altera o html: o item que você deseja no final é listado primeiro no html.
— Joel Coehoorn

@JoelCoehoorn, isso mesmo. É sua decisão se você prefere isso ao invés de usar uma tabela ou não.
— Danijar

2
Isso funciona muito bem. Use float: left em vez de right para criar um tagger no estilo do facebook ou algo semelhante.
— 21414 hbberwickey

1
Isso funciona muito bem! Mas alguém pode explicar a lógica por trás de como isso funciona ?!
— Sherlock

1
Esta é uma resposta ruim. Parece que funciona se você apenas olhar para ele, mas tente o violino. Na verdade, é cortar metade da caixa de entrada, mas você não pode saber a menos que comece a testá-la. O objetivo é ajustar a caixa de entrada à largura da área de exibição, não truncá-la. Se você tentar fazer algum estilo (cantos arredondados, uma borda, justificação correta do texto), isso falhará totalmente.
— Roger Hill

55

Sugiro usar o Flexbox:

Certifique-se de adicionar os prefixos adequados do fornecedor!

form {
  width: 400px;
  border: 1px solid black;
  display: flex;
}

input {
  flex: 2;
}

input, label {
  margin: 5px;
}
<form method="post">
  <label for="myInput">Sample label</label>
  <input type="text" id="myInput" placeholder="Sample Input"/>
</form>


A pergunta é muito antiga ... provavelmente é assim que eu faria hoje. Se eu tiver a chance de experimentá-lo, e ele funcionar com todos os navegadores necessários, atualizarei a resposta aceita. Provavelmente, demorará muito tempo até eu tentar isso. Estou na equipe de administração do sistema agora, não faça mais tanta coisa na web.
— Joel Coehoorn

Você poderia fornecer um exemplo usando a label? Eu estaria especialmente interessado em saber como o código HTML a pergunta original poderia ser layouted usando border-box...
— Lacco

4
Por que flex: 2e não flex: 1?
— Iulius Curt

42

Por favor, use flexbox para isso. Você tem um contêiner que flexionará seus filhos em uma linha. O primeiro filho ocupa seu espaço conforme necessário. O segundo flexiona para ocupar todo o espaço restante:

<div style="display:flex;flex-direction:row">
    <label for="MyInput">label&nbsp;text</label>
    <input type="text" id="MyInput" style="flex:1" />
</div>


Oi cinco! :) Uma coisa que vale a pena acrescentar (no contexto de muitos de nós ainda adotando o modelo flexbox): que o INPUT estará em um FORM, que por sua vez pode acabar no contêiner flex geral (por exemplo, com outros itens não-forma ) e não funcionará mais, porque o comportamento de flexão se aplica apenas a descendentes diretos (ou seja, elementos filho). Portanto, o FORMULÁRIO também deve ser um contrainer flexível!
— Sz.

flex-direction já está rowpor padrão, você não precisa especificá-lo.
— Fabian Picone

flexionar para a vitória (novamente); resposta muito relevante em 2019
— secretwep 27/03/19

17

A maneira mais fácil de conseguir isso seria:

CSS:

label{ float: left; }

span
{
    display: block;
    overflow: hidden;
    padding-right: 5px;
    padding-left: 10px;
}

span > input{ width: 100%; }

HTML:

<fieldset>
    <label>label</label><span><input type="text" /></span>
    <label>longer label</label><span><input type="text" /></span>
</fieldset>

Parece que: http://jsfiddle.net/JwfRX/


Isto funciona bem para mim. O excesso evita que as coisas acondicionem, o estofamento à direita evita que o lado direito seja cortado.
— Prof Von Lemongargle

PS: Com navegador moderno Eu recomendo usar flex-caixa como descrito acima por Leishman ...
— llange

4

Um truque muito fácil é usar uma CSS calcfórmula. Todos os navegadores modernos, IE9, grande variedade de navegadores móveis devem suportar isso.

<div style='white-space:nowrap'>
  <span style='display:inline-block;width:80px;font-weight:bold'>
    <label for='field1'>Field1</label>
  </span>
  <input id='field1' name='field1' type='text' value='Some text' size='30' style='width:calc(100% - 80px)' />
</div>

4
Isso pressupõe que você saiba a largura exata da etiqueta ou esteja disposto a suportar espaço extra.
— precisa

2

você pode tentar isso:

div#panel {
    border:solid;
    width:500px;
    height:300px;
}
div#content {
	height:90%;
	background-color:#1ea8d1; /*light blue*/
}
div#panel input {
	width:100%;
	height:10%;
	/*make input doesnt overflow inside div*/
	-webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
            box-sizing: border-box;
	/*make input doesnt overflow inside div*/
}
<div id="panel">
  <div id="content"></div>
  <input type="text" placeholder="write here..."/>
</div>


melhor método hoje
— yota

0

Se você estiver usando o Bootstrap 4:

<form class="d-flex">
  <label for="myInput" class="align-items-center">Sample label</label>
  <input type="text" id="myInput" placeholder="Sample Input" class="flex-grow-1"/>
</form>

Melhor ainda, use o que está embutido no Bootstrap:

  <form>
    <div class="input-group">
      <div class="input-group-prepend">
        <label for="myInput" class="input-group-text">Default</label>
      </div>
      <input type="text" class="form-control" id="myInput">
    </div>
  </form>

https://jsfiddle.net/nap1ykbr/

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.