Posso impedir que as caixas de texto com largura de 100% se estendam além de seus contêineres?

181

Digamos que eu tenho uma caixa de texto que quero preencher uma linha inteira. Eu daria um estilo assim:

input.wide {display:block; width: 100%}

Isso causa problemas porque a largura é baseada no conteúdo da caixa de texto. As caixas de texto possuem margem, bordas e preenchimento por padrão, o que torna uma caixa de texto com 100% de largura maior que seu contêiner.

Por exemplo, aqui à direita:

insira a descrição da imagem aqui

Existe alguma maneira de fazer uma caixa de texto preencher a largura de seu contêiner sem se expandir além dele?

Aqui está um exemplo de HTML para mostrar o que quero dizer:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
    <style type="text/css">
        #outer{border: 1px solid #000; width: 320px; margin: 0px;padding:0px}
        #inner{margin: 20px; padding: 20px; background: #999;border: 1px solid #000;}
        input.wide {display:block; margin: 0px}
        input.normal {display:block; float: right}
    </style>
</head>
<body>
    <div id="outer">
        <div id="inner">
            <input type="text" class="wide" />
            <input type="text" class="normal" />
            <div style="clear:both;"></div>
        </div>
    </div>
</body>
</html>

Se isso for executado, você poderá ver olhando para a caixa de texto "normal" que a caixa de texto "larga" está saindo além do contêiner. A caixa de texto "normal" flutua até a borda real do contêiner. Estou tentando fazer com que a caixa de texto "larga" encha seu contêiner, sem expandir além da borda, como a caixa de texto "normal".

Dan Herbert
fonte

Respostas:

87

O que você pode fazer é remover os "extras" padrão no input:

input.wide {display:block; width:100%;padding:0;border-width:0}

Isso manterá o inputinterior do contêiner. Agora, se você quiser as bordas, envolva o inputem a div, com as bordas definidas no div(dessa forma, você pode remover display:blocko inputtambém). Algo como:

<div style="border:1px solid gray;">
 <input type="text" class="wide" />
</div>

Editar: Outra opção é, em vez de remover o estilo do input, compensá-lo no pacote div:

input.wide {width:100%;}

<div style="padding-right:4px;padding-left:1px;margin-right:2px">
  <input type="text" class="wide" />
</div>

Isso fornecerá resultados um pouco diferentes em navegadores diferentes, mas eles não se sobreporão ao contêiner. Os valores na div dependem do tamanho da borda inpute da quantidade de espaço que você deseja entre inputa borda e a borda.

Hilbrand Bouwkamp
fonte
3
Esta é uma solução muito criativa. O único problema que tenho é que não consigo definir um contorno na caixa de texto quando ele ganha foco, a menos que eu use JavaScript para alterar a borda da div do wrapper.
11119 Dan Herbert
@DanHerbert, você está certo, isso é uma grande falha UX deste método
Baumr
275

Existe alguma maneira de fazer uma caixa de texto preencher a largura de seu contêiner sem se expandir além dele?

Sim: usando a propriedade CSS3 'box-sizing: border-box', é possível redefinir o que 'width' significa incluir o preenchimento e a borda externos.

Infelizmente, por ser CSS3, o suporte não é muito maduro e, como o processo de especificação ainda não foi concluído, ele possui nomes temporários diferentes nos navegadores. Assim:

input.wide {
    width: 100%;
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
}

A alternativa da velha escola é simplesmente colocar uma quantidade de 'padding-right' no elemento <div> ou <td> anexo, igual a quanto estofamento / borda extra esquerda e direita em 'px' você acha que os navegadores dê a entrada. (Normalmente 6px para IE <8.)

bobince
fonte
Isso funcionaria muito bem, exceto que não posso usar isso porque estou segmentando dispositivos móveis que provavelmente não suportam isso há anos. : - \
Dan Herbert /
20
Acho que os dispositivos móveis terão suporte completo a HTML5 antes dos computadores.
Mariano Cavallo
4
@ Kindred: definitivamente não, se você incluir IEMobile e Blackberry nisso.
quer
1
Isto tem grande apoio para navegadores desktop, porém: quirksmode.org/css/contents.html
logan
2
Como demorei tanto tempo para encontrar esse molho de manteiga incrível ??? Podemos, por favor, fazer disso a resposta aceita?
Streetlogics
14

Isso resolveu o problema para mim!

Sem a necessidade de uma div externa. Basta aplicá-lo à sua caixa de texto.

box-sizing: border-box; 

Com esta propriedade "As propriedades de largura e altura (e propriedades mín. / Máx.) Incluem conteúdo, preenchimento e borda, mas não a margem"

Veja a descrição da propriedade em w3schools .

Espero que isso ajude alguém!

Jack Trowbridge
fonte
Maravilhosamente simples! THX!
Nurider 15/02/16
10

Eu mesmo me deparei com esse problema, e a única solução que encontrei que funcionou em todos os meus navegadores de teste (IE6, IE7, Firefox) foi a seguinte:

  1. Quebra o campo de entrada em dois DIVs separados
  2. Defina a DIV externa para largura 100%, para evitar que o contêiner transborde o documento
  3. Coloque o preenchimento no DIV interno da quantidade exata para compensar o estouro horizontal da entrada.
  4. Defina o preenchimento personalizado na entrada para que ela ultrapasse a mesma quantidade que eu permiti na DIV interna

O código:

<div style="width: 100%">
    <div style="padding-right: 6px;">
        <input type="text" style="width: 100%; padding: 2px; margin: 0;
                                  border : solid 1px #999" />
    </div>
</div>

Aqui, o estouro horizontal total do elemento de entrada é de 6px - 2x (preenchimento + borda) - portanto, definimos um preenchimento à direita para o DIV interno de 6px.

Tobias Cohen
fonte
adicionar ao elemento de entrada de um padding 8px e ele não funciona mais
JuHwon
7

o suporte ao dimensionamento de caixas é realmente bom: http://caniuse.com/#search=box-sizing

Portanto, a menos que você tenha como alvo o IE7, poderá resolver esse tipo de problema usando essa propriedade. Uma camada como sass ou menos facilita o manuseio de regras prefixadas como essa, btw.

chikamichi
fonte
3

Na verdade, é porque o CSS define 100% em relação a toda a largura do contêiner, incluindo suas margens, bordas e preenchimento; isso significa que o espaço está disponível. seu conteúdo é uma quantidade menor que 100%, a menos que o contêiner não tenha margens, bordas ou preenchimentos.

Isso é contra-intuitivo e amplamente considerado por muitos como um erro com o qual estamos presos agora . Isso significa efetivamente que as dimensões% não servem para nada além de um contêiner de nível superior e, mesmo assim, apenas se não tiver margens, bordas ou preenchimento.

Observe que as margens, bordas e preenchimento do campo de texto estão incluídos no tamanho CSS especificado para ele - é o contêiner que descarta as coisas.

Trabalhei de maneira tolerável usando 98%, mas essa é uma solução menos que perfeita, pois os campos de entrada tendem a ficar mais curtos à medida que o contêiner fica maior.


Edição: me deparei com essa pergunta semelhante - nunca tentei a resposta dada e não sei ao certo se isso se aplica ao seu problema, mas parece que sim.

Lawrence Dol
fonte
1

Uma solução que pode funcionar (funciona para mim) é aplicar margem negativa na entrada (caixa de texto) ... ou largura fixa para ie7 ou descartar o suporte ie7. Isso resulta em largura perfeita de pixel .. Para mim, são 7, então eu adicionei 3 e 4, mas ainda é pixel perfeito ..

Eu tive o mesmo problema e eu odiava ter divs extras para borda etc!

Então aqui está a minha solução que parece funcionar!

Você deve usar uma folha de estilo somente ie7 para evitar os starhacks.

input.text{
    background-color: #fbfbfb;
    border : solid #eee 1px;
    width: 100%;
    -box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    height: 32px;

    *line-height:32px;
    *margin-left:-3px;
    *margin-right:-4px;
    display: inline;   
    padding: 0px 0 0 5px;

}
GorillaApe
fonte
1

Se você não pode usá- box-sizing:border-boxlo, tente remover o atributo width:100%e colocar um sizeatributo muito grande no <input>elemento. No entanto, você deve modificar o html e não pode fazê-lo apenas com CSS:

<input size="1000"></input>
siddhadev
fonte
0

Se você não precisar fazer isso dinamicamente (por exemplo, seu formulário é de largura fixa), basta definir a largura dos <input>elementos filhos para a largura do contêiner, menos decorações como estofamento, margem, borda etc.:

 // the parent div here has a width of 200px:
.form-signin input[type="text"], .form-signin input[type="password"], .form-signin input[type="email"], .form-signin input[type="number"] {
  font-size: 16px;
  height: auto;
  display: block;
  width: 280px;
  margin-bottom: 15px;
  padding: 7px 9px;
}
Avishai
fonte
0

Se você não pode usar o tamanho da caixa (por exemplo, quando você converte HTML para PDF usando o iText). Tente o seguinte:

CSS

.input-wrapper { border: 1px solid #ccc; padding: 0 5px; min-height: 20px; } 
.input-wrapper input[type=text] { border: none; height: 20px; width: 100%; padding: 0; margin: 0; }

HTML

<div class="input-wrapper">
     <input type="text" value="" name="city"/>
</div>
robertad
fonte
0

Isso funciona:

<div>
    <input type="text" 
        style="margin: 5px; padding: 4px; border: 1px solid; 
        width: 200px; width: calc(100% - 20px);">
</div>

A primeira 'largura' é uma regra de fallback para navegadores mais antigos.

Mo'in Creemers
fonte
0

Basta estilizar a entrada para compensar o preenchimento extra. No exemplo a seguir, o preenchimento na entrada seria 10 px à esquerda e à direita para um deslocamento total do preenchimento de 20 px:

input[type=text]{
   width: calc(100% - 20px);
}
quinlo
fonte