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?

Joel Coehoorn
fonte
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>
cobbal
fonte
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 .

danijar
fonte
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>

leishman
fonte
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>

basarat
fonte
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/

llange
fonte
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>
Quem eu
fonte
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>

Andik
fonte
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/

DharmaTurtle
fonte