I'm noot good in english, so the title may seem a bit odd.
I want to use css function attr() like this:
I mean i have a container <div> and an inner <div> that i want to have width depending on data-width attribute. For example this would be great, but this doesnt work:
<div class="container">
<div data-width="70%">
</div
</div>
.container {
width: 600px;
height: 200px;
}
.container div {
width: attr(data-width);
height: 100%;
}
Is there any noJS way to use attributes like that?
UPDATE: Guys convinced me that the JS is the only way to do this :)
That's not a big problem (but that's bad. CSS, why youre so illogical? Is the difference between content:attr(data-width) and width: attr(data-width) so big ?).
One of the guys had an idea to go through the all elements with jQuery.
That's ok, but it is very... local? Don't know how to say it in english.
Anyway, i remaked his code a little bit and here it is:
allowed = ['width','color','float'];
$(document).ready(function () {
$('div').each(function (i, el) {
var data = $(el).data(),style = '';
if (!$.isEmptyObject(data)) {
$.each(data, function (attr, value) {
if (allowed.indexOf(attr) != - 1) {
style += attr + ': ' + value + '; ';
}
})
if (style.length != 0) {
$(el).attr('style', style);
}
}
})
})
Idea is simple:
1. We suppose that style we want to add to an element is the only one. I mean there are no scripts that will try to add some other styles,
2. We create an array of allowed attribute names, we need to avoid using wrong names at the style attribute, for example style="answerid: 30671428;",
3. We go through each element, save its data attributes in an object, check if object is empty, and if not - check every attribute if it is allowed, create a string that contains all styles that we need, and - finally - add our style string to the element as the content of style attribute.
That's all, thanks everybody
I would not advise to use CSS alone since it will not allow you to do what you're looking for... instead use a scripting language (in my case jQuery) to accomplish this functionality for you like so: jsFiddle
jQuery
jQuery(document).ready(function(){
var dataElem; // to store each data attribute we come accross
jQuery('div').each(function(){ //loop through each div (can be changed to a class preferably)
dataElem = jQuery(this); //get the current div
if(dataElem.data('width')){ //make sure it exists before anything further
dataElem.width(dataElem.data('width')); //set the element's width to the data attribute's value
dataElem.css("background-color", "yellow");
}
});
});
HTML
<p>The links with a data-width attribute gets a yellow background:</p>
<div>
w3schools.com
</div>
<div class="me" data-width="50"> <!-- change value to see the difference -->
disney.com
</div>
<div>
wikipedia.org
</div>
Notes on the above:
each, data, width.
Instead of doing data-width, use a class attribute. An html tag can have mutliple classes separated by spaces, so if you wanted to be very precise, you could set up as many classes as you need. For instance:
<div class="w70 h100">
</div>
Then in your css:
.w70{
width: 70%;
}
.h100{
height: 100%;
}
And so on.
Is there any noJS way to use attributes like that?
No, you cannot use CSS to set the width of the element to it's data-width attribute. CSS does not allow for this as attr() is only currently available for the CSS content property which is only available on css pseudo elements (::before and ::after).
How can you achieve this with as little javascript as possible?
This is extremely easy to do using the native host provided DOM API.
Select the elements using Document.querySelectorAll().
Iterate the elements and apply the styles using Element.style which can be retrieved from the data-width attribute using Element.dataset
(Demo)
var items = document.querySelectorAll('#container div'), item, i;
for(i = 0; (item = items[i]); i++) item.style.width = item.dataset.width;
I've created a html page and in that page I have forms, drop down lists and radio tags and tables. from one button I wanted to reset everything on the page when its clicked upon.
you can use the following JavaScript method to clear the HTML input file control's value:
function clearFileInputField(tagId) {
document.getElementById(tagId).innerHTML =
document.getElementById(tagId).innerHTML;
}
Or, if refactored in jQuery, this should work as well:
$("#control").html($("#control").html())
Or, for textbox type
var elements = document.getElementsByTagName("input");
for (var ii=0; ii < elements.length; ii++) {
if (elements[ii].type == "text") {
elements[ii].value = "";
}
}
You could use a reset button, please refer to this page for more information -> LINK
But if you have multiple form on the page you can write a javascript function to reset all of them like this:
$('#yourResetButton').click(function(){
$('form').each(function(idx, obj){
obj.reset();
});
});
You could also refresh your page as stated in other answers but in my opinion that could be very disappointing for your users to see that the page is refreshing
A little working fiddle as example
You can reset with reset however you won't be able to reset your inputs that doesn't included into forms, otherwise you can clear inputs within your forms like:
$('form').each(function (index, obj) { obj.reset(); });
Example
<input type="button" onclick="function() {window.location.href = window.location.href;}" name="Reset" value="Reset">
I'd like to tell the browser to assign certain CSS classes to elements matching a particular selector. Can I do it with pure CSS and if yes, how?
Example: I want all the h5 elements inside a div with id sidebar to have the class ui-corners-all
No, that isn't possible with pure CSS.
Only with JavaScript:
// jQuery
$("h5").addClass("ui-corners-all");
// Pure JavaScript
var elements = document.getElementsByTagName("h5");
for (var i=0; i<elements.length; i++)
{
var el = elements[i];
el.setAttribute( "class", el.getAttribute("class") + " ui-corners-all" );
}
There is no way to assign this value to those elements in pure CSS.
You would need to do:
#sidebar h5
{
}
Then copy all styles from ui-corners-all class into this.
Or alternatively, change your ui-corners-all CSS to:
.ui-corners-all, #sidebar h5
{
}
No, you can't. You can however use Javascript (jQuery recommended) to achieve this effect.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to write a:hover in inline CSS?
I need to generate some self-contained HTML code, so I cannot use any external stylesheet or style tag.
One of the requirement is that a link must have a hover, visited state etc. I know how to do that with a stylesheet, but how can I do it inline? i.e. what should I put in the style attribute:
<a style="???" href="http://example.com">Link</a>
You can manage it with Javascript:
var links = document.getElementsByTagName("a");
for(var i = 0; i < links.length; i++) {
if(links[i].className == "hoverThis") {
DoHover(links[i]);
}
}
function DoHover(link_element){
link_element.onmouseover = function(){
this.style.display = "block";
}
link_element.onmouseout = function(){
this.style.display = "none";
}
}
Just add the appropriate class ("hoverThis" in this example) to the links elements you want the over effect on, and alter effect as needed.
For those interested, I ended up adding a <style> tag just before my code:
<style>.my-link:hover { text-decoration:underline !important; }</style>
This is not standard since <style> tags are supposed to be inside the <head>. However it works on the latest versions of IE, Firefox, Safari and Chrome. The worst that could happen anyway is that the :hover state won't work on the selected links.
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"));
});