I am trying to change the page's background image depending on the image being hovered.
This is the layout of the page:
HTML:
<div id="main">
<img id="img1" src="1.jpg" />
<img id="img2" src="2.jpg" />
</div>
CSS:
#img1:hover #main
{
background: url('images/1.jpg'); /* not working */
}
#img2:hover #main
{
background: url('images/2.jpg'); /* not working */
}
'#main' is the ID I set for the tag.
Any ideas?
If you need change the background-image of #main div you should use CSS and jQuery:
http://jsfiddle.net/Soldier/cyAXv/1/
HTML
<body>
<div id="main">
<h1>Hi!</h1>
<img id="img1" src="img1"/>
<img id="img2" src="img2"/>
</div>
</body>
JS
$('#img1').hover(function() {
$('#main').css("background","url('background1')");
})
$('#img2').hover(function() {
$('#main').css("background","url('background2')");
})
You can't traverse backwards in CSS selectors. That is to say, you can't apply a style to an ancestor/parent based on the state of a child/descendant.
You will need to use JavaScript unfortunately. You can use classes and define the styles in CSS though to make it less lame. Something like this:
jsFiddle
HTML
<div id="main">
<div id="img1"></div>
<div id="img2"></div>
</div>
CSS
#main.img1 {
background: url('https://www.google.com.au/images/srpr/logo4w.png');
}
#main.img2 {
background: url('https://www.google.com.au/images/srpr/logo4w.png');
}
#img1,
#img2 {
width:100px;
height:100px;
background-color:#F00;
margin:10px;
}
JavaScript
var main = document.getElementById('main'),
img1 = document.getElementById('img1'),
img2 = document.getElementById('img2');
img1.onmouseover = function () {
main.className = 'img1';
};
img2.onmouseover = function () {
main.className = 'img2';
};
img1.onmouseout = function () {
main.className = '';
};
img2.onmouseout = function () {
main.className = '';
};
Related
I have an array of divs containing book names that I generate using a .map function on some fetched data from my database. Some of the book names are too long so I have used the following CSS to hide them:
.book-title{
font-weight: 600;
height: 1.5rem;
max-width: 15rem;
overflow: hidden;
padding-top: 0.7rem;
}
But I would like to make the text visible when user hovers over the div. My current solution applies to all divs generated and displayed by the .map function - I am unsure how to make it just apply to divs where the text is too long.
.book-title:hover{
height: 6rem;
overflow: visible;
}
Is there a proper way to do this with react?
here is the relevant .jsx
const listsForFrontPage = listArray.map((book, id) => {
return (
<Link className="book-link" to={`/books/${book.book_id}`} key={id}>
<div className="book-card">
<div className="book-card-image">
<img
className="cover-image"
src={book.cover_image}
alt="The book cover"
/>
</div>
<div className="book-info">
<div className="book-title">{book.title}</div>
<div className="author-name">{book.name}</div>
</div>
</div>
</Link>
)
})
You need to check if the element is overflowing
add useRef:
const refs = useRef(listArray.map(() => React.createRef()));
then you should create a function that checks if the element is overflowing:
const isOverflown = (el) => {
if(!el) return;
const { clientWidth, clientHeight, scrollWidth, scrollHeight } = el;
return scrollHeight > clientHeight || scrollWidth > clientWidth;
}
and then you need to add class based on isOverflown value:
const listsForFrontPage = listArray.map((book, id) => {
return (
<Link className="book-link" to={`/books/${book.book_id}`} key={id}>
<div className="book-card">
<div className="book-card-image">
<img
className="cover-image"
src={book.cover_image}
alt="The book cover"
/>
</div>
<div className="book-info">
<div ref={refs.current[id]} className={`book-title ${isOverflown(refs.current[id].current) ? 'book-title-overflow' : ''}`}>{book.title}</div>
<div className="author-name">{book.name}</div>
</div>
</div>
</Link>
)
})
don't forget to add your css:
.book-title-overflow:hover{
height: 6rem;
overflow: visible;
}
I would like to make a bar (see image). I have 3 values when I would like to display with text.
I'm using HTML and CSS Is it possible to do it?
I can't speak to PrimeFaces, so here's a solution using plain HTML, CSS, and Javascript.
let value1 = document.getElementById("value1");
if (value1) { value1.style.width = 150 + "px" }
let value2 = document.getElementById("value2");
if (value2) { value2.style.width = 150 + "px" }
let maxi = document.getElementById("maxi");
if (maxi) { maxi.style.width = 150 + "px" }
.bar div { float:left; color:white; padding:1ex; margin:0;
text-align:center; font-family:sans-serif; }
#value1 { background-color:#5b9bd5; }
#value2 { background-color:#70ad47; }
#maxi { background-color:#a6a6a6; }
<div class="bar">
<div id="value1">value1</div>
<div id="value2">value2</div>
<div id="maxi">maxi</div>
</div>
The JS may need to go inside a function that you call after items have loaded, e.g. <body onload='populate_widths()'>.
This finds each placeholder and assigns its width programmatically. It assumes each width is 150, which you can change with server-side data or else within the Javascript code.
The above snippet demonstrates how you can alter values using Javascript, but if you have static server-side values, you could just pass CGI variables to add the width right into the elements' style attributes. I don't know PrimeFaces or other Java-based server side code, but the resulting HTML would look like this:
.bar div { float:left; color:white; padding:1ex; margin:0;
text-align:center; font-family:sans-serif; }
<div class="bar">
<div style="width:150px; background-color:#5b9bd5">value1</div>
<div style="width:150px; background-color:#70ad47">value2</div>
<div style="width:150px; background-color:#a6a6a6">maxi</div>
</div>
I'm trying to edit the border-bottom-color individual depending on a property of the element in ng-repeat.
Here is an example how the html is structured. The changed style is
.active-tool::after {border-bottom-color: rgb(247, 153, 248)}
html:
<div data-ng-repeat="row in rows">
<div class='container'>
<div
data-ng-style="getPrimaryColor(tvShow)"
class='folder tvshow'
data-ng-class="isActiveFolder(tvShow)"
id='{{tvShow.id}}'
data-ng-repeat="tvShow in row track by $index">
<div data-ng-click="setSelectedTvShow(tvShow)">
<p class="tvshow-name">{{tvShow.name}}</p>
</div>
</div>
</div>
controller.js
$scope.isActiveFolder = function(tvShow) {
if($scope.selectedTvShow !== null && tvShow.id !== null) {
return $scope.selectedTvShow===tvShow.id ? 'active-tool' : '';
}
};
$scope.getPrimaryColor = function(tvShow) {
if($scope.selectedTvShow !== null) {
var result = '{' + tvShow.id + '.active-tool::after {border-bottom-color: rgb(247, 153, 248)}}';
console.log(result);
return result;
};
Any ideas how this could be done?
I use this quick hack:
put this inside your template:
<style type="text/css">
.active-tool::after {
border-bottom-color: {{getShowBorderColor(tvShow)}};
}
</style>
and then in your controller:
$scope.getShowBorderColor = function(tvShow){
return tvShow.color; // change this for how you want to calculate the color
};
You cannot use ng-style like this, because html style attribute does not support css selectors.
Actually, you can do it with no javascript at all:
markup:
<div data-ng-repeat="row in rows">
<div class='container'>
<div class='folder tvshow'
data-ng-class="{active-tool : selectedTvShow === tvShow.id}"
id='{{tvShow.id}}'
data-ng-repeat="tvShow in row track by $index">
<div data-ng-click="selectedTvShow = tvShow.id">
<p class="tvshow-name">{{tvShow.name}}</p>
</div>
</div>
</div>
</div>
css:
.active-tool::after {
border-bottom-color: rgb(247, 153, 248);
}
I am having trouble setting the location of a canvas relative to another, so I wrote the following test harness.
I would expect that the positioning specified by "top" amd "left" in the div's at the top of the harness would move the origin of the canvases relative to each other.
What am I doing wrong?
<!DOCTYPE html>
<html>
<head>
<form id='form1' style="position:relative">
<div id='d1' style="position:absolute; top:0; left:0; z-index:1">
<canvas id='canvas1' width='200' height='100'>
Your browser does not support HTML5 Canvas.
</canvas>
</div>
<div id='d2' style="position:absolute; top:50; left:50; z-index:2">
<canvas id='canvas2' width='100' height='200'>
Your browser does not support HTML5 Canvas.
</canvas>
</div>
<div id='d3' style="position:absolute; top:75; left:75; z-index:3">
<canvas id='canvas3' width='50' height='50'>
Your browser does not support HTML5 Canvas.
</canvas>
</div>
</form>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<input id='btn1' type="button" onClick="demoDisplay()" value="Hide canvas with display property">
<input id='btn2' type="button" onClick="demoVisibility()" value="Hide canvas with visibility property">
<input id='btn3' type="button" onClick="demoOrder()" value="Place blue over red">
</head>
<body onLoad="loadMe()">
<script>
function loadMe()
{
var canvas = document.getElementById("canvas1");
if (canvas.getContext) { // Canvas Support
var ctx = canvas.getContext("2d");
// Work with context
var grd=ctx.createLinearGradient(0,0,ctx.canvas.height,ctx.canvas.width);
grd.addColorStop(0,'#8ed6ff');
grd.addColorStop(1,'#004cb3');
ctx.fillStyle=grd;
ctx.rect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.fill();
}
var canvas = document.getElementById("canvas2");
if (canvas.getContext) { // Canvas Support
var ctx = canvas.getContext("2d");
// Work with context
var grd=ctx.createLinearGradient(0,0,ctx.canvas.height,ctx.canvas.width);
grd.addColorStop(0,'#C00');
grd.addColorStop(1,'#D00');
ctx.fillStyle=grd;
ctx.rect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.fill();
}
var canvas = document.getElementById("canvas3");
if (canvas.getContext) { // Canvas Support
var ctx = canvas.getContext("2d");
// Work with context
var grd=ctx.createLinearGradient(0,0,ctx.canvas.height,ctx.canvas.width);
grd.addColorStop(0,'#00C');
grd.addColorStop(1,'#00D');
ctx.fillStyle=grd;
ctx.rect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.fill();
}
}
function demoVisibility()
{
btn = document.getElementById('btn2')
if (btn.value==='Hide canvas with visibility property') {
btn.value = 'Show canvas with visibility property';
document.getElementById("d2").style.visibility="hidden";
} else {
btn.value = 'Hide canvas with visibility property';
document.getElementById("d2").style.visibility="visible";
}
}
function demoDisplay()
{
btn = document.getElementById('btn1')
if (btn.value==='Hide canvas with display property') {
btn.value = 'Show canvas with display property';
document.getElementById("d1").style.display="none";
} else {
btn.value = 'Hide canvas with display property';
document.getElementById("d1").style.display="inline";
}
}
function demoOrder()
{
btn = document.getElementById('btn3')
if (btn.value==='Place blue over red') {
btn.value = 'Place red over blue';
document.getElementById("d1").style.zIndex=2;
document.getElementById("d2").style.zIndex=1;
} else {
btn.value = 'Place blue over red';
document.getElementById("d1").style.zIndex=1;
document.getElementById("d2").style.zIndex=2;
}
}
</script>
</body>
</html>
Add "px" to your style measurements. E.G top:50; => top:50px;
<form id='form1' style="position:relative">
<div id='d1' style="position:absolute; top:0px; left:0px; z-index:1">
<canvas id='canvas1' width='200' height='100'>
Your browser does not support HTML5 Canvas.
</canvas>
</div>
<div id='d2' style="position:absolute; top:50px; left:50px; z-index:2">
<canvas id='canvas2' width='100' height='200'>
Your browser does not support HTML5 Canvas.
</canvas>
</div>
<div id='d3' style="position:absolute; top:75px; left:75px; z-index:3">
<canvas id='canvas3' width='50' height='50'>
Your browser does not support HTML5 Canvas.
</canvas>
</div>
</form>
I will make your life simple. Here is the javascript code for the same.
var can = document.querySelector('canvas');
can.style.position = 'absolute';
can.style.top = "100px";
can.style.left = "100px";
Well enjoy styling the page....
As a starter, your HTML is invalid. The content (HTML elements like <form>, <canvas> etc.) should be in a <body> tag inside the <html> tag! The <script> should probably be in the <head>.
Also, note that the solution is using absolute positioning within an element using relative positioning.
I am using "background: #BDBDBD url(image.png) top left no-repeat" this css property for two div elements which has width and height set. On clicking a button I am changing the width of both the nested divs dynamically by making the function run continuously with the help of setInterval(). The image is not loading in chrome but it works fine in firefox and IE .. Many searches convey that using background image in chrome is not working but none of those solutions seems to work.
<div id="boxes">
<div id="dialog" class="window" style="overflow: auto">
<div id="progressBar" class="meter-wrap" style="display: block;position: relative; margin: auto;">
<div class="meter-value" style="background-color: #05C; width: 40%">
<div class="meter-text">
Loading...
</div>
</div>
</div>
<div class="meter-text-message">
Loading...
</div>
</div>
CSS:
.meter-wrap, .meter-value, .meter-text {
width: 155px; height: 30px;
}
.meter-wrap, .meter-value {
background: #bdbdbd url('/sf-images/tracker/inline_progress_bar.png') top left no-repeat;
}
js code:
function setProgressBar() {
var pgBar = jQuery("#progressBar");
pgBar.show();
running = true;
var inter = null;
function run() {
pgBar.find(".meter-value").css("width", progress + "%");
pgBar.find(".meter-text").text(progress + "%");
if (progress == 100) {
jQuery(".meter-text-message").html("Complete");
clearInterval(inter);
running = false;
}
}
inter = setInterval(run, 50);
}
Found that the image is not loading for first time, I made the div element visible with the image as background by another method. After that , when I execute the above js method image loads properly.