Related
I'm adding color themes (light/dark mode) to my application however, the styling does not affect my modal, built using react-modal. I am using data attributes and CSS variables to switch between themes, with the attribute within a div with class name App. The issue is that the React Portal that contains the Modal is a sibling element to the root div, which is the parent div to App. Thus, the Modal only inherits the CSS variables from :root and not from the [data-theme='dark'] data attribute. What would be the best workaround to this issue? I've thought of the following possible solutions:
Expanding the scope of the data attributes so that it lies in body, therefore encompassing the React Portal.
Setting the colors for the React Modal through JavaScript and getting the proper colors from other elements.
Reworking the way I am implementing different themes (least favorable solution as it works for all other parts of my application)
Screenshots of DOM:
Modal closed
Modal open
CSS:
:root {
--color-background: #F8F0E3;
--color-background-secondary: #E3EBF8;
--color-background-third: #E3EBF8;
--color-text: #000000;
--color-text-alternate: #757575;
--theme-color-strong: #FFFFFF;
--color-background-highlight: #6F7378;
--color-background-opaque: rgba(248, 240, 227, 0.75);
--color-link: #0000EE;
--color-button: #FFFFFF;
--okay-color: #F9E076;
}
[data-theme='dark'] {
--color-background: #121212;
--color-background-secondary: #181818;
--color-background-third: #caced3;
--color-text: #FFFFFF;
--color-text-alternate: #FFFFFF;
--theme-color-strong: #000000;
--color-background-highlight: #e6e6e6;
--color-link: #A5C9FF;
--color-button: #121212;
--okay-color: #d3c404;
}
.rating-modal{
top: 40px;
bottom: 40px;
border: 1px solid #ccc;
background-color: var(--color-background);
overflow: auto;
border-radius: 4px;
outline: none;
padding: 20px;
position: absolute;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
width: 50%;
height: 80%;
}
Using the CSS sibling selector, you can target and apply CSS to your modal portals.
Like
[data-theme='dark'] + .ReactModalPortal {
//your CSS to apply over ReactModalPortal div
}
And you can now target children of the ReactModalPortal div as follows
[data-theme='dark'] + .ReactModalPortal .rating-modal {
//your CSS to apply over class rating-modal div
}
Background
I have an HTML div which contains a ‘tooltip’-like feature (i.e., a text box pops up when a certain element is clicked or hovered over); this tooltip has decorative pseudo-elements to make it look like a ‘speech bubble,’ added in css as :before and :after .
I have a JS script, which is intended to show and hide the tooltip and decoration, in response to click events (i.e., toggle them between ‘show’ and ‘hide’ states).
Problem
I can’t get the decorative pseudo-elements to hide when the tooltip is hidden; as pseudo-elements, they are not part of the DOM and so I can’t use normal selectors to manipulate them.
When the tooltip is hidden on click, the decorative pseudo-elements persist, which is not a usable result.
I can’t do away with the decorative elements, they are part of the work specification.
Approach tried so far
Based on this question, my thought was to add an empty span with its own class, to which I’d prepend and append these pseudo-elements. Then, add or remove the class on click based on whether it exists already, or not.
I have also tried setting the class to which the pseudo-elements are pre/appended to display:none on click, but this also seems not to work
However, I cannot convince the pseudo-elements to hide on click.
I’ve included a screenshot of what these remnant pseudo-elements look like in the live environment.
Note: I tried to work up a running simulation for the purpose of this question, but I wasn’t able to and the original css file is massive; the code included below is for reference only.
All guidance is much appreciated!
const barContainer = document.querySelector(".bar-container");
const decorationElement = document.querySelector("#decoration");
document.addEventListener('click', function(event) {
console.log('click event listener triggered');
if (event.target.closest('.link') || event.target.classList.contains('link')) {
if (barContainer.classList.contains('open')) {
barContainer.classList.remove('open')
decorationElement.classList.remove('decoration')
document.querySelector('.tooltip-container').setAttribute('style', 'display:none');
} else {
barContainer.classList.add('open')
decorationElement.classList.add('decoration')
document.querySelector('.tooltip-container').setAttribute('style', 'display:block');
}
} else {
barContainer.classList.remove('open')
decorationElement.classList.remove('decoration')
document.querySelector('.tooltip-container').setAttribute('style', 'display:none');
}
});
.foo-container {
height: auto;
position: relative;
}
.bar-container {
height: auto;
position: relative;
text-align: center;
}
.bar-container:hover .tooltip-container,
.tooltip-container:hover,
.bar-container.open .tooltip-container {
position: absolute;
display: block;
text-align: left;
background-color: #ffffff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
bottom: 50px;
right: 5%;
border-radius: 4%;
font-weight: 300;
max-width: 90%;
font-size: 14px;
padding: 20px 0;
}
/*the below two rule sets create the rotated 'decoration' */
.bar-container:hover .tooltip-container:before,
.tooltip-container:hover:before,
.bar-container.open .tooltip-container:before,
.foo-container .bar-container:hover .decoration:before {
content: "";
width: 65px;
height: 35px;
position: absolute;
overflow: hidden;
transform: rotate(-180deg);
z-index: 10;
bottom: 0;
left: 170px;
background-color: white;
}
.foo-container .bar-container.open .decoration:before,
.foo-container .bar-container:hover .decoration:before {
content: "";
position: absolute;
width: 30px;
height: 30px;
background: #fff;
transform: rotate(45deg);
left: 30px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
z-index: 2;
top: -42px;
}
/* end 'deocration' */
<div class="foo-container">
<div class="bar-container">
<p>text <span class='link'>the-link<span id='decoration' class='decoration'></span></span>
</p>
<div class='tooltip-container'>
<p>lorem </p>
</div>
</div>
</div>
Screenshot of the undesirable 'persistent pseudo-elements' behavior -->
I'm getting a background-color from an API, variable name settings.brand_color.
I want to use that variable in html element. I cant use style attribute becuase I'm using :before selector in my app.
I want to pass that API variable in my css file and use it in my :before pseudo selector.
JSX
<>
<input
type="radio"
name="language-select"
className="focus:ring-0 mr-5 my-18p default-style radio__input"
/>
<div className="radio__radio"></div>
</>;
CSS
.radio__radio {
width: 24px;
height: 24px;
background-color: #d8d8d8;
border-radius: 50%;
box-sizing: border-box;
padding: 6px;
margin-right: 20px;
z-index: 1;
}
.radio__radio::after {
content: "";
width: 100%;
height: 100%;
display: block;
background: #f28b46;
border-radius: 50%;
transform: scale(0);
z-index: 9;
}
Update
Another solution for this issue is to just use before & after from tailwinds
Pseudo-elements
While you cannot directly set the styling of a pseudo element in JS you can set a CSS variable and this can be picked up by the class setting for the pseudo element.
.radio__radio {
width: 24px;
height: 24px;
background-color: #d8d8d8;
border-radius: 50%;
box-sizing: border-box;
padding: 6px;
margin-right: 20px;
z-index: 1;
--bg: #f28b46; /* ADDED for initial condition */
}
.radio__radio::after {
content: "";
width: 100%;
height: 100%;
display: block;
background: var(--bg);
border-radius: 50%;
transform: scale(0);
z-index: 9;
}
Then in your Javascript when you get a new background color:
document.querySelector('.radio__radio').style.setProperty('--bg', newvalue);
or of course select all such radio buttons and change for each one if that is what is required.
You can use CSS Custom Properties as variables for the colors, using the :root class:
:root {
--brand-color: #f28b46;
}
.radio__radio {
width: 24px;
height: 24px;
background-color: #d8d8d8;
border-radius: 50%;
box-sizing: border-box;
padding: 6px;
margin-right: 20px;
z-index: 1;
}
.radio__radio::after {
content: "";
width: 100%;
height: 100%;
display: block;
background: var(--brand-color);
border-radius: 50%;
// transform: scale(0);
z-index: 9;
}
<div class="radio__radio"></div>
And when fetching the brand color from the API, create a style tag and update the :root brand color.
Note: the last :root variable will override any previous :root variable, so you need to make sure you create the <style> with the brand color after your initial CSS file.
:root {
--brand-color: yellow; // will be overridden
}
:root {
--brand-color: red; // that's the color that will show
}
I got the idea that you're using react, so you can do this like this:
const [brandColor, setBrandColor] = useState();
useEffect( () => {
fetchBrandColorFromAPI().then(brandColor => setBrandColor(brandColor));
}, [])
And then in the renderer:
{brandColor && <style dangerouslySetInnerHTML={{ __html: ` :root {
--brand-color: ${brandColor}
}`}} /> }
The best & easiest possible way is to add style in JSX code.
<input
id={languageLabel}
type="radio"
name="language-select"
value={languageLabel}
// defaultChecked={index === 0}
onChange={() => {
onLanguageChange(language, languageLabel);
}}
className="focus:ring-0 mr-5 my-18p default-style radio__input"
/>
Just add this part to your JSX File
<style>
{`
.radio__radio::before {
background-color: ${settings.brand_color}
}
`}
</style>
The issue is that you can't manipulate pseudo-elements in javascript; however, there are still a couple of options to manipulate them by knock-on effect.
Option 1: As A Haworth suggested, use a CSS variable.
Option 2: If you know there's only going to be a few different colours; then you could just toggle a class indicating which colour it should be. For instance, if you set the CSS up in a similar structure to this:
.radio__radio {
width: 24px;
height: 24px;
background-color: #d8d8d8;
border-radius: 50%;
box-sizing: border-box;
padding: 6px;
margin-right: 20px;
z-index: 1;
}
.radio__radio::after {
content: "";
width: 100%;
height: 100%;
display: block;
border-radius: 50%;
transform: scale(0);
z-index: 9;
}
.radio__radio.green::after{
background-color: #000066 /* Silly colour as an example */
}
.radio__radio.blue::after{
background-color: #006600 /* Silly colour as an example */
}
.radio__radio.red::after{
background-color: #660000 /* Silly colour as an example */
}
Then your javascript
var d = document.getElementsByClassName("radio__radio"); /* This way supports older browsers */
d.className += " otherclass";
Or if usimg jQuery
$('.radio__radio').addClass('green').removeClass('red').removeClass('blue');
There is no way I know of for you to directly inject a runtime variable from your API without using the javascript as a middle-man - there may be a way to do it with Blazor, but I haven't yet come across it.
<!DOCTYPE html>
<html>
<head>
<title>
How to define colors as variables in CSS?
</title>
<style>
:root {
--primary-color: rgb(15, 157, 88);
--secondary-color: rgb(255, 255, 255);
}
.first {
width: 50%;
padding: 40px 0px;
margin: 10px 0px;
text-align: center;
/* Apply color using CSS var */
background-color: var(--primary-color);
color: var(--secondary-color);
}
.second {
width: 50%;
padding: 40px 0px;
text-align: center;
/* Apply color using CSS var */
background-color: var(--primary-color);
color: var(--secondary-color);
}
</style>
</head>
<body>
<div class="first">
<h1>Stackoverflow</h1>
</div>
<div class="second">
<h1>gyan-js</h1>
</div>
</body>
</html>
I'm new to React so, I'll provide the answer with Vannila JS.
The color change can be done in the following steps:
Set a root css variable :root{ --myColor: #545454; }
Set the DOM element's color to the css variable declared in the root like color: var(--myColor);
Since, you mentioned that the element is not loaded yet so there is not point in what color this myColor has because it has not effect except the variable itself because we will use it in JS to change it.
In JS, Get the Color from the API response and store it in a variable
Use document.documentElement to set the color of the css variable myColor with the color we get from the API
All the elements with the color of the CSS variable will also change.
The Element which gets loaded will have the color by then.
// I couldn't find a fake API response giving a Color, so this function mocks the API which gives the color string after 2 seconds.
let getColorFromAPI = new Promise((resolve) => {
setTimeout(function() {
resolve('#FFFFFF')
}, 2000)
});
async function main() {
console.log("The Existing Color is: ", getComputedStyle(document.documentElement).getPropertyValue('--mainColor'))
console.log('Getting the Color from the API... ')
let newColor = await getColorFromAPI // Get the color from API
console.log('The New Color is: ', newColor)
document.documentElement.style.setProperty('--mainColor', newColor) // Changing the color of the CSS variable
}
main()
:root {
--mainColor: #545454;
}
.buttonElement {
background-color: var(--mainColor);
}
<button class="buttonElement">See the Color of this button</button>
To Wrap things up:
The function gets the color from the API and we set the color using document.documentElement.style.setProperty
You can also create a dummy class with just the background-color and append it to the element since, Browser computes the style with the latest CSS style declaration.
Hope this helps.
I had a similar problem one time that I actually solved by using another div element instead of the pseudo element. I apologize if that doesn't work for your specific use case, since you said you wanted to use the pseudo element. However, since it seems like you have access to the JS, JSX, and CSS, it might be something you could consider.
The before and after pseudo elements are almost equivalent to div elements placed as the first or last child of the parent element so adding another div like this
<div className="radio__radio">
<div
className="radio__radio__after"
style={{ backgroundColor: apiColor || '#f28b46' }}
></div>
</div>
and changing your second CSS selector like this
.radio__radio__after {
content: "";
width: 100%;
height: 100%;
display: block;
border-radius: 50%;
transform: scale(0);
z-index: 9;
}
to allow the background color to be controlled by the style prop should work - although you might need to make some slight adjustments to the CSS or JSX.
I'm having a div in HTML which is dynamically creating from the server side. I want to apply css in HTML(front-end) only on that div if and only if its having some-content. If it doesn't have any content then I have no need to apply the new styling.
The sample of HTML code is:
<div class="attr-marker">
Some-text-content <!-- Apply New Styling on it -->
</div>
<div class="attr-marker">
<!-- No need of new styling -->
</div>
<div class="attr-marker">
<!-- No need of new styling -->
<i class="fas fa-car" style="color:#d42424;font-size:px"></i>
</div>
And the CSS which I tried but failed is:
.attr-marker text {
display: block;
width: 12px;
height: 12px;
border-radius: 50%;
line-height: 12px;
font-size: 9px;
text-align: center;
background: #000;
color: #fff;
}
I can achieve it by using javascript but I want purely CSS solution so it'll help me to minimize the code.
You can set default style for empty div by using :empty pseudo selector. And then for regular div, just set the style as given above.
Or you can use :not(:empty) Pseudo Selector to set the style for the div that is not empty.
Here's an example:
.attr-marker:not(:empty) {
display: block;
width: 12px;
height: 12px;
border-radius: 50%;
line-height: 12px;
font-size: 9px;
text-align: center;
background: #000;
color: #fff;
}
Let me know in case you have any questions.
Regards,
AJ
You can use the :empty pseudo-class. However your server will need to output the .attr-marker div with no whitespace.
Like...
<div class="attr-marker"></div>
not
<div class="attr-marker">
</div>
And then the css would be,
.attr-marker:empty {
display: block;
width: 12px;
height: 12px;
border-radius: 50%;
line-height: 12px;
font-size: 9px;
text-align: center;
background: #000;
color: #fff;
}
Additional reading, https://developer.mozilla.org/en-US/docs/Web/CSS/:empty
Writing .attr-marker text { } means you want to access child elements with tag text of class attr-maker. No such tag exists in HTML.
There are specific CSS text and CSS font properties which work only on text. They are to be used in the text's parent element (in your case div with class name attr-marker):
.attr-marker {
/* text properties */
/* some other properties */
}
Properties like display: block;, width: 12px;, height: 12px; and so on, won't work on text.
That being said, you don't need to worry whether your CSS properties will be applied to the text or to the whole div. If you're using the right properties, you can be sure they are only applied to the text.
As for the content(text) presence, you don't need to worry about it. If there is no text, CSS won't change anything.
Either add another class to that div from the server side if it will send content or wrap content with another element and give it some styling.
Edit:
If you know exact position of your element then you can select it with nth-child pseudo-class:
.attr-marker:nth-child(1):not(:empty) {
border: 1px solid #333;
background-color: yellow;
}
If these markers are block rendered elements, the browser should not display them, unless they have content, therefore you can trust the browser to not render the elements with no content, use the max-width and max-height properties below:
.attr-marker {
display: block;
max-width: 12px;
max-height: 12px;
border-radius: 50%;
line-height: 12px;
font-size: 9px;
text-align: center;
background: #000;
color: #fff;
/*If required*/
overflow:hidden
}
Example:
Link
How do I change the presentation of the "title" attribute in the browser?. By default, it just has yellow background and small font. I would like to make it bigger and change the background color.
Is there a CSS way to style the title attribute?
It seems that there is in fact a pure CSS solution, requiring only the css attr expression, generated content and attribute selectors (which suggests that it works as far back as IE8):
https://jsfiddle.net/z42r2vv0/2/
a {
position: relative;
display: inline-block;
margin-top: 20px;
}
a[title]:hover::after {
content: attr(title);
position: absolute;
top: -100%;
left: 0;
}
<a href="http://www.google.com/" title="Hello world!">
Hover over me
</a>
update w/ input from #ViROscar: please note that it's not necessary to use any specific attribute, although I've used the "title" attribute in the example above; actually my recommendation would be to use the "alt" attribute, as there is some chance that the content will be accessible to users unable to benefit from CSS.
update again I'm not changing the code because the "title" attribute has basically come to mean the "tooltip" attribute, and it's probably not a good idea to hide important text inside a field only accessible on hover, but if you're interested in making this text accessible the "aria-label" attribute seems like the best place for it: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute
You can't style an actual title attribute
How the text in the title attribute is displayed is defined by the browser and varies from browser to browser. It's not possible for a webpage to apply any style to the tooltip that the browser displays based on the title attribute.
However, you can create something very similar using other attributes.
You can make a pseudo-tooltip with CSS and a custom attribute (e.g. data-title)
For this, I'd use a data-title attribute. data-* attributes are a method to store custom data in DOM elements/HTML. There are multiple ways of accessing them. Importantly, they can be selected by CSS.
Given that you can use CSS to select elements with data-title attributes, you can then use CSS to create :after (or :before) content that contains the value of the attribute using attr().
Styled tooltip Examples
Bigger and with a different background color (per question's request):
[data-title]:hover:after {
opacity: 1;
transition: all 0.1s ease 0.5s;
visibility: visible;
}
[data-title]:after {
content: attr(data-title);
background-color: #00FF00;
color: #111;
font-size: 150%;
position: absolute;
padding: 1px 5px 2px 5px;
bottom: -1.6em;
left: 100%;
white-space: nowrap;
box-shadow: 1px 1px 3px #222222;
opacity: 0;
border: 1px solid #111111;
z-index: 99999;
visibility: hidden;
}
[data-title] {
position: relative;
}
Link with styled tooltip (bigger and with a different background color, as requested in the question)<br/>
Link with normal tooltip
More elaborate styling (adapted from this blog post):
[data-title]:hover:after {
opacity: 1;
transition: all 0.1s ease 0.5s;
visibility: visible;
}
[data-title]:after {
content: attr(data-title);
position: absolute;
bottom: -1.6em;
left: 100%;
padding: 4px 4px 4px 8px;
color: #222;
white-space: nowrap;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0px 0px 4px #222;
-webkit-box-shadow: 0px 0px 4px #222;
box-shadow: 0px 0px 4px #222;
background-image: -moz-linear-gradient(top, #f8f8f8, #cccccc);
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #f8f8f8),color-stop(1, #cccccc));
background-image: -webkit-linear-gradient(top, #f8f8f8, #cccccc);
background-image: -moz-linear-gradient(top, #f8f8f8, #cccccc);
background-image: -ms-linear-gradient(top, #f8f8f8, #cccccc);
background-image: -o-linear-gradient(top, #f8f8f8, #cccccc);
opacity: 0;
z-index: 99999;
visibility: hidden;
}
[data-title] {
position: relative;
}
Link with styled tooltip<br/>
Link with normal tooltip
Known issues
Unlike a real title tooltip, the tooltip produced by the above CSS is not, necessarily, guaranteed to be visible on the page (i.e. it might be outside the visible area). On the other hand, it is guaranteed to be within the current window, which is not the case for an actual tooltip.
In addition, the pseudo-tooltip is positioned relative to the element that has the pseudo-tooltip rather than relative to where the mouse is on that element. You may want to fine-tune where the pseudo-tooltip is displayed. Having it appear in a known location relative to the element can be a benefit or a drawback, depending on the situation.
You can't use :before or :after on elements which are not containers
There's a good explanation in this answer to "Can I use a :before or :after pseudo-element on an input field?"
Effectively, this means that you can't use this method directly on elements like <input type="text"/>, <textarea/>, <img>, etc. The easy solution is to wrap the element that's not a container in a <span> or <div> and have the pseudo-tooltip on the container.
Examples of using a pseudo-tooltip on a <span> wrapping a non-container element:
[data-title]:hover:after {
opacity: 1;
transition: all 0.1s ease 0.5s;
visibility: visible;
}
[data-title]:after {
content: attr(data-title);
background-color: #00FF00;
color: #111;
font-size: 150%;
position: absolute;
padding: 1px 5px 2px 5px;
bottom: -1.6em;
left: 100%;
white-space: nowrap;
box-shadow: 1px 1px 3px #222222;
opacity: 0;
border: 1px solid #111111;
z-index: 99999;
visibility: hidden;
}
[data-title] {
position: relative;
}
.pseudo-tooltip-wrapper {
/*This causes the wrapping element to be the same size as what it contains.*/
display: inline-block;
}
Text input with a pseudo-tooltip:<br/>
<span class="pseudo-tooltip-wrapper" data-title="input type="text""><input type='text'></span><br/><br/><br/>
Textarea with a pseudo-tooltip:<br/>
<span class="pseudo-tooltip-wrapper" data-title="this is a textarea"><textarea data-title="this is a textarea"></textarea></span><br/>
From the code on the blog post linked above (which I first saw in an answer here that plagiarized it), it appeared obvious to me to use a data-* attribute instead of the title attribute. Doing so was also suggested in a comment by snostorm on that (now deleted) answer.
Here is an example of how to do it:
a.tip {
border-bottom: 1px dashed;
text-decoration: none
}
a.tip:hover {
cursor: help;
position: relative
}
a.tip span {
display: none
}
a.tip:hover span {
border: #c0c0c0 1px dotted;
padding: 5px 20px 5px 5px;
display: block;
z-index: 100;
background: url(../images/status-info.png) #f0f0f0 no-repeat 100% 5%;
left: 0px;
margin: 10px;
width: 250px;
position: absolute;
top: 10px;
text-decoration: none
}
Link<span>This is the CSS tooltip showing up when you mouse over the link</span>
CSS can't change the tooltip appearance. It is browser/OS-dependent. If you want something different you'll have to use Javascript to generate markup when you hover over the element instead of the default tooltip.
I have found the answer here: http://www.webdesignerdepot.com/2012/11/how-to-create-a-simple-css3-tooltip/
my own code goes like this, I have changed the attribute name, if you maintain the title name for the attribute you end up having two popups for the same text, another change is that my text on hovering displays underneath the exposed text.
.tags {
display: inline;
position: relative;
}
.tags:hover:after {
background: #333;
background: rgba(0, 0, 0, .8);
border-radius: 5px;
bottom: -34px;
color: #fff;
content: attr(data-gloss);
left: 20%;
padding: 5px 15px;
position: absolute;
z-index: 98;
width: 350px;
}
.tags:hover:before {
border: solid;
border-color: #333 transparent;
border-width: 0 6px 6px 6px;
bottom: -4px;
content: "";
left: 50%;
position: absolute;
z-index: 99;
}
<a class="tags" data-gloss="Text shown on hovering">Exposed text</a>
I thought i'd post my 20 lines JavaScript solution here. It is not perfect, but may be useful for some depending on what you need from your tooltips.
When to use it
Automatically styles the tooltip for all HTML elements with a TITLE attribute defined (this includes elements dynamically added to the document in the future)
No Javascript/HTML changes or hacks required for every tooltip (just the TITLE attribute, semantically clear)
Very light (adds about 300 bytes gzipped and minified)
You want only a very basic styleable tooltip
When NOT to use
Requires jQuery, so do not use if you don't use jQuery
Bad support for nested elements that both have tooltips
You need more than one tooltip on the screen at the same time
You need the tooltip to disappear after some time
The code
// Use a closure to keep vars out of global scope
(function () {
var ID = "tooltip", CLS_ON = "tooltip_ON", FOLLOW = true,
DATA = "_tooltip", OFFSET_X = 20, OFFSET_Y = 10,
showAt = function (e) {
var ntop = e.pageY + OFFSET_Y, nleft = e.pageX + OFFSET_X;
$("#" + ID).html($(e.target).data(DATA)).css({
position: "absolute", top: ntop, left: nleft
}).show();
};
$(document).on("mouseenter", "*[title]", function (e) {
$(this).data(DATA, $(this).attr("title"));
$(this).removeAttr("title").addClass(CLS_ON);
$("<div id='" + ID + "' />").appendTo("body");
showAt(e);
});
$(document).on("mouseleave", "." + CLS_ON, function (e) {
$(this).attr("title", $(this).data(DATA)).removeClass(CLS_ON);
$("#" + ID).remove();
});
if (FOLLOW) { $(document).on("mousemove", "." + CLS_ON, showAt); }
}());
Paste it anywhere, it should work even when you run this code before the DOM is ready (it just won't show your tooltips until DOM is ready).
Customize
You can change the var declarations on the second line to customize it a bit.
var ID = "tooltip"; // The ID of the styleable tooltip
var CLS_ON = "tooltip_ON"; // Does not matter, make it somewhat unique
var FOLLOW = true; // TRUE to enable mouse following, FALSE to have static tooltips
var DATA = "_tooltip"; // Does not matter, make it somewhat unique
var OFFSET_X = 20, OFFSET_Y = 10; // Tooltip's distance to the cursor
Style
You can now style your tooltips using the following CSS:
#tooltip {
background: #fff;
border: 1px solid red;
padding: 3px 10px;
}
A jsfiddle for custom tooltip pattern is Here
It is based on CSS Positioning and pseduo class selectors
Check MDN docs for cross-browser support of pseudo classes
<!-- HTML -->
<p>
<a href="http://www.google.com/" class="tooltip">
I am a
<span> (This website rocks) </span></a> a developer.
</p>
/*CSS*/
a.tooltip {
position: relative;
}
a.tooltip span {
display: none;
}
a.tooltip:hover span, a.tooltip:focus span {
display:block;
position:absolute;
top:1em;
left:1.5em;
padding: 0.2em 0.6em;
border:1px solid #996633;
background-color:#FFFF66;
color:#000;
}
Native tooltip cannot be styled.
That being said, you can use some library that would show styles floating layers when element is being hovered (instead of the native tooltips, and suppress them) requiring little or no code modifications...
You cannot style the default browser tooltip. But you can use javascript to create your own custom HTML tooltips.
a[title="My site"] {
color: red;
}
This also works with any attribute you want to add for instance:
HTML
<div class="my_class" anything="whatever">My Stuff</div>
CSS
.my_class[anything="whatever"] {
color: red;
}
See it work at: http://jsfiddle.net/vpYWE/1/