written on:18 Feb, 2008 by Alen Grakalic

Fighting Form Spam With Css

Delicious Digg StumbleUpon Reddit Subscribe to RSS Feed

Fighting form spam is something almost every website owner has to face. If you allow comments on your site you will most likely be a subject of form spam attacks. The most effective and most popular way of fighting form spam is using generated images (captchas) that contain text that user should then retype into an input field. Since there are OCR algorithms that can read images, most of the time captchas contain messy and distorted text.

Fresh Solution

Messy and distorted text can be annoying to users, that it can prevent them from posting a comment. One more thing that can make to think twice when it comes to using some of the existing captcha solutions, is the fact that you can't control their appearance. Generated images can be, well - ugly! To a delicate designer soul that can be even greater issue than spending time every day moderating comments.

So how about we call CSS to the rescue.

The trick I am using on my comment forms doesn't appear to be that much different from regular captchas. But there is a great difference.
As we said there are some OCR technologies that can recognize symbols on the image. But in order for that to work you must have an image to start with.
Well, I don't use <img> tag so OCR doesn't apply to this trick. Instead, I use background image displayed with css. You'll agree when I say that there's absolutely no way that a robot can scan your html, locate your css file, compare css selectors, find a css definition, locate the image and read the image using OCR algorithm.

Here's a sample code from my form. You can of course use the same principle on your own form's markup.

The html code

<p>
	<label class="captcha" for="captcha">Answer?</label>
	<input type="text" name="captcha" id="captcha" />
</p>

The css code

label.captcha{
	display:block;	
	background:url(/images/captcha.gif) no-repeat 0 0;		
	height:28px;
	line-height:28px;
	padding-left:90px;
	margin-bottom:.5em;
}

Good sides

Good sides would be having easiest possible captcha and ability to design it anyway you like. You can put your own text, simple mathematical function, whatever...

Downsides

Downside to this trick is that people browsing your site with css disabled readers can't tell what you're asking them to do. Unfortunately, using this trick you prevent a part of your audience from commenting.

About the author:

cssglobe's image Designer, developer and a passionate standardista. Long time web professional with huge experience in all types of front-end work. Founder of Css Globe and creator of Easy front-end framework.
To get in touch, visit Alen's personal page, follow Alen on Twitter or become a Facebook friend.

Enjoyed the article?

Then don't miss our next one! Subscribe to our RSS feed or share it with your friends.

Delicious Digg StumbleUpon Reddit Subscribe to RSS Feed

Read more! Here are our most recent articles:

View All Articles

Comments

  1. Catar4x on 18 Feb, 2008 wrote:

    Great idea with css !
    Cssglobe forever :p
  2. Brian Rock on 18 Feb, 2008 wrote:

    Nifty solution, although I suppose it would be possible to improve the auto-spam-bot to search for background-images if no captcha image is found. Wouldn't be easy, but spammers will go to great lengths...

    Another CSS tactic I read about was creating an extra field that didn't hold any meaningful data. Alter the CSS so a human won't see it. Then if a value is filled in, you know it was an auto-bot doing the spamming.
  3. warnis on 19 Feb, 2008 wrote:

    I think this solution is quite poor. Some form of captcha, like recaptcha seem like a much more accessible approach than this is.

    If you somehow could give users and alternative way of getting the data that would still bypass the spam bots as well then everything would be fine (I was thinking of the title="" attribute but I don't think that will cut it).

    One way that I have thought of would be using the noscript-tags to wrap an input element and then hide the input via CSS.

    Very few UAs would render that input (javascript and CSS disabled) and you could always give it a meaningful label (please dont fill this in or something). I don't know whether spam bots read content inside of noscript-tags or not so I guess it needs to be tested.
  4. James on 19 Feb, 2008 wrote:

    Never say never!
  5. Felipe on 19 Feb, 2008 wrote:

    What Firebug can find easily can be learned to a bot in a matter of minutes.

    IHow long does it takes to a spammer to learn to its bot that CSS rule learn.captcha in default.css has a link to an image?
    Wait, it isn't even an external CSS so the link won't change (or cache browsers would prevent regular users to see the recent image they should have seen and answered)
    So you just have to read http://cssglobe.com/v3.0/images/human_check.gif and I wonder if the image is changed session-based, daily (I can spam for a few hours now, great) or never (ouch, just have to learn a bot to enter "4" in the 3rd text input) ?
  6. Jermayn on 19 Feb, 2008 wrote:

    Ok a question!
    How do you get the captcha image to display different math questions? Would you have to use some more script?
  7. cssglobe on 19 Feb, 2008 wrote:

    I maybe went too far saying that image can't be located. You can use different css selectors or even apply class with JavaScript. Can bots read JavaScript?
    You can also make it really complicated to bots once they find your image. i.e. your image could say "Enter third letter from the word IGNORANT".
    Adding some more script you can make it as dynamic as you want, you can have several images appearing randomly.
    Actually, the idea behind this was more of aesthetic nature. I wanted to avoid ugly captcha images and have something that blends more into my design. Not to mention that I hate retyping barely recognizable letters.
  8. Barney on 19 Feb, 2008 wrote:

    The problem with all captcha is that they require hassle on the user's part. What I find infuriating with standardistas is that they'll say, "Hey, downside to this is a certain section of users - those using Lynx source code carved into a stone tablet - won't be able to use universal generic web tech from 1992"... When in fact realistic concerns would be "My users don't have time for this comment-customs crap", "My users don't necessarily have 20/20 vision", "My users might not be good at maths".

    So:

    # Create an additional field at the front of your form.
    # Label it " First name** ".
    # Style it to display:none.
    # Write an explanation for those CSS-disabled users (we should really start a charity for those guys): " ** Leave blank. "
    # Give that display:none too.
    # Tell your form not to submit if the form is filled in. Any robot will.

    The user has nothing extra to do, the code is much simpler, and you can run the same thing, staticly, over and over.
  9. Julien on 19 Feb, 2008 wrote:

    What about CSS Sprites?

    Just a thought: if your captcha image looked like " X Q W O K P M D ", and you just displayed a random portion of the image, via CSS, for the user to copy? (example: " O K ")
    The OCR would try to copy everything it recognizes in the image, but a human wouldn't.

    What do you think?
  10. Dennison Uy - Graphic Designer on 19 Feb, 2008 wrote:

    Julien that would cause cross-browser compatibility issues in addition to the fact that this will not work on browsers with CSS turned off.
  11. Julien on 19 Feb, 2008 wrote:

    you're right.
  12. kik on 19 Feb, 2008 wrote:

    Great idea :) regarding the downside - if someone is browsing my website with CSS turned off than go to hell :) I don't want him on my site
  13. Sarah on 19 Feb, 2008 wrote:

    Its a great idea! but there are also more ways available to do the same.
  14. Iain Fraser on 20 Feb, 2008 wrote:

    Nice idea. As a previous poster mentioned, another trick you can use is create a text area and give it a label of something like "please leave this field blank" and give it a name of "message". Then you use CSS to shift if a few thousand pixels out of the way. The beauty of this method is that it's accessible to screen readers and non-css browsers and you immediately know if you're being spammed. Again though, it's only a matter of time before spammers search for labels that contain the words "blank, empty, don't fill, etc" and marry up to a form field called "message, comments, etc". But hey, it works for now. I like your idea, but I don't like the fact that it's not accessible. Also, you have to realize that if your browser can render it, spammer's software can render it too, it's not that much of a stretch. Nice idea though
  15. Josh A. on 20 Feb, 2008 wrote:

    If this technique goes mainstream, bots will learn - at least if you have a class name like captcha. That's not difficult. They can find your CSS file by pulling out the first one with media="screen", and then finding the selector. It won't be easy, but it's not impossible.

    If you're going to use this technique then give it a class name that's completely irrelevant. That, I would argue, a robot couldn't detect.

    Personally, I think there are other methods. Check the percentage of links used, or whether real words are used, and make the decision to allow on the server-side. Or use another method.
  16. Fodcj on 20 Feb, 2008 wrote:

    An interesiting set of comments and suggestions are coming out of this thread, maybe we will someday be able to beat those g**s
  17. James Coletti on 21 Feb, 2008 wrote:

    Remember: CAPTCHA breaking tools aren't always bots, as in autonomous robots scanning for web pages to look for CAPTCHA images they can attempt to defeat. A tool could be developed where the user chooses the image (or DOM element) to be decoded or the image is saved and the process occurs entirely offline!
  18. derek allard on 21 Feb, 2008 wrote:

    I'm not a big fan of CAPTCHA - too often the letters are hard for me to read (and my eyes are still good!). The solution I've used with great success eliminates both the form spam and the CAPTCHA. All I do is create an extra form field and set it to display:none. A spam bot always find the hidden entry (which humans would not) and fills it in. Then behind the scenes I have some basic php that states if this hidden field is filled in don't send it to the intended recipient (or enter into the DB, etc.). I realize that if someone turns off CSS the hidden field will display but I'm willing to trade that off for not having a CAPTCHA field to fill in.
  19. Sirius on 22 Feb, 2008 wrote:

    How about mixing numbers, text and math, while still keeping it quite simple for a human to solve:

    Solution one: An image shows three numbers: "34 20 63", and the task is to "Type in the number with the lowest value, multiplied with five:".

    Solution two: An image shows five numbers: "9 4 6 3 7 2", and the task is to "Type in the sum of the three numbers with the lowest value".

    There's no symbols (like + - * /) to tell the bot what to do, and the bot doesn't know if it's going to use all of the numbers or only some of them.
  20. John on 23 Feb, 2008 wrote:

    Sadly, this doesn't work for spammers that are targeting just one site and develop software specifically for it... which makes the method kinda pointless.
  21. Richard on 4 Mar, 2008 wrote:

    Good article
  22. Ralph on 7 Mar, 2008 wrote:

    First, thank you for this idea to avoid much more spam every day.

    Second, we all know, behind the spam are only people the write code for machines. If somebody of spam-code writer will be here they will improve your code to send more spams, it's your job (:

    Ralph
  23. Test Commenter on 7 Apr, 2008 wrote:

    Just trying to see how it works.
  24. Dave on 13 Apr, 2008 wrote:

    Thanks so much, this will help tremedously!
    Dave
  25. Eric on 28 Apr, 2008 wrote:

    Thank you for the guide, going to use this in my new website!
  26. Arabia on 11 Jun, 2008 wrote:

    very nice method
    thank you
  27. Nikita Baffix on 14 Jun, 2008 wrote:

    Its a great idea! but there are also more ways available to do the same.
    CAPTCHA breaking tools aren't always bots, as in autonomous robots scanning for web pages to look for CAPTCHA images they can attempt to defeat.
    Good article.
  28. Miadeo on 20 Jun, 2008 wrote:

    Nice trick, I´ll try it. thanks
  29. sander houttekier on 23 Jul, 2008 wrote:

    i also use the technique, previously mentioned, i hide a textfield ckecking if the bot has filled it, but even then i think this is not 100% safe enough...
    if a bot can check for css selectors, and can find a background image, it can also check if a field is hidden or not... (so i believe)
    thus it might leave fields be when they are hidden....

    so my solution, do not hide the field and label
    but wrap them in a div and hide that one, or if you are using tables (*curse, go to hell, *curse) you can hide your tablerow for example...

    Sander
  30. smt on 1 Dec, 2008 wrote:

    if a bot can OCR your image, how can you be shure it will never learn to understand CSS(when browser libraries already exist for that)?
  31. Busby SEO on 2 Dec, 2008 wrote:

    Nice nice nice....it was not in my mind. Before i just add it in HTML. Little bit clear now. Thanks
  32. Busby SEO Test on 7 Jan, 2009 wrote:

    Thanks a lot for the code... now i get more idea for getting unspamm friendly form :)

    Regards.
  33. busby seo test info on 13 Jan, 2009 wrote:

    Nice tips. I'll use it :)
  34. Inventory Management Software on 21 Jan, 2009 wrote:

    this is new to me, i will learn and try it myself.. thanks for the tips dude.. :)
  35. Barbara on 30 Jan, 2009 wrote:

    just testing
  36. craig on 7 Feb, 2009 wrote:

    you will need to change you captcha image constantly do you ?
  37. gosip artis on 11 Apr, 2009 wrote:

    Cool idea on using css for fighting spam. Gonna try this on my blogs. Thanks for sharing.
  38. redips on 1 May, 2009 wrote:

    It's worth trying ... thanks!
  39. Kris Utter on 16 Jun, 2009 wrote:

    I just implemented this on my site. We'll see how it goes.

Sorry, further comments are disabled for this post.

Need help with your website?
Hire a CSS/JavaScript expert!

Hey, you are not logged in!
Apply for a membership or login here.

Subscribe to CSSG Feed

Want to join?

If you wish to contribute with your own articles, updates or gallery entries you can apply for a membership and even become our editor.

Apply here

Become a friend