Workaround for broken <select> with -moz-transform? - css

There seems to be a bug in Firefox (which has been marked as resolved but fails on my FF12) that causes <select> elements to work incorrectly when their position has been altered with -moz-transform. This can be replicated with this simple test case:
<style type="text/css">
div {
-moz-transform:translate(380px,140px);
}
</style>
<div>
<select>
<option>One</option>
<option>Two</option>
<option>Three</option>
</select>
</div>
This causes the select box to be rendered in the correct position, but all of the options are unselectable with the mouse. Selecting them using the keyboard works fine.
Is there any other workaround for this problem than removing all the transformations? The problem does not exist for any other browser.

I've had problems like this before with elements that have been transformed, and I solved it with some JavaScript and extra CSS.
document.addEventListener("transitionend", function(event) {
var style = event.target.style;
if (event.propertyName.substr(-14) == "transitionend") {
style.position = "absolute";
style.left = "200px";
}
});
You need to bind mozTransitionEnd, webkitTransitionEnd, etc.

Related

Does CSS change the DOM?

I was wondering if CSS changes the DOM.
The reason I am asking, is that whenever I change an Element with CSS, I don't see it's value changed in the "element".style properties.
No, CSS does not change the DOM.
No. CSS does not change the DOM.
Nor content injected using :after or :before alter the DOM.
Actually... there are a few cases where CSS can change the DOM, but it's a bit far-stretched, as it won't change the DOM-tree structure, except in one yet even more far stretched case...
There is a being rendered definition in the HTML specs that does impact the behavior of the DOM in some cases, based on CSS computed styles.
For instance,
an HTMLImageElement can have its width and height IDL attributes value change whether it is being rendered or not:
onload = (evt) => {
console.log( 'rendered', document.getElementById( 'disp' ).width );
console.log( 'not rendered', document.getElementById( 'no-disp' ).width );
}
img { width: 100px; }
#no-disp { display: none; }
<img id="disp" src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">
<img id="no-disp" src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">
Elements that are not being rendered can not be focusable elements:
document.getElementById( 'rendered' ).focus();
console.log( document.activeElement ); // <input id="rendered">
document.getElementById( 'rendered' ).blur();
document.getElementById( 'not-rendered' ).focus();
console.log( document.activeElement ); // <body>
#not-rendered {
display: none;
}
<input id="rendered">
<input id="not-rendered">
And the one case where the DOM tree is modified, concerns the DOM tree of an inner Document: When an <object> or an <embed> element has its style set to display:none, per specs, its inner Document should be reloaded:
Whenever one of the following conditions occur
[...]
the element changes from being rendered to not being rendered, or vice versa,
...the user agent must queue an element task on the DOM manipulation task source given the object element to run the following steps to (re)determine what the object element represents.
So this means that simply switching the being rendered state of such an <object> or <embed> element is supposed to reload entirely its inner Document, which means also its DOM tree.
Now, only Safari behaves like that, Firefox never implemented that behavior, and Chrome did recently change their to match FF's one, against the specs.
For Safari users, here is a fiddle demonstrating it.

CSS styling via data attribute is not working properly on IE

I have a list with data attribute "data-layout", it can get two options "vertical" and "horizontal".
In my CSS i change the list items display property according to the layout.
On chrome it works as expected but on IE (tested on IE11) it does not redraw the screen with the change.
If i enter IE's devtools and select on of the items in the elements panel then only it redraws to the correct state.
Here is a reproduction of the problem.
http://fiddle.jshell.net/dimshik/bss3je3u/
Thank you.
document.getElementById('toggle').addEventListener('click',function(){
var list = document.getElementById('list');
if(list.dataset.layout == 'vertical'){
list.dataset.layout = 'horizontal';
} else {
list.dataset.layout = 'vertical';
}
});
[data-layout="horizontal"] li {
display: inline;
padding: 0 10px;
}
<ul id="list" data-layout="vertical">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<br>
<br>
<button id="toggle">Toggle Layout</button>
It seems dataset is changing, but not re-rendering the css.
I've changed your code to setAttribute and it worked (IE11);
http://fiddle.jshell.net/bss3je3u/2/
For some reason IE11 doesn't repaint dom when HTMLElement.dataset is used in Javascript
For Example the below snippet doesn't work on IE11 when you click the button - box color doesn't change from red to blue as expected.
To fix this use test.setAttribute('data-action','style'); instead in the button event listener.
var button = document.getElementById('check');
var test = document.getElementById('test');
button.addEventListener('click', function(evt) {
test.setAttribute('data-action', 'style');
});
#test {
width: 200px;
height: 200px;
background-color: red;
}
#test[data-action="style"] {
background-color: blue;
}
<div id="test"></div>
<button id="check">Click Me</button>
This seems like IE isn't seeing that it needs to redraw.
Here's a slightly inelegant approach, but it illustrates the issue.
Adding a function to hide then immediately show to element that should change forces a redraw and the update appears to work.
I'm not sure you'll be able to take this exact thing forward - you may need to choose a different way of forcing a redraw or it may work out that the styles you eventually apply force a repaint so you can lose this altogether, but it does at least perform the switch now.
document.getElementById('toggle').addEventListener('click',function(){
var list = document.getElementById('list');
if(list.dataset.layout == 'vertical'){
list.dataset.layout = 'horizontal';
} else {
list.dataset.layout = 'vertical';
}
list.style.display = "none"
list.style.display = "block"
});

Angular ng-show (or ng-if) not updating on value change

I have a simple example at plunker. I have an ng-show on one element and a select as another element. The select should toggle showing/hiding the other (input) element. Initially setting the select to Yes shows the other input element as expected. Then setting the select to No does toggle the scope value to false as expected, but does not hide the input element.
I've scoured the other posts related to this and the ones I found are around having or not having {{}} on the ng-show (I don't as it should be) or not having the value on $scope (which I do). I thought is may be a $scope.apply() issue, but then why does the 1st change to Yes work? Also adding the apply still does not make the No(false) work. What am I missing?
TIA!
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.conf = {};
});
You need to check ng-show="conf.is_ieee=='true'" instead of ng-show="conf.is_ieee". Check this plunker.
<div class="col-md-4" ng-show="conf.is_ieee=='true'">
<label class="form-label">IEEE Conference ID:</label>
<input type="text" class="form-control" name="ieee-id" ng-model="conf.ieee_id"/>
</div>
http://plnkr.co/edit/MXvuhSPB0ChJyDrvPI55?p=preview

Bootstrap DatePicker style not working properly angularjs

Can someone help me look at this plunkr. The style seems not to be working.
<!DOCTYPE html>
<div ng-controller="testController">
<h1>Hello Plunker!</h1>
<input type="text" name="bDay" ng-model="mydate | date : 'dd-MM-yyyy'" id="" value="" ng-click="showDatePicker('bday')" />
<div date-picker="mydate" view="year" min-view="date" ng-class="{hidden: (picker !== 'bday')}" auto-close="true"></div>
{{mydate}}
</div>
<script>
var app = angular.module('sample', ['datePicker']);
app.controller('testController', ['$scope', function($scope){
$scope.picker = 'null';
$scope.showDatePicker = function(picker){
$scope.picker = 'null';
setTimeout(function(){
$scope.picker = picker;
$scope.$apply();
}, 100);
}
}]);
</script>
http://plnkr.co/edit/94TifOjXZjEAhA25Kl4A?p=preview
I assume you mean you want it to look like this datepicker. For the most part, it does look like the yearly datepicker from that page. Few differences:
The arrows need the "prev" and "next" classes for proper font sizing
The difference in color is the difference between the "active" and "now" classes being applied to that year box
Your datepicker isn't in a popup since the html is inserted inline, rather than as a grandchild of an element with body as its parent.
If you want any gray dates, you need to apply the "old" class.
Make sure your jquery versions are not clashing.i had the exact same issue and resolved it.You cant use jquery 1.10.4 and 1.1.34....etc...

IE select issue with hover

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.

Resources