Developing Locally on a Mac

May 23, 2010

It's taken a while (see an earlier post), but I've finally found my perfect setup for developing locally on my Mac.

MAMP & VirtualHostX

MAMP is essential for developing locally on Mac. But with URLs like http://localhost/mysite, testing in a browser was a pain.

Not anymore. A nifty little app called VirtualHostX makes setting up virtual hosts like http://mysite a snap. Goes with MAMP like peanut butter and jelly. (NOTE: VHX works with MAMP 1.8.4, but I couldn't get it working with MAMP 1.9.)

VMWare Fusion

Testing in Windows is a necessity, but how do you access your test site in IE if you're on a Mac? VMWare Fusion, of course. You have to edit a file in Windows, but it's relatively simple.

Sean Sperte has an excellent writeup for setting up MAMP and VirtualHostX with VMWare Fusion for local development. NOTE: If you follow the instructions and Apache won't start, check your system preferences for Sharing and make sure Web Sharing is unchecked.

Other Tools

BBedit

I've tried Coda and TextMate, but for my work and development style, nothing yet beats the old powerhouse BBedit.

AutoPairs

I did miss the auto pairing in TextMate. It's just so convenient. Fortunately, AutoPairs is a great little app that runs as a system preference pane, which means autopairs is available for use in all your applications, including your browser. Nice!

Transmit

Sometimes using the command line feels like having blinders on. I want to see directories and where I'm at. For my money, Transmit is the best FTP client for the Mac.

It's always fun (and sometimes enlightening) to see other developers' set ups. How do you develop on a Mac?

CSS for Layout

May 16, 2010

From the presentation I gave this weekend at the Phoenix Desert Code Camp. You can also view and download the notes at http://bit.ly/cssforlayout

Why Use CSS?

Cascading style sheets (CSS) allow us to separate content from presentation.

  1. Saves time and money. It's easier to change one style sheet than, say, 20 font tags on every page of a 200 page web site.
  2. File sizes are smaller and load faster, saving more time, money and your users from frustration.
  3. Machines love it because...
HTML (Hypertext Markup Language) is a machine language.
Machines don't care what a page looks like, only that it makes logical sense.

HTML is intended to tag content with meaningful labels so that machines know what the bits of data are. Browsers are not the only machines that access your pages. Devices such as handhelds, mobile devices, text readers, screen readers, bots, spiders, search engines, feed readers, data scrapers, etc., will pull (or push) your content. The data must be identified in a logical, meaningful way. Information about the visual display of those elements is junk to machines.

SEMANTIC MARKUP

Writing semantic markup ensures that your content can be consumed by almost every method and machine accessing the web, and that those machines can repurpose and display the content in a suitable manner.

There's no secret or difficulty in writing semantic markup. Just call things what they are.

  • Lists - use UL, OL, or DL
  • Heads - label H1 (only once per page), H2, H3, etc., in a logical hierarchy
  • Paragraphs - wrap paragraphs in P tags.
  • Divs and spans - are gimmes from W3C. Generic style containers with no visual or presentational attributes of their own, they are used to style or layout content when no other HTML element is available. As "meaningless" tags, they are ignored by most machines.

Never use HTML to indicate how something should be displayed in a browser. For most machines, that's junk code.

All About Boxes

In CSS every element is a box. To understand CSS, you need to understand the box model, the types of boxes, and the flow of elements in a document.

The Box Model

Margin adds spacing outside the element, padding adds spacing inside the element. Borders fall between.


From W3C's "Visual formatting model" http://www.w3.org/TR/CSS2/visuren.html

The size of a box is calculated as:

content + margin + padding + border = size (width or height)

If we have content with a width of 200px, right and left margins of 10px, right and left padding of 20px, and a 1px border, the width of the box would be 262px:

200px + (2 x 10px) + (2 x 20px) + (2 x 1px) = 262px

When calculating sizes, keep in mind a strange characteristic of margins. When margin bumps up to other margin, it collapses into the larger margin. (Padding never collapses.) There is a good reason for this. Margins are used on paragraphs, so this keeps the spacing between paragraphs consistent.

Browser Resets

Every browser has defaults set by the manufacturer for displaying elements. Most software providers try to comply with the W3C standards, but some have dragged their feet a bit. We can use a reset method to remove the default styling browsers put on the elements and bring them all back in line.

Eric Meyers' Browser Reset: really good at removing all styling:

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } /* remember to define focus styles! */ :focus { outline: 0; } body { line-height: 1; color: black; background: white; } ol, ul { list-style: none; } /* tables still need 'cellspacing="0"' in the markup */ table { border-collapse: separate; border-spacing: 0; } caption, th, td { text-align: left; font-weight: normal; } blockquote:before, blockquote:after, q:before, q:after { content: ""; } blockquote, q { quotes: "" ""; }

Global reset: removes margins and padding on all elements (*):

* { margin: 0; padding: 0; }

NOTE: Removing margins on the ul doesn't remove the style: disc rule. They're just hidden. We need to add list-style-type: none.

Box Types: Block & Inline

In CSS there are two types of boxes: block and inline.

Block-level elements

Block level elements are normally displayed as blocks with line breaks before and afterwards. By default block-level elements are the width of their parent (or ancestor containing) item and cannot have elements at their side. In the normal flow of the document, sibling blocks "stack." Think of sibling blocks as boxes stacked on one another, or rectangular pieces of paper laid out in a vertical row.

Block elements can contain descendent, or child, blocks inside themselves, but not alongside. Think of parent and descendent blocks as boxes set within one another, or pieces of paper placed on top of one another.

Examples of block-level elements include: <div>, <h1>...<h6>, <p>, <ul>, <ol>, <dl>, <li>, <table>, <blockquote>, <form>, <button>

Inline elements

By default inline-level elements create a "mini" block within a line of text and do not break up the flow of that line. Inline elements can exist inside block elements, but never the other way around.

<span><div>Never do this!</div></span>

Here, <p> generates a block box, with several inline boxes inside it.

<p>Some <em>emphasized</em> and <span>other</span> text.</p>

Two or more inline elements will stack sideways, starting from the left and extending to the right. If they are wider than the containing element, they will wrap. Inline elements can't be given a width or height. They will only take left and right padding and margins, never top and bottom. Examples of inline-level elements include: <span>, <a>, <strong>, <em>, <img>, <abbr>, <acronym>, <cite>, <small>, <sub>, <textarea>

Conclusion: The good news

Block and inline elements can be styled. We can change:

  • font colors, sizes, families, styles, weights, and more
  • give block elements heights and weights
  • put background colors or images on them
  • move them around the page

Positioning Schemes (Layout)

There are three ways to layout or position a block in CSS:

  • Normal flow: This is the default flow of documents. Boxes are stacked on one another, beginning at the top of a containing block.
  • Floats: A box is first laid out according to the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content may flow along the side of a float.
  • Absolute positioning: A box is removed from the normal flow entirely (it has no impact on later siblings) and assigned a position with respect to a containing block.

Float

You can float elements left or right. They also take the value "none." The odd thing about floats is that, when you float something, it's almost but not entirely removed from the normal flow of the document. Other content "flows around" it. In fact, floats were intended to allow for text to flow around floated elements like images and to float elements side-by-side, such as a horizontal navigation list of block-level li boxes.

Content below will wrap around a floated element, while border, background image and background color will extend underneath.

Floating a block left causes content to flow around it.


From W3C's "Visual formatting model" http://www.w3.org/TR/CSS2/visuren.html

If you don't want a block to wrap, you can apply the clear property to the element using clear: left, clear: right or clear: both.

The second paragraph has a clear: left on it.



From W3C's "Visual formatting model" http://www.w3.org/TR/CSS2/visuren.html

To float two blocks side-by-side, you must make room for them by explicitly stating a width on the blocks. In the example below, putting a width of 50% on both boxes and a float: right on the preceding content box causes the following sidebar box to "flow" around the content box and into the "empty" space.

Floats are often used for layout, but they were not originally intended for that purpose. In fact, that role goes to the CSS property called "position."

Position

All elements have default position value of "static," although this is generally thought of as "unpositioned" and is never really stated because it's default. You can give elements three types of positions: relative, absolute, and fixed. "Position" is a powerful property and can be used to do all kinds of crazy and wonderful things in laying out web pages.

Position: relative

The relative value is actually exactly what it sounds like--elements are positioned top, bottom, right or left relative to their current position. Relatively positioned elements are offset, and the space they would have occupied is retained. In the normal document flow, block boxes stack.

We can reposition the third paragraph relative to its current position in the flow by adding postion: absolute and the properties top and left:

p {position: absolute; top: 20px; left: 20px;}

Notice the fourth paragraph respects the space the third paragraph occupied.

In situations where the size of the blocks is not known, the "relative" position may change. For this reason, relative positioning is good for minor page adjustments, but should probably not be used for major layout.

Position: absolute--The Queen of Layout

Absolutely positioned elements act differently than any normally flowed elements.

With absolute positioning, the top, right, bottom, and left properties are in relation to a parent element. The parent element can be a containing block with a position: anything tag on it. If there's no positioned ancestor element, the parent is the document itself--in most browsers this means the <html> tag.

An element with position:absolute is removed from the document flow. The rest of the document acts as if the element weren’t there. It could easily end up layered over other elements, unless we make sure it doesn’t.

The first absolute positioned div is covered by the second absolute positioned div by default.
Adding a higher z-index to the second absolute positioned div causes it to be positioned higher in the stack.

From "Big John" Gallant's "The difference between 'The Flow' and 'Positioning' for Web Pages" http://bit.ly/aIdZAj

Finally, by default, absolutely positioned elements shrink-to-fit their widths (and heights) around any child elements they may hold.

Resources

Learn from the Best

Layout Repositories

* Google 'css layout' for hundreds more

Using MAMP & VMWare Fusion on a Mac to Test in IE

February 7, 2010

I'm a diehard Mac and Firefox user, and if I were Queen of the Universe, everyone else would be, too. My royal aspirations aside, I realize that I have to take into consideration The Browser That Can't Be Named when developing a site. On average, about 58% of all people are still using some version of TBTCBN. At my place of employment, I'm sorry to say, that number is even higher—up to 68% of ASU's web visitors are poor, misguided souls.

Because I develop locally on a Mac with MAMP, I don't test in TBTCBN as much or as often in the process as I should. Until now. This weekend I discovered a few tricks for MAMP and VMWare Fusion that will make testing in TBTCBN a whole lot easier.

Get MAMP working in VMWare

  1. In VMWare Fusion, go to Virtual Machine > Settings > Network. Make sure your Network settings are set to Bridged.
    VMWare Fusion Network settings
  2. In MAMP, click on Preferences > Ports and check that your MAMP ports are 8888 and 8889.
    MAMP port settings
  3. Find your Mac's IP address. From the Apple, go to About This Mac > More Info... > Network and find the "IPv4 Address." It's usually something like 192.168.xxx.xxx.
  4. Open VMWare and start WIndows. In My Computer, click on Local Disk (c:), and navigate to the file located at C:\WINDOWS\system32\drivers\etc\hosts. Open /hosts using Notepad. You'll see a list of at least a few IPs followed by a site name. Add your Mac's IP address and a name for your site. For instance, I added:
    192.168.0.23 myawesomesite
  5. Now you should be able to open http://myawesomesite:8888 in IE.

I work primarily with Drupal, and this setup works like a dream for me. However, I've read that this may not work with some applications, such as WordPress, which require a a base URI of localhost:8888. Because IE has it's own separate localhost, "localhost:8888" won't work, which is why we renamed it to something else (like myawesomesite).

A couple more tips I picked up along the way that may help streamline your process:

  • Say good-bye to good old MultipleIE. IE8 (yes, I named it) is the only IE you really need if, like me, your organization no longer fully supports IE6 (yay! ASU). The Developer Tools for IE8 allow you to switch your browser mode to IE7, which is pretty nice, considering it's TBTCBN.
  • You can set IE to open when you start your Mac. Open IE in VMWare, and switch to Unity view. The IE icon will appear in your dock. Right-click on the icon and select Keep in Dock and Open at Login.
  • In MAMP, I had a problem with relative paths not working on my local site, which was at http://localhost:8888/myawesomesite. I discovered it's easy to reset the location of your root directory In MAMP. Click on Preferences > Apache, and set your "Document Root" to your site.
    MAMP Apache root directory