Basically, break it into pieces. Usually individual pages and estimate each based on prior experience. Add to it other things you may need to do like designing a schema, interfacing with other APIs, etc. This will probably give you your best case scenario. Then multiply times two because stuff always comes up that you didn't think about. This is what I use for "ballpark" estimates.
This is definately open to optimization.
I think it is important to understand "both sides". Clients usually like fixed-bid or per project pricing because it limits their risk. That way they won't be surprised by a huge bill.
As a freelance developer, I disklike fixed bids because it requires me to manage scope really carefully, otherwise my effective rate falls really quickly. So this really means that I need to increase my bid by some amount (I do 25%) do limit my exposure. So this isn't quite as good for the client as it might look on the surface.
A better way to do it is a lesser rate, such as hourly or weekly, and then break the work into iterations or phases, each resulting in something demonstrable so they can see what they are getting for their money. After they pay for the phase, they can walk with the source code written so far if they want. This limits risk on both sides. I've gotten paid for what I've done so far, and they have something tangible for what they've paid so far.
I start out with prototypes/proofs of concept to explore the most risky aspects of the application first and then feed what I find back into the estimate. This way, I can the client can know sooner than later about gotchas that can affect schedule or cost.
But seriously, most guys who can predict hours needed with any amount of reliability are the guys who have been doing it for awhile and have already done a similar job. They use past experience to predict amount of work hours needed to finish something. If you truly have no idea how long it will take you, you could begin by breaking up the project into each piece and try to project how much time each of those pieces would take. For example, how long will the design take, the homepage, the about page, the forms. Break each feature apart and try to estimate time for each, then add them up.
My best suggestion is just to overshoot your hours. If they accept the offer you should work hard to make sure you meet the deadline and if you go under the deadline, be honest and tell them how much money you saved them.
I have noticed that my estimates are becoming more accurate over time but I'd also like to know if people have some sort of a procedure/workflow that they follow.
Another approach I experimented with was using the scrum methodology. I tried breaking the tasks up into smaller chunks (user stories) and then valuing the effort/time required for the individual parts before adding the values up.
Run it through your peers (specially anyone else involved in delivering it). Listen to the most pessimistic ones, rather than the über optimistic.
Multiply that estimation you have now by π.
Believe me, you will more often than not correct with such a calculation.
Bonus: You will be right by more or less ~10% which you can either give as a discount to your client, or you can charge them 10% extra in the end.
Warn them that there is ALWAYS risk when estimating, and all risk should be shared. Win Win FTW!
Even with a lot of experience, the only thing that's really certain is that unexpected things tend to jump out and eat your budget.
Fibonacci, elephants and mice do not come into it.
plan carefully. If you don't know enough to plan carefully, prototype, then plan.