Showing posts with label html. Show all posts
Showing posts with label html. Show all posts

Monday, March 02, 2009

Super Easy Fast-Forward Reverse Carousel with YUI 3!

I've been mucking with YUI 3 and playing around with carousels using their Animation Utility. If you don't know what a carousel is, here's a suggested reading. Our carousel is a little different. Ours rewinds when we reach the end or fast-forwards when we're on the first and go to the last element. We come up with something like this --



Play with it. It'll work on all the big browsers -- IE, FF, Safari and Opera. Think of the carousel as a queue with a start and an end. So, all we're doing is traversing the queue from the front to the end and back again. It's a simple exercise which we probably did in Data Structures 101!

Go ahead and view the source. The code is easy to understand and it'll just be another YUI 3 example.


There are several important points to remember. We'll use an HTML template to represent the carousel. Our JavaScript will reference this for the animation --
            <div class="view-port">
<ul class="carousel">

<li>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</li>

<li>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</li>

<li>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
</li>

<li>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
</li>

<li>
<div>17</div>
<div>18</div>
<div>19</div>
<div>20</div>
</li>

<li>
<div>21</div>
<div>22</div>
<div>23</div>
<div>24</div>
</li>

</ul>
</div>
We've grouped our items -- this is the unordered list -- and each group represents the "viewable" area and each list contains content. Content of course can be anything -- a div, another list, an image, a table or a collection of all those things. It's the unordered list with the class name "carousel" that we'll be animating. The important thing to remember is that we can easily calculate the width of each list by using the element's "offsetWidth" property. There's no need to hardcode anything. This is the width of the viewable area and this is also the distance which we'll move by. If we view the source, this is the variable WINDOW_WIDTH.

Another thing that we're doing is that we never set the animation object's "from" attribute. This is because "from" is implicit. Once we move to a position, we know where we're at ( obviously! ). We just need to specify where we want to move and so throughout the animation, we just set the "to" attribute. In reality, we can always get our current position by calling the method getX() on the element that we're moving.
                function scrollLeft() {

if (_currentIndex === _startIndex) {

_currentXPosition = -1 * WINDOW_WIDTH * (TOTAL_PAGES - 1) + _carousel.getX();
_currentIndex = TOTAL_PAGES - 1;

} else {

_currentXPosition = _carousel.getX() + WINDOW_WIDTH;
--_currentIndex;

}

}

where _carousel is the unordered list that we're moving.

That's it. It's pretty straightforward and easy. Feel free to use the code and have fun!

Sunday, October 26, 2008

Don't Ever Put Block Inside Inline Elements

It's been incredibly busy at work so I haven't blogged at all in over two months.

I did discover something which may seem obvious to you, but is worth repeating. Don't ever put block elements inside inline elements. If you do, in most cases, nothing bad will happen. If you do, watch out. It's better not to do it. Here's what the W3C spec says.
Probably many of us do it anyways and it seems to work, but it's "go
to hell" incorrect. Block elements visually begin on a new line.
They can contain inline and other block-level elements ( div, p, ul,
etc. ). Inline elements visually don't begin on a new line. They
contain only text and other inline elements ( span, a, img, etc. ).

Take this example of the two Colas --



Visually, they look identical, but study the HTML and you'll see that they're constructed differently.

Block in Inline Element
<a href="#">
<img src="./captainColaHeadShot.jpg">
<div class="title">Cola the Yorkie BAD</div>
<div>Inline containing a block element. This is bad!</div>
</a>

Inline in Block Element
<a href="#">
<img src="./captainColaHeadShot.jpg">
<span class="title">Cola the Yorkie GOOD</span>
<span>Inline containing an inline element. This is good!</span>
</a>
So, what's the big deal? After all, it works. Well, sort of.

You'll need a couple of things to see what I mean. First, you'll need to run the example in Firefox 2.x or 3.x, but before you do that make sure you've installed Firebug. Now, using Firebug, inspect and edit the text "Inline containing a block element. This is bad!" that's found in the div. Just type in some additional text like "Hello world!" or just anything. Now, inspect the div. You'll notice that the text is now contained inside an anchor tag which is inside the div! What happened?

I'm not sure, but I think Firefox attempts to correct the HTML by putting an inline inside a block-level element ( here's a really good writeup on invalid markup funkiness among the browsers ). If you try the same thing ( editing the text for "Inline containing a block element. This is good!" ), you won't observe this problem. This is because the markup is correct -- we've got a block-level element containing an inline element.

So, in my real job I saw this funkiness happen. Every once in a blue moon on page refresh, the text would be found in an mysterious anchor tag creating an ugly "blown" up visual. Correcting the markup fixed this problem for good.

You might be wondering what's the difference between a block-level element ( <div> ) and using CSS to make an inline element a block-level element ( <span style="display:block;"> ).

If an element by default -- like a div -- is a block-level element then it cannot be placed inside an inline element. However, an inline element made into a block-level element via CSS can be placed inside an inline element. This is because the style that's applied is irrelevant to the correctness of the markup. In other words, styling is our stated intention for what the element should look like and that's completely separate from valid markup.

Have fun!

Monday, June 30, 2008

On the Importance of Clearing Floats

I've been doing a lot of work with the Big Three of web development -- HTML, CSS and JavaScript. Prior to Yahoo!, I had done a lot of work with Bindows, a powerful "do everything" JavaScript framework. You built your entire web application with Bindows. You never manipulated HTML or CSS directly. It was all abstracted for you with their API.

I loved working with Bindows. It allowed me to improve my JavaScript skills and to build some really cool prototypes. Unfortunately, one of the niceties of Bindows -- that of abstraction and protecting you from the details of HTML and CSS -- turned out to be a real detriment for me.

My HTML and CSS skills suffered, but more importantly, to really fine tune the layout, you have to have access to the underlying structure and presentation layer.

Even some of the most basic and important concepts such as the importance of using and clearing floats weren't etched into my brain until I stepped foot at Yahoo!. I had read about it, understood enough to recognize it ( at least pass the interview ), but it wasn't until I really started doing hardcore development that I realized that to control layout means to control how things flow on the page and that meant understanding how to float and clear elements.

In fact, understanding floats is probably THE most important thing that you need to know when using HTML and CSS. Arguably, there are a bunch of other things that are also important such as knowing how to invoke hasLayout for IE, but I've found that a lot of the layout problems can be fixed by knowing when to clear floats.

When you float an element, you position an element to the left or right of another element. It's a very effective and fundamental way to position elements. Here's an example.

We're floating only two elements. The first is the entire "Left Side" div. It's floated to the left of the "Right Side" div. The second, is the image of Cola, the Yorkshire Terrier. That's floated to the left of the descriptive text. Everything is nicely formatted in Firefox, Safari, Opera and IE7 ( I haven't tried IE6, but it should work there as well ).

If you use Firebug, you'll see that we "clear floats" in three places --
  • At the container level -- this is the div with class "container" that contains the "Left Side" and the "Right Side" divs
  • The "Right Side" div -- this is the div with the class "right-stories"
  • The list element found inside the "Right Side" div
When we clear floats we put elements back into the flow so that they don't flow outside of the layout. There are many ways to clear floats, but the easiest way that I've found is to set the CSS property overflow to hidden. A good writeup of that technique is found here. It's found near the end.

So using Firebug, look for "overflow:hidden" and disable all of it. The elements overrun their borders and resembles a jumbled mish-mash of elements and seem to defy the box model. Here it is.

Whenever you observe strange layout like that, make sure that you're clearing your floats. Remember, floated elements come out of the flow so adjacent or containing elements need to set overflow so that all elements fall back into position. Think of setting overflow:hidden as getting all the misbehaving elements back into line.

Note that you can observe this visually, but you can also use Firebug and inspect the element. Hover over the element and if that element overlays another, that element is out of the flow. If you can identify and fix float issues, you'll be King for a Day!

Have fun!

Wednesday, January 30, 2008

Dashing All the Way... Not

In programming, nothing ever just happens. There aren't any gremlins or magical incantations that cause code to work. Programming is about logic and good sound reasoning. If your code doesn't work, there's a really good explanation. The challenge is finding that explanation.

As a web developer, you someti
mes see really weird problems like the one I saw today.

In HTML, how do you add a comment?

You'd do this --

<!-- This is a comment -->


and you'd be right of course, but what if you did this --

<!-- This is a comment -- at least I think it is! -->


Is that a comment? Well, sort of. In the HTM
L 4.0 specification, "--" or two hyphens is considered the comment close delimiter whereas ">" is considered to be the markup declaration close delimiter.

Here's the explanation directly from the spec --

White space is not permitted between the markup declaration open delimiter(""). A common error is to include a string of hyphens ("---") within a comment. Authors should avoid putting two or more adjacent hyphens inside comments.

Information that appears between comments has no special meaning (e.g., character references are not interpreted as such).

Note that comments are markup.

So, what actually happens when you use the hypens in the middle of a comment? Here's an example --



If you're using Firefox, you'd see this --

The comments are visible. On any other browser, IE, Safari or Opera, you'd see a normal page --

So, using hyphens in an HTML comment breaks pages on Firefox. Keep that in mind the next time you put in a comment.

Note that in our example, we're specifying a HTML 4.01 DTD. We're using a "strict" DTD, but the problem would still occur if you'd specify a "transitional" or "frameset" DTD.

If you don't specify the HTML 4.01 DTD, you won't see this problem in Firefox.

Additional information and discussion is found on Ben Buchanan's the 200ok weblog.

Have fun!