IE select issue with hover - css

A friend and myself are trying to workaround IE (7/8). We have built a canonical example here:
http://www.mathgladiator.com/share/ie-select-bug-hover-css-menus.htm
Using a CSS menu, we would like to have selects in them. However, in IE, the menu goes away when you interact with the select box. We believe this has to do with a bug in how selects affect events.
Is there a workaround? At least with pure CSS or DOM hacks?

I do not think there is a pure CSS way around this. This is due to a very common bug to the way IE handles events on select elements.
You can however work around it with Javascript:
<script type="text/javascript">
$(document).ready(function () {
$('.nav_element a').mouseover(function() {
$('.submenu').hide();
$(this).parent().find('.submenu').show();
});
$('.submenu').mouseover(function() {
$(this).show();
});
$('.submenu').mouseout(function (e) {
// Do not close if going over to a select element
if (e.target.tagName.toLowerCase() == 'select') return;
$(this).hide();
});
});
</script>
The code above uses jQuery.

Here is a way to improver select behavior in IE7/8, but it does not fix the issue
Change DOCTYPE
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
Add script
<script>
function ddlOut(e) {
setTimeout(function() { e.className = e.className.replace(' over', ''); }, 1000)
}
</script>
Add css
#nav .over div.submenu
{
display: block;
}
#nav .nav_element{
behavior: expression(
this.onmouseover = new Function("this.className += ' over'"),
this.onmouseout = new Function("ddlOut(this)"),
this.style.behavior = null
);
}
It will work better at least but of course not perfect.
My advice is to change select control to html equivalent. I use OboutDropDown that has a nice view. There are many implementations that can suite you needs.

First you need to expand the :hover surface underneath your menu.
So in your css add width:310px;height:220px to #nav .nav_element a.
(also add a class or an id on the second div styled with top:220px)
Now you just need to simulate a mousedown triggered when you click on the select which will halt when the selection between the options is done - you can probably do the last part if you check for the onfocus state of the select which will stop the mousedown.

Related

SASS smart alternate link underline on hover

and if a link is underlined, i want it to get rid of the underline on hover. If a link has no underline, i want it to get one on hover.
Is there a smart way to do this with SASS rather than hard coding it for every link?
As others have stated, to do this within CSS or SASS this is something that requires a default style for links and a class or data attribute that must be applied to alternative links.
The type of auto-smart styling is possible with javascript though if that's an acceptable alternative. I made a quick jQuery Fiddle that would work by checking all links for the text-decoration style. This has performance drawbacks due to scanning the DOM for all links every page load. It also breaks the law of keeping styling with the CSS realm so it's up to you if it's worth it.
var links = $('a');
links.each(function (i) {
var $this = $(this);
// if this has underline
if ($this.css('text-decoration') == 'underline') {
$this.hover(
function() {
$this.css('text-decoration', 'none');
}, function() {
$this.css('text-decoration', 'underline');
});
} else {
$this.hover(
function() {
$this.css('text-decoration', 'underline');
}, function() {
$this.css('text-decoration', 'none');
});
};
});
https://jsfiddle.net/ym8s6Lwh/

Hovering over an image changes HTML background

Basically:
div:hover
{
body{ background-image:(bg.png); }
}
This is logical code, I know it does not work, but its the best how I can show you my problem.
Well what your trying to accomplish cannot be achieved that way using Css only, You can do it using jquery like this
$("#someDiv").hover(function(){
$("body").css("background-image", "url('image_url')")
});
In css ,You can not do this as "body" is parent element to "div" and it should come next to the element hovered to use the for format like
firstelement:hover second_element {/*styles*/}
you can use jquery to achieve it
$("div").hover(function(){
$("body").css("background", "url('url_of_image_here')")
});
or javascript
elem = document.getElementById("ID");
elem.addEventListener("mouseout", function(){
document.getElementsByTagName("body")[0].style.backgroundImage="url()";
});

Make checkbox look like button

In my web app (c#/MVC3), I have a huge set of checkboxes in a table. Rather than a table of checkboxes, I'd like for it to look like a wall of toggle buttons. To the user I want it to look like a wall of buttons and when they click one it is 'checked' and the button changes color.
I wasn't sure if there was CSS that could make a checkbox do this (look like a button and change colors on check rather than show a check mark), or if I would have to use some combination of buttons and javascript/jquery and hidden checkboxes or what.
The jQuery UI Button widget can handle that:
http://jqueryui.com/button/#checkbox
Yes, it is definitely possible to do what you want with pure CSS.
I think you should check out the jsFiddle mentioned on this question.
Radio buttons are generated by the operating system and cannot be easily styled.
If you wany something different you need to generate it using CSS/images and JavaScript.
First of all, I'd actually avoid doing this for usability concerns but if you still want to then read on.
This is actually quite tricky to achieve but it is possible. My solution avoids the need to assign individual IDs to your check-boxes.
Essentially, you will need an image sprite for the "on" and "off" states which you will position with the CSS background-position property, using a toggle class. Then, the following jQuery will allow you to not only swap the image state, but also confirm the respective checkbox as checked or unchecked for use of the form. Do note, that the "actual" checkbox is hidden from view but the functionality remains.
<form>
<input type="checkbox" class="custom" />
</form>
<style type="text/css">
.checkbox {
clear:left;
float:left;
background:url('your_image');
background-position:top;
width:20px;
height:20px;
display:block;
}
.toggled {
background-position:bottom !important;
}
</style>
$(document).ready(function () {
var checkboxes = $('form .custom'),
custom = $('<span></span>').addClass('checkbox');
checkboxes.before(custom);
checkboxes.css('visibility', 'hidden');
$('.checkbox').click(function () {
$(this).toggleClass('toggled');
var isChecked = $(this).next(':checkbox');
var value = isChecked.prop('checked') ? 'true' : 'false';
if (value == 'false') {
isChecked.prop('checked', true);
} else {
isChecked.prop('checked', false);
}
});
});
You will, of course, have to edit the CSS to suit your exact needs. I hope this helps as this task was deceptively non-trivial.

Applying Events Handler to Child Elements (Event Propogation in jQuery)

Edit : Problem wasn't related Event Propagation, if you want to know how to stop propagation in jQuery, then use event.stopPropagation();
When user moves his/her mouse over <span> element my jQuery code appends an <img>into this <span> element and when he moves out his mouse off <span> than the element appended is removed. It helps people to edit the field when clicking on the appended <img> element.
The reason I used append() method to add <img> into <span> is because I want to keep <img> element visible when user moves his mouse over to appended <img> element (<img> is becoming <span>'s child element) But it didn't happen and when user moves his mouse over it <img> is being deleted. I am thinking it is because event propagation but I couldn't find how to activate it in jQuery as we do with addEventListener in Firefox based browsers.
Here is the code :
JQuery Code :
$(document).ready(function() {
$('.EditEnabled').bind("mouseover", ShowEditFields);
$(".EditEnabled").bind("mouseout", HideEditFields);
});
function ShowEditFields(event) {
$(event.target).append(" <img id='editImg' src='images/edit.png' style='margin-bottom:-3px'/>");
}
function HideEditFields(event) {
$(event.target).children("#editImg").remove();
}
Simple HTML :
<span id="something" class="EditEnabled">Something Here</span>
Can you explain my how to solve it.
Thank you.
You want to use the jQuery mouseenter and mouseleave events, not mousover and mouseout. The reason is that mouseout will fire when you move the mouse over the img.
Thankfully, jQuery combines this into a hover method:
$(document).ready(function() {
$('.EditEnabled').hover(ShowEditFields, HideEditFields);
});
However I agree with the other answer that you should use CSS to do this vs. manipulating the DOM. I would just use the :hover pseudo selector, and then add special support for IE6.
CSS
span.EditEnabled img { display: none }
span.EditEnabled:hover img,
span.EditEnabled.hover img { display: block }
Make sure you have the img in the span in your HTML to begin with, and that is all you need for most browsers and IE7+
To support IE6 add:
<!--[if lte IE 6]>
<script type="text/javascript">
$(function(){
$(".EditEnabled").hover(
function(){ $(this).addClass('hover') },
function(){ $(this).removeClass('hover')}
);
});
</script>
<![endif]-->
Firstly, I would avoid as much DOM manipulation as you can. The ideal scenario is to construct your markup like this:
<span class="editEnabled">Some data<img ...></span>
with CSS:
span.editEnabled img { display: none; }
span.editEnabled img.visible { display: inline; }
and Javascript:
$(function() {
$("span.editEnabled").hover(function() {
$(this).children("img").addClass("visible");
}, function() {
$(this).children("img").removeClass("visible");
});
});
That should pretty much do it.
I would avoid the jQuery effects as making things visible will make them block level elements rather than inline like you want.
I've found another answer actually, the way I am looking for. It might not be a best practice but at least I've found out how to solve that.
$(document).ready(function() {
// $('.EditEnabled').bind("mouseenter", ShowEditFields);
// $(".EditEnabled").bind("mouseleave", HideEditFields);
$(".EditEnabled").hover(ShowEditFields, HideEditFields);
});
function ShowEditFields(event) {
var target = $(event.target);
if (target.is(":has(#editImg)") == false)
target.append(" <img id='editImg' src='images/edit.png' style='margin-bottom:-3px;display:inline'></img>");
}
function HideEditFields(event) {
// event.stopPropagation();
// if ($(event.relatedTarget).is("#editImg") == false)
$(event.target).children("#editImg").remove();
}

How can I customise the browser's output for print/print preview?

I'm trying to dynamically hide certain DIV's when a print (or print preview) occurs from the browser.
I can easily differentiate statically by having two style sheets, one for normal and one for print media:
But I need to go one step further and hide some elements dynamically when the print style sheet becomes active during a print based upon certain criteria
One way to easily solve it would be to handle a DOM event for handling print / printview, then I could just use jQuery to change the display:none on the classes that need to be hidden, but I can't find a DOM print event!!
Anyone know what the solution is?
Not all browsers allow you to capture the print event. I've seen this tackled by adding a 'print this page' link and then using that click event to accomplish what you need.
I don't think you need a print event. All you need to do is adjust your #media print styles based on your Javascript(?) criteria. When the user attempts to print the page, the #media print style will apply and your styles will be in effect:
<html>
<head>
<style id="styles" type="text/css">
#media print { .noprint { display:none; } }
</style>
<script type="text/javascript">
var x = Math.random();
if (x > .5) {
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '#media print { .maybe_noprint { display:none; } }';
document.getElementsByTagName('head')[0].appendChild(style);
}
</script>
</head>
<body>
<div class="noprint">This will never print.</div>
<span class="maybe_noprint">This may print depending on the value of x.</span>
</body>
</html>
If you are using server-side criteria to determine what prints, then just have server-side code spit out #media print to decorate the classes as necessary. Also, you may want to consider modifying an existing class that's already inside #media print, or building up the new CSS using something other than innerHTML, which I'll admit smells awful to me, but seems to work in Opera 9.6, Safari for Windows 3.1.2, IE 6 and Firefox 2.0.0.17 (I didn't test any other browsers).
Just tag those DIVs with a class that's hidden on the print stylesheet:
HTML
<div id='div19' class='noprint'>
...
</div>
print.css
.noprint {
display: none;
}
If you don't know in advance which elements you need to hide, you can use javascript to set the class for the given objects:
Javascript
document.getElementById('div19').className='noprint';
There's an onbeforeprint event in IE. It doesn't appear to be supported by other major browsers. (I tested Firefox 3.0.3 and Safari 3.1.2.)

Resources