Élément d'entrée de style pour remplir la largeur restante de son conteneur

197

Disons que j'ai un extrait html comme celui-ci:

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

Ce n'est pas mon code exact, mais l'important est qu'il y ait une étiquette et une entrée de texte sur la même ligne dans un conteneur à largeur fixe. Comment puis-je styliser l'entrée pour remplir la largeur restante du conteneur sans emballage et sans connaître la taille de l'étiquette?

Joel Coehoorn
la source
Je sais que la question était il y a longtemps mais j'ajouterai une bonne solution qui bien sûr n'est pas dépassée.
danijar

Réponses:

138

autant que tout le monde déteste les tableaux pour la mise en page, ils aident avec des trucs comme celui-ci, soit en utilisant des balises de tableau explicites, soit en utilisant 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
la source
Est-ce que cela fonctionnerait avec IE6? Sinon, je devrai peut-être définir un petit tableau pour cela :(
Joel Coehoorn
Je ne sais pas, je dirais de faire un test rapide pour voir ce qu'ils font, mais je n'ai pas facilement accès à IE
cobbal
Ça va: cela m'a orienté vers quelque chose qui fonctionne.
Joel Coehoorn
42
Envie de partager Joel?
John
10
D'accord, vous devriez partager votre solution réelle avec le reste d'entre nous et marquer cela comme la réponse à la place - tel quel, c'est un peu ennuyeux.
BrainSlugs83
155

Voici une solution simple et propre sans utiliser de hacks JavaScript ou de disposition de table. Il est similaire à cette réponse: saisie de la largeur automatique du texte de saisie à 100% avec d'autres éléments flottants

Il est important d'envelopper le champ de saisie avec une plage qui est display:block. La prochaine chose est que le bouton doit venir en premier et le champ de saisie en second.

Ensuite, vous pouvez faire flotter le bouton vers la droite et le champ de saisie remplit l'espace restant.

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>

Un simple violon: http://jsfiddle.net/v7YTT/90/

Mise à jour 1: Si votre site Web est destiné uniquement aux navigateurs modernes, je suggère d'utiliser des boîtes flexibles . Ici vous pouvez voir le support actuel .

Mise à jour 2: Cela fonctionne même avec plusieurs boutons ou autres éléments qui partagent pleinement avec le champ de saisie. Voici un exemple .

danijar
la source
Cela change le html, cependant: l'élément que vous voulez à la fin est répertorié en premier dans le html.
Joel Coehoorn
@JoelCoehoorn, c'est vrai. C'est à vous de décider si vous préférez cela à l'utilisation d'une table ou non.
danijar
2
Cela fonctionne très bien. Utilisez float: left au lieu de droite pour créer un tagueur de style facebook ou quelque chose de similaire.
hobberwickey le
1
Cela fonctionne très bien! Mais quelqu'un peut-il expliquer la logique derrière comment cela fonctionne?!
sherlock
1
C'est une mauvaise réponse. Il semble que cela fonctionne si vous le regardez, mais essayez le violon. Il s'agit en fait de la moitié de la zone de saisie, mais vous ne pouvez pas le dire à moins de commencer à le tester. L'objectif est d'adapter la zone de saisie à la largeur de la zone d'affichage, et non de la tronquer. Si vous essayez de faire un style (coins arrondis, bordure, justification à droite du texte), cela échoue complètement.
Roger Hill
55

Je suggère d'utiliser Flexbox:

Assurez-vous cependant d'ajouter les préfixes de fournisseur appropriés!

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
la source
La question est très ancienne ... c'est probablement comme ça que je le ferais aujourd'hui. Si j'ai la chance de l'essayer et que cela fonctionne avec tous les navigateurs dont j'avais besoin, je mettrai à jour la réponse acceptée. Cependant, il faudra probablement beaucoup de temps avant que je ne puisse essayer. Je suis dans l'équipe d'administration sys maintenant, ne fais plus autant de trucs web.
Joel Coehoorn
Pourriez-vous donner un exemple en utilisant un label? Je serais particulièrement intéressé par la façon dont le code HTML de la question d'origine pourrait être mis en page en utilisant border-box...
lacco
4
Pourquoi flex: 2et non flex: 1?
Iulius Curt
42

Veuillez utiliser flexbox pour cela. Vous avez un conteneur qui va plier ses enfants en ligne. Le premier enfant prend son espace au besoin. Le second fléchit pour prendre tout l'espace restant:

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

basarat
la source
Salut cinq! :) Une chose qui mérite d'être ajoutée (dans le contexte de beaucoup d'entre nous qui adoptent encore récemment le modèle flexbox): cette entrée sera sous une forme, qui à son tour peut se retrouver dans le conteneur flex global (par exemple avec d'autres éléments non formels) ), puis cela ne fonctionnera plus - car le comportement flexible ne s'applique qu'aux descendants directs (c'est-à-dire les éléments enfants). Donc, le FORM doit aussi être un contrainer flex!
Sz.
flex-direction est déjà rowpar défaut, vous n'avez pas besoin de le spécifier.
Fabian Picone
flex pour la victoire (encore); réponse très pertinente en 2019
secretwep
17

Le moyen le plus simple d'y parvenir serait:

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>

Ressemble à: http://jsfiddle.net/JwfRX/

llange
la source
Cela fonctionne bien pour moi. Le débordement empêche les choses de s'enrouler, le rembourrage à droite empêche le côté droit d'être coupé.
Prof Von Lemongargle
PS: Avec un navigateur moderne, je recommanderais d'utiliser la flex-box comme décrit ci-dessus par leishman…
llange
4

L'astuce très simple consiste à utiliser une CSS calcformule. Tous les navigateurs modernes, IE9, une large gamme de navigateurs mobiles devraient prendre en charge cela.

<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>
Qui
la source
4
Cela suppose que vous connaissez la largeur exacte de l'étiquette ou que vous souhaitez accepter un espace supplémentaire.
Nelson Rothermel
2

vous pouvez essayer ceci:

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
la source
meilleure méthode aujourd'hui
yota
0

Si vous utilisez 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>

Mieux encore, utilisez ce qui est intégré à 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
la source