Category: web development

Misunderstanding Cookies

In a recent column, Tracey Capen posits the reason so many sites are displaying the “This site uses cookies. Click ‘okay’ to continue” banner is because of Advertising—specifically because many people use ad-blockers so the advertisers want to still be able to track you.

 

Cookies in the EU

He almost accidentally mentions the actual reason for these banners: EU Regulations on privacy. Specifically, the regs state that websites must notify visitors before the site places cookies on the visitor’s browser, AND give them an option to opt out before that happens.

English: Tor Logo
(credit: Wikipedia)

So why do we in the non-EU part of the world see these banners? Because it is simply easier to display the banner to everyone, rather than by attempting to determine if the visitor is in the EU and displaying the banner IFF they are.

There are a myriad of ways to mask one’s location, such as using the TOR network, so the risks of failing to show the banner (and getting fined) versus just displaying it to everyone is a no-brainer.

But what about Advertisements?

Ads—and their ad-delivery network—use cookies in a variety of ways. Advertisers are charged by the networks for impressions (number of people to whom the network delivers the ad or CPM) and for the number of people who click on the ad (clickthroughs). The latter is more valuable to the advertiser and thus the networks charge more.

The ads aren’t directly loaded on the page without the network because there needs to be a system that counts the number of impressions, rotates multiple ads in the page location, and stops showing an ad when the ad’s CPM is exhausted. If an advertiser pays for 5,000 CPM, once 5,000,000 visitors visit the page, the next visitor will not see that ad.

When an adblocker runs it does at least one of two things: it blocks the ad code or (more likely) it blocks the ad delivery network code. What this means is the visitor’s browser doesn’t even request the code from the server; NOTHING from that server is requested. No code means the ad network can’t run and deliver the ads. Also, without a request, there is no cookie.

Even if somehow the site displayed the banner (“please accept our marketing/advertising cookie” Capen imagines them saying), the cookie can’t be added because there is no cookie. There is no ad network that loads. There is no ad to display.

Don’t hate your users

If you want to enable your users to do something, such as create an account on your system, DO NOT MAKE IT IMPOSSIBLY HARD.

Case in point:

This image will make you cry
Go ahead and register, I dare you

If algebra is too hard, just refresh and you’ll see something else.

Another scary image
I laugh at your feeble Calculus skills!

Woah, better refresh.

You can't escape the Maths
Make your time

You know what this does? It not only keeps out any bots, but turns a normal human into something else:

rageface
Apoplectic: overcome with anger; extremely indignant.

With a zillion other websites out there, are you sure yours is compelling enough or contains such rare information that people will jump the gorge to get to it?

https://www.youtube-nocookie.com/embed/P7vte1epVpE?rel=0

 

Decoupling presentation from content

Box model in CSS
Box model in CSS (credit: Wikipedia)

I recently ran across the anti-pattern of what I see as a common problem amongst designers and developers: coupled presentation and content. I’ve found that decoupling the presentation from the content makes things much easier to write, maintain and expand.

Here’s a simple example:

HTML

<section>
    <div class="margin-top-10">Lorem Ipsum</div>
</section>

CSS

.margin-top-10 { margin-top: 10px };
.margin-top-20 { margin-top: 20px };
(etc)

Take a look at what is going on here: we’re adding a 10px margin to the top of the div. DON’T DO THIS. You want your class names to be contextual, not descriptive of the style.


Rule of thumb

To change the layout, you should only have to edit the CSS, not the HTML.

Here’s where our anti-pattern falls down and will cause grief.

  1. You decide to adjust the positioning of the section. You can:
    • Edit the CSS, changing the class’s margin value and breaking every other element that uses that class.
    • Edit the HTML create a new class, then edit its CSS class definition. If you have to experiment with different margin values, you’ll need a LOT of classes. “Will 14px work or 15px? What about .25em? Argh!”
  2. You can’t have too many attributes in each class, because they will have unintended consequences for the other elements that are using them. Add a red border to one class because you need a border for a specific element, now you have red borders on ALL the elements that share that class. So, you’ll have to have many single- (or few-) attribute values, and include all of the necessary ones on the required HTML elements.
  3. The violent psychopath maintenance programmer (who knows where you live) will kill you in your sleep. You have made her job insanely hard by turning this:
<div class="margin5 blueborder mediumwidth floatingleft" ...

into this

<div style="margin:5px;border:3px blue outset;float:left;width:75%" ...

for no good reason.

The Cure

Think about the element in terms of content or a functional space. What is it and what does it do? In our example above, let’s assume it is the lede section of an article. Then we would do:

HTML

<section>
    <div class="lede">Lorem Ipsum</div>
</section>

CSS

.lede { 
  margin-top: 10px;
  border-bottom: 2px #9fe2f9 outset;
  float: right;
  position: relative;
  width: ...
};

By decoupling the content (div) from the presentation (style-dependent class), we are free  to adjust the style of that element by making whatever changes to the CSS and leaving the HTML alone.

“But,” you shriek, “I have common elements for everything! Rounded corners! Gradients! (except IE…) Et cetera!”

 

For this, we will turn to our trusty companions Less and/or Sass in a future post.

SASS: Style w/ Attitude
SASS: Style w/ Attitude
Enhanced by Zemanta

Flashback: Skip Intro for flash introductions

Remember when flash introduction pages were all the rage? They were ‘cool’ from the web designer‘s standpoint, but utterly annoying and off-putting to the visitor. Fortunately, most people figured out that people visited their site for the content, not the snappy graphics (unless it was a gallery site), and certainly not for the mandatory intro pages.

Yet, some people still haven’t gotten the clue that the 80s called and they want their flash intros back.

xkcd: the seventies called

For those who remember with revulsion, here’s the old SkipIntro parody. The site is long gone, but it would be a shame to let it fade away!

SkipIntro

(click the ‘play ball’ to start)

[kml_flashembed publishmethod=”static” fversion=”8.0.0″ movie=”https://www.neonrocket.com/wp-content/uploads/2012/10/skipintro98.swf” width=”600″ height=”500″ targetclass=”flashmovie”]

Get Adobe Flash player

[/kml_flashembed]

If you haven’t clicked on it, do it now! Relive the pain of the never-ending flash intro to the sound of weird indian music and gunfire!

Enhanced by Zemanta

Find Something You Like and Dissect It

Image representing Wikipedia as depicted in Cr...
Image via CrunchBase

I’m always on the lookout for a new technique or Better Mousetrap. I admit I don’t know all that much, so I’m happy to learn.

I was playing around with Wikify @ appointment.net (a nifty tool that goes through a block of text and ‘wikifies’ it–that is, links all the words it can find to relavant Wikipedia articles) when I noticed the behavior seemed rather…odd. I could see it go through the word list as it created links, and every time it linked up a word, every duplicate word was linked.

Let’s take some example text (from the now-defunct Dilbert Mission Statement Generator) and run it through the site:

“We have committed to synergistically fashion high-quality products so that we may collaboratively provide access to inexpensive leadership skills in order to solve business problems

Our mission is to continually leverage existing seven-habits-conforming catalysts for change as well as to competently leverage other’s error-free materials.

We globally leverage other’s professional meta-services as well as to conveniently integrate competitive solutions in order to solve business problems.

“It is our job to continually foster world-class infrastructures as well as to quickly create principle-centered sources to meet our customers needs

“Our challenge is to assertively network economically sound methods of empowerment so that we may continually negotiate performance based infrastructures

For example, the additional instances of “leverage,” “problems,” and “business” were quickly linked, once the first one was completed. Poking around their code, I noticed all the action takes place in wikify.js. There are a few gems in there. For example, the function call to reduce an array to only unique values:

function array_unique( array ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      input by: duncan
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Nate
    // +      input by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Michael Grier
  // %          note 1: the second argument, sort_flags is not implemented
    // *     example 1: array_unique(['Kevin','Kevin','van','Zonneveld','Kevin']);
    // *     returns 1: ['Kevin','van','Zonneveld']
    // *     example 2: array_unique({'a': 'green', 0: 'red', 'b': 'green', 1: 'blue', 2: 'red'});
    // *     returns 2: {'a': 'green', 0: 'red', 1: 'blue'}

    var key = '', tmp_arr1 = {}, tmp_arr2 = [];
    var val = '';
    tmp_arr1 = array;

    var __array_search = function (needle, haystack) {
        var fkey = '';
        for (fkey in haystack) {
            if ((haystack[fkey] + '') === (needle + '')) {
                return fkey;
            }
        }
        return false;
    };

    for (key in tmp_arr1) {
        val = tmp_arr1[key];
        if (false === __array_search(val, tmp_arr2)) {
            tmp_arr2[key] = val;
        }
        delete tmp_arr1[key];
    }
    return tmp_arr2;
}

Aha! See how that works?

Enhanced by Zemanta

The Importance of Not “Designing” your own Security

Recently, at a client, I had the opportunity to review their security implementation on their website. I realized that it is very important to never try to design one’s own security, because of the Dunning Kruger effect. In a nutshell, folks who don’t know very much about security think they know “enough,” and folks who are very knowledgable (e.g., Bruce Schneier) realize they don’t know all that much.

So what does this mean? It means simply this:

If you design your own security system, you’re going to get it wrong.

English: A Master padlock with "r00t"...
(Photo credit: Wikipedia)

Here are some examples of how to get things wrong.

Storing passwords in plaintext so you can send the person the password if they forget.
When (not if) someone breaks into your database, they instantly own every single account. They can log in, view your user’s details and change them. Since most people reuse the same password for multiple systems, the attacker can try those passwords on other popular services, such as Facebook, GMail, LinkedIn, Twitter, etc.
Relying on application-level security to protect your data.
This is dangerous because it is hard to ensure 100% coverage. EVERY access point—of many—to your data must be secure. Failing to cover one point leaves the system wide open. A better solution is to apply security at the data-store level. Typically, this is done using triggers and stored procedures. Your RDBMS doesn’t support those (or weakly supports them)? Find another RDBMS.
Using the same salt for every password in the system.
You don’t understand what salts are for and how to use them properly.
Requiring “complex” (a number, upper- and lower-case letters and symbols but not very long) passwords.
Nope. Ineffective.
Relying on Two-Factor Authentication.
For now it is working, somewhat, but crackers are rapidly finding ways to circumvent this technique.
Relying on a “security question” in case the person forgets his/her password.
Oh, you’ll love this. You’re creating a weak password as a backup to a (hopefully) strong password. Fail.
Assuming by keeping the details of your implementation secret, you will be secure.
This is dangerous because you think you’re secure. In fact, you are less secure. Kerckhoffs’s Principle is always a good starting point for security implementation: if an attacker could see all of my code and had a copy of my database, could she/he break into my system?

Getting it right

The first step is admitting that you don’t know what you’re doing.

Now go find someone who does: there are plenty of security libraries out there for every language. Find one that is mature and widely used and implement it. Keep up to date on the library’s mailing list so you will receive alerts, and update whenever there’s a new version.

Security is hard to do. It is extremely hard to do correctly. Don’t fall into the trap of thinking you can get it right without years and years of study and experience.

Enhanced by Zemanta

Don’t Call Yourself A Programmer

I’ve always hated the term “Programmer.” Like a craftsman, I’m a Developer.

Patrick McKenzie has a great writeup on this:

Engineers are hired to create business value, not to program things: Businesses do things for irrational and political reasons all the time (see below), but in the main they converge on doing things which increase revenue or reduce costs.

Producing beautiful software is not a goal. Solving complex technical problems is not a goal. Writing bug-free code is not a goal. Using sexy programming languages is not a goal. Add revenue. Reduce costs. Those are your only goals.

I’ll add that adding perceived business value is also a goal (playing off McKenzie’s “Businesses do things for irrational…reasons”). If your boss feels happy, then you’re doing the right thing. Most of the time.

Where we run into trouble is when the boss is a micro-manager, is inexperienced and/or plain-ol-wrong. What do you do? As a professional, speak up and say what’s on your mind, diplomatically. Then do whatever the boss says, cheerfully.

Is this always the best solution? Sometimes it is and sometimes it is not. The boss that thinks for his employees is doing exactly the wrong thing, though:

by Kathy Sierra
“The more you use the reins, the less they’ll use their brains.”

App Development in the Real World

When developing applications for mobile phones, it is easy to get tricked into thinking the emulator will accurately represent how a user will interact with the application.

This is dangerous for a few reasons.

I ran into one reason today: real devices move around. They rotate, yaw, pitch and jiggle. The emulator does not. Sure, you can rotate it and simulate a “shake,” but no way are you going to move it around like you would a real device. One app in development has two screens: a main screen and a settings screen. As long as the user keeps the device orientation the same when switching too/from the settings screen, everything is great. The problem occurs when the user is looking at the main screen, switches to the settings screen, rotates the device, and switches back. The main screen still thinks it is not rotated, so the display is messed up.

Another problem is there is no way to use the emulator as you would a real device. You wrap your fingers around your phone and type with your thumbs. You select options a certain way, you scroll, pinch, expand, and press buttons in a way that is natural for you to do so. None of that is obvious on the emulator, since it is all keyboard, with the mouse acting like a “finger.” What looks great and works great on the emulator can suddenly become clunky and hard to use on a real device.

Lots of device testing (with different size screens) is time consuming, but getting it right is important.