Saturday, August 8, 2009

How to change the background color of web pages in your browser

If you spend too much time browsing the web on your computer, you may start to notice that you're getting too much darkness around your eyes. It's because of this white background color on most web pages, it's slowly turning you into a raccoon. Luckily, this can be changed.

Most web browsers allow you to control the colors of web pages. Here's how to change the background and text colors in all the popular browsers:

Internet Explorer
  1. On the menu, go to Tools > Internet Options
  2. On the Internet Options dialog box, click the Colors button (at the bottom left corner).
  3. Uncheck the Use Windows colors check box, then change the text and background colors to the colors you want (I use black for the background and grey for the text), then click OK.
  4. Next, click the Accessibility button (this time at the bottom right corner).
  5. Check the Ignore colors specified on Web pages check box and click OK.
  6. Click OK on the Internet Options dialog box to close it and apply the new settings.
FireFox
  1. On the menu, go to Tools > Options
  2. On the Options dialog box, click the Content tab (at the top)
  3. Now, click the Colors button.
  4. Uncheck the Use system colors check box and select the colors you want for the background and text (black and grey for example)
  5. Uncheck the Allow pages to choose their own colors, instead of my selections above check box
  6. Click OK to close the Colors dialog box.
  7. Click OK to close the Options dialog box and apply the new settings
Opera

It's a little trickier with Opera but fortunately it's still possible.
  1. Create a new text file (using Notepad or your favorite text editor) and copy and paste the code below into it, save the file anywhere you want but remember where you saved it (you may name the file opera.css, but this is optional, you can give it any other name you like)

    *
    {
        background: transparent !important;
        color: #C0C0C0 !important;
        border-color: #C0C0C0 !important;
    }
    html, body
    {
        background: #000 !important;
    }
    a:link, a:hover, a:active
    {
        color: #00E !important;
    }
    a:visited
    {
        color: #551A8B !important;
    }

  2. Now in Opera, on the menu, go to Tools > Preferences
  3. Click the Advanced tab
  4. On the left side, click Content
  5. Click the Style Options button
  6. On the Style Options dialog box, under My style sheet, select the file you created in step #1 (you'll replace the value already in there but this is ok)
  7. Now click the Presentation Modes tab (also on the Style Options dialog box).
  8. By default, you should only have The Page style sheet and Page fonts and colors check boxes checked under both the Author mode and User mode (left and right), you should also have Default mode set to Author mode (the drop down list at the bottom right). Now, under the Author mode on the left, check the My style sheet check box and click OK.
  9. Click OK to close the Preferences dialog box and apply the new settings
Google Chrome

Unfortunately for Google Chrome, you can't control the page background or text colors (this is true as to the latest version at the time of writing this post, the version I have here is 2.0.172.39 which is the latest version). The only solution I found was to use a bookmarklet, this is a short piece of code that you add to your bookmarks, you click it everytime you want to change the colors of the page (actually you can also paste it into your browser's bar then press Enter to make it work). This is not really practical but it's all what you've got for now, hope google will fix this soon. I created this little bookmarklet for you which will change the background color to black and the text color to light grey (copy the code and paste it into the address bar in Google Chrome then press Enter, you should add it to your bookmarks to make it easier to change the color of the page by only clicking it):

javascript:(function(){var allElements=document.getElementsByTagName("*");for(var i=0;i<allElements.length;i++){var element=allElements[i];element.style.background="#000 !important";element.style.color="#C0C0C0 !important";element.style.borderColor="#C0C0C0 !important";if(element.tagName.toLowerCase()=="a"){element.style.color="#00E !important";}}})()

Friday, February 13, 2009

How to make a textbox and a textarea same width cross-browsers

Thanks to the *brilliant* CSS box model, very simple tasks have become a nightmare.

I've been struggling lately to do a very simple thing which is to make a textbox (ie. <input type="text">) and a textrea same width so that they align nicely.

The problem with making a textbox and textarea same width is that all browsers add 1px padding to textboxes that can't be removed, in other words setting the padding to 0px won't remove that 1px padding, a common trick to get rid of padding is to float the element but unluckily this doesn't work with textboxes, well, this means we have extra 2px in the width of the textbox that we simply can't get rid of. Now this won't be a problem if the same thing applies to textreas as well but unfortunately this is not the case, in most browsers (IE, Safari and Chrome) setting the padding of a textrea to 0px *unfortunately* works. One exception to this is FireFox which applies the 1px non-removable padding to textareas as well, this is why the problem doesn't exist with FireFox, but should we ignore IE, Safari and Chrome and assume everybody is using FireFox? I guess not, it makes more sense to make it work in those browsers and find a hack for FireFox and actually this is what I did.

Having had a look on mozilla's website, I came across those two extensions to CSS, -moz-padding-start and
-moz-padding-end.

So, to make a textbox and a textrea same width cross-browsers use this code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<style type="text/css">
*
{
    padding: 0px;
    margin: 0px;
}
#textbox
{
    width: 500px;
    -moz-padding-start: 1px;
    -moz-padding-end: 1px;
}
#textarea
{
    width: 500px;
    padding: 1px;
}
</style>
</head>
<body>
<input type="text" id="textbox" /><br />
<textarea id="textarea"></textarea>
</body>
</html>

Adding 1px to the textrea makes the text looks nicer than with no padding at all (with 0px padding, the text sticks to the border which is not visually appealing). In FireFox we will have 2px padding for the textarea and 2px left and right padding for the textbox but visually speaking it almost looks the same (try to view the code in FireFox).

This code was tested with IE, Safari, Chrome, FireFox and SeaMonkey (which uses the same rendering engine like FF) and it worked perfectly. Note that this hack is not perfect, for example Opera will display the textarea 2px wider than the textbox. For me I don't care about Opera very much (not so many people use it), besides it's only 2px, so, it's not something that will make your site unusable or something, there could probably be a hack for Opera too but again I'm not interested in Opera, so for me it's not worth the time. It probably won't work with other less popular browsers too, I tested it with the ones I care about (2 extra pixels in a not popular browser is not a big deal, I can live with that).

In terms of rendering engines (aka layout engines), this will work with Trident based browsers (Internet Explorer), WebKit based browsers (Safari, Google Chrome and other browsers) and Gecko based browsers (FireFox, SeaMonkey and other browsers).

Finally, this won't work if the visual styles are not enabled in Windows XP or Vista (with the exception of FireFox and the other browsers that are based on the same engine), but as very few people (almost none) disable the visual styles so I'm not so worried about that one too.

Finally, if you're a control freak and you want it to work in every browser then your last resort is javascript (I was working on that but gave up on it after I came up with this simple hack), but even this won't work if javascript is disabled in the browser.

Saturday, December 27, 2008

How to align checkboxes and their labels consistently cross-browsers

This is something that drove me crazy for a long time, finally I came up with this solution. I tested it in IE6, FF2 and Chrome and it rendered same pixel by pixel in all the three browsers (also browsershots.org confirmed the result for other browsers), hope this post help you avoid the headache I had been through.

<style type="text/css">
*
{
    padding: 0px;
    margin: 0px;
}
#wb
{
    width: 15px;
    height: 15px;
    float: left;
}
#somelabel
{
    float: left;
    padding-left: 3px;
}
</style>

<div>
<input id="wb" type="checkbox" /><label for="wb" id="somelabel">Web Browser</label>
</div>

* If you don't want to set the padding and margin to zero for all elements as I did here, you could only set them for the label and checkbox.

Wednesday, October 15, 2008

A problem when setting the page title dynamically in ASP.NET

Today I encountered a weird problem with ASP.NET. What I wanted to do was really simple. I wanted to change the page title dynamically in code, that's all. In my scenario I had a page that inherits from a basepage class. In that base page class I append the site name to the page title, e.g. if the page title is 'page title' (without the quotes) and the site name is 'mysite.com', I add the site name to the page title so that it becomes 'page title - mysite.com'

In my page, I overrode OnLoad and set the page title in there, but for an unknown reason I always got an empty string for the page title in the basepage class. So, I created a test page, overrode OnLoad() and set the page title in there, surprisingly that worked. I couldn't see any difference between the two pages, I commented all my code and still got a blank title in the basepage class. Finally, I noticed that the only difference between the two pages is that in my page, the title is set to an empty string in the page directive (ie. Title=""). While in the test page, the title is set to the default value (which is "Untitled Page"). By not keeping the title set to an empty string (just put anything in there) it finally worked.

This seems like a bug, I doubt this behavior is by design. Anyway, to sum up. If you want to set the page title dynamically in your code, make sure you have a "non empty string" for the page title, i.e., if you have Title="" in your page directive, replace it with any other value, e.g. Title="some value" (even though you're going to change this value), otherwise, it will not work.

Thursday, September 4, 2008

Are Web Designers Getting too Lazy?!!

Recently, I changed the color scheme on my computer because I was literally starting to look like a raccoon (with incredibly dark circles under my eyes). Anyway, I changed the background color of all windows to black and the text color to light gray. After I made the changes I started to surf the net to realize that so many websites don't specify the colors for the page background and/or the text, they leave them to the browser's default colors!! I had strange (and ugly) looking websites on my computer (unfortunately so many of them for well-known and big websites) some pages with white background (they specified the background color correctly) but with light gray for the text! which is almost unreadable, while other websites had black for the text color and also black for the background! which is completely unreadable! (they specified the text color but not the background color), and many websites didn't specify both, so you have black background and light gray text with the images having white background which is really ugly! What the heck is going on?! Are web designers getting so lazy that they decided to count on the browser's default color settings as if they were hard-coded?!! Didn't it come to their minds that anybody can change the color scheme? It's only two lines in CSS for God's sake!!!!

Tuesday, May 27, 2008

The Myth of for being faster than foreach

You probably, like me, heard this so many times that for is faster than foreach and you should use it whenever you can. Well, today I wanted to know how much this is true so I did a little test (find below the test and results). As you can see in the results of the test they are both identical but as I find using foreach is much more convenient for many reasons (including thread safety in some scenarios) so it makes more sense to use foreach.

More details:

The release build was used in the test
Software used in the test:
  • Windows XP Pro SP2
  • .NET Framework 2.0

The specs of my computer (where the test was done) are:
  • CPU Intel 1.6GHz Dual Core
  • 1024 MB RAM


Used Code
using System;
using System.Collections.Generic;
using System.Text;

namespace for_vs_foreach
{
class Program
{
static void Main(string[] args)
{
const int LOOP_COUNT = 10000000;
int myVar;
MyCustomObject[] customObjects = new MyCustomObject[LOOP_COUNT];
for (int i = 0; i < LOOP_COUNT; i++)
{
customObjects[i] = new MyCustomObject(i);
}

System.Threading.Thread.Sleep(1000);

// foreach
//
DateTime beforeForeach = DateTime.Now;
foreach (MyCustomObject customObject in customObjects)
{
myVar = customObject.Var;
}
DateTime afterForeach = DateTime.Now;

// for
//
DateTime beforeFor = DateTime.Now;
for (int i = 0; i < LOOP_COUNT; i++)
{
myVar = customObjects[i].Var;
}
DateTime afterFor = DateTime.Now;

Console.WriteLine("{0} (foreach test results)", afterForeach.Subtract(beforeForeach));
Console.WriteLine("{0} (for test results)", afterFor.Subtract(beforeFor));
Console.Read();
}
}

public class MyCustomObject
{
public MyCustomObject(int var)
{
_var = var;
}

private int _var;
public int Var
{
get
{
return _var;
}
set
{
_var = value;
}
}
}
}

Results:
00:00:00.0625000 (foreach test results)
00:00:00.0625000 (for test results)

Saturday, May 10, 2008

Efficiently Copying Items from One Array to Another in C# (Also generally in .NET)

I've been searching recently for an efficient way in C# to copy items from an array to another. At first it seemed that efficient way simply didn't exist. In C++ you can do this very easily by copying the memory block using memcpy() or memmove() but in C# you can't do this in a safe way (sure you can write some unsafe code but this is not really what I wanted, I just wanted to do it the 'clean and safe way'). Anyway, my options were to use Array.Copy() or a for loop (iterate through the source array and copy the items to the destination array). Unfortunately the documentation for Array.Copy() clearly states that it's an O(n) operation where n is length, so, it seemed that the for loop and Array.Copy() were almost equivalent so I decided I could use any of them as it wouldn't make any real difference (my decision was based on what's written in the documentation about Array.Copy() being an O(n) operation)

Anyway, today I was using .NET Refelctor to view the code for List<T>.ToArray(), I found that the Array.Copy() was used in the code, see below the code for List<T>.ToArray() copied from .NET Reflector:

public T[] ToArray()
{
T[] destinationArray = new T[this._size];
Array.Copy(this._items, 0, destinationArray, 0, this._size);
return destinationArray;
}


So, I wanted to have a look on Array.Copy(), this is how it shows in .NET Refelctor:

[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length)
{
Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length, false);
}


The code for Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length, false); can't be viewed using .NET Reflector, here's what you get:

[MethodImpl(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);


To make a long story short I just was curious to see whether using Array.Copy() is really equivalent to using a simple for loop, so, motivated by my inability to view the code for Array.Copy(),I decided to do my own testing (see the code and results below). Well, despite what's written in the documentation about Array.Copy() being an O(n) operation, Array.Copy() was 10 times faster on my computer! So my guess is that it internally uses some memory copying so it's not really an O(n) operation.

More details:

The release build was used in the test
Software used in the test:
  • Windows XP Pro SP2
  • .NET Framework 2.0

The specs of my computer (where the test was done) are:
  • CPU Intel 1.6GHz Dual Core
  • 1024 MB RAM


Used Code
using System;
using System.Collections.Generic;
using System.Text;

namespace array_copy
{
class Program
{
static void Main(string[] args)
{
const int ArraySize = 5000;
const int LoopCount = 100000;

MyCustomObject[] customObjects1 = new MyCustomObject[ArraySize];
MyCustomObject[] customObjects2 = new MyCustomObject[ArraySize];
for (int i = 0; i < ArraySize; i++)
{
customObjects1[i] = new MyCustomObject(i);
customObjects2[i] = new MyCustomObject(i);
}

// Array.Copy()
//
DateTime beforeArrayCopy = DateTime.Now;
for (int j = 0; j < LoopCount; j++)
{
Array.Copy(customObjects1, 0, customObjects2, 1, customObjects1.Length - 1);
}
DateTime afterArrayCopy = DateTime.Now;

// For Loop Copy
//
DateTime beforeForLoopCopy = DateTime.Now;
for (int j = 0; j < LoopCount; j++)
{
int length = customObjects1.Length - 1;
for (int i = 0; i < length; i++)
{
customObjects2[i + 1] = customObjects1[i];
}
}
DateTime afterForLoopCopy = DateTime.Now;

Console.WriteLine("{0} Array.Copy()", afterArrayCopy.Subtract(beforeArrayCopy));
Console.WriteLine("{0} For Loop Copy", afterForLoopCopy.Subtract(beforeForLoopCopy));

Console.Read();
}
}

public class MyCustomObject
{
public MyCustomObject(int var)
{
_var = var;
}

private int _var;
public int Var
{
get
{
return _var;
}
}
}
}

Results:
00:00:00.5937500 Array.Copy()
00:00:04.9062500 For Loop Copy