How to position a liquid/elastic textbox next to a button? - html

I want to position a textbox and a button next to each other in an 'elastic' or 'liquid' way (what's the correct term?) like so:
(source: ocactus.org)
When placed in a container of arbitrary width (incl. browser window resizing), the button should right align and take up as much width as it requires while the textbox should use the remaining width. Unfortunately the button's width cannot be fixed in CSS as it depends on the caption (different actions, languages etc.).
What is a good solution for the above that works cross browser?

I was able to get this to work within a table (I know, but it works) where it would correctly handle page resizing as well as the value of the button changing:
<table class="elastic">
<tr>
<td><input class="textbox" type="text"></td>
<td class="button"><input type="button" value="Test Button"></td>
</tr>
</table>
There may be a <div> alternative out there for styling.
EDIT: I revamped my example to use the following style sheet:
.elastic { width:100%; }
.elastic .textbox { width: 100%; }
.elastic .button { width: 1%; }

It's hard to give a definitive answer without seeing some code but the following will size the input 50% of the browser width with the button next to it.
input {width:50%}
<input>
<button>save</button>

HTML:
<div class="widebox">
<input type="text" value="" />
<button>Button</button>
</div>
jQuery:
<script type="text/javascript">
$(document).ready(function(){
var w = $(".widebox");
$(".widebox input:text").css({ width: (w.width - (w.children("button:first").width + 20)) });
});
</script>
Note: Be sure to include the jQuery library in your document's <head>. For speed I recommend using the one hosted by Google: http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js

Here's a jQuery extension I wrote based on NGJ Graphics' answer. It takes into account multiple buttons such as Ok/Cancel options.
(function($) {
$.fn.extend({
widebox: function() {
var el = $(this);
var width = 0;
el.children("button").each(function() {
width += $(this).outerWidth( true );
});
el.children("input:text").css({ width: (el.width() - (width + 40)) });
}
});
})(jQuery);

Related

How can I get placeholder text to shrink to fit within its text input element and show its entire value? [duplicate]

This question already has answers here:
Change a HTML5 input's placeholder color with CSS
(43 answers)
Changing Font Size and Margin of Placeholder Text in IE
(1 answer)
Closed 7 years ago.
I have the following HTML:
<form>
<table border="1">
<tr>
<td>Traveler's name:</td>
<td>
<input type="text" id="travelername" placeholder="Last Name, First Name, Middle Initial"/>
</td>
</tr>
<tr>
<td>Traveler's E-mail:</td>
<td>
<input type="email" id="traveleremail"/>
</td>
</tr>
</table>
</form>
I want the placeholder val to be fully visible at all times, but it's not:
I tried adding this CSS:
input[placeholder] {
font-size: 0.6em;
}
...but, while this reduces the size of the font admirably, the text is truncated:
I tried adding to the CSS like so:
input[placeholder] {
font-size: 0.6em;
width: 500;
}
...but it does nothing to expand/widen the placeholder's text area within the input text (the input text is wide enough to hold the reduced text, but it is still squished into a too-small area within itself).
How can this be accomplished?
Original Reply - July 2015
What about doing something like this? I used jQuery to demonstrate it. If you want it to be more 'exact' in terms of width of the text, you can look at a way to get the text's width and then setting the width in jquery's CSS to the value returned from the function that gets the text's width (in which case you will likely have to create an element, set its html to the placeholder's content, get the text's width and then delete the element). In any case, the code below is what I would do to accomplish what you are asking.
I decided to use setInterval because getting changes to input fields are not black and white. each loops through the input elements. The code then checks to see if input is empty, if it is, is downscales the font-size (to 10px as I hardcoded it), otherwise it sets it to the default (let's say you want 14px, it gets 14px).
setInterval(function() {
$('input').each(function(){
if($(this).val() === ''){
$(this).css({
"width":$(this).width()+"px",
"height":$(this).height()+"px"
});
if(parseFloat($(this).css('font-size'))<=14){
$(this).animate({
"font-size":10+"px"
});
}
}
else {
$(this).finish().clearQueue().css({
"font-size":14+"px"
});
}
});
}, 100);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<table border="1">
<tr>
<td>Traveler's name:</td>
<td>
<input type="text" id="travelername" placeholder="Last Name, First Name, Middle Initial"/>
</td>
</tr>
<tr>
<td>Traveler's E-mail:</td>
<td>
<input type="email" id="traveleremail"/>
</td>
</tr>
</table>
</form>
If you want, you can lower or increase the interval for the setInterval function to allow it to execute faster or slower (keep in mind performance and different computing speeds)
EDIT - May 2017
Seeing that this question has been viewed over a thousand times, I felt I should update my answer to be a little more useful and be less reliant on manual input.
The code below works as follows:
Create your CSS style for both the input fields and their associated clones (this logic can be customized to your needs, but for simplicity purposes, I've given all input element clones the same class)
Loops over all input elements and creates a clone
Gets the clone's width and compares its width to the input element's width while reducing the font-size on each iteration by the step
Once the clone's width is less than or equal to the input element's width, we delete the clone element and set the input's font-size.
Upon user input inside the input element, we undo our changes to font-size
Note: When "undoing" our changes to the input element, we are in fact removing the inline property and value. Any styles for these elements should be done in CSS (or you'll have to try to find a way around this, such as creating a hidden element with id, accessing it, pulling the style and applying it back to the input element).
When testing the code below, I, personally, found that a step of 0.1 was sufficient and that a value smaller (of say 0.01) impacted performance. You can, however, play with this value as you wish.
// Step is used to reduce font-size by value X
var step = 0.1;
setInterval(function() {
// Loop over input elements
$('input').each(function() {
// Only change font-size if input value is empty (font-size should only affect placeholder)
if ($(this).val() === '') {
// Create clone
$clone = $('<span></span>')
.appendTo('body')
.addClass('inputClone')
.text($(this).attr('placeholder'));
// Adjust font-size of clone
var fontSize = $(this).css('font-size');
do {
fontSize = parseFloat($clone.css('font-size')) - step;
$clone.css({
'font-size': fontSize
});
} while ($clone.width() > $(this).width());
// Maintain input field size
$(this).css({
"width": $(this).width() + "px",
"height": $(this).height() + "px"
});
// Change input font-size
$(this).animate({
'font-size': fontSize
});
// Delete clone
$clone.remove();
} else {
// Default input field back to normal
$(this)
.finish()
.clearQueue()
.attr('style', function(i, style) {
// Remove inline style for font-size
return style.replace(/font-size[^;]+;?/g, '');
});
}
});
}, 100);
input,
.inputClone {
font-family: "Arial", Helvetica, sans-serif;
font-size: 14px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<table border="1">
<tr>
<td>Traveler's name:</td>
<td>
<input type="text" id="travelername" placeholder="Last Name, First Name, Middle Initial" />
</td>
</tr>
<tr>
<td>Traveler's E-mail:</td>
<td>
<input type="email" id="traveleremail" />
</td>
</tr>
</table>
</form>

force input element's width to size to its content/value

I'm trying to unstyle an input element so that its text looks like plain/inline-text, and I've reset pretty much every css property it can have, but I can't get the input's width to adjust/shrink to its content (input { width:auto; min-width:0; } does not work). It obeys an arbitrary width like input { width: 10px; }, so obviously its width is adjustable.
I see people trying to do it with javascript (the fiddle from the answer doesn't work anymore), so I'm wondering if what I want is even possible.
Here's a fiddle.
Played with this. Couldn't do it. What are you trying to achieve? Are you aware of the contenteditable attribute?
This might get you what you need.
https://developer.mozilla.org/en-US/docs/HTML/Content_Editable
What if you just avoid the whole style snafu and do a little text shuffling? You already have everything you need with jQuery.
http://jsfiddle.net/2fQgY/8/
The date is <span class="dateSpoof"></span><input class="myDate" type="hidden" value="foo" />.
Thanks for coming.
$('.myDate').datepicker({
showOn: 'button',
buttonText: 'select...',
onClose: function () {
var dateText = $(this).val();
$('.dateSpoof').html(dateText);
$('.ui-datepicker-trigger').hide();
},
dateFormat: 'd M yy'
});
Here's an example that's resettable: http://jsfiddle.net/2fQgY/11
And here's one that's all text and nothing but text: http://jsfiddle.net/2fQgY/14

zoomin/zoomout of an image in html5

i have simple application which should work on keyboard events like onfocus and onblur instead of onmouseover and onmouseout.
here is my code snippet to zoomin/zoomout:
<script>
var nW,nH,oH,oW;
function zoom(iWideSmall,iHighSmall,iWideLarge,iHighLarge,whichImage)
{
oW=whichImage.style.width;oH=whichImage.style.height;
if((oW==iWideLarge)||(oH==iHighLarge))
{
nW=iWideSmall;nH=iHighSmall;
}
else
{
nW=iWideLarge;nH=iHighLarge;
}
whichImage.style.width=nW;whichImage.style.height=nH;
}
</script>
calling this function in this way:
<td align=center valign=middle >
<figure>
<button style="background-color:black; height:160px;width:160px ; border:none"><img src="F:\rashmi\icons_tv\Help_Normal.png" onfocus="zoom('57px','120px','96px','136px',this);"
onblur="zoom('57px','120px','57px','120px',this);" > </button>
<figcaption><font size="5" color="white" style="font-weight:bold"><center>help</center></font></figcaption>
</figure>
</td>
but problem is when i select image using tab key i cant see any zoomin/zoomout effect. if i replace onfocus/onblur with onmouseover/onmouseout respectively it works well.
please some one help me where i am going wrong.
regards
rashmi
You will not get focus on an img element by tabbing but on the button element instead. Move your onblur/onfocus events to the button element. This will change your button's size each time you focus/lose focus on it, but it will not change your image size. What you have to do then is to modify your code so the change is mapped on the button's contained image dimensions as well. Something that I can think of right now is
<script type="text/javascript">
var nW,nH,oH,oW;
function zoom(iWideSmall,iHighSmall,iWideLarge,iHighLarge,whichElement)
{
theImage = whichElement.firstChild;
theImage.style.width=nW;theImage.style.height=nH;
oW=whichElement.style.width;oH=whichElement.style.height;
if((oW==iWideLarge)||(oH==iHighLarge))
{
nW=iWideSmall;nH=iHighSmall;
}
else
{
nW=iWideLarge;nH=iHighLarge;
}
whichElement.style.width=nW;whichElement.style.height=nH;
theImage.style.width=nW;theImage.style.height=hH;
}
</script>
Here, the first child of the button element, which happens to be the image, takes the same height and width with the button, whenever that changes.

Is there a way to get a textarea to stretch to fit its content without using PHP or JavaScript?

I am filling a textarea with content for the user to edit.
Is it possible to make it stretch to fit content with CSS (like overflow:show for a div)?
one line only
<textarea name="text" oninput='this.style.height = "";this.style.height = this.scrollHeight + "px"'></textarea>
Not really. This is normally done using javascript.
there is a good discussion of ways of doing this here...
Autosizing textarea using Prototype
Alternatively, you could use a contenteditable element, this will fit to the text inside.
<div contenteditable>Try typing and returning.</div>
Please note that it's not possible to send this value along in a form, without using some javascript. Also contenteditable will possibly generate HTML-content and allows styling, so this may need to be filtered out upon form submit.
This is a very simple solution, but it works for me:
<!--TEXT-AREA-->
<textarea id="textBox1" name="content" TextMode="MultiLine" onkeyup="setHeight('textBox1');" onkeydown="setHeight('textBox1');">Hello World</textarea>
<!--JAVASCRIPT-->
<script type="text/javascript">
function setHeight(fieldId){
document.getElementById(fieldId).style.height = document.getElementById(fieldId).scrollHeight+'px';
}
setHeight('textBox1');
</script>
Here is a function that works with jQuery (for height only, not width):
function setHeight(jq_in){
jq_in.each(function(index, elem){
// This line will work with pure Javascript (taken from NicB's answer):
elem.style.height = elem.scrollHeight+'px';
});
}
setHeight($('<put selector here>'));
Note:
The op asked for a solution that does not use Javascript, however this should be helpful to many people who come across this question.
Not 100% related to the question as this is for Angular when using Angular Material Design only.
There is a npm package associated with Angular called #angular/cdk (if using Angular Material Design). There is a property included in this package that can be associated to a textarea called cdkTextareaAutosize. This automatically sets the textarea to 1 line and stretches the textarea to fit the content accordingly. If you are using this library, something like this should work.
<textarea
maxLength="200"
cdkTextareaAutosize
type="text">
</textarea>
Another simple solution for dynamic textarea control.
<!--JAVASCRIPT-->
<script type="text/javascript">
$('textarea').on('input', function () {
this.style.height = "";
this.style.height = this.scrollHeight + "px";
});
</script>
Answers here were good but were lacking a piece of code that I had to add to avoid a shrinking that is not welcome when you type for the first time :
var $textareas = $('textarea');
$textareas.each(function() { // to avoid the shrinking
this.style.minHeight = this.offsetHeight + 'px';
});
$textareas.on('input', function() {
this.style.height = '';
this.style.height = this.scrollHeight + 'px';
});
There are a lot of answers here already, but I think some improvement can still be made to the textarea resizing code.
This script snippet will loop over ALL of the textareas on your page, and make sure they resize both on load and on change.
<script>
document.querySelectorAll("textarea").forEach(element => {
function autoResize(el) {
el.style.height = el.scrollHeight + 'px';
}
autoResize(element);
element.addEventListener('input', () => autoResize(element));
});
</script>
Vanilla JS only, no libraries needed.
Solution for React
I used the length of the text that was being displayed and divided that number by 30 (I adjusted this number until it felt right form my App)
{array.map((text) => (
<textarea
rows={text.length / 30}
value={text}
></textarea>
)}

Select dropdown with fixed width cutting off content in IE

The issue:
Some of the items in the select require more than the specified width of 145px in order to display fully.
Firefox behavior: clicking on the select reveals the dropdown elements list adjusted to the width of the longest element.
IE6 & IE7 behavior: clicking on the select reveals the dropdown elements list restricted to 145px width making it impossible to read the longer elements.
The current UI requires us to fit this dropdown in 145px and have it host items with longer descriptions.
Any advise on resolving the issue with IE?
The top element should remain 145px wide even when the list is expanded.
Thank you!
The css:
select.center_pull {
background:#eeeeee none repeat scroll 0 0;
border:1px solid #7E7E7E;
color:#333333;
font-size:12px;
margin-bottom:4px;
margin-right:4px;
margin-top:4px;
width:145px;
}
Here's the select input code (there's no definition for the backend_dropbox style at this time)
<select id="select_1" class="center_pull backend_dropbox" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>
Full html page in case you want to quickly test in a browser:
<!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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>dropdown test</title>
<style type="text/css">
<!--
select.center_pull {
background:#eeeeee none repeat scroll 0 0;
border:1px solid #7E7E7E;
color:#333333;
font-size:12px;
margin-bottom:4px;
margin-right:4px;
margin-top:4px;
width:145px;
}
-->
</style>
</head>
<body>
<p>Select width test</p>
<form id="form1" name="form1" method="post" action="">
<select id="select_1" class="center_pull backend_dropbox" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>
</form>
</body>
</html>
For IE 8 there is a simple pure css-based solution:
select:focus {
width: auto;
position: relative;
}
(You need to set the position property, if the selectbox is child of a container with fixed width.)
Unfortunately IE 7 and less do not support the :focus selector.
I did Google about this issue but didn't find any best solution ,So Created a solution that works fine in all browsers.
just call badFixSelectBoxDataWidthIE() function on page load.
function badFixSelectBoxDataWidthIE(){
if ($.browser.msie){
$('select').each(function(){
if($(this).attr('multiple')== false){
$(this)
.mousedown(function(){
if($(this).css("width") != "auto") {
var width = $(this).width();
$(this).data("origWidth", $(this).css("width"))
.css("width", "auto");
/* if the width is now less than before then undo */
if($(this).width() < width) {
$(this).unbind('mousedown');
$(this).css("width", $(this).data("origWidth"));
}
}
})
/* Handle blur if the user does not change the value */
.blur(function(){
$(this).css("width", $(this).data("origWidth"));
})
/* Handle change of the user does change the value */
.change(function(){
$(this).css("width", $(this).data("origWidth"));
});
}
});
}
}
Here is a little script that should help you out:
http://www.icant.co.uk/forreview/tamingselect/
For a simple Javascript-free solution, adding a title-attribute to your <option>s holding the text might be enough, depending on your requirements.
<option value="242" title="Very long and extensively descriptive text">
Very long and extensively descriptive text
</option>
This will show the cut-off text in a tool-tip fashion on hovering the <option>, regardless of the width of the <select>.
Works for IE7+.
Not javascript free i'm afraid, but I managed to make it quite small using jQuery
$('#del_select').mouseenter(function () {
$(this).css("width","auto");
});
$('#del_select').mouseout(function () {
$(this).css("width","170px");
});
Simply you can use this plugin for jquery ;)
http://plugins.jquery.com/project/skinner
$(function(){
$('.select1').skinner({'width':'200px'});
});
Small, but hopefully useful update to the code from MainMa & user558204 (thanks guys), which removes the unnecessary each loop, stores a copy of $(this) in a variable in each event handler as it's used more than once, also combined the blur & change events as they had the same action.
Yes, it's still not perfect as it resizes the select element, rather than just the drop-down options. But hey, it got me out of a pickle, I (very, very unfortunately) still have to support an IE6-dominant user base across the business.
// IE test from from: https://gist.github.com/527683
var ie = (function () {
var undef, v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i');
while (
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]
);
return v > 4 ? v : undef;
} ());
function badFixSelectBoxDataWidthIE() {
if (ie < 9) {
$('select').not('[multiple]')
.mousedown(function() {
var t = $(this);
if (t.css("width") != "auto") {
var width = t.width();
t.data("ow", t.css("width")).css("width", "auto");
// If the width is now less than before then undo
if (t.width() < width) {
t.unbind('mousedown');
t.css("width", t.data("ow"));
}
}
})
//blur or change if the user does change the value
.bind('blur change', function() {
var t = $(this);
t.css("width", t.data("ow"));
});
}
}
A different approach:
instead of a select make it an edit box, disabled so noone can enter anything manually or change contents after selection
another hidden edit to contain an id of a selected option (explained below)
make a button [..] and script it to show that div below
make a hidden div with absolute position under or near the edit box
make that div to contain a select with style size="6" (to show 6 options and a scrollbar rather than a drop-down list) and a button "select" and maybe "cancel"
Do not style width so the whole thing will assume width of the widest option or the button plus maybe some padding of your choice
script the "select" button to copy id of the selected option to the hidden edit box and it's value to the visible one, also to hide the div again.
4 simple javascript commands total.
I found a pretty straightforward fix for this. In the <select> html element add these properties:
onmouseover="autoWidth(this)"
onblur="resetWidth(this)"
So whenever user clicks on that the width will automatically expand, and user moves out of the select box, the width will be reset to original.
similar solution can be found here using jquery to set the auto width when focus (or mouseenter) and set the orignal width back when blur (or mouseleave) http://css-tricks.com/select-cuts-off-options-in-ie-fix/.
for (i=1;i<=5;i++){
idname = "Usert" + i;
document.getElementById(idname).style.width = "100%";
}
I used this way to showed the drop down list when the width is not showed correctly.
It work for IE6, Firefox and Chrome.
A full fledged jQuery plugin is available, check out the demo page: http://powerkiki.github.com/ie_expand_select_width/
disclaimer: I coded that thing, patches welcome
Why would anyone want a mouse over event on a drop down list? Here's a way of manipulating IE8 for the way a drop down list should work:
First, let's make sure we are only passing our function in IE8:
var isIE8 = $.browser.version.substring(0, 2) === "8.";
if (isIE8) {
//fix me code
}
Then, to allow the select to expand outside of the content area, let's wrap our drop down lists in div's with the correct structure, if not already, and then call the helper function:
var isIE8 = $.browser.version.substring(0, 2) === "8.";
if (isIE8) {
$('select').wrap('<div class="wrapper" style="position:relative; display: inline-block; float: left;"></div>').css('position', 'absolute');
//helper function for fix
ddlFix();
}
Now onto the events. Since IE8 throws an event after focusing in for whatever reason, IE will close the widget after rendering when trying to expand. The work around will be to bind to 'focusin' and 'focusout' a class that will auto expand based on the longest option text. Then, to ensure a constant min-width that doesn't shrink past the default value, we can obtain the current select list width, and set it to the drop down list min-width property on the 'onchange' binding:
function ddlFix() {
var minWidth;
$('select')
.each(function () {
minWidth = $(this).width();
$(this).css('min-width', minWidth);
})
.bind('focusin', function () {
$(this).addClass('expand');
})
.change(function () {
$(this).css('width', minWidth);
})
.bind('focusout', function () {
$(this).removeClass('expand');
});
}
Lastly, make sure to add this class in the style sheet:
select:focus, select.expand {
width: auto;
}
Not javascript free, I am afraid too and my solution do require a js library, however, you can only use those files which you need rather than using them all, maybe best suited for those who are already using YUI for their projects or deciding which one to use. Have a look at: http://ciitronian.com/blog/programming/yui-button-mimicking-native-select-dropdown-avoid-width-problem/
My blog post also discusses other solutions as well, one is referenced back to here on stackoverflow, why I went back to create my own SELECT element is because of simple reason, I don't like mouseover expand events. Maybe if that helps anyone else too!
The jquery BalusC's solution improved by me. Used also: Brad Robertson's comment here.
Just put this in a .js, use the wide class for your desired combos and don't forge to give it an Id. Call the function in the onload (or documentReady or whatever).
As simple ass that :)
It will use the width that you defined for the combo as minimun length.
function fixIeCombos() {
if ($.browser.msie && $.browser.version < 9) {
var style = $('<style>select.expand { width: auto; }</style>');
$('html > head').append(style);
var defaultWidth = "200";
// get predefined combo's widths.
var widths = new Array();
$('select.wide').each(function() {
var width = $(this).width();
if (!width) {
width = defaultWidth;
}
widths[$(this).attr('id')] = width;
});
$('select.wide')
.bind('focus mouseover', function() {
// We're going to do the expansion only if the resultant size is bigger
// than the original size of the combo.
// In order to find out the resultant size, we first clon the combo as
// a hidden element, add to the dom, and then test the width.
var originalWidth = widths[$(this).attr('id')];
var $selectClone = $(this).clone();
$selectClone.addClass('expand').hide();
$(this).after( $selectClone );
var expandedWidth = $selectClone.width()
$selectClone.remove();
if (expandedWidth > originalWidth) {
$(this).addClass('expand').removeClass('clicked');
}
})
.bind('click', function() {
$(this).toggleClass('clicked');
})
.bind('mouseout', function() {
if (!$(this).hasClass('clicked')) {
$(this).removeClass('expand');
}
})
.bind('blur', function() {
$(this).removeClass('expand clicked');
})
}
}
Its tested in all version of IE, Chrome, FF & Safari
// JavaScript code
<script type="text/javascript">
<!-- begin hiding
function expandSELECT(sel) {
sel.style.width = '';
}
function contractSELECT(sel) {
sel.style.width = '100px';
}
// end hiding -->
</script>
// Html code
<select name="sideeffect" id="sideeffect" style="width:100px;" onfocus="expandSELECT(this);" onblur="contractSELECT(this);" >
<option value="0" selected="selected" readonly="readonly">Select</option>
<option value="1" >Apple</option>
<option value="2" >Orange + Banana + Grapes</option>
I've got yet another contribution to this. I wrote this a while back that you may find helpful: http://dpatrickcaldwell.blogspot.com/2011/06/giantdropdown-jquery-plugin-for-styling.html
It's a jquery plugin to make a styleable unordered list backed by the hidden select element.
The source is on github: https://github.com/tncbbthositg/GiantDropdown
You'd be able to handle behaviors and styles on the UL that you can't with the SELECT. Everything else should be the same because the select list is still there, it's just hidden but the UL will use it as a backing data store (if you will).
I wanted this to work with selects that I added dynamically to the page, so after a lot of experimentation, I ended up giving all the selects that I wanted to do this with the class "fixedwidth", and then added the following CSS:
table#System_table select.fixedwidth { width: 10em; }
table#System_table select.fixedwidth.clicked { width: auto; }
and this code
<!--[if lt IE 9]>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery(document).on(
{
'mouseenter': function(event) {
jQuery(this).addClass('clicked');
},
'focusout change blur': function() {
jQuery(this).removeClass('clicked');
}
}, 'select.fixedwidth');
});
</script>
<![endif]-->
A couple of things to note:
In spite of the fact that my selects are all in a table, I had to do "on" to the jQuery(document).on instead of to jQuery('table#System_table').on
In spite of the fact that the jQuery documentation says to use "mouseleave" instead of "blur", I found that in IE7 when I moved the mouse down the drop down list, it would get a mouseleave event but not a blur.
Here is a solution that actually works.
It sets the width in IE and doesn't mess up your page layout and doesn't close the dropdown when you mouse over the select options like some of the other solutions on this page.
You will need however to change the margin-right value and width values to match what you have for your select fields.
Also you can replace the $('select') with $('#Your_Select_ID_HERE') to only effect a specific select field. As well you will need to call the function fixIESelect() on the body onload or via jQuery using DOM ready as I did in my code below:
//////////////////////////
// FIX IE SELECT INPUT //
/////////////////////////
window.fixIESelect_clickset = false;
function fixIESelect()
{
if ($.browser.msie)
{
$('select').mouseenter(function ()
{
$(this).css("width","auto");
$(this).css("margin-right","-100");
});
$('select').bind('click focus',function ()
{
window.fixIESelect_clickset = true;
});
$('select').mouseout(function ()
{
if(window.fixIESelect_clickset != true)
{
$(this).css("width","93px");
window.fixIESelect_clickset = false;
}
});
$('select').bind('blur change',function ()
{
$(this).css("width","93px");
});
}
}
/////////////
// ONLOAD //
////////////
$(document).ready(function()
{
fixIESelect();
});
For my layout, I didn't want a hack (no width increasing, no on click with auto and then coming to original). It broke my existing layout. I just wanted it to work normally like other browsers.
I found this to be exactly like that :-
http://www.jquerybyexample.net/2012/05/fix-for-ie-select-dropdown-with-fixed.html
A workaround if you don't care about the strange view after an option is selected (i.e. Select to jump to a new page):
<!-- Limit width of the wrapping div instead of the select and use 'overflow: hidden' to hide the right part of it. -->
<div style='width: 145px; overflow: hidden; border-right: 1px solid #aaa;'>
<select onchange='jump();'>
<!-- '▼(▼)' produces a fake dropdown indicator -->
<option value=''>Jump to ... ▼</option>
<option value='1'>http://stackoverflow.com/questions/682764/select-dropdown-with-fixed-width-cutting-off-content-in-ie</option>
...
</select>
</div>
A pure css solution : http://bavotasan.com/2011/style-select-box-using-only-css/
.styled-select select {
background: transparent;
width: 268px;
padding: 5px;
font-size: 16px;
line-height: 1;
border: 0;
border-radius: 0;
height: 34px;
-webkit-appearance: none;
}
.styled-select {
width: 240px;
height: 34px;
overflow: hidden;
background: url(http://cdn.bavotasan.com/wp-content/uploads/2011/05/down_arrow_select.jpg) no-repeat right #ddd;
border: 1px solid #ccc;
}
<div class="styled-select">
<select>
<option>Here is the first option</option>
<option>The second option</option>
</select>
</div>
Best solution: css + javascript
http://css-tricks.com/select-cuts-off-options-in-ie-fix/
var el;
$("select")
.each(function() {
el = $(this);
el.data("origWidth", el.outerWidth()) // IE 8 can haz padding
})
.mouseenter(function(){
$(this).css("width", "auto");
})
.bind("blur change", function(){
el = $(this);
el.css("width", el.data("origWidth"));
});