Hover on element and highlight all elements with the same class - css

I have many elements with the same class on a web page. I would like to highlight all these elements when I hover one of them. How can I do that in CSS?
Right now, I have this CSS:
p.un:hover { background-color:yellow;}
And my HTML:
<div class="book">
<div class="page left">
<p class="un">Karen…</p>
</div>
<div class="page right">
<p class="un">Karen ne se retourne pas. Mme Tilford reste là, apparemment confuse et abattue.</p>
</div>

The best you can do using pure CSS is this:
.classname:hover ~ .classname {
background-color: yellow;
}
But this only highlights all siblings with a class classname after the hovered element.
You have to use JavaScript to highlight all elements;
var elms = document.getElementsByClassName("classname");
var n = elms.length;
function changeColor(color) {
for(var i = 0; i < n; i ++) {
elms[i].style.backgroundColor = color;
}
}
for(var i = 0; i < n; i ++) {
elms[i].onmouseover = function() {
changeColor("yellow");
};
elms[i].onmouseout = function() {
changeColor("white");
};
}
If you have multiple classes and want to generalize this, use something like this:
var classes = ["one", "two", "three"]; //list of your classes
var elms = {};
var n = {}, nclasses = classes.length;
function changeColor(classname, color) {
var curN = n[classname];
for(var i = 0; i < curN; i ++) {
elms[classname][i].style.backgroundColor = color;
}
}
for(var k = 0; k < nclasses; k ++) {
var curClass = classes[k];
elms[curClass] = document.getElementsByClassName(curClass);
n[curClass] = elms[curClass].length;
var curN = n[curClass];
for(var i = 0; i < curN; i ++) {
elms[curClass][i].onmouseover = function() {
changeColor(this.className, "yellow");
};
elms[curClass][i].onmouseout = function() {
changeColor(this.className, "white");
};
}
};

Thanks to the answer from Chris. I used his code to write a simple function that does the job. You can place the function in the <head></head> but you need to call it when the page has been loaded, i.e. place in the end of the body. colorout is the background-color
The function:
function hoverByClass(classname,colorover,colorout="transparent"){
var elms=document.getElementsByClassName(classname);
for(var i=0;i<elms.length;i++){
elms[i].onmouseover = function(){
for(var k=0;k<elms.length;k++){
elms[k].style.backgroundColor="orange";//colorover;
}
};
elms[i].onmouseout = function(){
for(var k=0;k<elms.length;k++){
elms[k].style.backgroundColor=colorout;
}
};
}
}
and call the function like this:
hoverByClass("un","yellow");
hoverByClass("un2","pink");
I know the question is old, but maybe that help someone else :)
Try it here:
function hoverByClass(classname,colorover,colorout="transparent"){
var elms=document.getElementsByClassName(classname);
for(var i=0;i<elms.length;i++){
elms[i].onmouseover = function(){
for(var k=0;k<elms.length;k++){
elms[k].style.backgroundColor=colorover;
}
};
elms[i].onmouseout = function(){
for(var k=0;k<elms.length;k++){
elms[k].style.backgroundColor=colorout;
}
};
}
}
hoverByClass("un","yellow");
hoverByClass("un2","pink");
<div class="book">
<div class="page left">
<p class="un">Karen…</p><p class="un2">Karen2…</p>
</div>
<div class="page right">
<p class="un">Karen ne se retourne pas. Mme Tilford reste là, apparemment confuse et abattue.</p><p class="un2">Karen2 ne se retourne pas. Mme Tilford2 reste là, apparemment confuse et abattue.</p>
</div>
</div>

Related

Auto save image or by button

This code is for writing text on the image .. I had trouble saving the image, I cannot save it to the phone
I got a solution here and succeeded in saving the pictures to the phone ..
In answer number 1
Save image to local automatically
but I couldn't use it for my code
function myFunction() {
document.getElementById("canvas").style.display = "block";
var x = document.getElementById("myText").value;
//demoo document.getElementById("demo").innerHTML = x;
addTextToImage("https://l.top4top.io/p_1549mpaz31.png", x);
}
function addTextToImage(imagePath, text) {
var circle_canvas = document.getElementById("canvas");
var context = circle_canvas.getContext("2d");
// Draw Image function
var img = new Image();
img.src = imagePath;
img.onload = function () {
context.font = "40px Cairo";
context.textAlign = "center";
context.drawImage(img, 0, 0);
context.lineWidth = 1;
context.fillStyle = "#ffffff";
context.lineStyle = "#ffff00";
context.fillText(text, 520, 790);
}
}
#import url('https://fonts.googleapis.com/css?family=Cairo:300,400,600,700,900');
.container {
position: relative;
font-family: Arial;
font-family: 'Cairo';
}
<canvas style="display:none" id="canvas" width="1080" height="1080"></canvas>
<input type="text" id="myText" value="write your name">
<button onclick="myFunction()">button</button> ..
<p id="demoo"></p>
I have added a codepen for you. Please check and let me know if you have any more query. I just focused on how you can download image from canvas. I think that is your most concerned issue.
HTML
<input type="text" id="text" placeholder="write your name">
<button onclick="writeText()">Show Image</button>
<button onclick="download()">Download Image</button>
<canvas id="canvas" width="200" height="200"></canvas>
JS
function writeText() {
console.log("Hello")
var canvas = document.getElementById("canvas");
var name = document.getElementById("text").value;
if(name.trim() == "" || name.trim().length == 0) {
alert("Write something in the text box first");
return;
}
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText(name, 10, 50);
}
function download() {
writeText()
var link = document.createElement('a');
link.download = 'text.png';
link.href = document.getElementById("canvas").toDataURL()
link.click();
}
https://codepen.io/kousik-mandal/pen/RwWjmqM
Thank you.

How can I make sematic-ui-react Tab responsive?

I'm developing a react application and I recently start to use semantic ui react module.
Unfortunately I'm not able to make the Tab object responsive...
A really simple script to show this is:
import React from 'react'
import { withRouter } from 'react-router-dom'
import {Tab} from 'semantic-ui-react';
// import NavSection from './NavSection'
var sections = ["SectionA","SectionB","SectionC","SectionD","SectionE","SectionF"]
const NavigatorHeader = () => (
<div>
<h1>Navigator</h1>
<div>
<Tab menu={{ pointing: true }} panes={getPanes(sections)} />
</div>
</div>
)
export default withRouter(NavigatorHeader)
function getPanes(sections){
return sections.map( function(section){
return {
menuItem: section,
render: () =>
<Tab.Pane attacched="false">
<div>
<p>
Some Text that we can change tab from tab. E.g. with the title: <b>{section}</b>
</p>
</div>
</Tab.Pane>
}
})
}
The tabs look great, inline, but if I reduce the screen they just overflow, while I was expecting they would have moved to a second line.
Look like that this is coming from the Selenium-ui css I'm using (https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css). Current version is 2.3.1 but if I go back to use a version before 2.0.0, it was responsive.. is there a way to obtain the same behavior with the new version?
Thanks,
Michele.
Thanks,
Michele.
Based on the previous answer I found an easier way to achieve this.
I defined a CSS with the values suggested:
.wrapped{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
and then just passed that additional class to the menu
<Tab menu={{ pointing: true, className: "wrapped" }} panes={getPanes(sections)} />
That solved the problem without any additional javascript.
Here is a solution that I created some time ago in regular Semantic. It behaves like Bootstrap and does not require a second set of menu items. It requires just a tiny bit of JS and CSS.
The JS:
$(function() {
// Set up to handle wrapping of tab menu (tab actuator) items
$(window).resize(function() {
checkIfWrapped();
});
checkIfWrapped(); // Make sure the function is fired upon document ready
});
// Detect whether a Semantic UI tabular menu is wrapped
function checkIfWrapped() {
var pos_top_1st = $('.tabular.menu .item').first().position().top;
$('.tabular.menu .item:not(first-child)').each(function() {
var pos_top = $(this).position().top;
if (pos_top > pos_top_1st) {
$(this).parent().addClass('wrapped');
return;
} else if (pos_top == pos_top_1st) {
$(this).parent().removeClass('wrapped');
}
});
The HTML structure. (Note that placing the .tabular.menu .item-s inside a div within the overall .tabular.menu allows the use of a separate .right.menu within the .tabular.menu if desired) :
<div id="tabs-menu" class="ui top attached tabular menu">
<div id="qj-tabs">
<div class="tab item"></div>
<div class="tab item"></div>
<div class="tab item"></div>
</div>
<div class="right menu">
<a class="tab item"><i class="add icon"></i> Add Job</a>
<a class="tab item"><i class="copy icon"></i> Copy Item</a>
</div>
</div>
<div class="botttom attached tab segment"></div>
<div class="botttom attached tab segment"></div>
</div>
The CSS:
#qj-tabs {
display: flex !important; /* Will not work unless defined as display: flex */
flex-direction: row !important;
flex-wrap: wrap !important;
}
#tabs-menu .wrapped .item {
border-radius: 5px !important;
border: 1px lightgray solid !important; /* Just styling for the default theme here */
margin: 0 2px 2px 0 !important;
}
#tabs-menu .wrapped .active.item {
background-color: lightgray;
}
This is what i did some weeks ago in regular Semanitic-ui.
! function($) {
var WinReszier = (function() {
var registered = [];
var inited = false;
var timer;
var resize = function(ev) {
clearTimeout(timer);
timer = setTimeout(notify, 100);
};
var notify = function() {
for (var i = 0, cnt = registered.length; i < cnt; i++) {
registered[i].apply();
}
};
return {
register: function(fn) {
registered.push(fn);
if (inited === false) {
$(window).bind('resize', resize);
inited = true;
}
},
unregister: function(fn) {
for (var i = 0, cnt = registered.length; i < cnt; i++) {
if (registered[i] == fn) {
delete registered[i];
break;
}
}
}
};
}());
var TabDrop = function(element, options) {
this.element = $(element);
var $this = this;
this.dropdown = $('<div class="ui item right dropdown" data-popup data-content="' + options.text + '" data-position="bottom center">' +
options.icon +
'<div class="menu"></div>' +
'</div>').appendTo($this.element);
this.click = function() {
$this.element.removeClass("pointing");
$this.element.find("a.item").not(this).removeClass("active");
};
this.reverseclick = function(el) {
$this.element.find(".item.right.dropdown .menu a.item").removeClass("active selected");
$this.element.addClass("pointing");
};
WinReszier.register($.proxy(this.layout, this));
this.layout();
$(".ui.dropdown").dropdown();
$("[data-popup]").popup();
};
TabDrop.prototype = {
constructor: TabDrop,
layout: function() {
var $main = this;
var $this = this.element;
var $drpdwn = this.dropdown;
var $fullwidth = $this.width() - 25;
this.element
.append($drpdwn.find('.ui.item.right'))
.find('a.item')
.not('.item.right.dropdown')
.each(function() {
var $blockLenght = parseInt($(this).width());
var $space = $fullwidth - $blockLenght;
if ($space > $blockLenght) {
$(this).click($main.reverseclick)
if ($drpdwn.find('.menu a').length > 0) {
var $reverse = $drpdwn.find('.menu a:first-child');
$reverse.click($main.reverseclick).removeClass("selected")
$reverse.insertBefore($drpdwn);
}
} else {
var $dropItem = $(this)
$dropItem.click($main.click)
$drpdwn.find('.menu').append($dropItem);
}
$fullwidth = $space;
});
}
};
$.fn.tabdrop = function(option) {
return this.each(function() {
var $this = $(this),
data = $this.data('tabdrop'),
options = typeof option === 'object' && option;
if (!data) {
$this.data('tabdrop', (data = new TabDrop(this, $.extend({},
$.fn.tabdrop.defaults, options))));
}
if (typeof option == 'string') {
data[option]();
}
});
};
$.fn.tabdrop.defaults = {
text: 'More',
icon: '<i class="icon align justify m-0"></i>'
};
$.fn.tabdrop.Constructor = TabDrop;
}(window.jQuery);
var Tabs = {
tabDrop: function() {
setTimeout(function() {
$('.tabdrop').tabdrop({
text: 'More Configuration'
});
}, 1000)
}
};
$(document).on("ready", function() {
$('.menu .item').tab();
Tabs.tabDrop();
$(window).resize(function() {
Tabs.tabDrop();
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.3/semantic.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.3/semantic.min.js"></script>
<div class="ui top attached pointing menu tabdrop">
<a class="item" data-tab="tab1">Tab Item 1</a>
<a class="item" data-tab="tab2">Tab Item 2</a>
<a class="item" data-tab="tab3">Tab Item 3</a>
<a class="item" data-tab="tab4">Tab Item 4</a>
<a class="item" data-tab="tab5">Tab Item (A very long tab title)</a>
</div>

Images doesn't show in media print with Google Chrome

I have an application which prints barcodes using images for each column (p.png) and the same for spacing (b.png) as follow:
<img src="imagens/p.png" width="1" height="50" border="0">
<img src="imagens/b.png" width="1" height="50" border="0">
<img src="imagens/p.png" width="1" height="50" border="0">
<img src="imagens/b.png" width="2" height="50" border="0">
<img src="imagens/p.png" width="2" height="50" border="0">
[...]
I didn't use any of css to change img in #media print.
The problem is: Chrome doesn't print some imgs ( p.png ).
1. Original barcode
2. Print in Chrome
3. Print in Firefox
Alternative solution: Use javascript canvas to solve this problem.
I create a code in codePen for use in all browsers:
https://codepen.io/eltonsrc/pen/OpXyrQ
HTML:
<div style="width: 600px">
<canvas id="barcode" class="barcode">
Code for browsers without canvas support. For example:
<img src="blackBar.gif" width="1" height="50">
<img src="whiteBar.gif" width="1" height="50">
</canvas>
</div>
CSS:
.barcode {
width: 100%;
height: 50px;
}
Javascript:
var barCode = (function (){
this.WHITE = 'rgb(255, 255, 255)';
this.BLACK = 'rgb(0, 0, 0)';
this.THIN_BAR = 1;
this.THICK_BAR = 3;
this.lastPixel = 0;
this.drawBar = function (barWidth, color) {
this.ctx.fillStyle = color;
this.ctx.fillRect(this.lastPixel, 0, barWidth, this.canvas.height);
this.lastPixel += barWidth;
};
this.draw2of5BarCode = function (barcodeNumber) {
var barCodes = ['00110', '10001', '01001', '11000', '00101', '10100', '01100', '00011', '10010', '01010'];
for (var f1 = 9; f1 >= 0; f1--) {
for (var f2 = 9; f2 >= 0; f2--) {
var f = f1 * 10 + f2;
var texto = '';
for (var i = 0; i < 5; i++) {
texto += barCodes[f1].substr(i, 1) + barCodes[f2].substr(i, 1);
}
barCodes[f] = texto;
}
}
// begin of barcode
this.drawBar(this.THIN_BAR, this.BLACK);
this.drawBar(this.THIN_BAR, this.WHITE);
this.drawBar(this.THIN_BAR, this.BLACK);
this.drawBar(this.THIN_BAR, this.WHITE);
if (barcodeNumber.length % 2 != 0) {
barcodeNumber = '0' + barcodeNumber;
}
do {
var i = Number(barcodeNumber.substr(0, 2));
if (barcodeNumber.length == 2) {
barcodeNumber = '';
} else {
barcodeNumber = barcodeNumber.substr(2, barcodeNumber.length - 2);
}
var f = barCodes[i];
for (i = 0; i < 10; i += 2) {
if (f.substr(i, 1) == '0') {
this.drawBar(this.THIN_BAR, this.BLACK);
} else {
this.drawBar(this.THICK_BAR, this.BLACK);
}
if (f.substr(i + 1, 1) == '0') {
this.drawBar(this.THIN_BAR, this.WHITE);
} else {
this.drawBar(this.THICK_BAR, this.WHITE);
}
}
} while(barcodeNumber.length > 0);
this.drawBar(this.THICK_BAR, this.BLACK);
this.drawBar(this.THIN_BAR, this.WHITE);
this.drawBar(this.THIN_BAR, this.BLACK);
}
this.drawBarcode = function (canvasId, barcodeNumber) {
this.canvas = document.getElementById(canvasId);
// verify canvas support
if (!this.canvas.getContext) {
return;
}
this.lastPixel = 0;
this.ctx = this.canvas.getContext('2d');
this.draw2of5BarCode(barcodeNumber);
};
return this;
})();
barCode.drawBarcode('barcode', '856000000005227702201707619934651263800000000003');
Alternative Solution: Use SVG to generate your barcodes!
I found a library to which creates 'ITF' barcodes without errors: https://github.com/kreativekorp/barcode
include 'barcode.php';
$generator = new barcode_generator();
/* Generate SVG markup. */
$symbology = 'itf';
$data = '23790198019000000053081017674607670300000001000';
$options['w'] = '50';
$options['p'] = '2';
$svg = $generator->render_svg($symbology, $data, $options);
echo $svg;
Many thanks to #kreativekorp for this awesome php library.

placing 50% transparent div over canvas so canvas is still visible

I am having trouble placing a div over a canvas where the canvas is still visible. I can only get it to where the div is over the canvas but the canvas is hidden. If anyone has an example that would be lovely.
var canvas = document.querySelector('canvas');
canvas.width = screen.width;
canvas.height = screen.height;
var context = canvas.getContext('2d');
var tau = 2 * Math.PI;
function Triangle(canvs, cnt, sid, f) {
this.phase = 0;
this.ctx = canvs.getContext('2d');
this.first = f;
this.sides = sid;
this.canv = canvs;
this.draw = drawTriangle;
this.size = 100;
}
function drawTriangle() {
requestAnimationFrame(drawTriangle.bind(this));
var x = 0;
var y = 0;
var centerX = this.canv.width / 2;
var centerY = this.canv.height / 4;
this.phase += 0.005 * tau;
if (this.first == 1) {
this.ctx.clearRect(0, 0, this.canv.width, this.canv.height);
}
this.ctx.beginPath();
for (var i = 0; i <= this.sides; i++) {
this.ctx[i ? 'lineTo' : 'moveTo'](
centerX + this.size * Math.cos(this.phase + i / this.sides * tau),
centerY + this.size * Math.sin(this.phase + i / this.sides * tau)
);
}
this.ctx.strokeStyle = '#dda36b';
this.ctx.stroke();
this.size--;
}
var collection = [];
var triangle1 = new Triangle(canvas, context, 3, 1);
triangle1.draw();
var i = 0;
function nextFrame() {
if (i < 1000) {
collection[i] = new Triangle(canvas, context, 3, 0);
collection[i].draw();
i++;
setTimeout(nextFrame, 500);
}
}
setTimeout(nextFrame, 0);
body {
background-color: #19191b
}
<div align="center">
<button id="test">Test button that needed some text to make it longer</button>
<br>
</div>
<div>
<canvas></canvas>
</div>
So the button takes up the entire width of the screen and you cannot see anything beneath it. I would like the div to be transparent so you can see the triangles beneath it.
Use position:absolute so you can freely position elements in their parent element with top or bottom and left or right. This allows HTML elements to overlap. Make sure that those elements you want to be in the foreground come after those you want to be in the background (or alternatively, use the z-index CSS property).
This is your code slightly modified for faster results. I did not change anything of matter in the JS section (just removed the resizing code so the demonstrated behavior is visible sooner). Interesting are the changes to the CSS and HTML below.
var canvas = document.querySelector('.mycanvas');
var context = canvas.getContext('2d');
var tau = 2 * Math.PI;
function Triangle(canvs, cnt, sid, f) {
this.phase = 0;
this.ctx = canvs.getContext('2d');
this.first = f;
this.sides = sid;
this.canv = canvs;
this.draw = drawTriangle;
this.size = 100;
}
function drawTriangle() {
requestAnimationFrame(drawTriangle.bind(this));
var x = 0;
var y = 0;
var centerX = this.canv.width / 2;
var centerY = this.canv.height / 4;
this.phase += 0.005 * tau;
if (this.first == 1) {
this.ctx.clearRect(0, 0, this.canv.width, this.canv.height);
}
this.ctx.beginPath();
for (var i = 0; i <= this.sides; i++) {
this.ctx[i ? 'lineTo' : 'moveTo'](
centerX + this.size * Math.cos(this.phase + i / this.sides * tau),
centerY + this.size * Math.sin(this.phase + i / this.sides * tau)
);
}
this.ctx.strokeStyle = '#dda36b';
this.ctx.stroke();
this.size--;
}
var collection = [];
var triangle1 = new Triangle(canvas, context, 3, 1);
triangle1.draw();
var i = 0;
function nextFrame() {
if (i < 1000) {
collection[i] = new Triangle(canvas, context, 3, 0);
collection[i].draw();
i++;
setTimeout(nextFrame, 500);
}
}
setTimeout(nextFrame, 0);
.mycanvas {
position:absolute;
background-color: #19191b
}
.mydiv {
position:absolute;
left:100px;
top:30px;
opacity:0.5;
background-color: rgb(100, 100, 200);
}
<div>
<div>
<canvas class="mycanvas"></canvas>
</div>
<div class="mydiv">
Hello World!
</div>
</div>

Chrome Extension - iFrame auto-height

I have created an iFrame in my Google Chrome Extension popup and applied CSS so it has no border and height: 100%.
However, it appears with a limited height and shows a vertical scrollbar.
How do I set it to adjust to the height of the loaded HTML page?
This will work, source here.
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js?ver=1.3.2'></script>
<script type='text/javascript'>
$(function(){
var iFrames = $('iframe');
function iResize() {
for (var i = 0, j = iFrames.length; i < j; i++) {
iFrames[i].style.height = iFrames[i].contentWindow.document.body.offsetHeight + 'px';}
}
if ($.browser.safari || $.browser.opera) {
iFrames.load(function(){
setTimeout(iResize, 0);
});
for (var i = 0, j = iFrames.length; i < j; i++) {
var iSource = iFrames[i].src;
iFrames[i].src = '';
iFrames[i].src = iSource;
}
} else {
iFrames.load(function() {
this.style.height = this.contentWindow.document.body.offsetHeight + 'px';
});
}
});
</script>
<body style="margin:0px;padding:0px;overflow:hidden">
<iframe src="http://www.youraddress.com" frameborder="0" style="overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;position:absolute;top:0px;left:0px;right:0px;bottom:0px" height="100%" width="100%"></iframe>
</body>

Resources