How to Set CSS Width Equal to Length of Longest Text

how to set css width equal to length of longest text

first step: remove fixed width from .dropdown ul li a

second step: add the css li li {width:100%;}

third step: add .mainNav li a {white-space:nowrap;}

It's ready: http://jsfiddle.net/K2Zzh/10/

Width equal to content

By default p tags are block elements, which means they take 100% of the parent width.

You can change their display property with:

#container p {
display:inline-block;
}

But it puts the elements side by side.

To keep each element on its own line you can use:

#container p {
clear:both;
float:left;
}

(If you use float and need to clear after floated elements, see this link for different techniques: http://css-tricks.com/all-about-floats/)

Demo: http://jsfiddle.net/CvJ3W/5/

Edit

If you go for the solution with display:inline-block but want to keep each item in one line, you can just add a <br> tag after each one:

<div id="container">
<p>Sample Text 1</p><br/>
<p>Sample Text 2</p><br/>
<p>Sample Text 3</p><br/>
</div>

New demo: http://jsfiddle.net/CvJ3W/7/

Change width of div depending on size of longest possible text

One way is hide the element without display:none so no remove it from the flow. Try this:

.hover-btn .hover-on, .hover-btn:hover .hover-off {

height: 0;

display:block;

overflow:hidden;

visibility:hidden;

}

.hover-btn:hover .hover-on, .hover-btn .hover-off {

height:auto;

visibility:visible;

}
<button id="myButton" class="hover-btn">

<span class="hover-off">hey!</span>

<span class="hover-on">click me!</span>

</button>

Making div width equal to the longest word/sentence length inside it

New Edit from OP's comments :

The only way I can see to resolve this is using javascript,

I made a uggly and probably overkilling snippet which does the work :

It creates a clone of the node, set it as inline with white-space: nowrap and then add each word one at a time, compare the clone width with parent's width. If it's larger, then it assigns display: table-caption to the orginal div, else it adds the next word.

CSS

div {
display: inline-block;
background-color:pink;
margin-bottom:5px;
}
.caption {
display : table-caption;
}
.cloned {
visibility : hidden;
white-space : nowrap;
}

Javascript

 var clone, el,w;

(cloneIt)();
function cloneIt(){
el = document.getElementById('3');
clone = el.cloneNode(true);
clone.className = "cloned";
el.parentNode.appendChild(clone);
w = clone.innerHTML.split(' ');
wrapIt();
}
window.onresize = wrapIt;

function wrapIt(){
clone.innerHTML = w[0]; //minimum content is first word
for(i=1; i<w.length; i++){
clone.innerHTML += w[i]+' ';//add next word
if(i==w.length-1 && clone.offsetWidth <= el.parentNode.offsetWidth){
//we're at the end and it's still smaller than parent width?
el.style.width = clone.offsetWidth+ 1 + 'px';
return;
}
if(clone.offsetWidth <= el.parentNode.offsetWidth){
//add a new word
continue;
}
//Gone too far? remove last word
clone.innerHTML = clone.innerHTML.replace(w[i], '');
el.style.width = clone.offsetWidth+ 1 + 'px';
return;
}
}

Here is Fiddle

Make the longest content item set the width for the entire column

The primary container (.matches-container) has three flex items (.match).

Those items can be set to track each others' width because they are siblings. There is a direct association between them, as they share the same parent.

However, the divs you want to target (.justify-center) are descendants of the items (.match), making them cousins, meaning they have no direct association and there are no natural CSS solutions for relative sizing.

Hence, unless you want to make all your content items siblings, or use tables or JavaScript, you can't get your content items in one row to set the width of content items in other rows.

More information:

  • Equal height children of flex items
  • Equal height children of grid items

How assign the width of the longest element to other elements

If you're looking for solution in CSS only, there's one way using the display property as table, table-row and table-cell. I think you can extend it for your markup:



.btn-container {

display: table;

border: 1px #000 solid !important;

}

.btn {

display: table-row;

}

.btn-text {

display: table-cell;

padding: 3px;

}

.btn-label {

width: 30px;

display: table-cell;

}

.btn-label-red {

background: #F00;

}

.btn-label-green {

background: #0F0;

}

.btn-label-blue {

background: #00F;

}
<div class="btn-container">

<div class="btn">

<span class="btn-text">Button 1</span>

<span class="btn-label btn-label-green"> </span>

</div>

<div class="btn">

<span class="btn-text">Button 2 with large text</span>

<span class="btn-label btn-label-red"> </span>

</div>

<div class="btn">

<span class="btn-text">Btn 3</span>

<span class="btn-label btn-label-blue"> </span>

</div>

</div>

Using css to set width of li with content

Just add these display: table; table-layout: fixed; to your ol:

ol.nlist
{
counter-reset: li; /* Initiate a counter */
padding: 10px;
display: table;
table-layout: fixed;
}

Demo

Note that table-layout: fixed; is optional. Its more for a performance improvement than style.

CSS, how to create a label width of the longest containing text?

You have to wrap each label-input combination in a element, and then wrap that element in some container. This container should have a min-width, and display: inline-block;.
Then you let all the input items float to the right, and you're done.

This results in a very simple, clean and semantic markup with eqaully clean and maintainable CSS, and no requirements for JavaScript, jQuery, or other fancy stuff.

You could make something like:

 <form>
<fieldset>
<p><label for="lorem">lorem</label><input type="text" id="lorem" /></p>
<p><label for="ipsum">ipsum</label><input type="text" id="ipsum" /></p>
<p><label for="li">li</label><input type="text" id="li" /></p>
</fieldset>
</form>

with the css

 fieldset {
min-width: 100px;
display: inline-block;
}

fieldset input{
float: right;
}

Here you can see how that looks.
Clearly you can style your form with margins, paddings etc.

And additionally if you want to have a wrapper that's semantically more accurate, you can use a ordered list. You can then style everything like you want to, and have even a nice additional wrapper (the <ol>) that you can use without adding semantic garbage.

A example would be:

 <form>
<fieldset>
<legend>First Example:</legend>
<ol>
<li><label for="lorem">lorem</label><input type="text" id="lorem" /></li>
<li><label for="ipsum">ipsum</label><input type="password" id="ipsum" /></li>
<li><label for="li">li</label><input type="text" id="li" /></li>
</ol>
</fieldset>

<fieldset>
<legend>Second Example:</legend>
<ol>
<li><label for="a">a</label><input type="text" id="a" /></li>
<li><label for="b">b</label><input type="number" id="b" /></li>
<li><label for="c">c</label><input type="range" id="c" /></li>
</ol>
</fieldset>

<fieldset>
<legend>Third Example:</legend>
<ol>
<li><label for="XXXXXXXX">XXXXXXXX</label><input type="email" id="XXXXXXXX" /></li>
<li><label for="YYYYYYYYYYYY">YYYYYYYYYYYY</label><input type="search" id="YYYYYYYYYYYY" /></li>
<li><label for="z">z</label><input type="text" id="z" /></li>
</ol>
</fieldset>
</form>

styled by

  fieldset {
border: 1px solid silver;
margin: 10px;
padding: 10px;
min-width: 100px;
display: inline-block;
}

fieldset li{
width: 100%;
display: block;
position: relative;
}

fieldset label{
margin-right: 10px;
position: relative;
}

fieldset label:after{
content: ": ";
position: absolute;
right: -0.2em;
}

fieldset input{
float: right;
}

would result in this view. You can even play around with it on this fiddle: http://jsfiddle.net/ramsesoriginal/b6Taa/

EDIT to show how this adds no markup

With the following html:

 <form>
<label for="lorem">lorem<input type="text" id="lorem" /></label>
<label for="ipsum">ipsum<input type="text" id="ipsum" /></label>
<label for="li">li<input type="text" id="li" /></label>
</form>

and the following CSS:

form{
min-width: 100px;
display: inline-block;
}

form input{
float: right;
}

form label{
display:block;
margin-bottom: 2px;
}

You get the effect that you want. You can play around with it here. But adding <fieldsets> with <legend>s isn't adding unnecessary markup, on the contrary: it helps you to group the inputs. And adding a <ol> is semantically correct too, since the label/input combinations are semantic units and the form is a list of fields that have to be filled in a logical order.

Again, you can avoid the fieldsets, the lists, and everything and still achieve the desired effect, but semantically it would make sense to have at least the fieldset with a label..

EDIT2: this is how a "real" registration form with good semantic markup may look like:

 <form>
<ol>
<fieldset>
<legend>Account</legend>
<li><label for="username">Username</label><input type="text" id="username" required /></li>
<li><label for="password">Password</label><input type="password" id="password" required /></li>
</fieldset>

<fieldset>
<legend>Personal Data</legend>
<li><label for="name">Name</label><input type="text" id="name" /></li>
<li><label for="surname">Surname</label><input type="text" id="surname" /></li>
<li><label for="dob">Date of birth</label><input type="date" min="1900-01-01" max="2012-02-17" placeholder="YYYY-MM-DD" id="dob" /><span class="additionalInfo">Please input the date of birth in the following format: YYYY-MM-DD</span></li>
</fieldset>

<fieldset>
<legend>Contact Information</legend>
<li><label for="email">E-mail</label><input type="email" id="email" required placeholder="example@example.com" /></li>
<li><label for="tel">Telephone number</label><input type="tel" id="tel" placeholder="(555) 555-5555"
pattern="^\(?\d{3}\)?[-\s]\d{3}[-\s]\d{4}.*?$" /><span class="additionalInfo">Please input the telephone number in the following format: (555) 555-5555</span></li>
<li><label for="url">Website</label><input type="url" id ="url" placeholder="http://www.example.com"></li>
</fieldset>

<li><input type="submit" /></li>
</ol>
</form>

and the styling:

 fieldset {
border: 1px solid silver;
margin: 10px;
padding: 10px;
min-width: 100px;
display: inline-block;
}

fieldset li{
width: 100%;
display: block;
position: relative;
margin-bottom: 2px;
}

fieldset label{
margin-right: 10px;
position: relative;
}

fieldset label:after{
content: ": ";
position: absolute;
right: -0.2em;
}

fieldset input{
float: right;
}

fieldset li .additionalInfo{
position: absolute;
padding: 5px;
margin-top: 5px;
display: none;
background-color: white;
border: 1px solid black;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 5px 5px 5px 5px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 5px 5px 5px 5px rgba(0, 0, 0, 0.5);
box-shadow: 5px 5px 5px 5px rgba(0, 0, 0, 0.5);
z-index: 10;
}

fieldset li:hover .additionalInfo{
display: block;
}

I included some additional info, to show you how it would all come together to one logical entity. Similarly you could include errors and whatever else you may want to include. This is just a quick example i threw together, but it's should show that you can achieve interesting things with this technique. One thing I also changed was that I put the <ol> directly under the form, so you don't have to repeat it for every fieldset. I personally find this somehow.. unpleasing, but since you want to have minimal markup, this would work pretty well and would be very accessible. Again, read this article if you haven't. It provides some great insight in marking up correctly a form.

Oh, and the "real-life" example is visible here: http://fiddle.jshell.net/ramsesoriginal/b6Taa/9/show/

And you can play with it here:
http://jsfiddle.net/ramsesoriginal/b6Taa/9/

EDIT: i updated the last example

There was an error in my code. The wrapper element (the <li>in the second and in the last example, the <label> in the minimal one and the <p> in the first one should have at least 1 pixel margin at the bottom, or else some browsers see the input fields as overlapping and won't float them correctly. I updated the last example so that it works there, everywhere else you should keep this in mind.



Related Topics



Leave a reply



Submit