How to add arrows in matTooltip? - javascript

I'm trying to add arrows on matTooltip, there is any way to add arrows on matTooltip.
<button mat-raised-button
matTooltip="Info about the action"
aria-label="Button that displays a tooltip when focused or hovered over">
Action
</button>

You need to override material styles. and add before/after pseudo-element as arrow. For example if you need to style a tooltip with left border and arrow just do something like that
.mat-tooltip {
// to make possible place arrow pseudo element outside tooltip with absolute positioning
overflow: visible;
position: relative;
&.right {
border-left: 6px solid red;
margin-left: 5px;
&::before {
position: absolute;
content: '';
display: inline-block;
background-color: red;
clip-path: polygon(50% 0, 0 50%, 50% 100%);
left: -12px;
width: 15px;
height: 15px;
top: 50%;
transform: translateY(-50%);
}
}
}

Following the usage of Material Design, arrows are not included in angular tooltip component. Here you could take a look what you can do and not to do with tooltips https://material.io/components/tooltips/

Related

HTML & CSS Tooltip Keeping On Screen

I need help keeping my CSS tooltip on screen for my website. It unfortunately is too big for the website near the edge of the screen and also is WAY too big for any mobile device and doesn't position correctly (probably because I plan to add very large descriptions in each tooltip). I would like to just use CSS but would be willing to use JS as I'm starting to think that may be the only way to do it correctly, but I'm having a lot of trouble figuring out how to make it work.
I basically had copied over the code from another website with many tweaks if it helps you understand my code better: https://www.w3schools.com/css/css_tooltip.asp
The only results I could find online were about centering the tooltip on the screen which strangely didn't work and code using SCSS which I'm not experienced with and would prefer not to use.
Here is my partial HTML and CSS code:
body {
overflow-x: hidden;
overflow-y: scroll;
}
.ref {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
}
.ref .versekjv {
visibility: hidden;
width: 250px;
background-color: black;
color: #fff;
text-align: left;
padding: 5px;
border-radius: 6px;
z-index: 98;
position: absolute;
top: 100%;
left: 50%;
margin-left: -125px;
flex-direction: column;
}
.ref .versekjv::after {
content: " ";
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent black transparent;
}
.ref:hover .versekjv {
visibility: visible;
}
.redletters {
color:red;
}
#media screen and (max-width:1000px){
.ref .versekjv {
font-size: 1rem;
max-width: 20rem;
position: fixed;
bottom: auto; top: 13%;
left: 78%;
text-align: left;
transform: translate(-50%);
transform: translateX(-50%);
white-space: normal;
z-index: 98;
}
.ref .versekjv::after {
border-color: transparent;
}
}
<li class="box"><a>
<div class="innerbox">Reference</div>
<div class="innerbox"><u class="ref">Reference<span class="versekjv"><b>Bible Book</b><p><i>#</i> Verse Text</p></span></u></div>
<div class="innerbox"><u class="ref">Reference<span class="versekjv"><b>Bible Book</b><p><i>#</i> Verse Text</p></span></u>; <u class="ref">Reference<span class="versekjv"><b>Bible Book</b><p><i>Verse Num.</i> Verse Text</p></span></u></div>
</a></li>
Thank you so much for your help!
First, you need to get the DOM object of your tooltip,
let tooltip = document.querySelector(".ref .versekjv")
Then, you can use the js method "getBoundingClientRect", which gives you an object that has top, right, left and bottom fields which give you the distances of your element from top, right, left and bottom of the viewport. If your element is fully visible inside the element, all four fields would be positive numbers, otherwise it means it's partly invisible, for example a left field of "-10" means about 10px of length of your elements is beyond the left edge of the viewport.
What you can do is that you always check the top, left, ... distances of your element, and if they are negative numbers, manually change them and thus position your element correctly, which could be achieved like this:
tooltip.style.left = 20

How to center tooltips for block elements with CSS or JS?

I'm trying to create a custom Tooltip component where the direction of the tooltip is passed via a prop:
Hello, <Tooltip>Right tooltip (Hover).</Tooltip>
I made this component, which works fine with inline elements, has position issues when it comes to a component with block elements:
Hello, <Tooltip><div className="box">This has click event tooltip with a block element.</div></Tooltip>
The issue is when a tooltip has a block element as its child, the tooltip misaligns and completely breaks.
Is there an approach where the tooltip can be positioned on the center edge of the component, just like how it works with inline text?
How can I fix this?
I've changed margin-bottom: 0; to margin-bottom: -6px; for tooltip triangle to plced in center of tooltip edge.
[data-tooltip-dir="left"]:before {
margin-left: 0;
margin-right: -12px;
margin-bottom: -6px;
border-top-color: transparent;
border-left-color: #000;
border-left-color: hsla(0, 0%, 20%, 0.9);
}
[data-tooltip-dir="right"]:before {
margin-bottom: -6px;
margin-left: -12px;
border-top-color: transparent;
border-right-color: #000;
border-right-color: hsla(0, 0%, 20%, 0.9);
}
then
.tooltip {
position: relative;
cursor: pointer;
display: inline-block;
}
Here is the sandbox containing the fixed version.hope to solve your problem!
Update
For Next.js and style jsx
accesing to data-attribute in <style jsx> is a bit different.insted of
[data-tooltip-dir="left"] you should use class name in front of [] like this
.tooltip[data-tooltip-dir="left"]
temporary sandbox

circle with gradient background border and changing colors with js

I need to make a circular border something like this code snippet / fiddle:
.box {
width: 250px;
height: 250px;
position: relative;
margin: auto;
margin: 30px;
border-radius: 50%;
background: #fff;
}
.box:after {
content: '';
position: absolute;
top: -15px;
bottom: -15px;
right: -15px;
left: -15px;
background-image: linear-gradient(to bottom left, #7B73A4 0%, #150E5E 100%);
z-index: -1;
border-radius: inherit;
}
<div class="box"></div>
except the inner space needs to be transparent and there needs to be a way of changing the border's gradient color.
I can use anything with js/jquery/css/html
Is it possible? If yes, how? Thanks
It is possible using a <canvas> element (which is supported in all browsers except for IE 8 and older).
Here are some useful links:
Canvas tutorial - MDN
Canvas API - MDN
Canvas Cheat Sheet
You could also use an SVG element, but that makes the animation much more difficult.

Positioning disables hover selector and mouseover events

This jsfiddle..
https://jsfiddle.net/9e1wd245/12/
..demonstrates a browser behavior I'd like to understand better than I do.
If you remove the positioning from the crumbtray and the crumb, the hover- selected CSS is applied when the crumb is hovered and mouseover events are triggered when the mouse enters the crumb.
With the positioning in place, neither of those things happen; but if you hover over the top border, the hover CSS is applied and the mouseover event is triggered.
(In this situation, the approach used uses positioning to enable z-indexing so that the curved right border will appear over the left side of the adjacent elements.)
Note that you can take the negative right margin off the crumb, and the problem persists, so it isn't being caused by the negative margin.
I realize I could use an svg for a crumb, or maybe use a couple of separator elements over a shared background rather than using positioning and z-indexing, but why doesn't this work? Is there something in the spec that says hover and mouseover events aren't expected to work for positioned elements? Is there something else entirely that I'm overlooking?
html:
<div class="crumbtray">
<span class="crumb">USA</span>
<span class="crumb">California</span>
<span class="crumb">Sacremento</span>
</div>
css:
.crumbtray {
position: relative;
top: 0px;
left: 0px;
display: inline;
z-index: -10;
font-family: ariel, sansserif
font-size: 12px;
}
.crumb {
position: relative;
top: 0px;
left: 0px;
display: inline;
border: solid 1px gray;
border-left: none;
border-radius: 0px 10px 10px 0px;
padding: 0px 8px 0 12px;
margin-right: -10px;
cursor: pointer;
background: #c3f4c6;
background: -moz-linear-gradient(top, #c3f4c6 0%, #96f788 8%, #98e0a4 92%, #419330 96%, #188700 100%);
background: -webkit-linear-gradient(top, #c3f4c6 0%,#96f788 8%,#98e0a4 92%,#419330 96%,#188700 100%);
background: linear-gradient(to bottom, #c3f4c6 0%,#96f788 8%,#98e0a4 92%,#419330 96%,#188700 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c3f4c6', endColorstr='#188700',GradientType=0 );
}
.crumb:hover {
background: none;
background-color: yellow;
}
.crumb:first-child {
border-left: solid 1px gray;
z-index: 60;
padding-left: 2px;
}
.crumb:nth-child(2) {
z-index: 50;
}
.crumb:nth-child(3){
z-index: 40;
}
JavaScript:
var ViewModel = {
init: function(){
console.log("ViewModel.init called");
$('.crumbtray').on('mouseover','span',function(){
console.log('mouseover crumb: ', this);
});
}
};
$(ViewModel.init);
Your problem is here:
z-index: -10;
This puts the element behind the background, which means although you can see it, the mouse can't "see" it because it is behind the (transparent) background, so it does not recieve mouseover events.
Now, it should still work, because the .crumbs have a positive z-index, above the background. It's likely that there is simply a bug, I do not believe this behaviour is documented anywhere.
It doesn't work, because you've set a negative z-index to parent element (Why did you do that?). Just remove it from there or change it to some positive value, like 1, for example.
When you set a negative z-index to element, it creates negative stacking context of all children element, so z-index width 40, 50, 60 just make sense inside it's parent, but main z-index will be negative (under body element).
So the main problem is negative z-index, you can cut it and search some information with 'negative z-index hover' keywords to clear the situation
.crumbtray {
position: relative;
top: 0px;
left: 0px;
display: inline;
z-index: -10;
font-family: ariel, sansserif
font-size: 12px;
}

How can I make an arrow on an instruction box on the right move to point to the field on the left that is in focus?

I have a web page with a form on it. The page is separated into two columns, left and right. The form is on the left and there is a box with instructions on the right.
Currently, the box on the right is comprised of a cssarrowplease #arrow_box div that is configured with the arrow pointing left.
I would like that arrow to move so that it points to the form field on the left that has focus.
By playing with the CSS, I can manually move the arrow up and down. However, I am unsure how to make those moves dynamically as I tab or click to focus on each different form field.
If I understand correctly, you can add classes for each position and change the class of the #arrow_box div according to the style when focus is on certain form fields.
Although this is a lengthy method.
CSS Class 1:
.arrow_box
{
position: relative;
background: #88b7d5;
border: 4px solid #c2e1f5;
}
.arrow_box:after, .arrow_box:before
{
left: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.arrow_box:after
{
border-color: rgba(136, 183, 213, 0);
border-left-color: #88b7d5;
border-width: 10px;
top: 10%;
margin-top: -10px;
}
.arrow_box:before
{
border-color: rgba(194, 225, 245, 0);
border-left-color: #c2e1f5;
border-width: 16px;
top: 10%;
margin-top: -16px;
}
and CSS Class 2:
The only change will be the className and the following:
Example:
.arrow_box
{
top: 10%;
}
becomes
.arrow_box_element2
{
top: 20%;
}
Lets say you have a JavaScript method which is called when Focus is on element:
function onFocusElement1()
{
$("#arrow_box").attr('class', 'arrow_box');
}
function onFocusElement2()
{
$("#arrow_box").attr('class', 'arrow_box_element2');
}
Hope this helps :)

Categories