onfocus="this.blur();" problem - asp.net

// I am trying to apply an "onfocus="this.blur();"" so as to remove the dotted border lines around pics that are being clicked-on
// the effect should be applied to all thumb-nail links/a-tags within a div..
// sudo code (where I am):
$(".box a").focus( // so as to effect only a tags within divs of class=box | mousedown vs. onfocus vs. *** ?? | javascript/jquery... ???
function ()
{
var num = $(this).attr('id').replace('link_no', '');
alert("Link no. " + num + " was clicked on, but I would like an onfocus=\"this.blur();\" effect to work here instead of the alert...");
// sudo bits of code that I'm after:
// $('#link_no' + num).blur();
// $(this).blur();
// $(this).onfocus = function () { this.blur(); };
}
);
// the below works for me in firefox and ie also, but I would like it to effect only a tags within my div with class="box"
function blurAnchors2()
{
if (document.getElementsByTagName) {
var a = document.getElementsByTagName("a");
for (var i = 0; i < a.length; i++) {
a[i].onfocus = function () { this.blur(); };
}
}
}

Thanks guys - I have gone for the css(a:focus):
img, a:focus{
outline: none;
}
It seems to be working right(tabbing is still working and the borders are gone when clicking) for me... in both ie and firefox. Will have to now retrofit some other links to use it...
Thanks again.

It's not recommended to blur. If all you're looking at doing is hiding the focus lines, use this instead:
a[i].onfocus = function () { this.hideFocus = true; };
This will work for all versions of IE. For other browsers (including IE8 in standards mode) you can set the outline CSS style to hide focus outlines:
a {
outline: none;
}
This would make your page much more keyboard friendly than blurring an element as it takes focus.

I would suggest using only CSS to remove the border.
img, a:active{
outline: none;
}
Or is there a specific reason why JS must be used?

Related

Hide custom cursor on hover over selected div

I have a custom cursor with some hover effects on a page (wordpress). This custom cursor shall hide, when hovering a certain div, due to some text. Please take a look here: https://florianwmueller.com/work-test/
I tried a lot, including some javascript, but nothing works. Any idea?
I gave the pictures a special class: .no-cursor
Thankful for any help...
Add this script on your website.
<script>
var elements = document.getElementsByClassName("no-cursor");
var style;
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener("mouseover", function() {
style = document.createElement("style");
style.innerHTML = "body.cursor-element-shape a { cursor: default !important; } .wpcc-active > .wpcc-cursor { display: none !important; }";
document.head.appendChild(style);
});
elements[i].addEventListener("mouseleave", function() {
document.head.removeChild(style);
});
}
</script>

Can autoprefixer solve the issue of CSS variables for Internet Explorer?

I am using css variables in my angular7 application. Everything works fine on other browsers. But IE is not supporting css variables. Is there a way to make it work on IE. Can Autoprefixer do this?
color: var(--primary, #7F583F);
According to caniuse.com, of current browsers only IE, Edge (older versions) and Opera Mini do not support CSS variables. This polyfil appears to work on all three really well.
This is an attempt at a very basic CSS variables (custom properties) polyfil. In reality this is more of a partial polyfill as it will not cover variables inside of variables, DOM scoping or anything else "fancy". Just taking variables declared anywhere in the CSS and then re-parsing the CSS for var() statements and replacing them in browsers that don't natively support CSS variables.
I try to test this polyfil in IE 11 and looks like it is working with it.
/*!
* css-var-polyfill.js - v1.0.0
*
* Copyright (c) 2018 Aaron Barker <http://aaronbarker.net>
* Released under the MIT license
*
* Date: 2018-03-09
*/
let cssVarPoly = {
init: function() {
// first lets see if the browser supports CSS variables
// No version of IE supports window.CSS.supports, so if that isn't supported in the first place we know CSS variables is not supported
// Edge supports supports, so check for actual variable support
if (window.CSS && window.CSS.supports && window.CSS.supports('(--foo: red)')) {
// this browser does support variables, abort
console.log('your browser supports CSS variables, aborting and letting the native support handle things.');
return;
} else {
// edge barfs on console statements if the console is not open... lame!
console.log('no support for you! polyfill all (some of) the things!!');
document.querySelector('body').classList.add('cssvars-polyfilled');
}
cssVarPoly.ratifiedVars = {};
cssVarPoly.varsByBlock = {};
cssVarPoly.oldCSS = {};
// start things off
cssVarPoly.findCSS();
cssVarPoly.updateCSS();
},
// find all the css blocks, save off the content, and look for variables
findCSS: function() {
let styleBlocks = document.querySelectorAll('style:not(.inserted),link[rel="stylesheet"]');
// we need to track the order of the style/link elements when we save off the CSS, set a counter
let counter = 1;
// loop through all CSS blocks looking for CSS variables being set
[].forEach.call(styleBlocks, function(block) {
// console.log(block.nodeName);
let theCSS;
if (block.nodeName === 'STYLE') {
// console.log("style");
theCSS = block.innerHTML;
cssVarPoly.findSetters(theCSS, counter);
} else if (block.nodeName === 'LINK') {
// console.log("link");
cssVarPoly.getLink(block.getAttribute('href'), counter, function(counter, request) {
cssVarPoly.findSetters(request.responseText, counter);
cssVarPoly.oldCSS[counter] = request.responseText;
cssVarPoly.updateCSS();
});
theCSS = '';
}
// save off the CSS to parse through again later. the value may be empty for links that are waiting for their ajax return, but this will maintain the order
cssVarPoly.oldCSS[counter] = theCSS;
counter++;
});
},
// find all the "--variable: value" matches in a provided block of CSS and add them to the master list
findSetters: function(theCSS, counter) {
// console.log(theCSS);
cssVarPoly.varsByBlock[counter] = theCSS.match(/(--.+:.+;)/g) || [];
},
// run through all the CSS blocks to update the variables and then inject on the page
updateCSS: function() {
// first lets loop through all the variables to make sure later vars trump earlier vars
cssVarPoly.ratifySetters(cssVarPoly.varsByBlock);
// loop through the css blocks (styles and links)
for (let curCSSID in cssVarPoly.oldCSS) {
// console.log("curCSS:",oldCSS[curCSSID]);
let newCSS = cssVarPoly.replaceGetters(cssVarPoly.oldCSS[curCSSID], cssVarPoly.ratifiedVars);
// put it back into the page
// first check to see if this block exists already
if (document.querySelector('#inserted' + curCSSID)) {
// console.log("updating")
document.querySelector('#inserted' + curCSSID).innerHTML = newCSS;
} else {
// console.log("adding");
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = newCSS;
style.classList.add('inserted');
style.id = 'inserted' + curCSSID;
document.getElementsByTagName('head')[0].appendChild(style);
}
};
},
// parse a provided block of CSS looking for a provided list of variables and replace the --var-name with the correct value
replaceGetters: function(curCSS, varList) {
// console.log(varList);
for (let theVar in varList) {
// console.log(theVar);
// match the variable with the actual variable name
let getterRegex = new RegExp('var\\(\\s*' + theVar + '\\s*\\)', 'g');
// console.log(getterRegex);
// console.log(curCSS);
curCSS = curCSS.replace(getterRegex, varList[theVar]);
// now check for any getters that are left that have fallbacks
let getterRegex2 = new RegExp('var\\(\\s*.+\\s*,\\s*(.+)\\)', 'g');
// console.log(getterRegex);
// console.log(curCSS);
let matches = curCSS.match(getterRegex2);
if (matches) {
// console.log("matches",matches);
matches.forEach(function(match) {
// console.log(match.match(/var\(.+,\s*(.+)\)/))
// find the fallback within the getter
curCSS = curCSS.replace(match, match.match(/var\(.+,\s*(.+)\)/)[1]);
});
}
// curCSS = curCSS.replace(getterRegex2,varList[theVar]);
};
// console.log(curCSS);
return curCSS;
},
// determine the css variable name value pair and track the latest
ratifySetters: function(varList) {
// console.log("varList:",varList);
// loop through each block in order, to maintain order specificity
for (let curBlock in varList) {
let curVars = varList[curBlock];
// console.log("curVars:",curVars);
// loop through each var in the block
curVars.forEach(function(theVar) {
// console.log(theVar);
// split on the name value pair separator
let matches = theVar.split(/:\s*/);
// console.log(matches);
// put it in an object based on the varName. Each time we do this it will override a previous use and so will always have the last set be the winner
// 0 = the name, 1 = the value, strip off the ; if it is there
cssVarPoly.ratifiedVars[matches[0]] = matches[1].replace(/;/, '');
});
};
// console.log(ratifiedVars);
},
// get the CSS file (same domain for now)
getLink: function(url, counter, success) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.overrideMimeType('text/css;');
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
// console.log(request.responseText);
if (typeof success === 'function') {
success(counter, request);
}
} else {
// We reached our target server, but it returned an error
console.warn('an error was returned from:', url);
}
};
request.onerror = function() {
// There was a connection error of some sort
console.warn('we could not get anything from:', url);
};
request.send();
}
};
cssVarPoly.init();
:root {
--externalcolor: red;
--samename: orange;
--samename: #0f0;
--foo: green;
--FOO: #0f0;
--halfsuccess: orange;
--success: green;
--success2: #0f0;
}
html {
font-family: var(--fontsans);
}
.success {
color: green;
}
.fail {
color: red;
}
span {
display: inline-block;
margin: 5px;
}
.samename {
color: var(--samename);
}
.demo1 {
color: #f00;
color: var(--success);
}
.demo2 {
color: #f00;
color: var( --success2);
}
.demo3 {
color: #f00;
color: var(--halfsuccess);
color: var(--success);
}
.demo4 {
color: red;
border-color: #f00;
}
.inlineoverlink {
color: #f00;
}
p {
padding: var(--spacing-l);
}
.lower {
color: var(--foo);
}
.upper {
color: var(--FOO);
}
.externalcolor {
color: var(--externalcolor);
}
.fallback {
color: #f00;
color: var(--wrongname, green);
}
// for the top documentation
.supports {
color: green;
.no {
display:none;
}
}
.showforpolyfill {
display:none;
}
.cssvars-polyfilled {
.supports {
color: red;
.no {
display:inline;
}
}
.showforpolyfill {
display:inline;
}
.hideforpolyfill {
display:none;
}
}
.hide,
.hide-the-docs .documentation {
display:none;
}
/* declare some font-family stuff at bottom of file to reflect on stuff above it*/
:root {
--fontsans: arial;
}
<!-- Copy below for codepen update -->
<h1>CSS Variables Polyfill</h1>
<p>This is now managed (and available for PRs) at https://github.com/aaronbarker/css-variables-polyfill.</p>
<p>
This is an attempt at a very basic CSS variables (custom properties) polyfil. In reality this is more of a <em>partial</em> polyfill as it will not cover variables inside of variables, DOM scoping or anything else "fancy". Just taking variables declared anywhere in the CSS and
then re-parsing the CSS for var() statements and replacing them in browsers that don't natively support CSS variables.
</p>
<p>According to caniuse.com, of current browsers only IE, Edge and Opera Mini do not support CSS variables. This polyfil appears to work on all three really well. I don't see why this wouldn't work on older browsers as well, but I haven't been able to test it on them yet.</p>
<p>As far as we can tell your browser <span class="supports">does <span class="no">not</span> support</span> native CSS variables. <span class="showforpolyfill">That means if you see green tests results below, it is thanks to the polyfill :).</span> <span class="hideforpolyfill">All the green test results below are actually native CSS Variable support. Good job using a good browser :)</span></p>
<h3>Does this work on externally CSS files?</h3>
<p>Yes!</p>
<h3>Even ones loaded from another domain?</h3>
<p>To go across domain, CSS needs to be served up with <code>Access-Control-Allow-Origin:*</code> headers.</p>
</div>
Toggle documentation (for Opera Mini vs Codepen issue)
<style>
:root {
--newcolor: #0f0;
}
.inlineoverlink {
color: var(--success2);
}
</style>
<h2>Tests</h2>
<p>On mosts tests (unless otherwise noted) success will be green text. We start with a <code>color:red;</code> and then override it with a <code>color:var(--success);</code> (or similar) which is green.</p>
<ul>
<li><span class="samename">declare same variable over and over</span></li>
<li><span class="demo1">no whitespace on var() calls</span></li>
<li><span class="demo2">whitespace on var() calls</span></li>
<li><span class="demo3">Multiple variables in same call. orange means first var worked, green var worked</span></li>
<li><span class="inlineoverlink">orange if link won, green if style after link won</span></li>
<li><span class="lower">--foo: lowercase foo</span></li>
<li><span class="upper">--FOO: uppercase FOO</span></li>
<li><span class="fallback">uses fallback <code>--var(--wrongname, green)</code></span></li>
<li><span class="demo-import">css declared in an <code>#import</code></span> - not polyfilled yet. Identfied with a suggested fix, but will require a bit of a re-write (to use document.styleSheets), so haven't done it yet.</li>
</ul>
<h2>Tests on external, cross-domain file</h2>
<div class="documentation">
<p><strong>Edge</strong> appears to be working well on Edge 13. Edge 12 was having some problems.</p>
<p><strong>Opera mini</strong> seems to work well too. This demo fails because not all the page is displayed, but I think that is a codepen issue, not a polyfill issue. When the upper documentation is removed, all tests display well.</p>
<p><strong>IE 11</strong> seems to do fine.</p>
</div>
<ul>
<li><span class="demo4">Gets stuff from external .css file. Should start red and change to green on LINK load. border proves the CSS loaded, missing colors means script didn't get parsed and reinserted</span></li>
<li><span class="externalcolor">--externalcolor: should start red and change to green on LINK load</span></li>
<li><span class="externalfallback">uses fallback. should be green</span></li>
</ul>
<p>Another set of text under the test for Opera Mini testing.</p>
<!-- Copy above for codepen update -->
Testing result:
References:
(1) Codepen example link
(2) aaronbarker/css-variables-polyfill

Is there a way to detect if ie has animation disabled

I have an animated gif that works perfectly in all browsers except ie (surprise, surprise). After much searching I have found the gif is not animated in ie due to a setting in the options:
Settings -> Advanced settings -> Multimedia -> Play animations in webpages
Is there any way to detect if this is enabled as I would like to display something else instead of a static loading gif, or is there a way to force ie to play the animation?
In case there is a workaround, here is the code I use to show my loader and the type of gif I am using:
#loading {
background:url(http://preloaders.net/preloaders/712/Floating%20rays.gif) center center no-repeat;
position:fixed;
left:0;
right:0;
bottom:0;
top:0;
}
<div id="loading"></div>
You can use root class from body which shows only IE browser then write like as below in your css:
.rootclassname #loading {
background : //use static image here
}
Hmmm, seems a bit dirty but what the hell, punish the stupid ie users...
As a workaround, I did a mixture of Prajwal and lonut's answers - adding an ie class to my loader I then saved out each part of the animated gif and then used the following js to give me an animated loader for ie:
var ieLoadingCount = 1,
ieLoadingInt;
function addLoading() {
var loading = $('#paving-designer-loading');
if (loading.hasClass('ie')) { // only do this for ie
clearInterval(ieLoadingInt); // need to clear interval as this is a multi-step form and addLoading may be called multiple times
ieLoadingInt = setInterval(function () { animateIELoading(loading, true); }, 175); // preload images
}
}
function animateIELoading(loading, firstRun) {
loading.css('background-image', 'url(' + baseUrl + 'images/presentation/toolbox/pavingdesigner/loading/' + ieLoadingCount + '.png)');
if (ieLoadingCount == 12) { // loading gif had 12 parts in it
ieLoadingCount = 1;
if (firstRun) {
clearInterval(ieLoadingInt); // finish preload
ieLoadingInt = null;
}
} else {
ieLoadingCount++;
}
}
function showLoading(loading) {
if (loading.hasClass('ie')) {
clearInterval(ieLoadingInt);
ieLoadingInt = setInterval(function () { animateIELoading(loading, false); }, 175);
}
loading.show();
}
function hideLoading(loading) {
loading.hide();
if (loading.hasClass('ie')) {
clearInterval(ieLoadingInt);
}
}
I'll leave this open in case anyone can find a way to check if the animation is allowed in the first place as currently I apply this for all ie users regardless of if the animation is allowed or not. Would be good to only apply it to the browsers that have their animations turned off.

Hide a whole div with CSS with part of it is empty

Is there a way to hide a whole div if part of it is empty? For example if "dd" is empty as shown below can I hide the whole class "test" so the keyword Restrictions does not show either. I tried .test dd:empty { display: none; } but this does not work. thanks!
<div class="test"><dt>Restrictions:</dt>
<dd></dd></div>
I don't think there's any easy way to do what you're talking about with just CSS. Better to test it server-side if you can. But if you can't here's some JS that will do the job.
<script type="text/javascript">
// handles multiple dt/dd pairs per div and hides them each conditionally
function hideIfEmpty() {
// get all the elements with class test
var els = document.getElementsByTagName('dl');
// for every 'test' div we find, go through and hide the appropriate elements
Array.prototype.map.call(els, function(el) {
var children = el.childNodes;
var ddEmpty = false;
for(var i = children.length - 1; i >= 0; i--) {
if(children[i].tagName === 'DD' && !children[i].innerHTML.trim()) {
ddEmpty = true;
} else if(children[i].tagName === 'DT') {
if(ddEmpty) {
children[i].style.display = 'none';
}
// reset the flag
ddEmpty = false;
}
}
});
}
window.addEventListener('load', hideIfEmpty);
</script>
<div class="test">
<div style="clear: both;"></div>
<dl>
<dt>Restrictions:</dt>
<dd></dd>
<dt>Other Restrictions:</dt>
<dd>Since I have content, I won't be hidden.</dd>
</dl>
</div>
Just a fair warning: the code uses some functions that may not exist in older IE, such as Array.prototype.map, String.prototype.trim, and addEventListener. There are polyfills available for these and you could also write your own pretty easily (or just do it with a for loop instead).
CSS alone can't do that. Either, you need a javascript to retrieve empty elements and hide their parents, or your CMS applies special CSS classes if there's no content.
Put as an answer as requested by #Barett.
You could update your CSS to be
.test{
display: none;
color: transparent;
}
This would make the text transparent too, but display:none should hide it anyway.
To make the div with the id test ONLY show when the dd tag is EMPTY, and you can use jQuery, try the following JavaScript along with the CSS:
if($("dd").html().length ==0)
{show();
}
Note: this solution requires jQuery, which is a JavaScript library.

Can I accomplish this with CSS?

If I've got elements like this:
A
B
A
C
I know I can use something like
body
{
counter-reset:section;
}
a:before
{
counter-increment:section;
content:counter(section)". ";
}
to get
1. A
2. B
3. A
4. C
but is there a way to get the following?
1. A
2. B
1. A
3. C
ie. uniquely identify all links on a page by prefixing the text with the same number.
Note: hardcoding specific URLs isn't an option, I'm potentially dealing with hundreds of links and don't know the URLs ahead of time.
I realize this would be easy/possible with javascript, I am only interested in CSS-based solutions or an explanation of why this isn't possible with CSS.
Ok, I got what you mean with your question. Just with plain CSS it's not possible (at least not cross-platform..)
If you can use javascript, you have several possibilities.
My preference would be to use a data-attribute to hold the value, for this example I chose data-counter. If you do like this, the CSS becomes trivial:
CSS
a:before
{
content:attr(data-counter)". ";
}​
And the Javascript would look like this if you have jQuery:
JS with jQuery
var linkcounter = {};
var counter = 0;
$("a").each(function() {
if (!linkcounter.hasOwnProperty($(this).attr("href"))) {
counter++;
linkcounter[$(this).attr("href")] = counter;
}
$(this).attr("data-counter", linkcounter[$(this).attr("href")]);
});
​
or like this without jQuery:
vanilla JS
var linkcounter = {};
var counter = 0;
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
if (!linkcounter.hasOwnProperty(anchors[i].getAttribute("href"))) {
counter++;
linkcounter[anchors[i].getAttribute("href")] = counter;
}
anchors[i].setAttribute("data-counter", linkcounter[anchors[i].getAttribute("href")]);
}
You can view the version without jQUery here: http://jsfiddle.net/ramsesoriginal/CVW7Y/5
And the version with jQuery here: http://jsfiddle.net/ramsesoriginal/CVW7Y/4
Sadly there is no CSS only way to do this (yet). I hope this helps.
​
I don't think you can get this behaviour with pure CSS, and you need Javascript. And there are always cases like this:
http://google.com/
http://google.com
google.com
google.com/
www.google.com
You get the point.
In jQuery this is quite trivial, so I'd suggest you use that.
If using jQuery is OK, this can be done by manipulating the :before pseudo element's content:
Demo: http://jsfiddle.net/rwMWx/2/
JS
var labels = [
"1",
"2",
"1",
"3"
// and so on...
];
// OR maybe put in some algo for this sequence
$('a').each(function(i) {
$(this).attr('data-label', labels[i] + '. ');
});
CSS
a:before {
content: attr(data-label);
color: red;
text-align: left;
padding-right: 10px;
font-size: 11px;
display: inline;
}
You could use :contains but I'm not sure how supported it is so you might be better off with JavaScript.
a:contains("A") {
/* Styles here */
}
a:contains("B") {
/* Styles here */
}
EDIT:
Apparently :contains isn't supported at all. I'll leave this up here though so no one else bothers putting it.
You could use :contains in jQuery though and add a class accordingly.
$('a:contains(A)').addClass('CLASS_NAME');
try this code:
var counter = 0, cache = {};
$('a').each(function (i, a) {
a = $(a);
var href = a.attr('href');
var c = cache[href];
if (!c) {
counter++;
c = counter;
cache[href] = c;
}
a.text(c + '. ' + a.text());
});
​
I'm using jQuery, and that's how it works: http://jsfiddle.net/pDLbQ/

Resources