Conflicting hover/mouseover functions - javascript

Relative newbie here. I have two different mouseover/hover functions I can get to work just fine: one, an inline mouseover that 'darkens' an image/box by making it lose opacity; and the second, text that appears over this image/box on hover (jumping up from a hidden position).
The problem is, I want to get them working together without this text losing opacity, which it does when part of the same div class as the image/box. But when I try two separate div classes and position them on top of each other (using z-index), whichever one I put on top seems to block the other one. Is there any way to have it so the image/box loses opacity, but the text that appears doesn't, all in the same mouseover/hover action?
These are the relevant bits in my stylesheet, mostly covering the text part:
.rightbox {
background: rgb(140, 183, 98);
width: 290px;
height: 160px;
margin-bottom: 18px;
padding: 2px;}
.rightboxtext {
display: table-cell;
height: 160px;
width: 290px;
vertical-align: bottom;
text-align: center;
font-weight: bold;
font-size: 20px;
color: #8CB762;
}
.rightboxtext span {
display: block;
height: 0px;
overflow: hidden;
}
.rightboxtext:hover span {
height: 80px;
}
This is the inline stuff that I used where everything, including text, gets the opacity treatment. (In this case the image is attached to the rightboxtext div class, but I also tried it attached to the rightbox div class.)
<div class="rightbox"
onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"
onmouseover="this.style.opacity=0.6;this.filters.alpha.opacity=60">
<div class="rightboxtext"
style="background-image: url(image.jpg); height: 160px; width: 290px;">
<span>Hello text.</span></div>
</div>
Otherwise I achieved this mangled bit of code, where one seems to block the other:
<div class="rightboxcontainer">
<div class="rightboxtext"
style="position: absolute; z-index: 100; height: 160px; width: 290px;">
<span>Hello text.</span></div>
<div class="rightbox"
style="position: absolute; z-index: 50; height: 160px; width: 290px;"
onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"
onmouseover="this.style.opacity=0.6;this.filters.alpha.opacity=60"><img
src="image.jpg">
</div>
</div>
With this extra bit in the stylesheet:
.rightboxcontainer { width: 290px; height: 160px; margin-bottom: 18px;}
Thanks in advance!

As a commenter pointed out above, you can do this entirely with CSS:
<style>
* {
padding: 0;
margin: 0;
}
.box {
width: 250px;
height: 250px;
overflow: hidden;
}
.box img {
width: 250px;
height: 250px;
}
.box .message {
background: rgba(0, 0, 0, 0.5);
opacity: 0;
width: 250px;
height: 250px;
position: relative;
top: -256px;
color: #fff;
font-size: 32px;
line-height: 250px;
text-align: center;
font-weight: bold;
font-family: arial;
}
.box .message:hover {
opacity: 1;
}
</style>
<div class="box">
<img src="http://www2.le.ac.uk/departments/geology/people/clark-n/personal/copy_of_images/Satellite-map-of-Antarctica/image">
<div class="message">Antarctica</div>
</div>
.message is positioned on top of the container, .box. When you hover over .message, it fades in from 0 opacity. Its background is semi-opaque (using RGBA, where the fourth value is the opacity), so it dims the image. You could make the image the background-image of the .box if you wanted to.
http://jsfiddle.net/dgGG3/4/

Fist of all, try to avoid inline event handling as you can achieve the desired result with css :hover.
The problem as you can see here http://jsfiddle.net/UjY5Q/ is with opacity on a parent element all child elements also get that opacity.
.rightbox:hover {
opacity:0.5;
}
You can cheat on that one by setting positions to the elements and overlap one to the other one. That's kind a tricky and may also need browser support.
so the easyest way to get what you want is on :hover show a transparent background image example here: http://jsfiddle.net/UjY5Q/1/
I would say that's the way to go

Related

div with a large z-index is under the div with a smaller z-index

I had a problem:
Element overlapped element because it has a higher z-index (10 vs 5). Element has the child elements #sub-block-1 & #sub-block-2, and #sub-block-1 had child text #text1 with z-index = 20. But #text1 with z-index = 20 still under with z-index = 10. Why?
Tell me, how can I solve this problem?
The must have a predefined z-index (number, not 'auto', and less than z-index , for example, 5 vs 10).
My example:
https://jsfiddle.net/nynsjv3L/1/
P.S.
The above example is not displayed correctly in jsfiddle - the position of the elements (#sub-block-1 & #sub-block-2) does not work.
body {
background: #00ff00;
}
.screen {
position: absolute;
left: 0px;
top: 0px;
width: 100vw;
height: 100vh;
background: #ffffff;
opacity: 0.75;
z-index: 10;
}
#main-block {
position: absolute;
left: 500px;
top: 200px;
width: 700px;
height: 400px;
border: 2px solid #bb0000;
background: #ff0000;
z-index: 5;
}
.sub-block {
position: absolute;
width: 300px;
height: 150px;
background: #ffffff;
border: 4px solid #000000;
}
#sub-block-1 {
left: 100;
top: 100;
z-index: auto;
}
#sub-block-2 {
left: 275;
top: 175;
z-index: 11;
}
#text1 {
position: absolute;
left: 65px;
top: 55px;
color: #000000;
background: #ffff00;
font-size: 30px;
font-weight: 700;
z-index: 20;
}
#text2 {
position: absolute;
left: 65px;
top: 55px;
color: #00bbbb;
font-size: 30px;
font-weight: 700;
}
<div id='main-block'>
<div class='sub-block' id='sub-block-1'>
<div id='text1'>TEST TEXT</div>
</div>
<div class='sub-block' id='sub-block-2'>
<div id='text2'>NEW TEXT</div>
</div>
</div>
<div class='screen'></div>
The #text is still inside your block, that has a lower index than its sibling. The #text part is still in the same context block of its parent. You could check out the inner workings of z-indexes in this page.
You need to create a new stacking context for the text to appear above the other block. One of the possible ways is to change the opacity of the text to .99, or using the transform attribute. I do not recommend you to do it, though, as it will cause more troubles in the future.
Z-indexes should not be used very often. It is better to organize this inside the HTML itself. You should rethink your work.
#main-block is on the same level as .screen and has a lower z-index. So child elements of #main-block will always be overlapped by .screen and its children.
Whenever you set an element to be position: relative or position: absolute you open up a new z-index-stack for all of its children.
You either have to move the child elements of #main-block some levels up to make them independent or give the #main-block a higher z-index which will also result in overlapping .screen.
Hint: Negative z-index is also possible. And clean up your markup (keyword: single quotes). ;-)

Create a div with aspect ratio 1:1 knowing only its height in percentage

I was wondering if you can help me with this.
I have a div (in white) where I need to put two circular buttons (in green) on the borders. Everything should be done with CSS.
It should look like this:
Screenshot
Now, the thing is that I don't know the size of the white div, and I won't know it at the time of creation, because it will get added to the DOM afterwards. All I know is that the white div has a percentage width and height relative to its future parent. So, at the time of creation, since it's not yet added, any calls to width(), height() or its css values won't work.
I've seen all those snippets that tell you how to make a div with a fixed aspect ratio. I need this now, I need the button to be 1:1, but all I know about the dimensions, is that it has to be 100% of the height of the white div (and therefore, its width should be equal as its height). All the examples I've seen assume that you know the width and to make the height keep the ratio. In my case, what I know is the height (100%) and I want the width to adapt.
I have no idea how to achieve this.
This is my snippet:
body{
background-color: #DCDCDC;
}
.container {
width: 50%;
height: 7%;
background: white;
border-radius: 20px;
position: absolute;
}
.arrow {
background: green;
border-radius: 20px;
height: 100%;
position: absolute;
}
.arrow:after{
content: "";
display: block;
padding-right: 100%;
}
.arrow:last-child {
right: 0;
}
<div class="container">
<div class="arrow"></div>
<div class="arrow"></div>
</div>
https://jsfiddle.net/7bxecL9m/
If you know how can I do this without entering any fixed value (jQuery use is of course valid), I'd really appreciate it.
Thanks.
There are many variables here:
Since container's height is % and circle radius is px units, one is static and the other one will resize.
The only way to preserve 1:1 with just html/css, considering the container's height % will resize circle's height as well, would be to isolate circle's div width & height to something static like px units.
Now, since you said no fixed dimensions, the only thing I can think of is to comment .arrow's 100% height, to prevent resizing other than 1:1, and nesting a div inside .arrow to restrain 1:1 with static units (ideally impacting .arrow directly would be less code but if you don't want/can't set them on that element, maybe you consider this).
If you want the circle to remain circular as the content expands, you need to dynamically adjust the height to match the width. You could use Javascript to achieve this, but your border-radius is tied to container's in px static units, since container will always be bigger something like border-radius: 50% wouldn't work for both, 50% radius of circle would never match 50% of container's (that is, if you care about radius alignment).
body {
background-color: #DCDCDC;
}
body,
html {
height: 100%;
}
.container {
width: 50%;
height: 37%;
background: white;
border-radius: 20px;
position: relative;
}
.arrow {
background: green;
border-radius: 20px;
/*height: 100%;*/
position: absolute;
overflow: hidden;
}
.bLimit {
height: 40px;
width: 40px;
line-height: 40px;
}
.arrow:after {
content: "";
display: block;
padding-right: 100%;
}
.arrow:last-child {
right: 0;
}
<div class="container">
<div class="arrow">
<div class="bLimit">button overflow</div>
</div>
<div class="arrow">
<div class="bLimit">button</div>
</div>
</div>
Why not doing a fixed width in percent for your arrow :
.arrow {
background: green;
border-radius: 20px;
height: 100%;
position: absolute;
width: 10%;
}
body{
background-color: #DCDCDC;
}
.container {
width: 50%;
height: 7%;
background: white;
border-radius: 20px;
position: absolute;
}
.container:after,.container:before{
content: " ";
display: block;
padding: 4%;
z-index: 999;
top: 0;
position:absolute;
background: green;
border-radius: 50%;
}
.container:before {
left: 0;
}
.container:after{
right: 0;
}
<div class="container">
</div>
You can achieve using before and after CSS pseudo selectors. You check this Example.
There is a posibility to get this result using a image (that won't show) of the required ratio.
In this case, the ratio is 1:1 so we will use an image of 50px (but it can be any size)
.container {
width: 300px;
height: 20px;
border: solid 1px blue;
margin: 40px;
position: relative;
}
.container:nth-child(2) {
height: 40px;
}
.container:nth-child(3) {
height: 60px;
}
.arrow {
height: 100%;
background-color: red;
opacity: 0.5;
position: absolute;
border-radius: 50%;
transform: translateX(-50%);
}
.arrow:last-child {
right: 0px;
transform: translateX(50%);
}
img {
height: 100%;
opacity: 0;
}
<div class="container">
<div class="arrow">
<img src="https://placehold.it/50x50">
</div>
<div class="arrow">
<img src="https://placehold.it/50x50">
</div>
</div>
<div class="container">
<div class="arrow">
<img src="https://placehold.it/50x50">
</div>
<div class="arrow">
<img src="https://placehold.it/50x50">
</div>
</div>
<div class="container">
<div class="arrow">
<img src="https://placehold.it/50x50">
</div>
<div class="arrow">
<img src="https://placehold.it/50x50">
</div>
</div>

make div bigger and animate bigger section upwards on hover

I am trying to animate a div upwards when a user hovers on the div.
I am able to animate the div making it bigger, however the animation happens downwards. I am trying to keep the bottom of the div remain in the same place, and have a smooth animating increasing the size of the div upwards.
See jsfiddle here which demonstrates what my code is currently doing.
Please see code below:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
}
.content:hover {
height: 110%;
}
<div class="box">
<div class="content">TEST</div>
</div>
You can do this using transform:scaleY() and set the transform-origin to bottom. I also put a margin-top:100px to see the effect better. Also you can use transition to make the scale smoother
You also need to scale back the text.
See here: jsfiddle
You need to scale the text back to it's original state in the same time that you scale the div. so if you scale the div 2 times. You need to scale back the text with 1/2 , same if you scale 3 times...scale back with 1/3
In this case you enlarge .content by 1.5 so you need to scale down the text inside by 1/1.5 = 0.66
Code:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
margin-top: 300px;
transition:0.3s;
}
.content:hover p {
transform: scaleY(0.66)
}
.content:hover {
transform: scaleY(1.5);
transform-origin: bottom;
}
<div class="box">
<div class="content">
<p>
TEST
</p>
</div>
</div>
Try it like this (I have no other idea...): You can give to the class "box" a bigger height (I put a red border around, so you can see it) than the class "content". After that, you can use flexbox, to put the class "content" on the bottom. After that, you can do it with hover to change your heigth upwards and fill it. With transition you can make a nice animation. I hope this is good enough. Perhaps there is also a way with jQUery at the moment I havn't got an idea. Let me know, if this helps you (I'm not sure if I understanded the question well) - Cheers. (Important: This heights and so on are just random values for testing)
.box {
display: flex;
justify-content: flex-end;
flex-direction: column;
height: 100px;
border: 1px solid red;
}
.content {
background-color: #e3e4e6;
height: 50px;
width: 100%;
text-align: center;
-webkit-transition: height 1s;
/* Safari */
transition: height 1s;
}
.content:hover {
height: 100%;
}
<div class="box">
<div class="content">TEST</div>
</div>
If you just want to use css, just use:
.content:hover {
margin-top: -50px;
height: 110%;
}
See jsFiddle
since there isn't any space at top to expand, you may give an extra margin initially and remove it on hover like this JsFiddle -
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
margin-top:25px;
}
.content:hover {
height: 110%;
margin-top:0;
}
Set top property with the value of height - 100 * -1
https://jsfiddle.net/x3cL1cpt/7/
.content:hover {
height: 110%;
top: -10%;
position: relative;
}
Why position relative? It's because I move the box, but without modifying the space that the box occuped. If you need to modify that space, change top with margin-top.
Replace this CSS with your current, needed to add transition:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
transition: 1s all ease;
}
.content:hover {
transform: scaleY(1.2);
transform-origin: bottom right;
}

How do I move others divs around upon clicking my jQuery event?

I have inserted a jQuery event into my webpage which allows for a div in my page to expand to reveal more content. I'm having a problem with the surrounding divs not moving down to accommodate for the space needed to display the expanded div.
I initially tested this div in a separate document and found it to work successfully without too much fuss. I worked with other divs to be sure that they'd move upon clicking the event. Upon inserting the same code into my already developed web page however, the surrounding divs remain fixed and the expansion works behind those divs. Why might this be? Could it be that one of my divs beneath the expanded one is somehow fixed?
I researched the CSS property 'position' but can't make any link between these contributing to the problem.
Incase the problem relates to that of my expanded div (instead of the surrounding divs), I shall only post the code for the HTML, CSS & Javascript/jQuery that directly relates to that particular part of my webpage. Please request any further code if you feel it's necessary.
Thank you for taking time to read.
Here is my code:
HTML
<div id="showmorelocations-container"><p>More Locations</p>
<div class="toggler-expand">
</div>
</div>
CSS
#showmorelocations-container {
height: 100px;
line-height: 150px;
width: auto;
margin: auto;
margin-bottom: 50px;
}
#showmorelocations-container p {
text-align: center;
font-family: 'Hind', sans-serif;
font-size: 20px;
font-weight: bold;
text-decoration: none;
position: relative;
top: 50%;
transform: translateY(-50%);
line-height: 100px;
}
.toggler-expand {
height: 400px;
width: auto;
background-color: #FFBBBB;
display: none;
margin-top: -25px;
}
jQuery
$(function() {
$('#showmorelocations-container').click(function() {
$(this).find('.toggler-expand').slideToggle();
});
});
The issue is most likely related to the fact that you have set a fixed height for your parent container and try to expand the a child.
Change the following line:
#showmorelocations-container {
height: 100px; // change px to %
...
}
to
#showmorelocations-container {
height: 100%;
...
}
in order to allow the parent to expand if the child expands too.
Check the fiddle here: https://jsfiddle.net/n1dwz8v1/
Is this the behavior you are looking for?
$( document ).ready(function() {
$('#showmorelocations-container').click(function() {
$(this).find('.toggler-expand').slideToggle();
});
});
#showmorelocations-container {
height: 100px;
line-height: 150px;
width: auto;
margin: auto;
margin-bottom: 50px;
background-color:#ccc
}
#showmorelocations-container p {
text-align: center;
font-family: 'Hind', sans-serif;
font-size: 20px;
font-weight: bold;
text-decoration: none;
position: relative;
top: 50%;
transform: translateY(-50%);
line-height: 100px;
}
.toggler-expand {
height: 400px;
width: auto;
background-color: #FFBBBB;
display: none;
margin-top: -25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="showmorelocations-container">
<p>More Locations</p>
<div class="toggler-expand">
<p>Content</p>
</div>
</div>
use this :
$(function() {
$('#showmorelocations-container p').click(function() {
$(this).parent().find('.toggler-expand').slideToggle();
});
});

How can I use toggle("slide") to show a phrase one letter at a time

I am using a `.toggle("slide") function to try and get a piece of text I have to appear as if each letter is sliding in. Unfortunately, it looks as if the text is flying in instead. I tried to squeeze the margins in tight, so that it would start at a closer place, but it still looks as if it is flying in from the left side.
Is there a better way to do this, so it looks as if the letters are sliding in without "flying in"?
$("#home-learn").toggle("slide");
#blue {
background-color: #0085A1;
width: 100%;
height: 300px;
}
#home-learn {
color: #FFF;
display: none;
text-align: center;
position: relative;
margin: 0 40%;
top: 50%;
font-size: 2.3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="blue">
<div id="home-learn">Learn more...</div>
</div>
For the effect you want, put a div inside your container. Make the div position absolute, make it 100% the height and width of the container, and make it the same background color as the main background. Make the div's z index higher than the container so the div sits over the text like a curtain. Then use toggle() to slide the curtain to the right exposing the text underneath.
Note that this uses jQuery UI, without it, you can't make toggle() slide to the right like this needs.(at least to my knowledge you cant). If you dont want to use jquery UI, you could use .animate() instead of toggle()
$("#curtain-div").toggle("slide", {
direction: "right"
}, 3000);
#blue {
background-color: #0085A1;
position: relative;
width: 100%;
height: 300px;
}
#home-learn {
color: #FFF;
text-align: center;
position: relative;
top: 50%;
font-size: 2.3em;
}
#curtain-div {
width: 100%;
height: 100%;
position: absolute;
background-color: #0085A1;
top: 0;
left: 0;
z-index: 10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<div id="blue">
<div id="home-learn">
<div id="curtain-div"></div>
Learn more...
</div>
</div>

Categories

Resources