Thursday, April 16, 2009

Justifying a single line of text using HTML and CSS

If you have the need to match a single line of text to the width of its container, you may experience some of the frustration that I have gone through. There is a pseudo-fix for IE only, but since I generally oppose the very existence of IE I won't even bother mentioning it. (that is sarcastic, but IE gives me enough grief that I almost mean it)

Here is the issue: the css property text-align has an option of "justify" which causes inline text to flow to the full width of the container. Except for the last line. 

If you have a paragraph that is text-align:justify, all the lines will stretch to the full container width with the exception of the last, which will left-align.

I needed a tag line to match the width of a logo and I didn't want to use a graphic. The tag line was only one line of text and was supposed to match the width. Since it is just a single line, it was treated as the last line of a paragraph and not allowed to fill the width.

I played with the font size, letter spacing and padding, but in the end I used a little HTML to trick my page into working.

After the last word, I put a space in the HTML, and then 5 consecutive non breaking space characters back-to-back like this:       - this back-to-back string of these characters is interpreted by all current major browsers as a "word" and forced onto the next line, leaving the first line as just the tagline.

DEMO:
Here is my single line of text, text-aligned justify              


This isn't a perfect solution since it adds padding below the tagline, but I can accomodate that (I just put an overflow:hidden on my container and it kept it constrained properly). Also this is definitely a hack so not ideal, but I can be pragmatic and say I got what I needed working.

Leave any thoughts in the comments!

Friday, March 13, 2009

Problems I have had with GoGrid cloud hosting

There are a lot of great things about GoGrid, and you can read about them all over the net. I am writing this post because what I didn't find all over the net was anyone who had any real problems, or anything critical to say about GoGrid. I, however, have had some very serious problems with GoGrid, and they have exposed - to me - things that really need to be public for others going through the decision-making process.

This is not meant to be a "scathing" review. I am a little sore over some of the support issues, but this post is purely so others can be more informed. GoGrid really is cool, and I recognize that more great features are coming.

For the past several months I have been working with several clients on migrating and creating applications to/on the GoGrid cloud. This post is written by someone with real-world experience on GoGrid with both Linux and Windows servers.

Before my decision to recommend GoGrid, I did as much legwork as I could to really understand how GoGrid worked and why it was a better or worse option than a Dedicated host, VPS, or another cloud option (like Mosso or Amazon)

My choice in the end for GoGrid really was based on several key factors: 1) ease of use, 2) recommendations of peers, 3) relative cost and 4) lack of any real complaints out on the net.

The great part of GoGrid is the ease with which you can deploy new servers. It really is as easy as I have seen. A few clicks and a few minutes later you can remote desktop to you Windows server or SSH to a Linux server. Neat!

I want to stop there with the praise though, because as I mentioned above, you can read all about how great and easy GoGrid is elsewhere.

Here come the problems:

1) Your server is not really on a cloud - not really. I created and configured a CentOS 5.1 LAMP image, installed everything I needed, and configured all the sysadmin stuff. The server and the app were running perfectly. The night before the app running on the server was set to premier, I received an email from my client saying that the site was not working. Over the next 30 hours, I came to understand that a "node" on the gogrid cloud had gone down, and my server - and my app - along with it. 

What Gogrid has done is abstracted any clients from the cloud by putting them into these "nodes." So your server apparently isn't distributed in the cloud, it is sitting on a node that I assume is distributed on the cloud. But when the node my server was on went down, GoGrid couldn't get my server back. I have been waiting nearly 2 days now and the server is still just lost. It still shows up in my GoGrid control panel, but this server does not respond to any requests of any sort (ping, ssh, etc.). What is somewhat amusing is that I can still restart this server in the control panel, which indicates that it goes offline and then comes back online - but the control panel seems to be the only thing that can communicate with the server.

The rationale for using this node model (as explained to me by support) is that if a client creates several servers, each one is guaranteed to be on its own node, and then you can use the free load balancers to distribute the applications on the servers. The immediate glaring problem is that you can't clone a server (although I am being repeatedly told that this feature is coming), so you have to manually create the servers and set them all up on your own - or use some third party tool to help you.  

If a hosting environment takes a catastrophic hit, they can almost always bring everything back the way it was from a backup (at least in my experience). This has not been my experience with GoGrid, my server has not been recoverable for almost 2 days now. On a true grid, backups would not be necessary from the host since the server would be on the grid and a failure of some part of the grid wouldn't result in the loss of your server. Of course a user would create their own backups, which they could use to repair any damage they did themselves.

GoGrid, as it exists right now, should probably stop offering LAMP images or Windows images with included SQL Server 2005 Express; this leads potential customers like me to believe that these are good, easy choices on GoGrid. They are absolutely not good choices, until GoGrid makes creating custom images a reality, starts truly distributing the servers on the grid, or until GoGrid gets some sort of useful backup routine in place.

2) Your server is not scalable. The server you deploy cannot dynamically scale. I won't go into detail on this because you can find this documented on GoGrid's site and on other reviews of GoGrid. There is a scalable storage option, but this doesn't help if you need more RAM on a server.

3) There are no tools to manage or even view DNS zone settings for the servepath name servers. If you want to use the nameservers from GoGrid, you can, but you have to create a help ticket and hope whoever creates the entries does it right (they didn't get it right the first time at least once for me). Once they are set, you can request that support emails you your settings, but until DNS propagation is complete you have no other way to verify your name server settings - nothing real time, and nothing easy. I was coming from Rackspace, who had a control panel built into their interface for viewing and editing zone settings. Again, in GoGrid you can create a nameserver of your own and administer it - but that is completely up to you - nothing easy.

4) This brings me to my last big issue with GoGrid: support and support updates.

I was coming from a Rackspace dedicated hosting environment. My client was paying about 30% more for that Rackspace solution that they are currently paying for a comparable GoGrid solution. My experience with Rackspace has been absolutely fantastic. Rackspace support is really second to none. Rackspace understands that since they are in the business of leasing servers, it makes sense to provide as much information about how to best manage those servers to their clients as they can.

GoGrid support is not Rackspace support. If you need OS-specific help working something out, you and Google are on your own - or you have to shell out more $$ for paid support from GoGrid. Hear me out; how many times have you set something up that you have set up a hundred times before, but there is one little problem and for the life of you, you can't see where the issue is coming from? You just need a second set of eyes, and 2 minutes of someone's time to help you see past the problem. 

With Rackspace, that sort of help was always there. With GoGrid it falls away very quickly. I had a couple of these little issues, and eventually worked them out and slapped myself on the forehead. But in the moment, when I could have used a quick answer from the host that my client was shelling out good money for - there was only the suggestion that I look into their paid support.

I will say that you can end up on chat or on the phone with some very helpful people at GoGrid. But you can also get someone who is far less helpful. It seems clear to me that there are support staff who are stakeholders in GoGrid's success, but there are other (probably contracted) support staff who are not.

When my server went down, I opened a support case, jumped on chat and started trying to get any information about what was going on. It took several chat sessions, a handful of emails, several phone calls, and about 4 hours to finally get someone to tell me that a node had gone down on GoGrid, which is why my server stopped responding. This still raises my blood pressure, because when I finally got an answer about what had happened, the person who told me said that there had been an entry made (into whatever system they use to track problems) around the time I first logged my case about the server problem. 

I have things go wrong with clients sometimes. Sometimes it is the result of something that I did or didn't do. It happens. But I don't try to hide it, and I don't run them around if they ask me what happened. This has been my biggest disappointment to date with GoGrid; I feel as though I was given the run-around by support staff until I talked to the right person. 

One interesting aside is that I was using Twitter to document some of my experience and several GoGrid folks started following me. Someone from GoGrid support called and left a message last night at midnight to see if there was anything they could do, mentioning that one of their superiors had seen my tweets. That felt kind of cool, but I still have not had anyone update me on the open ticket on my server status since yesterday when I called to check. 

In the saga of the lost server, we ended up recreating the application on a shared host and changing our domain's name server settings to point to the shared host. The app is not expected to need too much bandwidth as it is only the preview version. We will probably still use GoGrid for the final app, we will just set everything up differently.

CONCLUSIONS:
  • GoGrid is really only easy for the first 20 minutes of a server's lifespan, after that you may as well be on a VPS for a lot less money (unless you want a distributed app).
  • I am going to continue to recommend GoGrid for some clients. 
  • I am going to recommend against GoGrid for far more clients.
  • I know now that having two 512KB (of RAM) servers, a separate database server with backups scheduled onto the cloud storage, and a free load balancer to distribute incoming requests to the 2 servers is better than a single 1GB LAMP server. 
  • I have found that there are some great support people with GoGrid, it is just a shame that there are also some less-great support people.
  • Don't use GoGrid if you need a single server. Seriously don't.
My suggestions to GoGrid
  • Stop offering LAMP images and Windows Server with SQL 2005 Express images until you can offer truly distributed server instances, or work out real backups.
  • Provide at least read access to the zone settings for domains within users' accounts. Better yet let them manage the zone settings for their domain, on your name servers, on their own.
  • Make cloning servers, or creating custom, boot-able images easy (I am being told this is coming)
  • Allow scaling of servers (this is supposed to be coming as well)
  • Get more "stakeholder" support staff, and when something really bad happens be proactive on keeping clients updated. (I've waited long enough for my update, I'm deleting my servers in the control panel now)

Labels: , , , , ,

Tuesday, October 28, 2008

IE6 OR IE7 Position Absolute not showing

I don't know why, but for some reason in IE6 or IE7 if there is a floated layout and you have an absolute-positioned div in the mix sometimes it just won't show up. I played with the developer toolbar and if I edit any CSS property in the tool, the div magically shows up, but if I implement all the CSS in the stylesheet then reload the page it won't show up.

If you wrap your absolutely positioned element in an arbitrary div (we gave ours a class of 'positionFix') that ISN'T FLOATED, the absolutely positioned element should magically reappear.

This assumes that you have already made sure that any wrappers around the absolutely positioned element are either relatively positioned or absolutely positioned (that is a freshman-level mistake)

I'm only documenting this here so other lost souls don't spend so much time searching Google fruitlessly.

Labels: , , , , , , ,

Thursday, February 28, 2008

Using Google Sites to create a useful small-business intranet

I own Western Ascent Inc. - a small web-developement company located in Fort Collins, CO.

Today I read the news that JotSpot had been relaunched under Google Sites and saw that the Google Apps and Docs were able to be embedded into the web pages.

I have already switched our email to gmail via Google Apps, and wondered what useful tool I could cobble together using Google Sites. When I saw the fact that you can embed forms from Google Docs into pages on Google Sites, and limit site access to members of your domain, I thought I would put together a little time-tracking application to test an idea I had.

I have been using Base Camp for quite a while now to manage projects and track time for our small team of developers and designers. It is generally useful, but I am not in love with it - meaning that if I find an adequate replacement for less money (or free) I will happily move on.

So far, I think my time-tracker is working well and I can see how the sites and access control can allow me to create "extranets" for client projects that will allow us to share files and ideas with clients - which, along with time tracking - is our primary use for Base Camp.

I will try and put together a quick tutorial of how I created our little intranet and how I made a form that all our employees are already using to track time on projects.

Labels: , , , , , , ,

Monday, February 18, 2008

Drupal 6 on 1and1.com

I successfully installed Drupal 6 today on a 1and1.com shared hosting plan.

I created the MySQL db (mySQL Version 5) and uploaded the files for the site to a folder that was alone on a subdomain.

I hit the site, the first step asked me to select a language. The next screen gave me an error saying that register_globals needed to be disabled.

I checked .htaccess in the root and for php 5 register_globals was set to 0.

After trying a handful of different things, all I needed to do was create a file called php.ini and add it to the root of the site. It only has 1 line of text:

register_globals = off

I found this on a Drupal.org comment here.

hopefully this saves at least one other person some grief.

2008.03.03 UPDATE: I kept running out of memory so I added the following line to php.ini:
memory_limit = 40M

I don't have a good reason to pick 40M, it seems to be running fine now though.

2008.10.19 UPDATE: I am installing Uberart 1.5 Deluxe (running Drupal 5.11) and the same php.ini file was required.

Wednesday, January 30, 2008

Jumpy scrolling in Flex 3 application

We've been beating our heads against the wall at work trying to fix an extremely irritating bug in a flex project we're working on.

The scenario was that we had a canvas with a background image, that would scroll when it exceeded the length of its container (a VBox in our scenario).

If we add the background image inline using the backgroundimage property, with a background size of 100%, then started scrolling over our content, suddenly the scroll behavior would become erratic and jumpy.

It was strange, because when we grab the drag handle, and stay over the "track" of the scroll area, it worked fine. Also, if we moved our cursor outside the container and kept dragging it worked fine. Finally, if we were dragging and went over a container INSIDE the jumpy canvas it would scroll normally.

What fixed the issue was taking the backgroundimage property off the canvas, giving the canvas a stylename, then in the mxml document added a style block and defined the backgroundImage property with a value of Embed("imageName.png").

This immediately stopped the jumpy-ness and it works great.

Labels: , , ,

Saturday, January 26, 2008

ASP.NET UpdatePanel, Ajax, and jQuery problems and solution

I am finishing work on an eCommerce application and there is some AJAX functionality that I had to add to several of the pages.

Prior to this, I was adding some behaviors to elements of the page using jQuery's ready function:


// inside my script.js file
jQuery(function($) {
$(document).ready(function(){
// code here
}});


I added several UpdatePanels that were being updated by some AJAX calls. Everything seemed to work great, until I noticed that once any of the AJAX updated the UpdatePanel that all the behaviours I was setting up using jQuery were gone!!

I spent a while digging around and found a comment by "gt1329a" here:
http://forums.asp.net/p/1189519/2039138.aspx#2039138

In his/her comment they mention that "pageLoad fires after every partial postback" - which was essentially resetting the page without re-initializing the jQuery $(document).ready()...

So to clarify his/her "quick and dirty solution", I modified the code so it looks like this:


// inside my script.js file
/* // sorry jQuery
jQuery(function($) {
$(document).ready(function(){ */

function pageLoad()
{
// code here
}

/*}});*/


I have some concerns about doing this, but being a pragmatist, I am satisfied with the result. The AJAX calls all work, and all the behaviors I need to add into the page are functioning as expected.

Please comment if this post is helpful.

Labels: , , , , ,