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.
Related
Result has no space.
Code has a space between words.
How do I fix this? I need to use inline-block (or any inline display) because my animation won't work without it.
CSS
This is the javascript for the animation.
const text = document.querySelector("h1");
const strText = text.textContent;
const splitTxt = strText.split("");
text.textContent = "";
for(let i=0; i < splitTxt.length; i++){
text.innerHTML += "<span>"+ splitTxt[i] + "</span>";
}
let char = 0;
let timer = setInterval(onTick, 50);
function onTick() {
const span = text.querySelectorAll('span')[char];
span.classList.add('fade');
char++;
if(char === splitTxt.length) {
complete();
return;
}
}
function complete() {
clearInterval(timer);
timer = null;
}
Edit: I fixed this by putting a in between the letters.
If you want every word of the h1 to be inside of a span tag, you should do the split with a whitespace, like this:
const splitTxt = strText.split(" ");
In your code you have the quotes inside the split function without the space between, and that will cause that every character to be in a span.
You mean this?
header {
position:relative;
height: 200px;
width: 200px;
border: 1px solid #333;
display: flex;
align-items: center;
justify-content: center;
}
<header>
<h1>
myText
</h1>
</header>
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>
based on this thread
I am trying to use images in the HTML from the above link. Fiddle is here
body {
margin: 0;
padding: 0;
}
.main {
background: yellow;
overflow: hidden;
width: 100%;
}
.columns {
background: red;
-webkit-column-fill: auto;
-webkit-column-width: 300px;
-webkit-column-gap: 40px;
-moz-column-fill: auto;
-moz-column-width: 300px;
-moz-column-gap: 40px;
height: 120px;
padding: 0 20px;
width: auto;
overflow-x: auto;
}
.columns img{
height:none;
display: block;
}
.columns > p:last-of-type {
margin-right: 20px;
}
Horizontal scrolling works great, but the image gets divided into columns as well. I didn't know that this is even possible. I like it to stay in one part with the height of the column and auto width not with the column width. So that the columns coming after it gets shifted.
I think I find a possible way to realize what I wanted.
Now it uses a bit JS and Jquery. Here is the fiddle.
Main point is to check page.offsetHeight < page.scrollHeight to see if the textfield has overflow. When it has create a new div.
Here is the JS:
$( document ).ready(function() {
$( ".element2" ).each(function( i,obj ) {
if(this.tagName == "IMG"){
$("#paginatedText").append(obj);
}else{
paginateText(obj);
}
console.log(this.tagName);
});
function paginateText(element) {
//console.log(element);
var text = $(element).html(); // gets the text, which should be displayed later on
//console.log(text);
var textArray = text.split(" "); // makes the text to an array of words
createPage(); // creates the first page
for (var i = 0; i < textArray.length; i++) { // loops through all the words
//$( ".element" ).last().append(textArray[i]);
var success = appendToLastPage(textArray[i]); // tries to fill the word in the last page
if (!success) { // checks if word could not be filled in last page
createPage(); // create new empty page
appendToLastPage(textArray[i]); // fill the word in the new last element
}
}
}
function createPage() {
var page = document.createElement("div"); // creates new html element
page.setAttribute("class", "page"); // appends the class "page" to the element
document.getElementById("paginatedText").appendChild(page); // appends the element to the container for all the pages
}
function appendToLastPage(word) {
var page = document.getElementsByClassName("page")[document.getElementsByClassName("page").length - 1]; // gets the last page
var pageText = page.innerHTML; // gets the text from the last page
page.innerHTML += word + " "; // saves the text of the last page
if (page.offsetHeight < page.scrollHeight) { // checks if the page overflows (more words than space)
page.innerHTML = pageText; //resets the page-text
return false; // returns false because page is full
} else {
return true; // returns true because word was successfully filled in the page
}
}
});
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;
}
Is there a way to reset a background-color property of a :hover rule?
I have a list of elements which are highlighted when mouse goes over. I want to apply an additional CSS rule that will disable highlighting. Here is a demo:
http://jsfiddle.net/vqLuU/1/
What should I put in the second appearance of the "style1:hover" rule in order to disable highlighting at all? The result must be the same with case when all "style1:hover" rules are removed.
I do not want to redefine all styles ("green" and "blue") again. My goal is to disable the "style1:hover" rule.
HTML:
<div class="style1 green">AAA</div>
<div class="style1 blue">BBB</div>
CSS:
.green {
background-color: green;
}
.blue {
background-color: blue;
}
.style1:hover {
background-color: red;
}
.style1:hover {
/* How to disable highlighting from here? */
}
Thanks!
Since the first appearance of the .style1:hover rule cannot be changed or removed, the only way to achieve that is by adding the following rules:
.green:hover {
background-color: green;
}
.blue:hover {
background-color: blue;
}
I feel the need to add a disclaimer: this solution is not very elegant, and I don't think of it as the best solution, I think it's the only possible solution given the requirements.
Note: this may not be a viable solution as you have not mentioned whether you can use JavaScript.
You can remove the CSS rule by editing the stylesheets with JavaScript. However it doesn't feel right to me, so I can't fully recommend this =) Maybe other SOers can comment on this method (see jsFiddle).
for (var i = 0; i < document.styleSheets.length; i++ ) {
var done = false;
var sheet = document.styleSheets[i];
# Some browsers use rules (Chrome) others use cssRules (Firefox)
var rules = sheet.rules || sheet.cssRules;
for (var j = 0; j < rules.length; j++) {
var rule = rules[j];
var selectorText = rule.selectorText;
if (selectorText.indexOf(".style1:hover") != -1) {
sheet.deleteRule(j);
done = true;
break;
}
}
if (done) break;
}
.style1:hover {
background-color: red;
}
.style1:hover {
background-color: transparent !important;
}
Easiest way I can think to achieve what I think you want is to add an extra class to the elements. I've chosen 'hoverEnabled'
You can simply add or remove the class hoverEnabled to an element to have a different :hover style attached.
CSS
.green {
background-color: green;
}
.blue {
background-color: blue;
}
.style1.hoverEnabled:hover {
background-color: #FFAAAA;
}
.style2.hoverEnabled:hover {
background-color: #AAAAAA;
}
HTML
<div class="style1 green">AAA</div>
<div class="style1 blue">BBB</div>
<div class="style1 hoverEnabled green">AAA</div>
<div class="style2 hoverEnabled blue">BBB</div>