Free Market Research Methods Part 1 – Analyzing Public Filings

Last week I attended a Market Research workshop presented by Dr. Dean Chang, Director of Mtech Ventures and Education. Instead of the general advice given at many market research presentations, Dr. Chang put himself in the shoes of a founder and walked us through some motions. This article will cover his take on analyzing public SEC filings.

Why should you bother doing market research?

  • It is expensive to develop products, but it is cheap/free to obtain research.
  • Since your product will most likely change, it is vital that you know your market so that you can successfully guide its evolution.
  • Investors and anyone with whom you may develop a business relationship will probably not take you seriously if you don’t know your market.

What is a 10-K SEC Filing?

Every publicly traded company is required to file an annual 10-K report. This document may have information on a company’s biggest competitors, distribution channels, sales figures, supply chain, and more. Some companies have their 10-K on their company website but we’ll just go to the SEC website and search for it. I use the search option “Company or fund name, ticker symbol, CIK (Central Index Key), file number, state, country, or SIC (Standard Industrial Classification)”.

*Note: While “Annual Reports” may seem to have the information we are looking for, they usually contain lots of marketing fluff and less of the data we are interested in analyzing. Make sure you see something like the following at the top of the report:
10-k_header

Three questions we should answer

  1. Who are your competitors and what are their competing products?
    (Financials, Product Differentiation, Market Strategy, Sales Channel, Resources, Investors)
  2. How big is the potential market? (1M,10M,100M,1B+)
  3. Who are your first customers and how many are there?

The Mock Company

Dr. Chang’s mock company was interested in the video game controller (peripheral) industry. We will answer some of the questions/sub-questions listed above by analyzing a competitor, Logitech’s, 10-K filing. If you search for “Logitech”, a number of filings come up but we are only interested in the 10-K.

Enough introduction, let’s get started.

What does the video game peripheral industry look like?

The 10-K has some information that helps us feel out the industry. We see the following paragraph in the “Industry Overview” section (page 6):

“We also believe that similar industry dynamics and personal peripheral device opportunities exist for non-PC platforms, such as video game consoles, digital music players and home-entertainment systems. As these additional platforms deliver new functionality, increased processing power and growing communications capabilities, we expect demand to increase for add-on, complementary devices connected to these platforms. The product expertise Logitech has developed around the PC extends to these other platforms as well and provides further opportunity for growth and leverage.”

Logitech believes that video game platforms will continue to improve, increasing the size of the video game peripheral market. This may not be ground breaking news but certainly good to hear from a market leader. Continuing to the “Digital Home Environment” section on page 7, we see this sentence:

“Logitech also offers a broad spectrum of products for gamers. We are leveraging our investments in the desktop PC to enhance gaming consoles with our expertise in force and vibration feedback, cordless connectivity, voice input and video input.”

Again, not groundbreaking given the peripherals already out on the market, but it does say that Logitech thinks highly interactive peripherals with feedback are the future.

What competing products and companies should we be aware of?

Skipping ahead to page 12 of Logitech’s 10-K, we can see that Logitech lists their major video game peripheral offerings. We should probably glance over these to make sure we are aware of what they have produced.

While we may already be aware of Logitech’s product offerings, we may not be aware of Logitech’s largest competitors in the Gaming market. On page 16, we find the following:

Competitors for our interactive entertainment products include Intec, Pelican Accessories, Mad Catz and its Saitek subsidiary. Our controllers for PlayStation also compete against controllers offered by Sony.

Obviously we will need to look at those companies if we haven’t already.

How big is our market?

Going back to the “Marketing, Sales and Distribution” section on page 13, we see that Logitech’s 2009 revenue was around $2.2 billion ( $2,208,832 in thousands ). This is great information but we need to find out what portion of that is gaming. Note that the revenue is also broken down by geographic region which is important for marketing purposes.

If we probe around for more financial figures in the 10-K, we find a very useful statement on page 42. We are given Logitech’s net sales broken down by product family. We see that for Retail – Gaming, the net sales is about $127 million. Now we know that we have at least a $100 million dollar market but probably much more since the industry was described as highly competitive and we already noted multiple competitors.

You have probably noticed that Logitech’s 2009 gaming sales decreased from their 2008 sales figure, $146 million. Continuing in this section, we see the following explanation for this decrease on page 43:

Retail sales of our gaming peripherals decreased 13% while units decreased 22% in fiscal year 2009. PC gaming sales decreased 13% with an 18% decrease in units, primarily due to lower sales of our G15 gaming keyboard and our MOMO Racing Force Feedback steering wheel, partially offset by sales of our G25 Racing Wheel. Console gaming sales decreased 12% with a 28% decline in units. The growth in sales of our GT Driving Force steering wheel were more than offset by declines in the sale of PlayStation gamepads and the Driving Force Pro steering wheel.

One piece of information we can grab from this section is that units decreased almost double the amount of sales which probably means customers are willing to pay a high premium for highly interactive peripherals.

What does our sales channel look like?

Skipping back to the “Sales and Distribution” section on page 14, we see:

“Logitech sells through many distribution channels, including distributors, OEMs and regional and national retail chains, including online retailers.” It goes on to list their third party distributors in the USA and from the “Principal Markets” section, we know that “In fiscal years 2009, 2008 and 2007, Ingram Micro Inc. and its affiliated entities together accounted for 14% of our net sales in each year. No other customers individually accounted for more than 10% of our net sales during fiscal years 2009, 2008 and 2007.”

From this information we know how they reach consumers and who their leading distributor is.

Supply Chain

Although not vital to our market research, there is good information about manufacturing in the 10-K which is important to our business strategy. On page 15, we see the following:

“To effectively respond to rapidly changing demand and to leverage economies of scale, we intend to continue our hybrid model of in-house manufacturing and third-party contract manufacturers to supply our products. Through our high-volume manufacturing operations located in Suzhou, China, we believe we have been able to maintain strong quality process controls and have realized significant cost efficiencies. Our Suzhou operation provides for increased production capacity and greater flexibility in responding to product demand. Further, by outsourcing the manufacturing of certain products, we seek to reduce volatility in production volumes as well as improve time to market.”

Here we are creating a gaming company and probably need to understand a production strategy. We may need the aforementioned hybrid model of in-house manufacturing and third-party contract manufacturers to supply our products. The above information should also raise a few questions. Is Suzhou, China the best place in the world to develop video game peripherals? If so, why is Suzhou the best? Maybe Suzhou is just really cheap, or maybe manufacturers in Suzhou specialize in these devices. I’m not sure the reason but it’s worth looking into.

Acquisitions

Another thing to look for in a SEC filing is acquisitions. Getting your technology bought out by the market leader for a large sum of money is obviously a nice exit strategy. Access to an exhaustive list of acquisitions conveniently starts on page 83 of the 10-K. You may want to read a little about the companies to understand what types of companies Logitech is interested in acquiring.

Conclusion

The purpose of this blog post was to demonstrate that 10-K’s can provide a good starting point for your market research. Much of the information is basic, but it is all free information and held to a high standard with regards to accuracy.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in marketing | Tagged , , , , | 2 Comments

Where is my crontab located on Mac OS X 10.5 Leopard?

I googled around for a few minutes with no luck. After probing around my system, here is where I found my crontab file:

Macintosh-2:mls TAmoyal$ sudo ls /usr/lib/cron/tabs/
Password:
TAmoyal

I found it by checking the crontab man page:

man crontab

Where I saw a “FILES” section:

FILES
     /usr/lib/cron/cron.allow
     /usr/lib/cron/cron.deny

And that lead me to probe around the /usr/lib/cron directory. Note that you can view your crontab my with:

crontab -l

but I wanted to view the actual file for debugging purposes.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Random, Software | Tagged , , , , | Leave a comment

Interning empty string error in Ruby on Rails

I don’t like writing short posts about fixing code errors but I think this one deserves a quick shout out. If you get an error in your Rails application that says “interning empty string”, there could be something wrong with an error message in your validations. For example, I had something like:

def geocoding_works_when_geotarget_is_true
    if geotarget and (self.lat == nil or self.lng == nil or self.address_changed?)
      errors.add("Provide better location information so that we can geotarget your reminders.") unless geocode
    end
end

The ‘.’ in my error message caused an “interning empty string” error. I hope I save someone an hour by posting this.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , | 11 Comments

Logging your Rails model (the easy way)

In one of my Rails applications, I have some pretty heavy tasks in my models. I decided to log to different files for two of my models so that I can easily make sure these tasks are performed correctly without going through my application log. I also call some of my model methods with rake tasks so it’s nice to have that action logged. The code below implements a custom log for the SomeClass model.

class SomeClass < ActiveRecord::Base
     LOGFILE = File.join(RAILS_ROOT, '/log/', "someclass_#{RAILS_ENV}.log")
 
     def self.do_something
          log "I am doing something"
     end
 
     def do_something_else
          SomeClass.log "Tried to do something else, but screwed up.", :error
     end
 
     def self.log(message, severity = :info)  
         @model_log ||= ActiveSupport::BufferedLogger.new(LOGFILE)
         @model_log.send severity, "[#{Time.now.to_s(:db)}] [#{severity.to_s.capitalize}] #{message}\n" 
     end
end

This will create separate logs for all of your environments. Notice that I reference the class when I log from an instance method. This is working great for me. Anyone have a better way?

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , | Leave a comment

Validating multiple fields with one validator in Flex3

I like laying out forms in MXML because it’s easy to read. In a recent project, I had five email fields and it looked something like this:

<mx:Form id="myForm">
	<mx:FormItem label="1." labelStyleName="tenEmailsLabel">
		<mx:TextInput id="email1" width="300" fontSize="13" />
	</mx:FormItem>
	<mx:FormItem label="2." labelStyleName="tenEmailsLabel">
		<mx:TextInput id="email2" width="300" fontSize="13" />
	</mx:FormItem>
	<mx:FormItem label="3." labelStyleName="tenEmailsLabel">
		<mx:TextInput id="email3" width="300" fontSize="13" />
	</mx:FormItem>
	<mx:FormItem label="4." labelStyleName="tenEmailsLabel">
	        <mx:TextInput id="email4" width="300" fontSize="13" />
	</mx:FormItem>
	<mx:FormItem label="5." labelStyleName="tenEmailsLabel">
		<mx:TextInput id="email5" width="300" fontSize="13" />
	</mx:FormItem>
</mx:Form>

I obviously wanted to use one validator for all of the email addresses since they all need to be validated the same way. I couldn’t find any great examples on the internet so I am posting the code to validate multiple fields with one validator.

private function submitForm():void{
     var result:ValidationResultEvent;
     var isValid:Boolean = false;
 
     for(var i:int=1; i<myForm.getChildren().length; i++){
	tenEmailsValidator.source = this["email"+i];
	result = tenEmailsValidator.validate();
	isValid = isValid && ( result.type == ValidationResultEvent.VALID )? true : false;
     }
 
     if(isValid){
	//...submit the form
     }else{
	 Alert.show("You cannot submit the form with errors.");
     }
}

If anyone has a better way to do this, please share!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , | 7 Comments

Configuring Phusion Passenger on a 256MB Ubuntu Slice @Slicehost

I installed Phusion Passenger a few weeks ago to get a production environment up and running for my Rails app. It was super easy to install and felt like magic. I checked off the item on my TODO and moved on. After all it didn’t say “YOUR APP WILL BE SLOW AS HELL IF YOU DON’T READ THIS MANUAL!!!” in their documentation. Well…it was too slow…and here’s how I fixed it.

Referencing the Phusion Passenger User Guide I was able to make changes that made my app run about 10 times faster. If you want to do this in 15 minutes, read this article. If you have a few hours, read through the user guide and experiment. My hardware setup is a 256MB Ubuntu VPS at my favorite hosting company – Slicehost.

The following are global settings I added to my httpd.conf:

RailsSpawnMethod smart
PassengerUseGlobalQueue on
PassengerMaxPoolSize 2
PassengerPoolIdleTime 0
PassengerMaxRequests 1000
RailsAutoDetect off
RailsAppSpawnerIdleTime 0
PassengerStatThrottleRate 5

RailsSpawnMethod smart/smart-lv2/conservative
This can speed up the spawn time tremendously (by as much as 90%) if your app is compatible. However, some Ruby on Rails applications and libraries are not compatible with smart spawning. Set your configuration to smart spawning and if your app works, then you are all good. If not, use another spawning method.

PassengerUseGlobalQueue ON/OFF
Turning this option ON tells Passenger to add requests to a global queue when your Rails instances are busy. As soon as an instance becomes available it will grab a request from the queue. If the option is OFF, each process will maintain its own queue. Localized queues can hurt you if an instance is processing a 60-second request and Passenger adds a 1-second request to the instance’s queue. ( Imagine waiting in a 10 person non-express line at Whole Foods when all you want is a bottle of water ). Therefore, it only makes sense to turn this OFF for the 5% performance gain if all of your requests take about the same amount of time.

PassengerMaxPoolSize INTEGER
This simply says how many application instances Passenger is aloud to Spawn. The default is 6 but the user guide recommends 2 for a 256MB slice so that’s what I went with. More could consume a lot of memory and crash my server. You can use 30 if you have 2GB of RAM.

***PassengerPoolIdleTime INTEGER
This is the minimum time an application instance can be idle without Passenger shutting it down. The default value was 300 which means if my app received no traffic for 300 seconds, it could shut down all of my app instances. The result? A visitor would have to wait way too long when viewing my website. I triple starred this because I think this setting alone will greatly improve your app speed. Note there is an obvious memory trade-off because your application instances will always be running.

PassengerMaxRequests INTEGER
This provides a safety net for memory leaks. It tells Passenger to restart an application instance after it receives a certain number of requests. My app is young so I am keeping it at 1000 requests but ideally you should set this to zero meaning no maximum.

RailsAutoDetect ON/OFF
Turn off auto-detection and tell Passenger exactly which directory contains your Rails app. Do this by adding the following line to your VirtualHost configuration block:

<VirtualHost>
    ...
    RailsBaseURI /
    ...
</VirtualHost>

RailsAppSpawnerIdleTime INTEGER
This is a similar setting to PassengerPoolIdleTime but applied to the ApplicationSpawner server. If the ApplicationSpawner server hasn’t done anything for the specified amount of time, it will automatically shut down. I set this at zero so it will never shut down and therefore take 10% of the time to spawn a Rails process as it would with the ApplicationSpawner server shut down. I would imagine this becomes increasingly important as your PassengerMaxPoolSize increases. Note that if your application is at it’s maximum number of instances allocated (PassengerMaxPoolSize), you may want the Spawner to shut down immediately after it spawns an app instance since the Spawner won’t be used much. Set the value to 1 if this is the case. I will probably do this in the future when my website has a more constant load ( another option is to write a script to periodically hit your Rails app and keep it at a constant load ).

PassengerStatThrottleRate INTEGER
Tell Passenger to only check for restart.txt up to once every 5 seconds instead of once per processed request.

Finally, try to turn on PassengerHighPerformance:

<VirtualHost>
    ...
    PassengerHighPerformance on
    ...
</VirtualHost>

Adding that line to your VirtualHost configuration block will improve your performance but make your Rails app incompatible with some Apache modules. If you turn that on, restart apache, and your Rails app works fine, chances are you are in the clear. Just keep this in mind for the future in case you add more Apache modules.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , , | 6 Comments

How to quickly set up a test for Twitter OAuth authentication from your local machine

Working with API’s such as Twitter from your local machine can be a pain. A problem that comes up is Twitter does not let you set your callback URL to hit your localhost. If you are working with OAuth on your local machine and want to test the user authorization flow, you are screwed. I will explain how to circumnavigate this issue on Mac OS X with Firefox. This tutorial assumes you have set up a Twitter oauth application and specified a callback url in the application settings. At the end of the tutorial, I will present a much faster way to accomplish this task.

Important Update:
As Mark Puig mentioned in the comments below, Twitter is currently allowing you to register URL’s like “http://127.0.0.1:8000/twitter_callback” as your Twitter callback URL (pretty sure this was not allowed before) . That being said, this article is still useful for those using API’s that do not allow you to register your local host as a callback and for those who want to learn more about hacking your DNS settings. And if Twitter restricts this in the future…

Step 1 (optional): Force Firefox to expire your DNS cache.
Expiring your DNS cache will force Firefox to take a fresh look at your /etc/hosts file on each request. Otherwise you may have to wait a minute forchanges to /etc/hosts to take effect. This step isn’t necessary but it will save you time if you edit /etc/hosts often.

  1. Type “about:config” into your browser address bar.
  2. When you get to the config options, right click and go to “New” -> “Integer”. Enter “network.dnsCacheExpiration” as the preference name and “0″ as the integer value.
  3. Repeat for Step 2 preference name “network.dnsCacheEntries” and the integer value “0″.

The integer value “0″ for dnsCacheExpiration is the number of seconds it will take for the DNS cache to expire. As a side note, you can increase the performance of Firefox by expiring the cache much less often (set dnsCacheExpiration to “3600″ for once per hour). Obviously you do not want to do this if you are messing around with your DNS settings such as in this example.

Step 2: Trick your browser
Open up /etc/hosts and add a line like the following:
127.0.0.1 xyz.com
where xyz.com is your real host.

If your Twitter callback URL has “www” like www.xyz.com, you must use www.xyz.com instead of xyz.com. This line forces your browser to resolve xyz.com to your localhost instead of visiting the actual website. If you completed step 1 you can type http://xyz.com into your browser address bar and watch it hit your localhost. If you skipped step 1, flush your browser’s DNS cache or wait a minute for the settings to pick up.

Step 3: Add directory and port redirection
Chances are your application’s twitter callback URL is not http://xyz.com, but rather something like http://xyz.com/twitter_callback …plus the oauth_token GET parameter. If this is true, you need to create an identical path on your localhost to a callback directory and forward to wherever you want. This is best explained by example.

My callback URL is http://xyz.com/twitter_callback and Twitter appends the oauth_token to the URL so it looks something like:
http://www.xyz.com/twitter_callback?oauth_token=pyOYM5tbvK71fvt…
Since my localhost points to “/Library/WebServer/Documents”, I created a directory “/Library/WebServer/Documents/twitter_callback/” which is where my browser will go when Twitter redirects me to the callback URL. Of course my browser will be looking for an index.php file, so I created one that looks like this:

<?php
	if($_SERVER['HTTP_HOST'] == 'xyz.com'){
                //$_SERVER['REQUEST_URI'] makes sure the oauth_token is appended 
		header("Location: http://localhost:3000".$_SERVER['REQUEST_URI']);
	}
?>

This file forwards the request to port 3000 which you cannot accomplish through DNS settings. Now I have the Twitter callback URL pointing to the proper directory in my Ruby On Rails application. Again, if your Twitter callback URL is of the form www.xyz.com, you must use www.xyz.com instead of xyz.com for the HTTP_HOST check.

Update:
There is actually a much easier way to accomplish this assuming you don’t need any URL parameters passed from the service to your application upon callback. You can use bit.ly, a URL shortening service. Just shorten the url “http://localhost:3000/twitter_callback” and register the shortened URL as the callback in your Twitter app. For this method, you have to create another Twitter OAuth app for development so that the callback URL’s can differ. Using bit.ly is faster and easier than the 3-step method above, but I will leave that method posted because it allows parameters to be passed back if necessary and it teaches you a little bit about FF and OS X.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , , , | 12 Comments

Defending Against Attacks With Rails

A couple weeks ago I presented on Rails security at a local Ruby On Rails meetup. I finally got around to posting the slides online.

The presentation covers topics including authentication, hashing, salting, key stretching, white listing, session hijacking, replay attacks, session fixation, cross-site request forgery, cross site scripting, sql injections, other injections, and some other Rails related security issues. Let me know if you have questions and please give me some feedback. I didn’t get too creative with the presentation because there was a lot of content to cover.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , , , , , , , , | 1 Comment

How to point your browser at websites on your server without registering a domain

I recently started managing my own server and found it difficult to point my browser somewhere on my system without going through DNS records and registering a domain name. That is sort of a pain, but here is a quick hack to make this super easy.

Let’s say you want to create an admin site for your server. This could be useful to view the output of phpinfo() or something like that. Just set up a virtual host like you normally would. For example:

<VirtualHost *:80>
     ServerAdmin youremail@email.com
     ServerName server-admin.net
     ServerAlias server-admin.net    
 
     DirectoryIndex index.php index.html
     DocumentRoot /var/www/server-admin
 
     <Directory "/var/www/server-admin">
         Options Indexes FollowSymLinks
         AllowOverride All
         Order allow,deny
         Allow from all
     </Directory>
</VirtualHost>

Then just add this to the bottom of your /etc/hosts file (assuming your OS is *nix):
your_servers_ip_address server-admin.net

Now you should be able to see that directory in your browser.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , | Leave a comment

Text inputs with rounded corners using jQuery (without image)

I have yet to find a solution for making rounded inputs without an image. I hacked one together today because I know it will save me a lot of time later. While the solution is hackish, I like it better than going into photoshop and making an image every time I want to change the length of a text input.

The solution has two dependencies: jQuery and jQuery.corner. Download jQuery here and jQuery.corner here.

You can skip the explanation and go straight to the demo, or check out this quick explanation. Note that in an effort to get this done quickly, my code isn’t too smart and you may have to mess with some of the values depending on the size of your text inputs. I still think it beats the crap out of getting on photoshop for every change.

First you must include the necessary files:

<script src="./js/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="./js/jquery.corner.js" type="text/javascript"></script>

and the roundInput function with the function calls:

/* input_id is the ID of the input element */
/* container_class will let you control the text input background color and padding */
/* border_class will let you control the border color */
function roundInput(input_id, container_class, border_class){
	var input = $('#'+input_id+'');
	var input_width = input.css("width"); //get the width of input
	var wrap_width = parseInt(input_width) + 10; //add 10 for padding
	wrapper = input.wrap("<div class='"+container_class+"'></div>").parent();
	wrapper.wrap("<div class='"+border_class+"' style='width: "+wrap_width+"px;'></div>"); //apply border
	wrapper.corner("round 8px").parent().css('padding', '2px').corner("round 10px"); //round box and border
}
 
/* round 2 inputs */
$(function(){
	roundInput('rounded_input1','rounded_container','rounded_border');
	roundInput('rounded_input2','rounded_container','rounded_border');
});

Obviously replace the above roundInput function calls with your own input id, container class, and border class. The CSS below allows you to control the border color, text input background color, and the space between the text input and the rounded corners.

<style>
/* Container class */
div.rounded_container{
        /* This background color should have the same background color as your text input */
        /* Changing this color will show you how the rounded input is laid out */
        background-color: #fff;
        /* This padding is between the text input and the rounded border on all sides */
        /* Decreasing the value may interfere with the rounded corners */
        padding: 4px;
}
/* Border class */		
div.rounded_border {  
	/* This is the color of your rounded border */
	background: #6666ff; 
}
input.rounded_input{
	border:0;
}
</style>

And finally the text inputs to round (replace these with your own):

<input id="rounded_input1" type="text" class="rounded_input" style="width: 286px;" />
<input id="rounded_input2" type="text" class="rounded_input" style="width: 286px;" />

This code has not been heavily tested, but it looks great on FF, IE7, Safari 5, and Chrome 5. I will post updated code if I decide to create something more flexible.

Enjoy the demo!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , | 12 Comments