I have a SVG of all countries in the world and I want to add a tooltip on whenever you hover over a country that is already highlighted blue above the country. That tooltip will contain a list of names. How can I achieve this?
What I am looking for is demonstrated here, just hover over the text "Top" at the top of the page here: https://www.w3schools.com/css/css_tooltip.asp
This is the SVG Map: http://occ.uk.com/occ/associate-members/
This is the code for the map: https://www.dropbox.com/s/ofm2io1ahv2k7gh/SVGWorldMapSharing.html?dl=0
Any help is greatly appreciated, thanks.
The code is available on
https://codepen.io/anon/pen/WdjJzz
Add the onmouseevent handler below to your svg element; i.e. handleMouseMove="onmousemove(event)"
function handleMouseMove(event) {
var countryId = event.target.id;
var tooltip = document.getElementById("tooltip");
switch (countryId) {
case "AT":
case "FR":
case "DE":
case "IT":
case "NL":
case "AU":
case "IL":
break;
default:
return tooltip.classList.remove("active");
}
var x = event.clientX;
var y = event.clientY;
tooltip.style.left = (x + 20) + "px";
tooltip.style.top = (y - 20) + "px";
tooltip.innerHTML = countryId;
tooltip.classList.add("active");
}
Use the following css
.tooltiptext {
display: none;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
position: fixed;
z-index: 1;
}
.tooltiptext.active {
display: initial;
}
Add the following element to your html, just before the svg element. You may control the tooltip content based on your work, and you can do that dynamically by changing the inner html manually on mouse over.
<span class="tooltiptext" id="tooltip">Tooltip text</span>
Related
I would like to create a button using that floats until footer and then stops
1) Button should be poisition: fixed; bottom: 0px when footer is not visible
2) When footer becomes visible, button should just sit on top of footer
The button should handle following cases.
when states change in angular, when we get data from server the footer is visible for a moment and then the page expands, what will happen then?
when the page has less content and footer is visible, button should sit on top of footer.
How can i do this?
Here is the plunker i started to play around with
http://plnkr.co/edit/SoCBjkUjFICiuTeTPxDB?p=preview
I came across this post when searching for a similar solution. Without a ready answer, this is what I ended up doing, based on this post https://ngmilk.rocks/2015/04/09/angularjs-sticky-navigation-directive/ .
Basicly you need a $scope.$watch to watch for scope change, and an event handler attached to the onscroll event.
angular.module('myApp')
.directive('stickyBottom', function($window) {
return {
restrict: 'A',
scope: {},
link: function (scope, elem, attrs) {
// the element box saved for later reference
var elemRect;
// element height
var height = elem[0].clientHeight;
// element top, will be changed as scope is updated
var top = 0;
// updates element's original position
scope.$watch(function(){
elemRect = elem[0].getBoundingClientRect();
return elemRect.top + $window.pageYOffset;
}, function(newVal, oldVal){
// this is the original element position, save it
if(!elem.hasClass('fixed-bottom')){
top = newVal;
}
// properly position the element even in `fixed` display
elem.css('width', elemRect.width);
elem.css('left', elemRect.left);
// check position
toggleClass();
});
// toggle `fixed-bottom` class based on element's position
var toggleClass = function() {
// the element is hidden
if (elem[0].getBoundingClientRect().top + height > $window.innerHeight) {
elem.addClass('fixed-bottom');
}
// the element is visible
else {
// the element is visible in its original position
if (top - $window.pageYOffset + height < $window.innerHeight && elem.hasClass('fixed-bottom')) {
elem.removeClass('fixed-bottom');
}
}
}
// bind to `onscroll` event
$window.onscroll = function() {
toggleClass();
};
}
};
})
;
And here's some css:
.fixed-bottom {
position: fixed;
top: auto;
bottom: 0;
}
You can accomplish this affect without using angular at all by modifying your style.css. The simplest solution in this case is just to set the bottom parameter of the #to-top element to be at minimum higher than the footer, for example:
#to-top {
position:fixed;
bottom: 60px;
right: 10px;
width: 100px;
padding: 5px;
border: 1px solid #ccc;
background: red;
color: white;
font-weight: bold;
text-align: center;
cursor: pointer;
}
I am looking for a way to animate (with #keyframes, transform...) some elements when the user scrolls the page. For example:
When offset is 0: div has height: 100px.
When offset is between 0 and 100: div is height: 50px and color: blue.
And so on...
Is is possible using pure CSS?
If it is not, what are the most efficient ways to do it with HTML or Javascript?
The most efficient way to animate an element's style properties depending on scroll position will probably be to add a class with a scroll function:
Working Example
myID = document.getElementById("myID");
var myScrollFunc = function() {
var y = window.scrollY;
if (y > 500) {
// myID.style.backgroundColor = "blue"; // you can add individual styles
myID.className = "blue" // or add classes
} else {
// myID.style.backgroundColor = "red";
myID.className = "red"
}
};
window.addEventListener("scroll", myScrollFunc);
body {
height: 1100px;
}
#myID {
position: fixed;
height: 100px;
line-height: 20px;
transition: all 1s;
}
.blue {
background: blue;
animation: myAnimation 1s both;
}
.red {
background: red;
}
#keyframes myAnimation {
0% {
border-radius: 0px;
line-height: 10px;
}
100% {
border-radius: 100%;
line-height: 100px;
}
}
<div id="myID" class="red">Hello world</div>
Docs:
.scrollY
.className
.addEventListener
Methinnks it's not possible to 'spy' scroll with pure css. If you want, you can do this with jQuery:
$(document).scroll(function() {
var pos = parseInt($(document).scrollTop())
if(pos == 0) {
$('.yourDivClass').css({
height : '100px' ,
color : '#fff'
})
}
if (pos > 0 && pos <= 100) {
$('.yourDivClass').css({
height : '50px' ,
color : 'blue'
})
}
console.log(pos)
})
and of course if you wanna get a smooth transition, you supposed to declare transitions in your css file
.yourDivClass {
transition: height 0.5s ease
}
Scrolling is an event. Once you scroll the page, the event gets triggered and something happens. You cannot control events using Pure CSS. Period.
Some people would argue that even :hover is an event. Yes, and it is for some strange reason, implemented in CSS, but not others.
With pure CSS: no.
But you can have a class with keyframed animation associated with it, and then say when the element is scrolled into view, to add the class to the element. This will make it start doing the animation.
You can use Waypoints.js to set what happens when you reach a specific element of a page.
I would like to add an arrow (or "triangle") after the current selected row of a html table (to highlight what is selected, rather than using a background color change).
The triangle should be facing left, like this '<'.
I have managed to add a class to the current selected row, and I think the rest can be done in css only, but I haven't been able to do it.
Fiddle: http://jsfiddle.net/j95f8met/
Here is the script to highlight the row:
document.querySelector('table').onclick = highlight;
function highlight(e) {
e = e || event;
var from = findrow(e.target || e.srcElement),
highlighted = /highlighted/i.test((from || {}).className);
if (from) {
var rows = from.parentNode.querySelectorAll('tr');
for (var i = 0; i < rows.length; i += 1) {
rows[i].className = '';
}
from.className = !highlighted ? 'highlighted' : '';
}
}
function findrow(el) {
if (/tr/i.test(el.tagName)) return el;
var elx;
while (elx = el.parentNode) {
if (/tr/i.test(elx.tagName)) {
return elx;
}
}
return null;
}
Here is my CSS:
tr.highlighted td {
background: red;
}
tr.highlighted:after {
border-bottom: 60px solid transparent;
border-left: 60px solid green;
border-top: 60px solid transparent;
height: 0;
width: 0;
float:right;
}
'Content' must fix your problem ;)
content: '';
http://jsfiddle.net/j95f8met/3/
You need to set the content attribute on the :after pseudo-element.
Why this is required you can read below this question: Why do pseudo-elements require a content property?
So, technically, you could also add content: "\003c"; and you will get the character (less-than) <. This can be used to replace the borders you have set to create the triangle.
To style the < character you can then use font-family, color, font-size etc.
To place the < character more appropriate you can work with CSS positioning.
Hope this helps.
I want to make my div tag with id "drag_me" to be draggable up to the length of 300px from left and 460px from top, only using CSS.
I also want to make it resizable. Again same condition as above i.e. no Javascript or jquery.
What's the solution for this?
This is the best you can do without JavaScript:
[draggable=true] {
cursor: move;
}
.resizable {
overflow: scroll;
resize: both;
max-width: 300px;
max-height: 460px;
border: 1px solid black;
min-width: 50px;
min-height: 50px;
background-color: skyblue;
}
<div draggable="true" class="resizable"></div>
Demo
draggable attribute on HTML5 Rocks
CSS resize property on MDN
You can take a look at HTML 5, but I don't think you can restrict the area within you can drag it, just the destination:
http://www.w3schools.com/html/html5_draganddrop.asp
And if you don't mind using some great library, I would encourage you to try Dragula.
Only using css techniques this does not seem possible to me. But you could use jqueryui draggable:
$('#drag_me').draggable();
I found this from W3Schools is really helpful:
// Make the DIV element draggable:
dragElement(document.getElementById("mydiv"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
// if present, the header is where you move the DIV from:
document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
} else {
// otherwise, move the DIV from anywhere inside the DIV:
elmnt.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
#mydiv {
position: absolute;
z-index: 9;
background-color: #f1f1f1;
border: 1px solid #d3d3d3;
text-align: center;
}
#mydivheader {
padding: 10px;
cursor: move;
z-index: 10;
background-color: #2196F3;
color: #fff;
}
<!-- Draggable DIV -->
<div id="mydiv">
<!-- Include a header DIV with the same name as the draggable DIV, followed by "header" -->
<div id="mydivheader">Click here to move</div>
<p>Move</p>
<p>this</p>
<p>DIV</p>
</div>
I hope you can use it to!
CSS is designed to describe the presentation of documents. It has a few features for changing that presentation in reaction to user interaction (primarily :hover for indicating that you are now pointing at something interactive).
Making something draggable isn't a simple matter of presentation. It is firmly in the territory of interactivity logic, which is handled by JavaScript.
What you want is not achievable.
You can do it now by using the CSS property -webkit-user-drag:
#drag_me {
-webkit-user-drag: element;
}
<div draggable="true" id="drag_me">
Your draggable content here
</div>
This property is only supported by webkit browsers, such as Safari or Chrome, but it is a nice approach to get it working using only CSS.
The HTML5 draggable attribute is only set to ensure dragging works for other browsers.
You can find more information here: http://help.dottoro.com/lcbixvwm.php
Draggable div not possible only with CSS, if you want draggable div you must need to use javascript.
http://jqueryui.com/draggable/
After going down the rabbit-hole of trying to do this myself by copy-pasting various code-snippets from Stack Overflow, I would highly recommend just using the InteractJS library, which allows you to create a draggable and resizable div (somewhat) easily.
$('#dialog').draggable({ handle: "#tblOverlay" , scroll: false });
// Pop up Window
<div id="dialog">
<table id="tblOverlay">
<tr><td></td></tr>
<table>
</div>
Options:
handle : Avoids the sticky scroll bar issue. Sometimes your mouse pointer will stick to the popup window while dragging.
scroll : Prevent popup window to go beyond parent page or out of current
screen.
I'm trying to create a page layout like This
But I am not sure how to achieve it. What I mean; in that page you can see there are two areas in the page and you can resize the areas using the bar between them.
Thanks!
Yes, it's certainly possible. There's probably a JQuery or MooTools plugin out there that does it. Otherwise, I rolled you a simple example using JQuery that you can play with. See this JSFiddle.
Basically the HTML is like this:
<div id="left">Left column!</div>
<div id="verticalresizer"> </div>
<div id="right">Right column!</div>
And then they are positioned absolutely (extra CSS from example cut for simplicity's sake):
html, body {
height: 100%;
}
#left {
width: 200px; /* default starting width */
position: absolute;
top: 0;
bottom: 0;
left: 0;
}
#right {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 204px; /* width of left col + 4 pixel wide resizer */
}
#verticalresizer {
background-color: black; /* so it can be seen */
width: 4px;
height: 100%;
cursor: col-resize;
position: absolute;
top: 0;
left: 200px; /* width of left col */
bottom: 0;
}
Then the JavaScript. First an explanation. Pretty much the code listens for the user to click down on the vertical resizer. Once that happens, it listens for the mouse moving. Every time the mouse moves, resize the columns accordingly and keep the slider underneath the mouse. When the user lets go of the mouse (mouseup), stop listening/resizing.
var left = 200; // starting left col width
var isClicked = false;
var startX = 200; // starting horizontal position of resizer bar
var isMouseDown = false;
// attach listeners to the document itself
$(document).mousedown(function() {
isMouseDown = true;
}).mouseup(function() {
isMouseDown = false;
}).mousemove( function(event) {
if (isClicked && isMouseDown) {
var newX = event.pageX;
if (startX != newX) {
left += (newX - startX);
if (left < 0) {
left = 0; // keep from moving the slider beyond the left edge of the screen
newX = 0;
}
setWidthOfLeftColumn( left );
startX = newX;
}
}
});
// attach click listeners to the resizer slider
$("#verticalresizer").mousedown( function(event) {
isClicked = true;
startX = event.pageX;
}).mouseup( function (event) {
isClicked = false;
});
// function to resize everything
function setWidthOfLeftColumn( value ) {
$("#left").css("width", "" + left + "px");
$("#right").css("left", "" + (left + 4) + "px");
$("#verticalresizer").css("left", "" + left + "px");
}
Try using the HTML frameset tag.
http://www.w3schools.com/tags/tag_frameset.asp