javascript和css实现垂直方向自适应的三角提示菜单

这是一个比较简单实用的菜单,最重要的是他不需要引用jQuery库。菜单在垂直方向上能做到自适应,当主菜单靠近顶部,子菜单将会在下面,当主菜单靠近底部,子菜单在上面。运用Modernizr的触摸检测功能,我们可以让子菜单的响应在pc上是hover,而在触摸设备上是点击。例子中还示范了如何在宽度比较窄的情况下如何调整布局。分享一个最好用的UI前端框架!

html代码:

.代码

  1. <ul id="cbp-tm-menu" class="cbp-tm-menu">
  2. <li>
  3. <a href="#">Home</a>
  4. </li>
  5. <li>
  6. <a href="#">Veggie made</a>
  7. <ul class="cbp-tm-submenu">
  8. <li><a href="#" class="cbp-tm-icon-archive">Sorrel desert</a></li>
  9. <li><a href="#" class="cbp-tm-icon-cog">Raisin kakadu</a></li>
  10. <li><a href="#" class="cbp-tm-icon-location">Plum salsify</a></li>
  11. <li><a href="#" class="cbp-tm-icon-users">Bok choy celtuce</a></li>
  12. <li><a href="#" class="cbp-tm-icon-earth">Onion endive</a></li>
  13. <li><a href="#" class="cbp-tm-icon-location">Bitterleaf</a></li>
  14. <li><a href="#" class="cbp-tm-icon-mobile">Sea lettuce</a></li>
  15. </ul>
  16. </li>
  17. <li>
  18. <a href="#">Pepper tatsoi</a>
  19. <ul class="cbp-tm-submenu">
  20. <li><a href="#" class="cbp-tm-icon-archive">Brussels sprout</a></li>
  21. <li><a href="#" class="cbp-tm-icon-cog">Kakadu lemon</a></li>
  22. <li><a href="#" class="cbp-tm-icon-link">Juice green</a></li>
  23. <li><a href="#" class="cbp-tm-icon-users">Wine fruit</a></li>
  24. <li><a href="#" class="cbp-tm-icon-earth">Garlic mint</a></li>
  25. <li><a href="#" class="cbp-tm-icon-location">Zucchini garnish</a></li>
  26. <li><a href="#" class="cbp-tm-icon-mobile">Sea lettuce</a></li>
  27. </ul>
  28. </li>
  29. <li>
  30. <a href="#">Sweet melon</a>
  31. <ul class="cbp-tm-submenu">
  32. <li><a href="#" class="cbp-tm-icon-screen">Sorrel desert</a></li>
  33. <li><a href="#" class="cbp-tm-icon-mail">Raisin kakadu</a></li>
  34. <li><a href="#" class="cbp-tm-icon-contract">Plum salsify</a></li>
  35. <li><a href="#" class="cbp-tm-icon-pencil">Bok choy celtuce</a></li>
  36. <li><a href="#" class="cbp-tm-icon-article">Onion endive</a></li>
  37. <li><a href="#" class="cbp-tm-icon-clock">Bitterleaf</a></li>
  38. </ul>
  39. </li>
  40. <a style="font-family: Arial; white-space: normal; background-color: #ffffff;" target="_blank" href="/topic/1132907">前端UI分享</a>
  41. </ul>

css代码分享一个最好用的UI前端框架!

.代码

  1. /* Iconfont made with icomoon.com */
  2. @font-face {
  3. font-family: ‘cbp-tmicons‘;
  4. src:url(‘../fonts/tmicons/cbp-tmicons.eot‘);
  5. src:url(‘../fonts/tmicons/cbp-tmicons.eot?#iefix‘) format(‘embedded-opentype‘),
  6. url(‘../fonts/tmicons/cbp-tmicons.woff‘) format(‘woff‘),
  7. url(‘../fonts/tmicons/cbp-tmicons.ttf‘) format(‘truetype‘),
  8. url(‘../fonts/tmicons/cbp-tmicons.svg#cbp-tmicons‘) format(‘svg‘);
  9. font-weight: normal;
  10. font-style: normal;
  11. }
  12. /* reset  list style */
  13. .cbp-tm-menu,
  14. .cbp-tm-menu ul {
  15. list-style: none;
  16. }
  17. /* set menu position; change here to set to relative or float, etc. */
  18. .cbp-tm-menu {
  19. display: block;
  20. position: absolute;
  21. z-index: 1000;
  22. bottom: 0;
  23. width: 100%;
  24. background: #47a3da;
  25. text-align: right;
  26. padding: 0 2em;
  27. margin: 0;
  28. text-transform: capitalize;
  29. }
  30. /* first level menu items */
  31. .cbp-tm-menu > li {
  32. display: inline-block;
  33. margin: 0 2.6em;
  34. position: relative;
  35. }
  36. .cbp-tm-menu > li > a {
  37. line-height: 4em;
  38. padding: 0 0.3em;
  39. font-size: 1.2em;
  40. display: block;
  41. color: #fff;
  42. }
  43. <a style="font-family: Arial;" target="_blank" href="/topic/1132907">前端UI分享</a>

.代码

  1. .no-touch .cbp-tm-menu > li > a:hover,
  2. .no-touch .cbp-tm-menu > li > a:active {
  3. color: #02639d;
  4. }
  5. /* sumbenu with transitions */
  6. .cbp-tm-submenu {
  7. position: absolute;
  8. display: block;
  9. visibility: hidden;
  10. opacity: 0;
  11. padding: 0;
  12. text-align: left;
  13. pointer-events: none;
  14. -webkit-transition: visibility 0s, opacity 0s;
  15. -moz-transition: visibility 0s, opacity 0s;
  16. transition: visibility 0s, opacity 0s;
  17. }
  18. .cbp-tm-show .cbp-tm-submenu {
  19. width: 16em;
  20. left: 50%;
  21. margin: 0 0 0 -8em;
  22. opacity: 1;
  23. visibility: visible;
  24. pointer-events: auto;
  25. -webkit-transition: visibility 0s, opacity 0.3s;
  26. -moz-transition: visibility 0s, opacity 0.3s;
  27. transition: visibility 0s, opacity 0.3s;
  28. }
  29. .cbp-tm-show-above .cbp-tm-submenu {
  30. bottom: 100%;
  31. padding-bottom: 10px;
  32. }
  33. .cbp-tm-show-below .cbp-tm-submenu {
  34. top: 100%;
  35. padding-top: 10px;
  36. }
  37. /* extreme cases: not enough space on the sides */
  38. .cbp-tm-nospace-right .cbp-tm-submenu {
  39. right: 0;
  40. left: auto;
  41. }
  42. .cbp-tm-nospace-left .cbp-tm-submenu {
  43. left: 0;
  44. }
  45. <a style="font-family: Arial;" target="_blank" href="/topic/1132907">前端UI分享</a>

.代码

  1. /* last menu item has to fit on the screen */
  2. .cbp-tm-menu > li:last-child .cbp-tm-submenu {
  3. right: 0;
  4. }
  5. /*
  6. arrow: depending on where the menu will be shown, we set
  7. the right position for the arrow
  8. */
  9. .cbp-tm-submenu:after {
  10. border: solid transparent;
  11. content: " ";
  12. height: 0;
  13. width: 0;
  14. position: absolute;
  15. pointer-events: none;
  16. }
  17. .cbp-tm-show-above .cbp-tm-submenu:after {
  18. top: 100%;
  19. margin-top: -10px;
  20. }
  21. .cbp-tm-show-below .cbp-tm-submenu:after {
  22. bottom: 100%;
  23. margin-bottom: -10px;
  24. }
  25. .cbp-tm-submenu:after {
  26. border-color: transparent;
  27. border-width: 16px;
  28. margin-left: -16px;
  29. left: 50%;
  30. }
  31. .cbp-tm-show-above .cbp-tm-submenu:after {
  32. border-top-color: #fff;
  33. }
  34. .cbp-tm-show-below .cbp-tm-submenu:after {
  35. border-bottom-color: #fff;
  36. }
  37. .cbp-tm-submenu > li {
  38. display: block;
  39. background: #fff;
  40. }
  41. .cbp-tm-submenu > li > a {
  42. padding: 5px 2.3em 5px 0.6em; /* top/bottom paddings in ‘em‘ cause a tiny "jump" in Chrome on Win */
  43. display: block;
  44. font-size: 1.2em;
  45. position: relative;
  46. color: #47a3da;
  47. border: 4px solid #fff;
  48. -webkit-transition: all 0.2s;
  49. -moz-transition: all 0.2s;
  50. transition: all 0.2s;
  51. }
  52. .no-touch .cbp-tm-submenu > li > a:hover,
  53. .no-touch .cbp-tm-submenu > li > a:active {
  54. color: #fff;
  55. background: #47a3da;
  56. }
  57. /* the icons (main level menu icon and sublevel icons) */
  58. .cbp-tm-submenu li a:before,
  59. .cbp-tm-menu > li > a:before {
  60. font-family: ‘cbp-tmicons‘;
  61. speak: none;
  62. font-style: normal;
  63. font-weight: normal;
  64. font-variant: normal;
  65. text-transform: none;
  66. line-height: 1;
  67. vertical-align: middle;
  68. margin-right: 0.6em;
  69. -webkit-font-smoothing: antialiased;
  70. }
  71. <a style="font-family: Arial;" target="_blank" href="/topic/1132907">前端UI分享</a>

.代码

  1. .cbp-tm-submenu li a:before {
  2. position: absolute;
  3. top: 50%;
  4. margin-top: -0.5em;
  5. right: 0.5em;
  6. }
  7. .cbp-tm-menu > li > a:not(:only-child):before {
  8. content: "\f0c9";
  9. font-size: 60%;
  10. opacity: 0.3;
  11. }
  12. .cbp-tm-icon-archive:before {
  13. content: "\e002";
  14. }
  15. .cbp-tm-icon-cog:before {
  16. content: "\e003";
  17. }
  18. .cbp-tm-icon-users:before {
  19. content: "\e004";
  20. }
  21. .cbp-tm-icon-earth:before {
  22. content: "\e005";
  23. }
  24. .cbp-tm-icon-location:before {
  25. content: "\e006";
  26. }
  27. .cbp-tm-icon-mobile:before {
  28. content: "\e007";
  29. }
  30. .cbp-tm-icon-screen:before {
  31. content: "\e008";
  32. }
  33. .cbp-tm-icon-mail:before {
  34. content: "\e009";
  35. }
  36. .cbp-tm-icon-contract:before {
  37. content: "\e00a";
  38. }
  39. .cbp-tm-icon-pencil:before {
  40. content: "\e00b";
  41. }
  42. .cbp-tm-icon-article:before {
  43. content: "\e00c";
  44. }
  45. .cbp-tm-icon-clock:before {
  46. content: "\e00d";
  47. }
  48. .cbp-tm-icon-videos:before {
  49. content: "\e00e";
  50. }
  51. .cbp-tm-icon-pictures:before {
  52. content: "\e00f";
  53. }
  54. .cbp-tm-icon-link:before {
  55. content: "\e010";
  56. }
  57. .cbp-tm-icon-refresh:before {
  58. content: "\e011";
  59. }
  60. .cbp-tm-icon-help:before {
  61. content: "\e012";
  62. }
  63. /* Media Queries */
  64. @media screen and (max-width: 55.6875em) {
  65. .cbp-tm-menu {
  66. font-size: 80%;
  67. }
  68. }
  69. <a style="font-family: Arial;" target="_blank" href="/topic/1132907">前端UI分享</a>

.代码

  1. @media screen and (max-height: 25.25em), screen and (max-width: 44.3125em) {
  2. .cbp-tm-menu {
  3. font-size: 100%;
  4. position: relative;
  5. text-align: center;
  6. padding: 0;
  7. top: auto;
  8. }
  9. .cbp-tm-menu > li {
  10. display: block;
  11. margin: 0;
  12. border-bottom: 4px solid #3793ca;
  13. }
  14. .cbp-tm-menu > li:first-child {
  15. border-top: 4px solid #3793ca;
  16. }
  17. li.cbp-tm-show > a,
  18. .no-touch .cbp-tm-menu > li > a:hover,
  19. .no-touch .cbp-tm-menu > li > a:active {
  20. color: #fff;
  21. background: #02639d;
  22. }
  23. .cbp-tm-submenu {
  24. position: relative;
  25. display: none;
  26. width: 100%;
  27. }
  28. .cbp-tm-submenu > li {
  29. padding: 0;
  30. }
  31. .cbp-tm-submenu > li > a {
  32. padding: 0.6em 2.3em 0.6em 0.6em;
  33. border: none;
  34. border-bottom: 2px solid #6fbbe9;
  35. }
  36. .cbp-tm-submenu:after {
  37. display: none;
  38. }
  39. .cbp-tm-menu .cbp-tm-show .cbp-tm-submenu {
  40. display: block;
  41. width: 100%;
  42. left: 0;
  43. margin: 0;
  44. padding: 0;
  45. bottom: auto;
  46. top: auto;
  47. }
  48. }

javascript代码

.代码

  1. /**
  2. * cbpTooltipMenu.js v1.0.0
  3. * http://www.codrops.com
  4. *
  5. * Licensed under the MIT license.
  6. * http://www.opensource.org/licenses/mit-license.php
  7. *
  8. * Copyright 2013, Codrops
  9. * http://www.codrops.com
  10. */
  11. ;( function( window ) {
  12. ‘use strict‘;
  13. var document = window.document,
  14. docElem = document.documentElement;
  15. function extend( a, b ) {
  16. for( var key in b ) {
  17. if( b.hasOwnProperty( key ) ) {
  18. a[key] = b[key];
  19. }
  20. }
  21. return a;
  22. }
  23. // from https://github.com/ryanve/response.js/blob/master/response.js
  24. function getViewportH() {
  25. var client = docElem[‘clientHeight‘],
  26. inner = window[‘innerHeight‘];
  27. if( client < inner )
  28. return inner;
  29. else
  30. return client;
  31. }
  32. // http://stackoverflow.com/a/11396681/989439
  33. function getOffset( el ) {
  34. return el.getBoundingClientRect();
  35. }
  36. // http://snipplr.com/view.php?codeview&id=5259
  37. function isMouseLeaveOrEnter(e, handler) {
  38. if (e.type != ‘mouseout‘ && e.type != ‘mouseover‘) return false;
  39. var reltg = e.relatedTarget ? e.relatedTarget :
  40. e.type == ‘mouseout‘ ? e.toElement : e.fromElement;
  41. while (reltg && reltg != handler) reltg = reltg.parentNode;
  42. return (reltg != handler);
  43. }
  44. function cbpTooltipMenu( el, options ) {
  45. this.el = el;
  46. this.options = extend( this.defaults, options );
  47. this._init();
  48. }
  49. <a target="_blank" href="/topic/1132907">前端UI分享</a>

.代码

  1. cbpTooltipMenu.prototype = {
  2. defaults : {
  3. // add a timeout to avoid the menu to open instantly
  4. delayMenu : 100
  5. },
  6. _init : function() {
  7. this.touch = Modernizr.touch;
  8. this.menuItems = document.querySelectorAll( ‘#‘ + this.el.id + ‘ > li‘ );
  9. this._initEvents();
  10. },
  11. _initEvents : function() {
  12. var self = this;
  13. Array.prototype.slice.call( this.menuItems ).forEach( function( el, i ) {
  14. var trigger = el.querySelector( ‘a‘ );
  15. if( self.touch ) {
  16. trigger.addEventListener( ‘click‘, function( ev ) { self._handleClick( this, ev ); } );
  17. }
  18. else {
  19. trigger.addEventListener( ‘click‘, function( ev ) {
  20. if( this.parentNode.querySelector( ‘ul.cbp-tm-submenu‘ ) ) {
  21. ev.preventDefault();
  22. }
  23. } );
  24. el.addEventListener( ‘mouseover‘, function(ev) { if( isMouseLeaveOrEnter( ev, this ) ) self._openMenu( this ); } );
  25. el.addEventListener( ‘mouseout‘, function(ev) { if( isMouseLeaveOrEnter( ev, this ) ) self._closeMenu( this ); } );
  26. }
  27. } );
  28. },
  29. _openMenu : function( el ) {
  30. var self = this;
  31. clearTimeout( this.omtimeout );
  32. this.omtimeout = setTimeout( function() {
  33. var submenu = el.querySelector( ‘ul.cbp-tm-submenu‘ );
  34. if( submenu ) {
  35. el.className = ‘cbp-tm-show‘;
  36. if( self._positionMenu( el ) === ‘top‘ ) {
  37. el.className += ‘ cbp-tm-show-above‘;
  38. }
  39. else {
  40. el.className += ‘ cbp-tm-show-below‘;
  41. }
  42. }
  43. }, this.touch ? 0 : this.options.delayMenu );
  44. },
  45. _closeMenu : function( el ) {
  46. clearTimeout( this.omtimeout );
  47. var submenu = el.querySelector( ‘ul.cbp-tm-submenu‘ );
  48. if( submenu ) {
  49. // based on https://github.com/desandro/classie/blob/master/classie.js
  50. el.className = el.className.replace(new RegExp("(^|\\s+)" + "cbp-tm-show" + "(\\s+|$)"), ‘ ‘);
  51. el.className = el.className.replace(new RegExp("(^|\\s+)" + "cbp-tm-show-below" + "(\\s+|$)"), ‘ ‘);
  52. el.className = el.className.replace(new RegExp("(^|\\s+)" + "cbp-tm-show-above" + "(\\s+|$)"), ‘ ‘);
  53. }
  54. },
  55. _handleClick : function( el, ev ) {
  56. var item = el.parentNode,
  57. items = Array.prototype.slice.call( this.menuItems ),
  58. submenu = item.querySelector( ‘ul.cbp-tm-submenu‘ )
  59. // first close any opened one..
  60. if( this.current &&  items.indexOf( item ) !== this.current ) {
  61. this._closeMenu( this.el.children[ this.current ] );
  62. this.el.children[ this.current ].querySelector( ‘ul.cbp-tm-submenu‘ ).setAttribute( ‘data-open‘, ‘false‘ );
  63. }
  64. if( submenu ) {
  65. ev.preventDefault();
  66. var isOpen = submenu.getAttribute( ‘data-open‘ );
  67. if( isOpen === ‘true‘ ) {
  68. this._closeMenu( item );
  69. submenu.setAttribute( ‘data-open‘, ‘false‘ );
  70. }
  71. else {
  72. this._openMenu( item );
  73. this.current = items.indexOf( item );
  74. submenu.setAttribute( ‘data-open‘, ‘true‘ );
  75. }
  76. }
  77. },
  78. arget="_blank" href="/topic/1132907">前端UI分享</a>
  79. _positionMenu : function( el ) {
  80. // checking where‘s more space left in the viewport: above or below the element
  81. var vH = getViewportH(),
  82. ot = getOffset(el),
  83. spaceUp = ot.top ,
  84. spaceDown = vH - spaceUp - el.offsetHeight;
  85. return ( spaceDown <= spaceUp ? ‘top‘ : ‘bottom‘ );
  86. }
  87. }
  88. // add to global namespace
  89. window.cbpTooltipMenu = cbpTooltipMenu;
  90. window );
时间: 2024-08-03 15:01:35

javascript和css实现垂直方向自适应的三角提示菜单的相关文章

利用CSS中的:after、: before制作的边三角提示框

小颖昨天分享了一篇参考bootstrap中的popover.js的css画消息弹框今天给大家再分享一篇使用:before和:after伪元素画消息弹框的CSS. 画出来是介个酱紫的: 有没有觉得画的萌萌哒,嘻嘻 不贫了,我们一起看代码吧!啦啦啦啦啦啦啦 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style med

用CSS让未知高度内容垂直方向居中

<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Demo</title> <style type="text/css"> #outer{ width:500px; height:200px; margin: 50px auto; border:1px solid #CCC; display:table; tex

HTML-移动端如何使用css让百分比布局的弹窗水平和垂直方向上居中

pc端让一个弹窗水平和垂直方向居中,在知道弹窗宽高的情况下很好计算,只需要用如下css即可: #date{ width: 300px; height: 300px; position: absolute; top: 50%; left: 50%; margin-left: -150px; margin-top: -150px; } 但是到了移动端,如果写百分比布局的话,高度不好确定,所以弹窗居中就会变得困难,今天遇到这个问题,百度了一下,看到这位朋友的资料,(http://www.shejida

css实现垂直水平居中的6种方案

1.绝对定位+margin:auto <code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; wor

如何使用JavaScript控制CSS Animations(动画)和Transitions(过渡)

Zach邮件跟我说,上Stack Overflow这类的论坛,他经常碰到一些关于JavaScript控制CSS 动画的问题,又提供给我几个例子.我很久就打算写一些关于这方面的文章,所以很高兴让Zach提出来并促使我写了这个教程. 有时候WEB开发人员认为CSS的动画比JavaScript的动画更难理解.虽然CSS动画有其局限性,但它的性能比大多数JavaScript库更加高效,因为它可以借助硬件加速啊!其效果绝对可以超出我们的预期. CSS animations和transitions再加上点J

无缝滚动--垂直方向

<!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-T

触发bfc解决父子元素嵌套垂直方向margin塌陷问题

首先看一下问题案例 .wrapper{ width: 100px; height: 100px; background-color: aqua; margin-top: 100px; margin-left: 100px; } .inner{ width: 50px; height: 50px; margin-top: 100px; margin-left: 50px; background-color:black; } <div class="wrapper"> <

现代 JavaScript 与 CSS 令人着迷滚动实现指南

一些(网站)滚动的效果是如此令人着迷但你却不知该如何实现,本文将为你揭开它们的神秘面纱.我们将基于最新的技术与规范为你介绍最新的 JavaScript 与 CSS 特性,(当你付诸实践时,)将使你的页面滚动更平滑.美观且性能更好. 大多数的网页的内容都无法在一屏内全部展现,因而(页面)滚动对于用户而言是必不可少的.对于前端工程师与 UX 设计师而言,跨浏览器提供良好的滚动体验,同时符合设计(要求),无疑是一个挑战.尽管 web 标准的发展速度远超从前,但代码的实现往往是落后的.下文将为你介绍一些

压缩 javascript 和 css

www.iwangzheng.com 目前我们项目中的 CSS/JS 文件比较多, 由于RAILS 3.0 没有提供asset pipeline功能,所以这样会制约我们的访问速度. 例如:  目前,我们的布局( origin.html.erb )页面有 19 个JS文件,15个CSS文件. 每次打开都需要发送 34个 request,严重影响体验. 所以,我们要把这些js, css 分别打包压缩成一个文件. 参考: http://stackoverflow.com/questions/71122