Wrox Professional CSS Cascading Style Sheets for Web Design phần 8 pdf

53 390 0
Wrox Professional CSS Cascading Style Sheets for Web Design phần 8 pdf

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Figure 8-5: With our understanding of how the cascade works, we can build even more complexity into our alternate CSS documents. Another Solution We (Almost) Can’t Quite Use As with some of the most promising features of CSS, adoption of alternate style sheets would be more widespread if browser support were more robust. As of this writing, the number of browsers that natively allow users to select alternate style sheets is limited to Gecko-based browsers such as Mozilla or Firefox, and the Opera browser. For example, Apple’s Safari has no way to select alternate or preferred style sheets. And, you guessed it, Internet Explorer (the browser known and loved the world over) won’t allow users to select the alternate user interfaces we build for them. If the world’s most popular browser keeps this feature out of the hands of our users, then we have a bit more work to do yet. 290 Chapter 8 10_588338 ch08.qxd 6/22/05 11:27 AM Page 290 Furthermore, the browsers that do natively support alternate style sheet switching have only a limited switching functionality. While these browsers do allow the user to easily switch between the default CSS and any alternates provided by the author, they do not remember the user’s selection. This means that, if a reader selects an alternate style sheet and then reloads the page or leaves and returns to it, the browser will forget the earlier choice and reinstate the default style. Obviously, neither of these scenarios will work for our users. We’re lucky that there are some additional steps we can take to bring the full benefits of CSS switching to them. The Reality: How It Can Work Today We’ve established that most of our audience won’t be able to use in-browser CSS switching (and identi- fied those who don’t have much functionality available to them) so we must build an interface into our page that allows users to overcome these limitations. Now, you might realize that the two client-side technologies we’ve been studying up to this point aren’t especially well equipped to handle this. While XHTML and CSS excel at describing and styling content, respectively, neither was designed to interact with the user. Sure, we can use XHTML to build a list of links on the page as follows: <div id=”switcher”> <ul> <li id=”style-default”><a href=”styleswitch.html”>Default style</a></li> <li id=”style-contrast”><a href=”styleswitch.html”>Higher Contrast</a></li> <li id=”style-hot”><a href=”styleswitch.html”>Gratuitous CSS</a></li> </ul> </div> And we can add some CSS to core.css (refer to Listing 8-2) to style them accordingly, as shown in Figure 8-6: /* switcher styles */ #switcher ul { text-align: right; list-style: none; } #switcher ul li { border-left: 1px solid; list-style: none; display: inline; padding: 0 0 0 1em; margin: 0 1em 0 0; } #switcher #style-default { border-left: 0; padding-left: 0; } #switcher ul a.now { color: #000; 291 Stuff and Nonsense: Strategies for CSS Switching 10_588338 ch08.qxd 6/22/05 11:27 AM Page 291 font-weight: bold; text-decoration: none; } /* END switcher styles */ Figure 8-6: We’ve added the links for our switcher to the top of our page, but all they can do at the moment is look pretty — and we’re about to change that. However, what happens when the user clicks on those links? If your answer was something akin to “zilch,” then you win the blue ribbon. XHTML and CSS can’t really do anything when you’re talking about responding to a user’s actions. They can, in turn, affect the content and the presentation of the page, but when the user tries to click a link to change the active style sheet, that’s where we need to turn to the third tool in the standards-savvy designer’s toolkit: JavaScript. Jumping on the JavaScript Bandwagon To put it simply, JavaScript was created as a client-side scripting language. JavaScript (or JS, to use the parlance of lazy typists everywhere) is a language designed to add a layer of interactivity into our Web pages. When a user visits a Web page that has some JavaScript code in it, the browser reads the JS, and then follows any instructions that might be contained therein. Those instructions might tell the browser to display helpful messages to a user as he or she completes a form, or to perform basic validation on the data he or she enters there. We can even use JS to instruct the browser to perform a certain action when the user clicks a link. In short, JavaScript is the means through which we bridge the divide between our content and our users, allowing the latter to fully interact with the former. Sounds intimidating (and more than a little stuffy), doesn’t it? Perhaps it’d be best to just dive right in. 292 Chapter 8 10_588338 ch08.qxd 6/22/05 11:27 AM Page 292 Gathering Requirements Before we begin a lick of coding, we should make sure that we understand exactly what it is that we’re building. Just as we discussed the benefits of requirements gathering to a client project in Chapter 1, the smallest development gig can benefit from some sort of needs analysis. With a better understanding of what we need to build and the goals that what we are building should achieve, we can code more quickly and efficiently— two qualities that will make our clients and us quite happy. So let’s take a quick inventory of what we’re working with: ❑ We have three link elements in the head of our XHTML document that include screen-specific CSS files: a persistent style sheet ( main.css), and two alternate style sheets (contrast.css in Listing 8-4 and the ultra-swank hot.css in Listing 8-5). ❑ Accordingly, at the top of our document we’ve created a list of three anchors, each correspond- ing to a different style sheets. Granted, these anchors are about as useful as a road map in the desert, but we’re going to change that shortly. With this in mind, what exactly should our function do? Ideally, when a user clicks a link: 1. The function should cycle through each of the link elements in the head of our XHTML, and inspect those that link to style sheets and have a title. 2. If the link matches the link that the user selected, then it should be set to be the “active” CSS. 3. Otherwise, the link should be set to “disabled,” which will prevent the browser from loading the style sheet. 4. Once the function has finished setting the active link element, it should remember the user’s choice. The style sheet the user selected will, therefore, remain “active” as the user browses through the site, and the choice will be remembered if the user returns to our site during a later browsing session. How, you may ask, will we do all of this? Well, the solution ultimately involves a fair amount of pixie dust and happy thoughts — but we shouldn’t get too far ahead of ourselves. Building the Switching Function With our goals firmly in mind, we can begin building our style sheet functions. Let’s create a new file called scripts.js, and include the following markup in the head of our XHTML document: <script type=”text/javascript” src=”scripts.js”></script> Much as we’re using the link element to include external CSS files for our site’s presentation, we can use the script element to reference an external JavaScript file. And, in that file, we can write in the first lines that will power our CSS switcher. If JavaScript syntax looks a bit intimidating, don’t worry. We’ll simply touch on some of the highlights, and get back to that “Professional CSS” malarkey as quickly as possible. // activeCSS: Set the active stylesheet function activeCSS(title) { var i, oneLink; for (i = 0; (oneLink = document.getElementsByTagName(“link”)[i]); i++) { if (oneLink.getAttribute(“title”) && findWord(“stylesheet”, oneLink.getAttribute(“rel”))) { 293 Stuff and Nonsense: Strategies for CSS Switching 10_588338 ch08.qxd 6/22/05 11:27 AM Page 293 oneLink.disabled = true; if (oneLink.getAttribute(“title”) == title) { oneLink.disabled = false; } } } } // findWord: Used to find a full word (needle) in a string (haystack) function findWord(needle, haystack) { return haystack.match(needle + “\\b”); } In this code snippet, we have two JavaScript functions, which are basically discrete chunks of functionality. The two functions we’re looking at here are activeCSS() and findWord(). Each function contains a series of instructions that are passed to the browser for processing. For example, when activeCSS is invoked, it performs the following tasks: 1. It assembles a list of all link elements in our document (document .getElementsByTagName(“link”) ), and proceeds to loop through them. 2. For each link element found, it checks to see if there is a title available, and then evaluates the rel attribute to see if the word “stylesheet” is present. The findWord() function is used here to search the rel for a whole-word match only. This means that if someone accidentally types rel=”stylesheets” or the like into their link element, our function ignores them. 3. Each link that meets the criteria in Step 2 will be disabled (oneLink.disabled = true;). 4. When the function is first invoked, an argument (or variable) is passed with the title of the desired “active” style sheet. So, as the function loops through each of the link elements, it checks to see if the title of the link matches the title of the function’s argument. If so, the link element is reactivated. Admittedly, this is a bit of a gloss of the functions’ syntax. JavaScript is a robust and rewarding language, but we’re nonetheless forced to breeze through some of its subtleties to get back on the CSS track. However, the preceding list demonstrates the high-level concepts at play in the code we’ve created, and should provide a fine starting point for those interested in further exploring JavaScript’s elegant syntax. While these two functions enable us to switch our CSS, they simply lie dormant until they are invoked (or called) by our markup. Because we want our switcher to fire when a user selects a link from our #switcher list, the easiest place to do so is within the anchors of our style switcher list: <div id=”switcher”> <ul> <li id=”style-default”><a href=”styleswitch.html” onclick=”activeCSS(‘default’); return false”>Default style</a></li> <li id=”style-contrast”><a href=”styleswitch.html” onclick=”activeCSS(‘Higher Contrast’); return false”>Higher Contrast</a></li> <li id=”style-hot”><a href=”styleswitch.html” onclick=”activeCSS(‘Gratuitous CSS’); return false”>Gratuitous CSS</a></li> </ul> </div> 294 Chapter 8 10_588338 ch08.qxd 6/22/05 11:27 AM Page 294 The onclick attribute we’ve introduced here is called an event handler. When the user performs a certain action or “event” (such as, in this case, a mouse click), the JavaScript contained in the attribute value is fired. So, in the preceding example, the onclick handler will detect when a user clicks on the anchor, and will in turn fire the activeCSS() function. Strictly speaking, you could argue that use of these event handlers, such as onclick, onblur, onmouseover, and so on, is analogous to relying on the style attribute— that these inline attributes blur the separation of structure and behavior, and can easily increase the cost of maintenance and sup- port. Rather than editing our XHTML to reflect any changes in the JavaScript, it would instead be possible to use more modern JS to automatically generate the event handlers our links will need, and, therefore, keep the necessary divide between our markup and our scripting. For more information, we recommend Peter-Paul Koch’s “Separating behavior and structure” ( http://digital-web.com/ articles/separating_behavior_and_structure_2/ ). However, as we look closely at the three different event handlers, we can see that each reference to activeCSS() differs slightly. Between the parentheses, we’ve included the title of the style sheet the link should activate. This is the argument we mentioned earlier and is the string of text that the activeCSS() function compares to the title of each link element. You may have noticed that after the call to the activeCSS() function, the onclick handler contains some additional text: return false;. This plays a very small (but integral) part in our switcher because it tells the handler not to follow the URL referenced in the anchor’s href attribute. Otherwise, the user would end up deposited on styleswitch.html after clicking any of the links. So, let’s do a bit of role-playing. Let’s just run through the steps that occur when we click a link. For argument’s sake (oh, aren’t we clever), let’s assume that our user selects the third anchor, the onclick handler that contains the activeCSS(‘Gratuitous CSS’); reference: 1. The three link elements are compiled into an array, and the function proceeds to loop over each of them. Remember that only those links that contain titles and that have a rel attribute that contains the word “stylesheet” will be examined. This leaves us with the links for contrast.css (refer to Listing 8-4) and hot.css (refer to Listing 8-5). 2. The first link element has a title of “Higher Contrast.” The function disables the link element. Because its title doesn’t match our function’s argument (“Gratuitous CSS”), it stays disabled. 3. The second link element has a title of “Gratuitous CSS.” The function disables the link element. Because the title does match our function’s argument, the link is immediately reactivated. And voilà! As you can see in Figure 8-7, we’ve completed the effect. Clicking each anchor activates the alternate style sheet whose title matches the one referenced in the activeCSS() function call. However, even though we’ve successfully built a function to switch between the different CSS files, we’re only halfway there. If the user refreshes the page or leaves the current one after selecting a new alternate style sheet, the choice is forgotten, and the default style sheet is restored. So, obviously, we’ve a bit more work to do. Let’s see if we can’t put a little memory into our JavaScript functions. 295 Stuff and Nonsense: Strategies for CSS Switching 10_588338 ch08.qxd 6/22/05 11:27 AM Page 295 Figure 8-7: With our JavaScript-enabled style switcher in place, our users can now select a look that best suits their needs. Baking a JavaScript Cookie As you’ve seen with our not-quite-finished CSS switcher, our browsers don’t seem to remember any- thing about a page once we’ve left or refreshed it. This is by design. The HTTP standard (which is the protocol over which the Web’s pages are transferred from a server to your desktop) was designed to be “stateless.” This means that each time you visit a page, the Web server considers it to be your first time, every time. Thankfully, we have a way to fill this memory gap. It’s called a cookie, and it’s less fattening than its baked namesake. A cookie is a small text file that is sent by a Web server to a user’s browser, and contains small bits of important information about that user’s browsing session. Cookies may contain user preferences, regis- tration information, or the items placed in an online shopping cart, and so on. Once it receives a cookie, the browser saves the information on the user’s computer, and sends it back to the Web server whenever the user returns to that Web site. We’re not just flapping our gums here. We’re mentioning cookies because we can use JavaScript to set and read them. So, armed with this knowledge, we can finally see our way to the finish line. By adding a few more JavaScript functions to those we’ve already written, we can build an improved style sheet switcher, and one that will respect our user’s preferences across multiple pages, or visits to, our site. 296 Chapter 8 10_588338 ch08.qxd 6/22/05 11:27 AM Page 296 From this, we need two tools in our cookie-baking toolkit (we can mix metaphors with the best of them). We need to be able to set a cookie containing our user’s style preference, and to then later read the cookie. So, let’s add a new cleverly named function to our scripts.js file, setCookie(): // Set the cookie function setCookie(name,value,days) { if (days) { var date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); var expires = “;expires=”+date.toGMTString(); } else { expires = “”; } document.cookie = name+”=”+value+expires+”;”; } And now, in our original activeCSS() function, we can add a single line to store our user’s preferences in a cookie on the user’s computer: // Set the active stylesheet function activeCSS(title) { var i, oneLink; for (i = 0; (oneLink = document.getElementsByTagName(“link”)[i]); i++) { if (oneLink.getAttribute(“title”) && findWord(“stylesheet”, oneLink.getAttribute(“rel”))) { oneLink.disabled = true; if (oneLink.getAttribute(“title”) == title) { oneLink.disabled = false; } } } setCookie(“mystyle”, title, 365); } With this one line, half of our work is finished! The setCookie() function accepts three arguments: a name for the cookie (so that we might later reference it), the value to be stored in the cookie, and the number of days until the cookie expires. So, in the previous code snippet, we’ve created a cookie named “mystyle”, the value of which is set to the value of the title argument of activeCSS(). This means that if a user selects a link that specifies activeCSS(‘Higher Contrast’) in its onclick handler (that is, it invokes activeCSS with a title argument of Higher Contrast), then our “mystyle” cookie will, therefore, have a value of Higher Contrast. In our setCookie() function, specifying the number of days until cookie expiration is optional. The latter argument is optional. In the preceding example, we’ve arbitrarily decided to set the “mystyle” cookie to expire in 365 days, or one calendar year. Because the argument is optional, we could leave it out entirely. However, omitting it will cause the setCookie() function to create a “mystyle” cookie that expires at the end of the user’s session — causing the user’s preference to be lost as soon as he or she closes the browser. 297 Stuff and Nonsense: Strategies for CSS Switching 10_588338 ch08.qxd 6/22/05 11:27 AM Page 297 So, with this lone call to setCookie(), we’ve managed to store the user’s selection from our list of style sheet anchors. But now that we’ve stored it, how do we read the cookie and honor the preference? Well, once we place the following lines in our scripts.js file, it would seem that the answer is, “simply enough”: window.onload = initCSS; // initCSS: If there’s a “mystyle” cookie, set the active stylesheet when the page loads function initCSS() { var style = readCookie(“mystyle”); if (style) { activeCSS(style); } } // Read the cookie function readCookie(name) { var needle = name + “=”; var cookieArray = document.cookie.split(‘;’); for(var i=0;i < cookieArray.length;i++) { var pair = cookieArray[i]; while (pair.charAt(0)==’ ‘) { pair = pair.substring(1, pair.length); } if (pair.indexOf(needle) == 0) { return pair.substring(needle.length, pair.length); } } return null; } With these last lines of JavaScript in place, we’re finally finished. Our new function, initCSS(), has two simple tasks. First, it checks to see if there is a “mystyle” cookie on the user’s machine (var style = readCookie(“mystyle”); ). If one is present (if (style)), then the activeCSS() function is invoked with the value of the user’s cookie as its argument. But it’s the first line of this code snippet that does the heavy lifting, even though it looks rather innocu- ous. window.onload = initCSS; fires our initCSS() function when the document finishes loading in the user’s browser. Now, as the user moves between the pages of our site (hypothetical though they may be), or when the user returns during a later session, we can immediately poll for the presence of a “mystyle” cookie as each of our pages comes up. As the user makes selections from our style switcher, our pages will honor them, allowing the user to tailor not only individual pages, but an entire site to his or her browsing needs. Listing 8-6 shows the complete JavaScript file. 298 Chapter 8 10_588338 ch08.qxd 6/22/05 11:27 AM Page 298 Listing 8-6: The Complete scripts.js File That Powers Our JavaScript-Enabled CSS Switcher /* Onload */ window.onload = initCSS; // initCSS: If there’s a “mystyle” cookie, set the active stylesheet when the page loads function initCSS() { var style = readCookie(“mystyle”); if (style) { activeCSS(style); } } /* Switcher functions */ // activeCSS: Set the active stylesheet function activeCSS(title) { var i, oneLink; for (i = 0; (oneLink = document.getElementsByTagName(“link”)[i]); i++) { if (oneLink.getAttribute(“title”) && findWord(“stylesheet”, oneLink.getAttribute(“rel”))) { oneLink.disabled = true; if (oneLink.getAttribute(“title”) == title) { oneLink.disabled = false; } } } setCookie(“mystyle”, title, 365); } // findWord: Used to find a full word (needle) in a string (haystack) function findWord(needle, haystack) { var init = needle + “\\b”; return haystack.match(needle + “\\b”); } /* Cookie functions */ // Set the cookie function setCookie(name,value,days) { if (days) { var date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); var expires = “;expires=”+date.toGMTString(); } else { expires = “”; (continued) 299 Stuff and Nonsense: Strategies for CSS Switching 10_588338 ch08.qxd 6/22/05 11:27 AM Page 299 [...]... aspects of Web standards is the ability for designers to work on presentations through CSS without changing the underlying markup (HTML or XHTML) of a Web page Nowhere is this demonstrated better than on Dave Shea’s CSS Zen Garden (www.csszengarden com/), where we see different designs of the same page made possible through using CSS style sheets “Switching” style sheets can be necessary for all sorts... media type: namely, “print”: When we try printing... XHTML for a little PHP-fu Once we’ve changed the file extension, we can insert the following code in the head of our document: . “simply enough”: window.onload = initCSS; // initCSS: If there’s a “mystyle” cookie, set the active stylesheet when the page loads function initCSS() { var style = readCookie(“mystyle”); if (style) { activeCSS (style) ; } } //. needs. Listing 8- 6 shows the complete JavaScript file. 2 98 Chapter 8 10_ 588 3 38 ch 08. qxd 6/22/05 11:27 AM Page 2 98 Listing 8- 6: The Complete scripts.js File That Powers Our JavaScript-Enabled CSS Switcher /* Onload */ window.onload. Switcher /* Onload */ window.onload = initCSS; // initCSS: If there’s a “mystyle” cookie, set the active stylesheet when the page loads function initCSS() { var style = readCookie(“mystyle”); if (style) { activeCSS (style) ; } } /* Switcher

Ngày đăng: 08/08/2014, 20:22

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan