I am making a voting system. When user click on a link with class "vote" a voting box appears just belov the clicked link. It looks like this at the moment:
My problem is that if the page is scrolled then the vote box is not positioned correctly. I want it to always appear just below the link and to stick to the link even when page is scrolled.
My container is styled like this:
#vote_container {
position: fixed;
height: 82px;
min-height: 83px;
background-color: #e7edf3;
border: 3px solid #d3d6d8;
border-radius: 10px;
left: 40%;
margin-top: 6px;
padding: 10px;
text-align: left;
top: 60%;
z-index: 199;
}
And this is the code I use to position the container:
var pos = $(this).offset();
var width = $(this).width();
$("#vote_container").css({ "left": (pos.left - 16) + "px", "top": (pos.top + 28) + "px" });
Ive even created a simplified example at jsFiddle.
Does changing the #vote_container position to absolute resolve your issue?
http://jsfiddle.net/xkNqG/9/
EDIT:
Also, in the css I added display:none and in the function added $('#vote_container').show()
The #vote_container should not be 'position: fixed' as ngen says it should instead be 'position: absolute' here is my fiddle I simplified your css (for temporary purposes) just to help get to the root of the problem and added more text so that the fiddle would actually demonstrate the scroll problem.
If you want a pure css solution try this.
css
.tipLink{
color:#33f;
cursor:pointer;
position:relative;
}
.tip{
position:absolute;
display:none;
top:80%;
left:110%;
background-color:#dddddd;
border:1px solid black;
width:100px;
color:black;
z-index:20;
padding:3px;
-webkit-border-radius:5px 5px 5px 5px;
-moz-border-radius:5px 5px 5px 5px;
border-radius:5px 5px 5px 5px;
text-align:center;
}
.tipLink:hover .tip{
display:block;
}
HTML
<span class="tipLink">
Mouse Over Me
<span class="tip">Hello World</span>
</span>
You will have to style the inner span tag to the design you need, but this should work.
Why don't you use the jQuery tooltip plugin, http://bassistance.de/jquery-plugins/jquery-plugin-tooltip, and enhance it by styling it the way you want. It already handles positioning and can have text or markup in it.
Related
I have a situation where, in normal CSS circumstances, a fixed div would be positioned exactly where it is specified (top:0px, left:0px).
This does not seem to be respected if I have a parent that has a translate3d transform. Am I not seeing something? I have tried other webkit-transform like style and transform origin options but had no luck.
I have attached a JSFiddle with an example where I would have expected the yellow box be at the top corner of the page rather than inside of the container element.
You can find below a simplified version of the fiddle:
#outer {
position:relative;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 300px;
border: 1px solid #5511FF;
padding: 10px;
background: rgba(100,180,250, .8);
width: 80%;
}
#middle{
position:relative;
border: 1px dotted #445511;
height: 300px;
padding: 5px;
background: rgba(250,10,255, .6);
}
#inner {
position: fixed;
top: 0px;
box-shadow: 3px 3px 3px #333;
height: 20px;
left: 0px;
background: rgba(200,180,80, .8);
margin: 5px;
padding: 5px;
}
<div id="container">
Blue: Outer, <br>
Purple: Middle<br>
Yellow: Inner<br>
<div id="outer">
<div id="middle">
<div id="inner">
Inner block
</div>
</div>
</div>
</div>
How can I make translate3d work with fixed-positioned children?
This is because the transform creates a new local coordinate system, as per W3C spec:
In the HTML namespace, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.
This means that fixed positioning becomes fixed to the transformed element, rather than the viewport.
There's not currently a work-around that I'm aware of.
It is also documented on Eric Meyer's article: Un-fixing Fixed Elements with CSS Transforms.
As Bradoergo suggested, just get the window scrollTop and add it to the absolute position top like:
function fix_scroll() {
var s = $(window).scrollTop();
var fixedTitle = $('#fixedContainer');
fixedTitle.css('position','absolute');
fixedTitle.css('top',s + 'px');
}fix_scroll();
$(window).on('scroll',fix_scroll);
This worked for me anyway.
I had a flickering on my fixed top nav when items in the page were using transform, the following applied to my top nav resolved the jumping/flickering issue:
#fixedTopNav {
position: fixed;
top: 0;
transform: translateZ(0);
-webkit-transform: translateZ(0);
}
Thanks to this answer on SO
In Firefox and Safari you can use position: sticky; instead of position: fixed; but it will not work in other browsers. For that you need javascript.
In my opinion, the best method to deal with this is to apply the same translate, but break children that need to be fixed out of their parent (translated) element; and then apply the translate to a div inside the position: fixed wrapper.
The results look something like this (in your case):
<div style='position:relative; border: 1px solid #5511FF;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 100px; width: 200px;'>
</div>
<div style='position: fixed; top: 0px;
box-shadow: 3px 3px 3px #333;
height: 20px; left: 0px;'>
<div style='-webkit-transform:translate3d(0px, 20px, 0px);'>
Inner block
</div>
</div>
JSFiddle: https://jsfiddle.net/hju4nws1/
While this may not be ideal for some use cases, typically if you're fixing a div you probably could care less about what element is its parent/where it falls in the inheritance tree in your DOM, and seems to solve most of the headache - while still allowing both translate and position: fixed to live in (relative) harmony.
I ran across the same problem. The only difference is that my element with 'position: fixed' had its 'top' and 'left' style properties set from JS. So I was able to apply a fix:
var oRect = oElement.getBoundingClientRect();
oRect object will contain real (relative to view port) top and left coordinates. So you can adjust your actual oElement.style.top and oElement.style.left properties.
I have an off canvas sidebar that uses -webkit-transform: translate3d. This was preventing me from placing a fixed footer on the page. I resolved the issue by targeting a class on the html page that is added to the tag on initialization of the sidebar and then writing a css :not qualifier to state "-webkit-transform: none;" to the html tag when that class is not present on the html tag. Hope this helps someone out there with this same issue!
Try to apply opposite transform to the child element:
<div style='position:relative; border: 1px solid #5511FF;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 100px; width: 200px;'>
<div style='position: fixed; top: 0px;
-webkit-transform:translate3d(-100%, 0px , 0px);
box-shadow: 3px 3px 3px #333;
height: 20px; left: 0px;'>
Inner block
</div>
</div>
Add a dynamic class while the element transforms.$('#elementId').addClass('transformed').
Then go on to declare in css,
.translat3d(#x, #y, #z) {
-webkit-transform: translate3d(#X, #y, #z);
transform: translate3d(#x, #y, #z);
//All other subsidaries as -moz-transform, -o-transform and -ms-transform
}
then
#elementId {
-webkit-transform: none;
transform: none;
}
then
.transformed {
#elementId {
.translate3d(0px, 20px, 0px);
}
}
Now position: fixed when provided with a top and z-index property values on a child element just work fine and stay fixed until the parent element transforms. When the transformation is reverted the child element pops as fixed again. This should easen the situation if you are actually using a navigation sidebar that toggles open and closes upon a click, and you have a tab-set which should stay sticky as you scroll down the page.
One way to deal with this is to apply the same transform to the fixed element:
<br>
<div style='position:relative; border: 1px solid #5511FF;
-webkit-transform:translate3d(0px, 20px , 0px);
height: 100px; width: 200px;'>
<div style='position: fixed; top: 0px;
-webkit-transform:translate3d(0px, 20px , 0px);
box-shadow: 3px 3px 3px #333;
height: 20px; left: 0px;'>
Inner block
</div>
</div>
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/
I've been playing around with a fixed navigation bar, but I've noticed that when it "fixes" itself, the content below all jumps up on the page.
This is the JSFiddle I've been working on, if you look closely you'll notice that when the nav bar becomes fixed to the top of the screen, the content jumps up ~1 line. I've tried playing around with the Javascript:
var win = $(window),
fxel = $('nav'),
eloffset = fxel.offset().top;
win.scroll(function() {
if (eloffset < win.scrollTop()) {
fxel.addClass("fixed");
} else {
fxel.removeClass("fixed");
}
});
but I'm fairly certain the problem is in the CSS:
*{
margin: 0;
padding: 0;
}
nav {
width: 100%;
background: white;
height: 35px;
border-bottom: solid 1px #E8E8E8;
}
nav.fixed {
position:fixed;
top: 0;
right:0px;
left:0px;
z-index:999;
height: 30px;
border-bottom: solid 1px #E8E8E8;
padding-bottom: 5px;
}
h1{
font-family: 'Lobster', cursive;
font-size: 50px;
text-align: center;
}
Any solutions on how to fix the jumping would be really helpful.
For refrence, I'm trying to get something sort of like this where the very top of the page isn't part of the navbar.
When an element is set to position: fixed, it no longer takes up space on the page, meaning it won't push other elements down on the page. So as soon as your javascript adds the fixed class, the element no longer takes up space, and so the other content jumps up to take the place where it was.
To offset this, you may need to add another rule to add something like a top margin to the next element. The top margin will need to be the height of the (now) fixed element, plus any padding and margin in the fixed element:
https://jsfiddle.net/h6g33wne/8/
nav.fixed + * {
margin-top: 35px;
}
I have the basic idea of my JavaScript operational.
The point of my JavaScript is to make an image of id 'player' move to the position that I click with the mouse, only when I click on the div with the id of 'stage' with the animation lasting 3 seconds.
At the same time, when the animation is running the head should change to 'player is moving' as opposed to when it is still and displaying 'player is still'.
Right now, in Chrome (maybe its a bug with Chrome) the basic functionality of the JS works. However, it seems to overshoot the position of where I click the mouse on the first round and then barely move when I click again in the 'stage' div.
If anyone sees where I might be running into a problem please let me know!
Here's my EDITED JQuery:
$(document).ready(function(){
$('#stage').click(function(e){
$('#header h1').html('Player is moving!');
$('#player').animate({
top: e.pageY + 'px',
left: e.pageX + 'px'
}, 3000, function(){
$('#header h1').html('Player is standing still...');
});
});
});
I have fixed my CSS issue, so don't worry about that but the code is located below for the CSS in case anyone thinks the issue may lie within.
Thanks!
EDIT:
Here's the CSS. The issue has been solved but it has been provided for convenience if you think the issue of the image overshooting the image may lie within for any reason:
#header {
width: 600px;
margin: 20px auto 10px;
padding: 5px;
background-color: whiteSmoke;
border: 1px solid #aaa;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
box-shadow: 0 0 5px #ccc;
}
#header h1 {
text-align: center;
margin: 0;
}
#stage {
overflow: hidden;
width: 600px;
height: 400px;
margin: 0 auto;
padding: 5px;
background-color: whiteSmoke;
border: 1px solid #aaa;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
box-shadow: 0 0 5px #ccc;
position: relative;
}
#player {
position: absolute;
width: 36px;
}
Poor man's example : jsfiddle but it works in FF and Chrome.
Also, I'm curious what styles you lose, simple color style is always applied.
So more information is needed, can you share the complete css?
Update: I'm still not seeing an issue in chrome (with the fiddle example)
Change #stage to something like
#stage {width:600px;height:600px;background-color:#333;position:fixed;top:20;left:0;}
Your player vs page is lying about it's position or where you can click. I wanted the stage to be a fixed item on the page, non-moving. I don't see any other reason (in your CSS or jQuery) why it'd overshoot.
I am looking for a way to have an image dynamically centered on any div size. How is this possible?
I have posted a jsFiddle for better understanding here http://jsfiddle.net/4exmm/ but as I said the div size is changed using a PHP script.
Vertically and horizontally aligned:
http://jsfiddle.net/4exmm/2/
Make your div text-align: center. http://jsfiddle.net/4exmm/1/
#image {
background: none repeat scroll 0 0 #FFFFFF;
border: 1px solid #E1E1E1;
float: left;
margin-right: 10px;
padding: 3px;
width: 300px;
text-align:center;
}
Just add this rule to #image:
text-align:center;
Why not just text-align: center on the div
you could also make your img margin: 0 auto to keep it aligned withing whatever object