├── example ├── images │ ├── bg.jpg │ ├── icon-ical.png │ ├── icon-idisk.png │ ├── icon-mail.png │ ├── icon-iphoto.png │ └── icon-addressbook.png ├── css │ └── example.css └── index.html ├── source ├── images │ ├── dock-l.png │ ├── dock-m.png │ └── dock-r.png └── dock.css ├── LICENSE └── README.md /example/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelhue/cssdock/HEAD/example/images/bg.jpg -------------------------------------------------------------------------------- /source/images/dock-l.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelhue/cssdock/HEAD/source/images/dock-l.png -------------------------------------------------------------------------------- /source/images/dock-m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelhue/cssdock/HEAD/source/images/dock-m.png -------------------------------------------------------------------------------- /source/images/dock-r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelhue/cssdock/HEAD/source/images/dock-r.png -------------------------------------------------------------------------------- /example/images/icon-ical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelhue/cssdock/HEAD/example/images/icon-ical.png -------------------------------------------------------------------------------- /example/images/icon-idisk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelhue/cssdock/HEAD/example/images/icon-idisk.png -------------------------------------------------------------------------------- /example/images/icon-mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelhue/cssdock/HEAD/example/images/icon-mail.png -------------------------------------------------------------------------------- /example/images/icon-iphoto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelhue/cssdock/HEAD/example/images/icon-iphoto.png -------------------------------------------------------------------------------- /example/images/icon-addressbook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelhue/cssdock/HEAD/example/images/icon-addressbook.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2011 Michael Hüneburg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /example/css/example.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font: normal 14px/1.5 "PT Sans", Helvetica, Arial, sans-serif; 5 | background: rgb(30, 30, 30); 6 | color: rgb(220, 220, 220); 7 | } 8 | 9 | .wrapper { 10 | position: absolute; 11 | top: 48%; 12 | left: 50%; 13 | width: 660px; 14 | height: 340px; 15 | margin: -190px 0 0 -330px; 16 | } 17 | 18 | .example { 19 | position: relative; 20 | width: 660px; 21 | height: 340px; 22 | overflow: hidden; 23 | background: rgb(15, 15, 15) url(../images/bg.jpg) no-repeat center bottom; 24 | -moz-border-radius: 10px; 25 | -webkit-border-radius: 10px; 26 | border-radius: 10px; 27 | -moz-box-shadow: 0 1px 10px rgb(10, 10, 10); 28 | -webkit-box-shadow: 0 1px 10px rgb(10, 10, 10); 29 | box-shadow: 0 1px 10px rgb(10, 10, 10); 30 | } 31 | 32 | h1 { 33 | margin-top: 1.5em; 34 | color: rgba(255, 255, 255, .9); 35 | line-height: 1; 36 | font-size: 70px; 37 | text-align: center; 38 | font-weight: bold; 39 | text-shadow: 0px 1px 5px rgb(255, 160, 55), 0px 1px 15px rgb(255, 160, 55); 40 | cursor: default; 41 | } 42 | 43 | h1 em { 44 | display: inline-block; 45 | font-size: .29em; 46 | font-style: normal; 47 | vertical-align: top; 48 | margin-left: -.4em; 49 | padding-top: .46em; 50 | } 51 | 52 | footer { 53 | position: absolute; 54 | bottom: -3em; 55 | left: 0; 56 | right: 0; 57 | font-size: 12px; 58 | text-align: center; 59 | text-shadow: 1px 1px 1px rgba(0, 0, 0, .8); 60 | color: rgb(160, 160, 160); 61 | } 62 | 63 | footer a { 64 | color: inherit; 65 | } -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CSS Dock (V2) 6 | 7 | 8 | 9 | 10 | 11 | 14 | 17 | 18 | 19 |
20 |
21 |

CSS Dock V2

22 | 23 | 24 |
25 | 57 |
58 | 59 |
60 | 61 | 64 |
65 | 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSS Dock (V2) 2 | 3 | An experiment mimicking the Dock of OS X using only CSS. Labels, animations, reflections and indicators... it's all there. 4 | 5 | ## How does it work? 6 | 7 | Glad you asked. The dock makes heavy use of the following sweet CSS techniques: 8 | 9 | * _Transforms_, _Transitions_ and _Animations_ for the magnification and bouncing effects. 10 | * `:before` and `:after` pseudo-classes to keep the HTML markup clean and display the status indicator. 11 | * `:target` pseudo class to determine which item is active. 12 | * `-webkit-box-reflect` for the reflection of the icons. 13 | 14 | ## Details, give me details! 15 | 16 | Alright, let's walk through this together. The dock is basically an unsorted list with each list item representing one icon. Every item and the list itself gets the `display: inline-block;` property to act like an inline element while preserving their block capabilities. This allows us to use `text-align: center;` in order to keep the items centered and `vertical-align: baseline;` to keep all items at the bottom at any time. This is important so the other items won't "lift off" when one them is enlarged. 17 | 18 | On mouseover the corresponding image is enlarged while a transition applied to `width` and `height` ensures a smooth animation. On mouse-out the image transitions back to its original size which results in a nice little magnification effect. 19 | 20 | The icon reflection only works in WebKit because of it's proprietary (but kind of awesome) `-webkit-box-reflect` property. A gradient is used as a mask in order to cut off the status indicator, so it won't be part of the reflection. 21 | 22 | The bouncing effect is a simple CSS animation which uses the `transform` property to move the item a few pixels to the top. The status indicator is an element generated in CSS and inserted after the active item. But how do we know which item is active? This is where it gets a bit tricky. 23 | 24 | CSS gives us an underestimated pseudo-class named `:target`. You all know how we can use URIs to refer to an element within the page, right? An example: the link `` brings us to the element with the `id` _about_. The bit after `#` is called _fragment identifier_ which is represented by the _id_ attribute on elements. As soon as you click on this link, the _about_ element becomes the current target and CSS applies the `:target` pseudo-class to it. 25 | 26 | So when you click on an item in the dock you actually click on a link that refers to it's parent `li` element, which in turn triggers the bounce animation using `:target`, repeats it three times and creates the status indicator below the icon. 27 | 28 | And that's all, folks. Be sure to check the source file, lots of comments in there to get you started. And it's actually not that much code. 29 | 30 | ## But is it actually... you know, useful? 31 | 32 | Probably not, at least not without modifications. This is just a quick demonstration to show what's possible using modern web technologies. Use this experiment as a starting point and go bat-shit crazy. I highly encourage it! 33 | 34 | I'd love to see what you come up with so please shoot me a line in case you did indeed go bat-shit crazy. 35 | 36 | ## How about compatibility? 37 | 38 | You love to be the party pooper, don't you? Just kidding. The dock works best in current WebKit browsers (Safari and Chrome) but the good news is: it degrades quite gracefully. So while you won't get all effects in all browsers, the experience won't be broken either (except for IE, of course). A quick overview: 39 | 40 | * Chrome 12 (Full Support) 41 | * Safari 5 (Full Support) 42 | * Firefox 5 (Advanced Support; no reflections) 43 | * Opera 11 (Basic Support; no reflections and animations) 44 | 45 | ## Anything else? 46 | 47 | Why yes! Thanks a bunch to [Iconsutra](http://iconsutra.com) for letting me use his wonderful MobileMe icon set and also to [Wolfgang Bartelme](http://bartelme.at) who allowed me to use his gorgeous [Flow Wallpaper](http://bartelme.at/journal/archive/flow_wallpaper). 48 | 49 | And not to forget all of you guys who gave me feedback and spread the word. Thank you! -------------------------------------------------------------------------------- /source/dock.css: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------- 2 | CSS Dock 3 | 4 | Version: 2.0 5 | Author: Michael Hüneburg 6 | URL: http://michaelhue.com/cssdock 7 | Copyright: (c)2011 by Michael Hüneburg 8 | License: MIT License (see LICENSE file) 9 | ----------------------------------------------- */ 10 | 11 | /* @group Animation */ 12 | /* Defines the bounce animation. Note that only the up motion is defined as 13 | the down motion is created automatically using 14 | `animation-direction: alternate;`. */ 15 | @-webkit-keyframes bounce { 16 | 0% { -webkit-transform: translateY(0); } 17 | 100% { -webkit-transform: translateY(-20px); } 18 | } 19 | 20 | @-moz-keyframes bounce { 21 | 0% { -moz-transform: translateY(0); } 22 | 100% { -moz-transform: translateY(-20px); } 23 | } 24 | /* @end */ 25 | 26 | /* @group Dock */ 27 | .dock { 28 | position: absolute; 29 | bottom: 0; 30 | z-index: 10; 31 | width: 100%; 32 | text-align: center; 33 | font: normal 14px/1 'Lucida Grande', Arial, sans-serif; 34 | } 35 | 36 | .dock ul { 37 | position: relative; 38 | display: inline-block; 39 | padding: 0 5px; 40 | margin: 0; 41 | background: url(images/dock-m.png) repeat-x bottom; 42 | } 43 | 44 | /* Creates the left and right end caps of the dock. You may not need these 45 | when creating your own dock. */ 46 | .dock ul:before, .dock ul:after { 47 | content: " "; 48 | position: absolute; 49 | top: 0; 50 | bottom: 0; 51 | width: 31px; 52 | } 53 | 54 | .dock ul:before { 55 | left: -31px; 56 | background: url(images/dock-l.png) no-repeat left bottom; 57 | } 58 | 59 | .dock ul:after { 60 | right: -31px; 61 | background: url(images/dock-r.png) no-repeat right bottom; 62 | } 63 | /* @end */ 64 | 65 | /* @group Items */ 66 | /* Defines a dock item. Note the `-webkit-box-reflect` property which creates 67 | a nice reflection below the item. The gradient is a mask in order to 68 | exlcude the status indicator from the reflection. */ 69 | .dock li { 70 | display: inline-block; 71 | position: relative; 72 | margin: 0 1px; 73 | margin-bottom: 15px; 74 | vertical-align: baseline; 75 | -webkit-box-reflect: below -16px -webkit-gradient( 76 | linear, left top, left bottom, 77 | from(transparent), 78 | color-stop(91%, rgba(255, 255, 255, .1)), 79 | color-stop(91.01%, transparent), 80 | to(transparent) 81 | ); 82 | } 83 | 84 | .dock a { 85 | display: inline-block; 86 | cursor: default; 87 | outline: none; 88 | } 89 | /* Applies the bounce animation to the targeted dock item. */ 90 | .dock li:target a { 91 | -webkit-animation: bounce .3s 6 alternate ease-out; 92 | -moz-animation: bounce .3s 6 alternate ease-out; 93 | } 94 | 95 | /* Generates the status indicator. Looks complex but most of this stuff is 96 | just repetition with different vendor prefixes. Isn't it fun to write 97 | everything three times? *sigh* */ 98 | .dock li:after { 99 | content: " "; 100 | position: absolute; 101 | bottom: -5px; 102 | left: 50%; 103 | width: 5px; 104 | height: 5px; 105 | opacity: 0; 106 | visibility: hidden; 107 | background-color: rgba(255, 255, 255, .8); 108 | margin-left: -2px; 109 | -moz-border-radius: 5px; 110 | -webkit-border-radius: 5px; 111 | -o-border-radius: 5px; 112 | border-radius: 5px; 113 | -webkit-box-shadow: 114 | inset 0 1px 3px rgba(75, 255, 255, .4), 115 | 0 0 4px rgba(75, 255, 255, .5), 116 | 0 -1px 7px rgb(75, 255, 255); 117 | -moz-box-shadow: 118 | inset 0 1px 3px rgba(75, 255, 255, .4), 119 | 0 0 4px rgba(75, 255, 255, .5), 120 | 0 -1px 7px rgb(75, 255, 255); 121 | box-shadow: 122 | inset 0 1px 3px rgba(75, 255, 255, .4), 123 | 0 0 4px rgba(75, 255, 255, .5), 124 | 0 -1px 7px rgb(75, 255, 255); 125 | -webkit-transition: opacity .5s; 126 | -moz-transition: opacity .5s; 127 | -o-transition: opacity .5s; 128 | } 129 | 130 | /* Displays the status indicator of the targeted dock item. */ 131 | .dock li:target:after { 132 | visibility: visible; 133 | opacity: 1; 134 | } 135 | /* @end */ 136 | 137 | /* @group Label */ 138 | /* This is just a wrapper in order to center the actual label horizontally. 139 | You may need to adjust the width negative margin if you have really long 140 | labels. */ 141 | .dock em { 142 | position: absolute; 143 | top: -34px; 144 | left: 50%; 145 | display: none; 146 | width: 150px; 147 | margin-left: -75px; 148 | text-align: center; 149 | } 150 | 151 | /* Generates the little arrow at the bottom of the label. */ 152 | .dock em:after { 153 | content: " "; 154 | position: absolute; 155 | bottom: -6px; 156 | left: 50%; 157 | margin-left: -6px; 158 | width: 0; 159 | height: 0; 160 | border-left: 6px solid transparent; 161 | border-right: 6px solid transparent; 162 | border-top: 6px solid rgba(0, 0, 0, .6); 163 | border-bottom: none; 164 | } 165 | 166 | /* This is the actual label. */ 167 | .dock em span { 168 | display: inline-block; 169 | padding: 5px 12px; 170 | font-size: 14px; 171 | font-style: normal; 172 | color: #FFF; 173 | background: #000; 174 | background: rgba(0, 0, 0, .6); 175 | text-shadow: 1px 1px 1px rgba(0, 0, 0, .9); 176 | -webkit-border-radius: 12px; 177 | -moz-border-radius: 12px; 178 | -o-border-radius: 12px; 179 | border-radius: 12px; 180 | } 181 | 182 | .dock li:hover em, .dock li a:focus em { 183 | display: block; 184 | } 185 | /* @end */ 186 | 187 | /* @group Icon */ 188 | /* Sets the icons to a smaller width so they can be enlarged and applies 189 | transitions for a smooth animation. Make sure to adjust the width so it 190 | matches your images. */ 191 | .dock img { 192 | width: 86px; 193 | height: auto; 194 | border: none; 195 | -webkit-transition: width .2s, height .2s; 196 | -moz-transition: width .2s, height .2s; 197 | -o-transition: width .2s, height .2s; 198 | } 199 | 200 | .dock li:hover img, .dock li a:focus img { 201 | width: 96px; 202 | } 203 | 204 | .dock li:active img { 205 | opacity: .9; 206 | } 207 | /* @end */ --------------------------------------------------------------------------------