CSS3+jQuery实现Win8风格的方格状菜单,注意,IE6到IE8不支持本代码,最好使用火狐测试看效果。可看到方格状的菜单,如果鼠标移上菜单并单击,该菜单项会放大显示至整个菜单区域,除了CSS3代码外,本效果还加入了jQuery和Js代码进行控制,代码稍嫌繁杂
代码如下所示:
复制代码代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>用CSS3实现Win8风格的方格导航菜单效果</title> <style> #about { color: #999; text-align: center; font: 0.9em Arial, Helvetica; } #about a { color: #777; } .menu { width: 620px; margin: 100px auto; padding: 15px; list-style: none; counter-reset: li; background: #eee; -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, .1) inset; -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .1) inset; box-shadow: 0 1px 2px rgba(0, 0, 0, .1) inset; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; } .menu:before, .menu:after { content: ""; display: table; } .menu:after { clear: both; } .menu { zoom:1; } /* -------------------------------- */ </p>
<p>.menu li { position: relative; float: left; cursor: pointer; height: 120px; width: 200px; margin: 10px 0 0 10px; color: #fff; } .menu li:hover, .menu li:focus { background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, .2)), to(rgba(255, 255, 255, 0))); background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, .2), rgba(255, 255, 255, 0)); background-image: -moz-linear-gradient(top, rgba(255, 255, 255, .2), rgba(255, 255, 255, 0)); background-image: -ms-linear-gradient(top, rgba(255, 255, 255, .2), rgba(255, 255, 255, 0)); background-image: -o-linear-gradient(top, rgba(255, 255, 255, .2), rgba(255, 255, 255, 0)); background-image: linear-gradient(top, rgba(255, 255, 255, .2), rgba(255, 255, 255, 0)); } .menu .cover { z-index: 2; } .menu .cover:focus { outline: 0; }</p>
<p>/* -------------------------------- */</p>
<p>.menu li::after { content: counter(li); counter-increment: li; font: italic bold 10px serif, georgia; position: absolute; color: rgba(255, 255, 255, .1); opacity: 0; -webkit-transition: all .2s ease-out; -moz-transition: all .2s ease-out; -ms-transition: all .2s ease-out; -o-transition: all .2s ease-out; transition: all .2s ease-out; } .menu li:hover::after, .menu li:focus::after { font-size: 100px; opacity: 1; } .menu .cover::after { z-index: -1; }</p>
<p>/* -------------------------------- */ </p>
<p>.menu li:nth-child(1), .menu li:nth-child(2), .menu li:nth-child(3) { margin-top: 0; } .menu li:nth-child(1), .menu li:nth-child(4), .menu li:nth-child(7) { margin-left: 0; }</p>
<p>/* -------------------------------- */ </p>
<p>.menu li:nth-child(1), .menu li:nth-child(1) .content, .menu li:nth-child(1) .close { background-color: #2c618f; } .menu li:nth-child(2), .menu li:nth-child(2) .content, .menu li:nth-child(2) .close { background-color: #91ab31; } .menu li:nth-child(3), .menu li:nth-child(3) .content, .menu li:nth-child(3) .close { background-color: #714a28; } .menu li:nth-child(4), .menu li:nth-child(4) .content, .menu li:nth-child(4) .close { background-color: #e58600; } .menu li:nth-child(5), .menu li:nth-child(5) .content, .menu li:nth-child(5) .close { background-color: #c33a00; } .menu li:nth-child(6), .menu li:nth-child(6) .content, .menu li:nth-child(6) .close { background-color: #7f5dac; } .menu li:nth-child(7), .menu li:nth-child(7) .content, .menu li:nth-child(7) .close { background-color: #5672b7; } .menu li:nth-child(8), .menu li:nth-child(8) .content, .menu li:nth-child(8) .close { background-color: #69003f; } .menu li:nth-child(9), .menu li:nth-child(9) .content, .menu li:nth-child(9) .close { background-color: #393043; } /* -------------------------------- */</p>
<p>.menu .content { opacity: 0; display: none\9; overflow: hidden; font: 12px Arial, Helvetica; position: absolute; height: 120px; width: 200px; /* Ideally: height: 100%; width: 100%; but works at it should just in FF */ -webkit-transition: all .3s ease-out; -moz-transition: all .3s ease-out; -ms-transition: all .3s ease-out; -o-transition: all .3s ease-out; transition: all .3s ease-out; } .menu .expanded { opacity: .95; display: block\9; overflow: visible; padding: 40px; height: 300px; width: 540px; /* Cover the entire area */ } .menu li:nth-child(3n) .content { /* 3,6,9 */ right: 0; } .menu li:nth-child(3n-1) .expanded { /* 2,5,8 */ left: 50%; margin-left: -310px; } .menu li:nth-child(7) .content, /* 7,8,9 */ .menu li:nth-child(8) .content, .menu li:nth-child(9) .content { bottom: 0; } .menu li:nth-child(4) .expanded, /* 4,5,6 */ .menu li:nth-child(5) .expanded, .menu li:nth-child(6) .expanded { margin-top: -190px; top: 50%; } /* -------------------------------- */ </p>
<p>.menu .title { position: absolute; height: 100%; width: 100%; text-align: center; font: italic bold 1em/120px 'trebuchet MS', Arial, helvetica; opacity: .2; } .menu li:hover .title { opacity: .7; } /* -------------------------------- */</p>
<p>.menu .close { display: none; border: 5px solid #fff; color: #fff; cursor: pointer; height: 40px; width: 40px; font: bold 20px/40px arial, helvetica; position: absolute; text-align: center; top: -20px; right: -20px; -moz-border-radius: 40px; -webkit-border-radius: 40px; border-radius: 40px; } .menu .cover .close { display: block; } </style> <script src="http://demo.jb51.net/jslib/jquery/jquery-1.7.1.min.js"></script> <!--[if (gte IE 6)&(lte IE 8)]> <script> (function(win) { if (/*@cc_on!@*/true) return; var doc = document; var root = doc.documentElement; var xhr = getXHRObject(); var ieVersion = /MSIE (\d+)/.exec(navigator.userAgent)[1]; if (doc.compatMode != 'CSS1Compat' || ieVersion<6 || ieVersion>8 || !xhr) { return; } var selectorEngines = { "NW" : "*.Dom.select", "MooTools" : "$$", "DOMAssistant" : "*.$", "Prototype" : "$$", "YAHOO" : "*.util.Selector.query", "Sizzle" : "*", "jQuery" : "*", "dojo" : "*.query" };</p>
<p> var selectorMethod; var enabledWatchers = []; // array of :enabled/:disabled elements to poll var ie6PatchID = 0; // used to solve ie6's multiple class bug var patchIE6MultipleClasses = true; // if true adds class bloat to ie6 var namespace = "slvzr"; // Stylesheet parsing regexp's var RE_COMMENT = /(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*/g; var RE_IMPORT = /@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))[^;]*;/g; var RE_ASSET_URL = /\burl\(\s*(["']?)(?!data:)([^"')]+)\1\s*\)/g; var RE_PSEUDO_STRUCTURAL = /^:(empty|(first|last|only|nth(-last)?)-(child|of-type))$/; var RE_PSEUDO_ELEMENTS = /:(:first-(?:line|letter))/g; var RE_SELECTOR_GROUP = /(^|})\s*([^\{]*?[\[:][^{]+)/g; var RE_SELECTOR_PARSE = /([ +~>])|(:[a-z-]+(?:\(.*?\)+)?)|(\[.*?\])/g; var RE_LIBRARY_INCOMPATIBLE_PSEUDOS = /(:not\()?:(hover|enabled|disabled|focus|checked|target|active|visited|first-line|first-letter)\)?/g; var RE_PATCH_CLASS_NAME_REPLACE = /[^\w-]/g; // HTML UI element regexp's var RE_INPUT_ELEMENTS = /^(INPUT|SELECT|TEXTAREA|BUTTON)$/; var RE_INPUT_CHECKABLE_TYPES = /^(checkbox|radio)$/;</p>
<p> // Broken attribute selector implementations (IE7/8 native [^=""], [$=""] and [*=""]) var BROKEN_ATTR_IMPLEMENTATIONS = ieVersion>6 ? /[\$\^*]=(['"])\1/ : null;</p>
<p> // Whitespace normalization regexp's var RE_TIDY_TRAILING_WHITESPACE = /([(\[+~])\s+/g; var RE_TIDY_LEADING_WHITESPACE = /\s+([)\]+~])/g; var RE_TIDY_CONSECUTIVE_WHITESPACE = /\s+/g; var RE_TIDY_TRIM_WHITESPACE = /^\s*((?:[\S\s]*\S)?)\s*$/; // String constants var EMPTY_STRING = ""; var SPACE_STRING = " "; var PLACEHOLDER_STRING = "$1"; function patchStyleSheet( cssText ) { return cssText.replace(RE_PSEUDO_ELEMENTS, PLACEHOLDER_STRING). replace(RE_SELECTOR_GROUP, function(m, prefix, selectorText) { var selectorGroups = selectorText.split(","); for (var c = 0, cs = selectorGroups.length; c < cs; c++) { var selector = normalizeSelectorWhitespace(selectorGroups[c]) + SPACE_STRING; var patches = []; selectorGroups[c] = selector.replace(RE_SELECTOR_PARSE, function(match, combinator, pseudo, attribute, index) { if (combinator) { if (patches.length>0) { applyPatches( selector.substring(0, index), patches ); patches = []; } return combinator; } else { var patch = (pseudo) ? patchPseudoClass( pseudo ) : patchAttribute( attribute ); if (patch) { patches.push(patch); return "." + patch.className; } return match; } } ); } return prefix + selectorGroups.join(","); }); }; function patchAttribute( attr ) { return (!BROKEN_ATTR_IMPLEMENTATIONS || BROKEN_ATTR_IMPLEMENTATIONS.test(attr)) ? { className: createClassName(attr), applyClass: true } : null; }; function patchPseudoClass( pseudo ) { var applyClass = true; var className = createClassName(pseudo.slice(1)); var isNegated = pseudo.substring(0, 5) == ":not("; var activateEventName; var deactivateEventName; if (isNegated) { pseudo = pseudo.slice(5, -1); } var bracketIndex = pseudo.indexOf("(") if (bracketIndex > -1) { pseudo = pseudo.substring(0, bracketIndex); } // check we're still dealing with a pseudo-class if (pseudo.charAt(0) == ":") { switch (pseudo.slice(1)) {</p>
<p> case "root": applyClass = function(e) { return isNegated ? e != root : e == root; } break;</p>
<p> case "target": // :target is only supported in IE8 if (ieVersion == 8) { applyClass = function(e) { var handler = function() { var hash = location.hash; var hashID = hash.slice(1); return isNegated ? (hash == EMPTY_STRING || e.id != hashID) : (hash != EMPTY_STRING && e.id == hashID); }; addEvent( win, "hashchange", function() { toggleElementClass(e, className, handler()); }) return handler(); } break; } return false; case "checked": applyClass = function(e) { if (RE_INPUT_CHECKABLE_TYPES.test(e.type)) { addEvent( e, "propertychange", function() { if (event.propertyName == "checked") { toggleElementClass( e, className, e.checked !== isNegated ); } }) } return e.checked !== isNegated; } break; case "disabled": isNegated = !isNegated;</p>
<p> case "enabled": applyClass = function(e) { if (RE_INPUT_ELEMENTS.test(e.tagName)) { addEvent( e, "propertychange", function() { if (event.propertyName == "$disabled") { toggleElementClass( e, className, e.$disabled === isNegated ); } }); enabledWatchers.push(e); e.$disabled = e.disabled; return e.disabled === isNegated; } return pseudo == ":enabled" ? isNegated : !isNegated; } break; case "focus": activateEventName = "focus"; deactivateEventName = "blur"; case "hover": if (!activateEventName) { activateEventName = "mouseenter"; deactivateEventName = "mouseleave"; } applyClass = function(e) { addEvent( e, isNegated ? deactivateEventName : activateEventName, function() { toggleElementClass( e, className, true ); }) addEvent( e, isNegated ? activateEventName : deactivateEventName, function() { toggleElementClass( e, className, false ); }) return isNegated; } break; default: if (!RE_PSEUDO_STRUCTURAL.test(pseudo)) { return false; } break; } } return { className: className, applyClass: applyClass }; }; function applyPatches(selectorText, patches) { var elms; var domSelectorText = selectorText.replace(RE_LIBRARY_INCOMPATIBLE_PSEUDOS, EMPTY_STRING); if (domSelectorText == EMPTY_STRING || domSelectorText.charAt(domSelectorText.length - 1) == SPACE_STRING) { domSelectorText += "*"; } try { elms = selectorMethod( domSelectorText ); } catch (ex) { // #DEBUG_START log( "Selector '" + selectorText + "' threw exception '" + ex + "'" ); // #DEBUG_END }</p>
<p> if (elms) { for (var d = 0, dl = elms.length; d < dl; d++) { var elm = elms[d]; var cssClasses = elm.className; for (var f = 0, fl = patches.length; f < fl; f++) { var patch = patches[f]; if (!hasPatch(elm, patch)) { if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) { cssClasses = toggleClass(cssClasses, patch.className, true ); } } } elm.className = cssClasses; } } }; function hasPatch( elm, patch ) { return new RegExp("(^|\\s)" + patch.className + "(\\s|$)").test(elm.className); }; function createClassName( className ) { return namespace + "-" + ((ieVersion == 6 && patchIE6MultipleClasses) ? ie6PatchID++ : className.replace(RE_PATCH_CLASS_NAME_REPLACE, function(a) { return a.charCodeAt(0) })); }; function log( message ) { if (win.console) { win.console.log(message); } }; function trim( text ) { return text.replace(RE_TIDY_TRIM_WHITESPACE, PLACEHOLDER_STRING); }; function normalizeWhitespace( text ) { return trim(text).replace(RE_TIDY_CONSECUTIVE_WHITESPACE, SPACE_STRING); }; function normalizeSelectorWhitespace( selectorText ) { return normalizeWhitespace(selectorText. replace(RE_TIDY_TRAILING_WHITESPACE, PLACEHOLDER_STRING). replace(RE_TIDY_LEADING_WHITESPACE, PLACEHOLDER_STRING) ); }; function toggleElementClass( elm, className, on ) { var oldClassName = elm.className; var newClassName = toggleClass(oldClassName, className, on); if (newClassName != oldClassName) { elm.className = newClassName; elm.parentNode.className += EMPTY_STRING; } }; function toggleClass( classList, className, on ) { var re = RegExp("(^|\\s)" + className + "(\\s|$)"); var classExists = re.test(classList); if (on) { return classExists ? classList : classList + SPACE_STRING + className; } else { return classExists ? trim(classList.replace(re, PLACEHOLDER_STRING)) : classList; } }; // --[ addEvent() ]----------------------------------------------------- function addEvent(elm, eventName, eventHandler) { elm.attachEvent("on" + eventName, eventHandler); };</p>
<p> // --[ getXHRObject() ]------------------------------------------------- function getXHRObject() { if (win.XMLHttpRequest) { return new XMLHttpRequest; } try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) { return null; } }; function loadStyleSheet( url ) { xhr.open("GET", url, false); xhr.send(); return (xhr.status==200) ? xhr.responseText : EMPTY_STRING; }; function resolveUrl( url, contextUrl ) { function getProtocolAndHost( url ) { return url.substring(0, url.indexOf("/", 8)); }; if (/^https?:\/\//i.test(url)) { return getProtocolAndHost(contextUrl) == getProtocolAndHost(url) ? url : null; } if (url.charAt(0)=="/") { return getProtocolAndHost(contextUrl) + url; } var contextUrlPath = contextUrl.split(/[?#]/)[0]; // ignore query string in the contextUrl if (url.charAt(0) != "?" && contextUrlPath.charAt(contextUrlPath.length - 1) != "/") { contextUrlPath = contextUrlPath.substring(0, contextUrlPath.lastIndexOf("/") + 1); } return contextUrlPath + url; }; function parseStyleSheet( url ) { if (url) { return loadStyleSheet(url).replace(RE_COMMENT, EMPTY_STRING). replace(RE_IMPORT, function( match, quoteChar, importUrl, quoteChar2, importUrl2 ) { return parseStyleSheet(resolveUrl(importUrl || importUrl2, url)); }). replace(RE_ASSET_URL, function( match, quoteChar, assetUrl ) { quoteChar = quoteChar || EMPTY_STRING; return " url(" + quoteChar + resolveUrl(assetUrl, url) + quoteChar + ") "; }); } return EMPTY_STRING; }; // --[ init() ]--------------------------------------------------------- function init() { // honour the <base> tag var url, stylesheet; var baseTags = doc.getElementsByTagName("BASE"); var baseUrl = (baseTags.length > 0) ? baseTags[0].href : doc.location.href; for (var c = 0; c < doc.styleSheets.length; c++) { stylesheet = doc.styleSheets[c] if (stylesheet.href != EMPTY_STRING) { url = resolveUrl(stylesheet.href, baseUrl); if (url) { stylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) ); } } } if (enabledWatchers.length > 0) { setInterval( function() { for (var c = 0, cl = enabledWatchers.length; c < cl; c++) { var e = enabledWatchers[c]; if (e.disabled !== e.$disabled) { if (e.disabled) { e.disabled = false; e.$disabled = true; e.disabled = true; } else { e.$disabled = e.disabled; } } } },250) } }; ContentLoaded(win, function() { // Determine the "best fit" selector engine for (var engine in selectorEngines) { var members, member, context = win; if (win[engine]) { members = selectorEngines[engine].replace("*", engine).split("."); while ((member = members.shift()) && (context = context[member])) {} if (typeof context == "function") { selectorMethod = context; init(); return; } } } }); function ContentLoaded(win, fn) {</p>
<p> var done = false, top = true, init = function(e) { if (e.type == "readystatechange" && doc.readyState != "complete") return; (e.type == "load" ? win : doc).detachEvent("on" + e.type, init, false); if (!done && (done = true)) fn.call(win, e.type || e); }, poll = function() { try { root.doScroll("left"); } catch(e) { setTimeout(poll, 50); return; } init('poll'); };</p>
<p> if (doc.readyState == "complete") fn.call(win, EMPTY_STRING); else { if (doc.createEventObject && root.doScroll) { try { top = !win.frameElement; } catch(e) { } if (top) poll(); } addEvent(doc,"readystatechange", init); addEvent(win,"load", init); } }; })(this); </script> <![endif]--> </head> <body> <ul class="menu"> <li tabindex="1"> <span class="title">One</span> <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse interdum dictum scelerisque. Morbi eu euismod lorem.</div> </li> <li tabindex="1"> <span class="title">Two</span> <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse interdum dictum scelerisque. Morbi eu euismod lorem.</div> </li> <li tabindex="1"> <span class="title">Three</span> <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse interdum dictum scelerisque. Morbi eu euismod lorem.</div> </li> <li tabindex="1"> <span class="title">Four</span> <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse interdum dictum scelerisque. Morbi eu euismod lorem.</div> </li> <li tabindex="1"> <span class="title">Five</span> <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse interdum dictum scelerisque. Morbi eu euismod lorem.</div> </li> <li tabindex="1"> <span class="title">Six</span> <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse interdum dictum scelerisque. Morbi eu euismod lorem.</div> </li> <li tabindex="1"> <span class="title">Seven</span> <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse interdum dictum scelerisque. Morbi eu euismod lorem.</div> </li> <li tabindex="1"> <span class="title">Eight</span> <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse interdum dictum scelerisque. Morbi eu euismod lorem.</div> </li> <li tabindex="1"> <span class="title">Nine</span> <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse interdum dictum scelerisque. Morbi eu euismod lorem.</div> </li> </ul> <script> (function(){ // Append a close trigger for each block $('.menu .content').append('<span class="close">x</span>'); // Show window function showContent(elem){ hideContent(); elem.find('.content').addClass('expanded'); elem.addClass('cover'); } // Reset all function hideContent(){ $('.menu .content').removeClass('expanded'); $('.menu li').removeClass('cover'); } // When a li is clicked, show its content window and position it above all $('.menu li').click(function() { showContent($(this)); }); // When tabbing, show its content window using ENTER key $('.menu li').keypress(function(e) { if (e.keyCode == 13) { showContent($(this)); } });</p>
<p> // When right upper close element is clicked - reset all $('.menu .close').click(function(e) { e.stopPropagation(); hideContent(); }); // Also, when ESC key is pressed - reset all $(document).keyup(function(e) { if (e.keyCode == 27) { hideContent(); } }); })(); </script> </body> </html>
|