├── .gitignore ├── LICENSE ├── README.md ├── Rakefile ├── docs ├── .gitignore └── src │ ├── index.html.erb │ ├── javascripts │ ├── project.yml │ ├── stylesheets │ └── tipsy-docs.css └── src ├── javascripts └── jquery.tipsy.js └── stylesheets └── tipsy.css /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | pkg 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2008 Jason Frame (jason@onehackoranother.com) 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tipsy 2 | 3 | Facebook-style tooltip plugin for jQuery 4 | 5 | (c) 2008-2010 Jason Frame (jason@onehackoranother.com) 6 | 7 | Released under The MIT License. 8 | 9 | ## Description: 10 | 11 | tipsy is a simple jQuery plugin for generating Facebook-style tooltips. 12 | 13 | It's used by Twitter, Github, Slideshare and Bitbucket, amongst others. 14 | 15 | ## Homepage: 16 | 17 | http://onehackoranother.com/projects/jquery/tipsy 18 | 19 | ## Source: 20 | 21 | Hosted at GitHub; browse at: 22 | 23 | http://github.com/jaz303/tipsy/tree/master 24 | 25 | Or clone from: 26 | 27 | git://github.com/jaz303/tipsy.git 28 | 29 | ## Usage: 30 | 31 | 1. Copy the contents of src/{images,javascripts,stylesheets} to the corresponding asset directories in your project. 32 | If the relative path of your images directory from your stylesheets directory is not "../images", you'll need to adjust tipsy.css appropriately. 33 | 34 | 2. Insert the neccesary elements in your document's `` section, e.g.: 35 | 36 | 37 | 38 | 39 | Remember to include jquery.tipsy.js *after* including the main jQuery library. 40 | 41 | 3. Initialise Tipsy in your document.onload, e.g.: 42 | 43 | 48 | 49 | Please refer to the docs directory for more examples and documentation. 50 | 51 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME='tipsy' 2 | PROJECT_VERSION='1.0.0a' 3 | MANIFEST=%w(src LICENSE README) 4 | 5 | def project_tag 6 | "#{PROJECT_NAME}-#{PROJECT_VERSION}" 7 | end 8 | 9 | def target 10 | File.join('pkg', project_tag) 11 | end 12 | 13 | task :clean do 14 | `rm -rf pkg` 15 | end 16 | 17 | task :docs do 18 | `cd docs && project-kit --target=archive build src build` 19 | end 20 | 21 | task :build => :clean do 22 | `mkdir -p #{target}` 23 | `cd docs && project-kit --target=archive build src build` 24 | `mv docs/build #{target}/docs` 25 | MANIFEST.each { |e| `cp -R #{e} #{target}/` } 26 | end 27 | 28 | task :package => :build do 29 | `cd pkg && zip -ro ../#{project_tag}.zip #{project_tag}` 30 | end 31 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /docs/src/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 |

Overview

21 | 22 |

Tipsy is a jQuery plugin for creating a Facebook-like tooltips effect based on 23 | an anchor tag's title attribute.

24 | 25 |

Examples & Usage

26 | 27 |

Basic

28 | 29 |

By default, tooltips will appear centred underneath their anchor:

30 | 31 |

32 | Hover over me 33 |

34 | 35 |
Basic example:
36 |
$('#example-1').tipsy();
37 | 38 |

Gravities

39 | 40 |

Using the gravity parameter, it's possible to control the positioning of the tooltip relative to the pointee:

41 | 42 | 43 | 44 | 47 | 50 | 53 | 54 | 55 | 58 | 59 | 62 | 63 | 64 | 67 | 70 | 73 | 74 |
45 | Northwest 46 | 48 | North 49 | 51 | Northeast 52 |
56 | West 57 |   60 | East 61 |
65 | Southwest 66 | 68 | South 69 | 71 | Southeast 72 |
75 | 76 | 88 | 89 |
Gravity example:
90 |
$('#foo').tipsy({gravity: 'n'}); // nw | n | ne | w | e | sw | s | se
91 | 92 |

As of version 0.1.3, it's possible to use a callback function to set the gravity dynamically at hover-time. Within the callback, this refers to the active element, and the function should return the calculated gravity as a string. Two demo callbacks are supplied - $.fn.tipsy.autoNS and $.fn.tipsy.autoWE - which select north/south and west/east gravity, respectively, based on the element's location in the viewport.

93 | 94 |

Here's an example (scroll the page to see the effect):

95 | 96 | Dynamic Gravity 97 | 98 |
Dynamic gravity example:
99 |
$('#foo').tipsy({gravity: $.fn.tipsy.autoNS});
100 | 101 |

Fading

102 | 103 |

For full Wob2.0 compliance, you must fade these badboys in:

104 | 105 |

106 | Hover over me 107 |

108 | 109 |
Fade example:
110 |
$('#example-fade').tipsy({fade: true});
111 | 112 |

Bonus Feature

113 | 114 |

You can EVEN COMBINE FADE AND GRAVITY! (exercise for reader)

115 | 116 |

Slightly Advanced Usage

117 | 118 |

Tooltip text can be set based on any attribute, not just title:

119 | 120 |

121 | Hover over me 122 |

123 | 124 |
Custom attribute example:
125 |
$('#example-custom-attribute').tipsy({title: 'id'});
126 | 127 |

If any attribute isn't good enough, you may pass a callback function instead. It should 128 | return the tooltip text for this element:

129 | 130 |

131 | Hover over me 132 |

133 | 134 |
Callback example:
135 |
$('#example-callback').tipsy({title: function() { return this.getAttribute('original-title').toUpperCase(); } });
136 | 137 |

Finally, it is possible to specify a fallback tooltip for any element which does not 138 | have any tooltip text:

139 | 140 |

141 | Hover over me 142 |

143 | 144 |
Fallback example:
145 |
$('#example-fallback').tipsy({fallback: "Where's my tooltip yo'?" });
146 | 147 |

If your tooltip content contains HTML, set the 148 | html option to true (relies on invalid HTML, sorry):

149 | 150 |

151 | Hover over me 152 |

153 | 154 |
HTML example:
155 |
$('#example-html').tipsy({html: true });
156 | 157 | 158 | 159 |

Custom Classes

160 | 161 |

162 | This className option can be used to add extra CSS classes to generated 163 | tooltips: 164 |

165 | 166 |
Custom class example:
167 |
$('#example-custom-class').tipsy({className: 'red'});
168 | 169 |

170 | Try me out 171 |

172 | 173 | 176 | 177 | 178 | 179 |

Show/Hide Delay

180 | 181 |
Delay example:
182 |
$('#example-delay').tipsy({delayIn: 500, delayOut: 1000});
183 | 184 |

185 | Hover and wait 186 |

187 | 188 | 191 | 192 | 193 | 194 |

Dynamically Updating Text

195 | 196 |

Tipsy tooltips are 'live' - if the source attribute's value changes, the tooltip text will be 197 | updated the next time the tooltip is shown. There's one caveat - if you wish to remove the tooltip 198 | by setting the title attribute to an empty string, set the original-title 199 | attribute instead (this only applies if you're using the title attribute). 200 |

201 | 202 |
Dynamic updating example:
203 |
204 | Hover over me | 205 | New tooltip text: 206 | 207 | 208 |
209 | 210 | 213 | 214 | 215 | 216 |

Using Tooltips on Form Inputs

217 | 218 |

Tooltips can be bound to form inputs' focus/blur events using the option 219 | {trigger: 'focus'}:

220 | 221 |
Form input tooltips example:
222 |
223 |
228 |
229 |
230 | 231 |
232 | 233 | 238 | 239 |
Form input tooltips code:
240 |
<script type='text/javascript'>
241 |   $(function() {
242 |     $('#focus-example [title]').tipsy({trigger: 'focus', gravity: 'w'});
243 |   });
244 | </script>
245 | 246 | 247 | 248 |

Manually Triggering a Tooltip

249 | 250 |

It's possible to disable hover events and instead trigger tooltips manually:

251 | 252 |
Manual triggering example:
253 |
254 | My tooltip is manually triggered | 255 | Show it | 256 | Hide it 257 |
258 | 259 | 262 | 263 |
Code for manual triggering:
264 |
<p id='manual-example'>
265 |   <a rel='tipsy' title='Well hello there'>My tooltip is manually triggered</a>
266 |   <a href='#' onclick='$("#manual-example a[rel=tipsy]").tipsy("show"); return false;'>Show</a>
267 |   <a href='#' onclick='$("#manual-example a[rel=tipsy]").tipsy("hide"); return false;'>Hide</a>
268 | </p>
269 | 
270 | <script type='text/javascript'>
271 |   $('#manual-example a[rel=tipsy]').tipsy({trigger: 'manual'});
272 | </script>
273 | 274 | 275 | 276 |

Support for Live Events

277 | 278 |

279 | Live events are supported using the option {live: true}. 280 | jQuery ≥ 1.4.1 is required and live tooltips do not support manual triggering. 281 |

282 | 283 |
Live events example:
284 |
285 | 286 |
287 |
288 | 289 | 292 | 293 |
Code for live events:
294 |
<script type='text/javascript'>
295 |   $('a.live-tipsy').tipsy({live: true});
296 | </script>
297 | 298 | 299 | 300 |

Summary of Configuration Options

301 |

Here is the default options declaration: 302 |

$.fn.tipsy.defaults = {
303 |     className: null,  // custom class to add to tooltip (string or function)
304 |     delayIn: 0,       // delay before showing tooltip (ms)
305 |     delayOut: 0,      // delay before hiding tooltip (ms)
306 |     fade: false,      // fade tooltips in/out?
307 |     fallback: '',     // fallback text to use when no tooltip text
308 |     gravity: 'n',     // gravity (string or function)
309 |     html: false,      // is tooltip content HTML?
310 |     live: false,      // use live event support?
311 |     offset: 0,        // pixel offset of tooltip from element
312 |     opacity: 0.8,     // opacity of tooltip
313 |     title: 'title',   // attribute/callback containing tooltip text
314 |     trigger: 'hover'  // how tooltip is triggered - hover | focus | manual
315 | };
316 | 317 | 318 | 319 |

Notes

320 | 321 |

Tipsy needs to erase any existing value for an element's title attribute in 322 | order to suppress the browser's native tooltips. It is stashed in the element's 323 | original-title attribute in case you need to retrieve it later.

324 | 325 |

As of version 0.1.4, the tooltip text is recomputed on every hover event so updating the 326 | title attribute will have the expected effect.

327 | 328 | 329 | 330 |

Download

331 | 332 |

Package

333 |

334 | Package downloads are available from the 335 | Github project page - 336 | select the latest version from the 'Switch Tags' menu then click 'Downloads'. 337 |

338 | 339 |

github

340 |
jason@donut ~ $ git clone git://github.com/jaz303/tipsy.git
341 | -------------------------------------------------------------------------------- /docs/src/javascripts: -------------------------------------------------------------------------------- 1 | ../../src/javascripts -------------------------------------------------------------------------------- /docs/src/project.yml: -------------------------------------------------------------------------------- 1 | project: 2 | title: "tipsy" 3 | subtitle: "Facebook-style tooltip plugin for jQuery" 4 | jquery_version: "1.4.2" 5 | main_nav: 6 | - ["Overview", "#overview"] 7 | - ["Examples & Usage", "#examples"] 8 | - ["Summary of Configuration Options", "#options"] 9 | - ["Notes", "#notes"] 10 | - ["Download", "#download"] 11 | stylesheets: ['stylesheets/tipsy.css', 'tipsy-docs.css'] 12 | javascripts: ['javascripts/jquery.tipsy.js'] 13 | -------------------------------------------------------------------------------- /docs/src/stylesheets: -------------------------------------------------------------------------------- 1 | ../../src/stylesheets -------------------------------------------------------------------------------- /docs/src/tipsy-docs.css: -------------------------------------------------------------------------------- 1 | #gravity { width: 100%; margin: 5px 0; border-spacing: 5px; } 2 | #gravity td { text-align: center; vertical-align: middle; padding: 5px 0; background-color: #d0d0d0; width: 33%; } 3 | #gravity a { } 4 | #gravity a:hover { color: #505050; background: none; } 5 | 6 | .red .tipsy-inner { background: red; } 7 | .red .tipsy-arrow-n { border-bottom-color: red; } 8 | .red .tipsy-arrow-s { border-top-color: red; } 9 | .red .tipsy-arrow-e { border-left-color: red; } 10 | .red .tipsy-arrow-w { border-right-color: red; } 11 | -------------------------------------------------------------------------------- /src/javascripts/jquery.tipsy.js: -------------------------------------------------------------------------------- 1 | // tipsy, facebook style tooltips for jquery 2 | // version 1.0.0a 3 | // (c) 2008-2010 jason frame [jason@onehackoranother.com] 4 | // released under the MIT license 5 | 6 | (function($) { 7 | 8 | function maybeCall(thing, ctx) { 9 | return (typeof thing == 'function') ? (thing.call(ctx)) : thing; 10 | }; 11 | 12 | function isElementInDOM(ele) { 13 | while (ele = ele.parentNode) { 14 | if (ele == document) return true; 15 | } 16 | return false; 17 | }; 18 | 19 | function Tipsy(element, options) { 20 | this.$element = $(element); 21 | this.options = options; 22 | this.enabled = true; 23 | this.fixTitle(); 24 | }; 25 | 26 | Tipsy.prototype = { 27 | show: function() { 28 | var title = this.getTitle(); 29 | if (title && this.enabled) { 30 | var $tip = this.tip(); 31 | 32 | $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); 33 | $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity 34 | $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body); 35 | 36 | var pos = $.extend({}, this.$element.offset(), { 37 | width: this.$element[0].offsetWidth, 38 | height: this.$element[0].offsetHeight 39 | }); 40 | 41 | var actualWidth = $tip[0].offsetWidth, 42 | actualHeight = $tip[0].offsetHeight, 43 | gravity = maybeCall(this.options.gravity, this.$element[0]); 44 | 45 | var tp; 46 | switch (gravity.charAt(0)) { 47 | case 'n': 48 | tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; 49 | break; 50 | case 's': 51 | tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; 52 | break; 53 | case 'e': 54 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}; 55 | break; 56 | case 'w': 57 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; 58 | break; 59 | } 60 | 61 | if (gravity.length == 2) { 62 | if (gravity.charAt(1) == 'w') { 63 | tp.left = pos.left + pos.width / 2 - 15; 64 | } else { 65 | tp.left = pos.left + pos.width / 2 - actualWidth + 15; 66 | } 67 | } 68 | 69 | $tip.css(tp).addClass('tipsy-' + gravity); 70 | $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0); 71 | if (this.options.className) { 72 | $tip.addClass(maybeCall(this.options.className, this.$element[0])); 73 | } 74 | 75 | if (this.options.fade) { 76 | $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}); 77 | } else { 78 | $tip.css({visibility: 'visible', opacity: this.options.opacity}); 79 | } 80 | } 81 | }, 82 | 83 | hide: function() { 84 | if (this.options.fade) { 85 | this.tip().stop().fadeOut(function() { $(this).remove(); }); 86 | } else { 87 | this.tip().remove(); 88 | } 89 | }, 90 | 91 | fixTitle: function() { 92 | var $e = this.$element; 93 | if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') { 94 | $e.attr('original-title', $e.attr('title') || '').removeAttr('title'); 95 | } 96 | }, 97 | 98 | getTitle: function() { 99 | var title, $e = this.$element, o = this.options; 100 | this.fixTitle(); 101 | var title, o = this.options; 102 | if (typeof o.title == 'string') { 103 | title = $e.attr(o.title == 'title' ? 'original-title' : o.title); 104 | } else if (typeof o.title == 'function') { 105 | title = o.title.call($e[0]); 106 | } 107 | title = ('' + title).replace(/(^\s*|\s*$)/, ""); 108 | return title || o.fallback; 109 | }, 110 | 111 | tip: function() { 112 | if (!this.$tip) { 113 | this.$tip = $('
').html('
'); 114 | this.$tip.data('tipsy-pointee', this.$element[0]); 115 | } 116 | return this.$tip; 117 | }, 118 | 119 | validate: function() { 120 | if (!this.$element[0].parentNode) { 121 | this.hide(); 122 | this.$element = null; 123 | this.options = null; 124 | } 125 | }, 126 | 127 | enable: function() { this.enabled = true; }, 128 | disable: function() { this.enabled = false; }, 129 | toggleEnabled: function() { this.enabled = !this.enabled; } 130 | }; 131 | 132 | $.fn.tipsy = function(options) { 133 | 134 | if (options === true) { 135 | return this.data('tipsy'); 136 | } else if (typeof options == 'string') { 137 | var tipsy = this.data('tipsy'); 138 | if (tipsy) tipsy[options](); 139 | return this; 140 | } 141 | 142 | options = $.extend({}, $.fn.tipsy.defaults, options); 143 | 144 | function get(ele) { 145 | var tipsy = $.data(ele, 'tipsy'); 146 | if (!tipsy) { 147 | tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options)); 148 | $.data(ele, 'tipsy', tipsy); 149 | } 150 | return tipsy; 151 | } 152 | 153 | function enter() { 154 | var tipsy = get(this); 155 | tipsy.hoverState = 'in'; 156 | if (options.delayIn == 0) { 157 | tipsy.show(); 158 | } else { 159 | tipsy.fixTitle(); 160 | setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); 161 | } 162 | }; 163 | 164 | function leave() { 165 | var tipsy = get(this); 166 | tipsy.hoverState = 'out'; 167 | if (options.delayOut == 0) { 168 | tipsy.hide(); 169 | } else { 170 | setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut); 171 | } 172 | }; 173 | 174 | if (!options.live) this.each(function() { get(this); }); 175 | 176 | if (options.trigger != 'manual') { 177 | var binder = options.live ? 'live' : 'bind', 178 | eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus', 179 | eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'; 180 | this[binder](eventIn, enter)[binder](eventOut, leave); 181 | } 182 | 183 | return this; 184 | 185 | }; 186 | 187 | $.fn.tipsy.defaults = { 188 | className: null, 189 | delayIn: 0, 190 | delayOut: 0, 191 | fade: false, 192 | fallback: '', 193 | gravity: 'n', 194 | html: false, 195 | live: false, 196 | offset: 0, 197 | opacity: 0.8, 198 | title: 'title', 199 | trigger: 'hover' 200 | }; 201 | 202 | $.fn.tipsy.revalidate = function() { 203 | $('.tipsy').each(function() { 204 | var pointee = $.data(this, 'tipsy-pointee'); 205 | if (!pointee || !isElementInDOM(pointee)) { 206 | $(this).remove(); 207 | } 208 | }); 209 | }; 210 | 211 | // Overwrite this method to provide options on a per-element basis. 212 | // For example, you could store the gravity in a 'tipsy-gravity' attribute: 213 | // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); 214 | // (remember - do not modify 'options' in place!) 215 | $.fn.tipsy.elementOptions = function(ele, options) { 216 | return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; 217 | }; 218 | 219 | $.fn.tipsy.autoNS = function() { 220 | return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; 221 | }; 222 | 223 | $.fn.tipsy.autoWE = function() { 224 | return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; 225 | }; 226 | 227 | /** 228 | * yields a closure of the supplied parameters, producing a function that takes 229 | * no arguments and is suitable for use as an autogravity function like so: 230 | * 231 | * @param margin (int) - distance from the viewable region edge that an 232 | * element should be before setting its tooltip's gravity to be away 233 | * from that edge. 234 | * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer 235 | * if there are no viewable region edges effecting the tooltip's 236 | * gravity. It will try to vary from this minimally, for example, 237 | * if 'sw' is preferred and an element is near the right viewable 238 | * region edge, but not the top edge, it will set the gravity for 239 | * that element's tooltip to be 'se', preserving the southern 240 | * component. 241 | */ 242 | $.fn.tipsy.autoBounds = function(margin, prefer) { 243 | return function() { 244 | var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)}, 245 | boundTop = $(document).scrollTop() + margin, 246 | boundLeft = $(document).scrollLeft() + margin, 247 | $this = $(this); 248 | 249 | if ($this.offset().top < boundTop) dir.ns = 'n'; 250 | if ($this.offset().left < boundLeft) dir.ew = 'w'; 251 | if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e'; 252 | if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's'; 253 | 254 | return dir.ns + (dir.ew ? dir.ew : ''); 255 | } 256 | }; 257 | 258 | })(jQuery); 259 | -------------------------------------------------------------------------------- /src/stylesheets/tipsy.css: -------------------------------------------------------------------------------- 1 | .tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; } 2 | .tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; } 3 | 4 | /* Rounded corners */ 5 | .tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } 6 | 7 | /* Uncomment for shadow */ 8 | /*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/ 9 | 10 | .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; } 11 | 12 | /* Rules to colour arrows */ 13 | .tipsy-arrow-n { border-bottom-color: #000; } 14 | .tipsy-arrow-s { border-top-color: #000; } 15 | .tipsy-arrow-e { border-left-color: #000; } 16 | .tipsy-arrow-w { border-right-color: #000; } 17 | 18 | .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } 19 | .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} 20 | .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} 21 | .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } 22 | .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } 23 | .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } 24 | .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } 25 | .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } 26 | --------------------------------------------------------------------------------