$o-tip-width: 28px; $o-tip-height: 38px; $o-tip-anchor-space: 0; $o-tip-bounce-half-size: 3px; $o-tip-color: $o-enterprise-color; $o-tip-border-width: 3px; $o-tip-border-color: white; $o-tip-animation-speed: 500ms; $o-tip-arrow-size: 12px; $o-tip-duration-in: 200ms; $o-tip-size-duration-in: floor($o-tip-duration-in * 3 / 4); $o-tip-size-delay-in: $o-tip-duration-in - $o-tip-size-duration-in; @keyframes move-left-right { 0% { transform: translate(-$o-tip-bounce-half-size, 0); } 100% { transform: translate($o-tip-bounce-half-size, 0); } } @keyframes move-bottom-top { 0% { transform: translate(0, -$o-tip-bounce-half-size); } 100% { transform: translate(0, $o-tip-bounce-half-size); } } .o_tooltip_parent { position: relative !important; // Tooltips are placed in the element with z-index 1070 because this // is the only way to position them above everything else. However, for // scrolling performance, the tooltip is placed in its ideal location (see // Tip._get_ideal_location). When in this location, the tooltip were // sometimes overlapping unwanted elements (e.g. chat windows). // // Changing the opacity of the tooltip parents forces the creation of a // stacking context; the home menu tooltips are thus now considered to be // root-level z-index auto (or the default home menu one) and should so // act like their parent (e.g. the home menu is below the chat windows so // the inner tooltips will be too). The tips will be above all elements of // the home menu as they still have a high z-index, but relative to the // home menu (this is especially useful in the website where most tooltips // are placed in the body and need to be placed above elements with z-index // like the navbar). opacity: 0.999 !important; } .o_tooltip { /*rtl:begin:ignore*/ position: absolute !important; top: 50% !important; left: 50% !important; /*rtl:end:ignore*/ z-index: $zindex-tooltip !important; // See comment on 'o_tooltip_parent' class opacity: 0 !important; width: $o-tip-width !important; height: $o-tip-width !important; // the shape must be done using transform margin: 0 !important; padding: 0 !important; transition: opacity 400ms ease 0ms !important; &.o_animated { animation: move-bottom-top $o-tip-animation-speed ease-in 0ms infinite alternate !important; &.right, &.left { animation-name: move-left-right !important; } } &.o_tooltip_visible { opacity: 1 !important; } &.o_tooltip_fixed { position: fixed !important; } // Use the ::before element to make the tip shape: a simple filled and // bordered square with one corner and 3 rounded corners, then transformed. // Transform, from right to left: 1) make the arrow point up, 2) scale along // Y axis so that the tip reach the desired height, 3) translate along the Y // axis so that the arrow exactly points at the original square tip border // = the border that will be against the pointed element, 4) rotate the // the shape depending on the tip orientation. &::before { content: ""; @include o-position-absolute(0, 0); width: $o-tip-width; // Not 100% need to stay small and square for close transition height: $o-tip-width; border: $o-tip-border-width solid $o-tip-border-color; border-radius: 0 50% 50% 50%; background: radial-gradient(lighten($o-tip-color, 7%), $o-tip-color); box-shadow: 0 0 40px 2px rgba(255, 255, 255, 0.5); } $-sqrt-2: 1.4142; $-tip-scale: $o-tip-height / ((1 + $-sqrt-2) * $o-tip-width / 2); $-tip-overflow: ($-sqrt-2 * $-tip-scale - 1) * $o-tip-width / 2; $-tip-translate: $o-tip-anchor-space + $-tip-overflow; &.top::before { transform: rotate(180deg) translateY($-tip-translate) scaleY($-tip-scale) rotate(45deg); } &.right::before { transform: rotate(270deg) translateY($-tip-translate) scaleY($-tip-scale) rotate(45deg); } &.bottom::before { transform: rotate(0deg) translateY($-tip-translate) scaleY($-tip-scale) rotate(45deg); } &.left::before { transform: rotate(90deg) translateY($-tip-translate) scaleY($-tip-scale) rotate(45deg); } > .o_tooltip_overlay { display: none; @include o-position-absolute(0, 0, 0, 0); z-index: -1; } > .o_tooltip_content { overflow: hidden; direction: ltr; position: relative; padding: 7px 14px; background-color: inherit; color: transparent; visibility: hidden; // Force style so that it does not depend on where the tooltip is attached line-height: $line-height-base; font-size: $font-size-base; font-family: $font-family-sans-serif; font-weight: normal; .o_skip_tour { display: inline-block; margin-top: 4px; cursor: pointer; color: gray; &:hover { color: darken(gray, 20%); } } > p:last-child { margin-bottom: 0; } } &.active { border: $o-tip-border-width solid $o-tip-color !important; background-color: white !important; transition: width $o-tip-size-duration-in ease $o-tip-size-delay-in, height $o-tip-size-duration-in ease $o-tip-size-delay-in, margin $o-tip-size-duration-in ease $o-tip-size-delay-in !important; &::before { width: $o-tip-arrow-size; height: $o-tip-arrow-size; border-color: $o-tip-color; border-radius: 0; background: white; box-shadow: none; } > .o_tooltip_overlay { display: block; } > .o_tooltip_content { // Content background must appear immediately to hide the bottom of // the square present to shape the bubble arrow. But text must // appear at the very end. color: black; visibility: visible; transition: color 0ms ease $o-tip-duration-in; } $-arrow-offset: ($o-tip-width - $o-tip-arrow-size) / 2 - $o-tip-border-width; $-tip-translate: $o-tip-anchor-space + $o-tip-arrow-size / 2; &.right { transform: translateX($-tip-translate) !important; &::before { @include o-position-absolute($left: -$o-tip-arrow-size, $top: $-arrow-offset); transform: translateX(50%) rotate(45deg); } } &.top { transform: translateY(-$-tip-translate) !important; &::before { /*rtl:begin:ignore*/ @include o-position-absolute($bottom: -$o-tip-arrow-size, $left: $-arrow-offset); /*rtl:end:ignore*/ transform: translateY(-50%) rotate(45deg); } } &.left { transform: translateX(-$-tip-translate) !important; &::before { @include o-position-absolute($right: -$o-tip-arrow-size, $top: $-arrow-offset); transform: translateX(-50%) rotate(45deg); } } &.bottom { transform: translateY($-tip-translate) !important; &::before { /*rtl:begin:ignore*/ @include o-position-absolute($top: -$o-tip-arrow-size, $left: $-arrow-offset); /*rtl:end:ignore*/ transform: translateY(50%) rotate(45deg); } } &.inverse { &.left, &.right { &::before { top: auto; bottom: $-arrow-offset; } } &.top, &.bottom { &::before { left: auto#{"/*rtl:ignore*/"}; right: $-arrow-offset#{"/*rtl:ignore*/"}; } } } } } @media print { .o_tooltip { display: none !important; } }