I am trying to achieve what should be a fairly simple CSS transition. I have an address with phone number below. When the phone number is hovered, I want it to slide and fade off to the left, and text ("Call Us") to slide in to take it's place. I have achieved this as shown below, but it is quite glitchy and it's as if you need to hover very precisely for it to work properly. Why is this? Also the phone number isn't centred with the rest of the address (but "Call Us" is when hovered). Thanks for any help.
HTML:
<div class="address">
<p><b>ASCO TRANSPORT & LOGISTICS</b><br>
15 Ashby Close, Forrestfield<br>
Western Australia, 6058<br></p>
<p><span id="address1-phone">+61 (0)8 6254 7400</span><span id="address1-phone-text">Call Us</span></p>
</div>
CSS:
#address1-phone, #address1-phone-text {
transition: 0.2s;
cursor: pointer;
color: #009ee3;
}
#address1-phone:hover {
margin-left: -200px;
opacity: 0;
}
#address1-phone-text {
margin-right: -200px;
opacity: 0;
}
#address1-phone:hover + #address1-phone-text {
margin-right: 0px;
opacity: 1;
}
As the previous answers suggest, the <span> element that transitions to the left releases from the scope of :hover once it is no longer under the pointer- causing erratic behavior. My solution involves wrapping the ids in another <span> which gives you a static field to have attributed to the :hover selector.
This might be a redundant answer- but it's different in terms of more succinct organization & it produces your desired result.
#phone,
#address1-phone,
#address1-phone-text {
transition: 0.2s;
cursor: pointer;
color: #009ee3;
}
#address1-phone {
position: relative; /******/
}
#phone:hover #address1-phone {
margin-left: -200px;
opacity: 0;
}
#address1-phone-text {
position: absolute; /******/
margin-left: 200px;
opacity: 0;
}
#phone:hover #address1-phone-text {
margin-left: 0;
opacity: 1;
}
<center><div class="address">
<p>
<b>ASCO TRANSPORT & LOGISTICS</b>
<br> 15 Ashby Close, Forrestfield
<br> Western Australia, 6058
<br>
</p>
<p>
<span id="phone">
<span id="address1-phone">+61 (0)8 6254 7400</span>
<span id="address1-phone-text">Call Us</span>
</span>
</p>
</div></center>
Your problem is when you hover and it starts to move,it will go out of under of your mouse. So css hover can not solve your problem.
Use jquery instead:
$('#address1-phone').mouseenter(function(){
$(this).css('margin-right', '-200px');
$(this).next().css('margin-right', '0');
});
$('.address p').mouseleave(function(){
$(this).children().eq(0).css('margin-right', '0');
});
Or if you want to do with css only:
.address p:hover #address1-phone {
margin-left: -200px;
}
Related
I'm making an information section with three dropdown options 'Course Length' 'Pricing' and 'Cancellations'
See it here live
For some reason, the checboxes can only be clicked in series (i.e. I cannot click to expand 'Cancellations' unless I have expanded 'Course Length' and 'Pricing' - in that order)
I'd like the user to be able to click these in any order they like. I believe it is a formatting issue, as the cursor changes when hovering slightly to the right of the arrow img
HTML and CSS:
.accordion {
width: 95%;
max-width: 400px;
margin: auto;
}
.accordion label {
display: block;
margin: auto;
text-align: center;
cursor: pointer;
}
.arrow img {
padding-left: 6px;
height: 15px;
}
.accordion p {
text-align: left;
visibility: none;
height: 0;
opacity: 0;
transition: .5s;
-webkit-transition: .5s;
}
#tm:checked ~ .hiddentext {
visibility: visible;
height: auto;
opacity: 1;
}
input#tm {
display: none;
position: relative;
}
#tn:checked ~ .hiddentext {
visibility: visible;
height: auto;
opacity: 1;
}
input#tn {
display: none;
position: relative;
}
#to:checked ~ .hiddentext {
visibility: visible;
height: auto;
opacity: 1;
}
input#to {
display: none;
position: relative;
}
<div class="accordion">
<label for="tm" class="accordionitem">
<h3 class="font">Course Length<span class="arrow"><img src="images/arrow.svg" /></span></h3>
</label>
<input type="checkbox" id="tm" />
<p class="hiddentext font">
Term - 16 Weeks
<br>Days - Monday to Tuesday 6-9pm
<br>Location - Levels Newton Academy
</p>
</div>
<div class="accordion">
<label for="tn" class="accordionitem">
<h3 class="font">Pricing
<span class="arrow">
<img src="images/arrow.svg" />
</span>
</h3>
</label>
<input type="checkbox" id="tn" />
<p class="hiddentext font">
Cost - £2,400
<br>Deposit required to secure place.
<br>Financial plans available. Please contact us for more information.
</p>
</div>
<div class="accordion">
<label for="to" class="accordionitem">
<h3 class="font">Cancellations<span class="arrow"><img src="images/arrow.svg" /></span></h3>
</label>
<input type="checkbox" id="to" />
<p class="hiddentext font">
We understand situations can arise and be out of your control, thats’s why you have until 21 days prior to your start date to receive a full refund if you need to cancel. There is a 20% cancellation charge on the amount already paid, then a full refund of what’s remaining. Any changes after 21 days and we can only offer a course date change, not a refund.
</p>
</div>
The problem is your p.hiddentext is placed on top of the next label that is why your labels are not clickable. Just place your label's on top of the p tag and it should work fine. Try adding the following CSS:
.accordion label {
position: relative;
z-index: 9;
}
I went through a number of questions regarding displaying image on hover here on Stackoverflow, but couldn't find a solution for my problem.
Right now I managed to display an image in the background of the paragraph once I hover on it. See on JSFiddle.
Ideally what would I like to do achieve: once I hover over an Example1 inside of a paragraph I would like to display Image1 in the background, not below the paragraph, but centered in the background, below all of the elements. As pictured here.
Hovering on Example2 would ideally display Image2, and Example3 would display Image3.
HTML
<div id="imgbg">
<p>Portfolio:</p>
<p>I worked with:<br />
Example1, Example2, Example3, Example4, Example5
</p>
</div>
CSS
#imgbg {
height: 100%;
width: 100%;
}
#imgbg:hover {
background-image: url('http://i.imgur.com/9bbjE1Mb.jpg');
}
Does anyone have a solution? Many thanks.
You can use javascript as that
function showBg() {
document.body.style.backgroundImage = "url('http://i.imgur.com/9bbjE1Mb.jpg')";
}
function hideBg() {
document.body.style.backgroundImage = null;
}
<div onmouseover="showBg()" onmouseleave="hideBg()" id="imgbg">
<p>I worked with:
<br />Example1, Example2, Example3, Example4, Example5
</p>
</div>
you should wrap Example1 and Example2 with span tag or div
and add css rules for these wraps.
<span id="ex1">Example1</span>, <span id="ex2">Example2</span>, Example3, Example4, Example5
and add css
#ex1, #ex2 {
display:inline-block;
height:50px;
}
#ex1:hover {
background-image:url('http://i.imgur.com/9bbjE1Mb.jpg');
}
#ex2:hover {
background-image:url('http://i.imgur.com/9bbjE1Mb.jpg');
}
Look at https://jsfiddle.net/4tubcy8e/6/
I hope this may help you.
#imgbg {
position: relative;
width: 100%;
height: 265px;
}
#imgbg .Example:hover:after {
display: block;
}
#imgbg .Example:after {
content: '';
display: none;
width: 160px;
height: 160px;
background: url('http://i.imgur.com/9bbjE1Mb.jpg');
background-size: contain;
position: absolute;
top: 50%;
left: 0;
margin-top: -80px;
margin-left: 145px;
z-index: -1;
}
<div id="imgbg">
<p>Portfolio:</p>
<p>I worked with:<br />
<span class="Example">Example1</span>,
<span class="Example">Example2</span>,
<span class="Example">Example3</span>,
<span class="Example">Example4</span>,
<span class="Example">Example5</span>
</p>
</div>
I'm working on this banner ad that I posted here yesterday and I got my images fading properly, but I had everything positioned in an absolute manner, and I need to have it so that when my ad expands, it pushes whatever content below it down. Right now, when I press expand, it covers the image below it, rather than push it down even though the picture's positioning is relative.
Here's a link to my project on codepen.
And here's my CSS:
#banner{
position: relative;
min-height: 100px;
}
.hide {
transition: opacity .5s ease-in-out;
opacity: 0;
position:absolute;
}
.show {
transition: opacity .5s ease-in-out;
opacity: 1;
position: absolute;
z-index: 1;
}
#toggle, #toggle2{
cursor: pointer;
}
#toggle{
margin-left:-123px;
}
#toggle2{
position: relative;
}
#twitterIcon{
position: relative;
}
.videoDiv > video {
display:inline-block;
border: 1px solid;
font-size:0;
margin: 0;
padding:0;
}
.videoDiv{
font-size:0;
margin-left:413px;
padding-top:152px;
}
I've read that absolute positioning makes it this way, but I need the collapsed and expanded version to be absolute so that they're on top of one another. Is there anyway I can make it so that the Coach ad pushes the image of Ron Swanson down rather than covering it?
Here is a complete solution: http://codepen.io/anon/pen/mewMEO
The solution is to make the smaller banner absolute with a negative z-index so it is in fact behind the normally positioned large banner.
Also, I took the liberty of improving your JS code by making it more generic and adding support for multiple banners on the page.
HTML
<div class="banner collapsed">
<img class="preview-size" src="http://i.imgur.com/y6foj3Z.jpg"/>
<img class="full-size" src="http://i.imgur.com/CeUfSAX.jpg"/>
<div class="btn-expand">
<img id="toggle" src="http://i.imgur.com/axmdldH.png" />
</div>
<div class="btn-collapse">
<img src="http://i.imgur.com/5wZwdGz.png" />
<a href="https://twitter.com/intent/tweet?text=I%20LOVE%20the%20new%20%40coach%20swagger!">
<img id="twitterIcon" src="http://i.imgur.com/WxSsDpb.png" />
</a>
</div>
</div>
<div class="push">
<img src="http://i.imgur.com/sFNERNs.jpg" />
</div>
CSS
.banner {
position: relative;
width: 970px;
}
.banner img {
/* Get rid of that margin on the bottom of the images */
display: block;
}
.banner .btn-collapse img {
display: inline;
}
.banner .btn-expand {
position: absolute;
bottom: 0;
right: 0;
}
.banner .preview-size {
z-index: -1;
position: absolute;
}
.banner .btn-expand {
display: none;
}
.banner.collapsed .preview-size {
z-index: 0;
position: relative;
}
.banner.collapsed .preview-size,
.banner.collapsed .btn-expand {
display: block;
}
.banner.collapsed .full-size,
.banner.collapsed .btn-collapse {
display: none;
}
JS
(function() {
var bannerEls = document.getElementsByClassName('banner');
// Support multiple banners
for (var index = 0; index < bannerEls.length; index++) {
var currBannerEl = bannerEls[index];
var expandEl = currBannerEl.getElementsByClassName('btn-expand')[0];
var collapseEl = currBannerEl.getElementsByClassName('btn-collapse')[0];
registerBannerToggle(expandEl, currBannerEl);
registerBannerToggle(collapseEl, currBannerEl);
}
function registerBannerToggle(clickableEl, bannerEl) {
clickableEl.addEventListener('click', function(e) {
toggleCollapseState(bannerEl);
});
}
function toggleCollapseState(bannerEl) {
if (bannerEl.className.indexOf('collapsed') !== -1) {
bannerEl.className =
bannerEl.className.replace(/collapsed/g, '');
}
else {
bannerEl.className += ' collapsed';
}
}
})();
The reason you are not able to do this was intentional to deter advertisers from messing with the actual website content. To pull it off, you would have to keep the position relative for the add or manipulate the ".push" div using javascript.
I dont know much plain javascript so I changed it for jQuery if you don't mind
All I've done was get images height and set animate on them with click on #toggle/#toggle2
CODEPEN
Is there any way to have a transition on the order of flex-box items?
In other words, can I have this (details in this fiddle)
#container {
display: flex;
}
#container:hover div:last-child {
order: -1;
}
animated (the element getting the new position assumes it's position over time), please?
I am not really answering the question because I am not using the order property.
But I wanted to do something similar to what you expect, and finally decided to :
In HTML, add a data-order attribute to the elements
Add the CSS properties for each element position
Change the data-order using Javascript
Using CSS transitions for the interpolation
setInterval(changeOrder, 3000);
function changeOrder() {
const allSlides = document.querySelectorAll(".single-slide");
const previous = "1";
const current = "2";
const next = "3";
for (const slide of allSlides) {
const order = slide.getAttribute("data-order");
switch (order) {
case current:
slide.setAttribute("data-order", previous);
break;
case next:
slide.setAttribute("data-order", current);
break;
case previous:
slide.setAttribute("data-order", next);
break;
}
}
}
.all-slides {
display: flex;
width: 80vw;
margin: 0 auto;
perspective: 500px;
height: 500px;
}
.single-slide {
padding: 30px 20px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
width: 30%;
position: absolute;
background-color: white;
transition: 2s ease;
box-shadow: 0px 5px 10px lightgrey;
}
/* Left slide*/
.single-slide[data-order="1"] {
left: 10vw;
transform: translate(-50%) scale(0.8, 0.8);
z-index: 1;
opacity: 0.7;
}
/* Middle slide */
.single-slide[data-order="2"] {
left: 40vw;
transform: translate(-50%);
z-index: 3;
opacity: 1;
}
/* Right slide*/
.single-slide[data-order="3"] {
left: 90vw;
transform: translate(-120%) scale(0.8, 0.8);
z-index: 2;
opacity: 0.7;
}
.single-slide:nth-child(2) {
order: 3;
}
.single-slide:nth-child(1) {
order: 2;
}
.single-slide:nth-child(3) {
order: 1;
}
<div class="all-slides">
<div class="single-slide" data-order="2">
<h3>First slide </h3>
<p>Some text</p>
</div>
<div class="single-slide" data-order="3">
<h3>Second slide</h3>
<p>Some other text</p>
</div>
<div class="single-slide" data-order="1">
<h3>Third slide</h3>
<p>Yet some other text</p>
</div>
</div>
This could be useful if you want to animate a slider (or anything else), but want to keep the order of the elements in the HTML for accessibility purposes, which is one of the useful usage of the order property. See https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items#The_order_property_and_accessibility
Sadly no: the order attribute is animatable, but only as integers. That means that for each step/frame of the animation it will interpolate the value by flooring to the neareast integer. So items will only ever show up in the slot that the computed integer value results in, never in-between in any smooth sort of motion way.
It's technically still an animation: the calculated integer position should still follow the timing function and keyframe rules of the animation, it's just that the items "jump" from position to position as they change.
See https://developer.mozilla.org/en-US/docs/Web/CSS/integer#Interpolation
This question is old now, but I recently tested this, using this Fiddle (adapted from the one posted by Jason in a comment): http://jsfiddle.net/aqrxcd1u/ (code below).
In both Chrome and Firefox this partially animates, in that the order transitions one at a time from the current value to the target value. Meaning it doesn't go from 5->1 but instead goes 5->4->3->2->1.
In desktop Safari it still goes 5->1 directly.
#container {
display: flex;
}
#container div {
width: 100px;
height: 100px;
margin-right: 10px;
background-color: red;
}
#container div:nth-child(even) {
background-color: blue;
}
}
#container div:last-child {
order: 5;
transition: order 1s;
}
#container:hover div:last-child {
order: -1 !important;
}
<div id="container">
<div style="order: 1">Element 1A</div>
<div style="order: 2">Element 2B</div>
<div style="order: 3">Element 3C</div>
<div style="order: 4">Element 4D</div>
<div style="order: 5">Element 5E</div>
</div>
As Emil stated, it only animates as an integer. However, I am thinking of a hack:
Put the element you want to display in a wrapper with 1/10 of the height, set the wrapper overflow: visible
Then put 9 spacing element between these wrappers with the same height.
Put order and transition on all of them.
Change order of a wrapper and watch it 'transitioning'.
Sadly, it's ugly and only work in Firefox.
Here is what I tested in Angular
I'm trying to create the following:
Using two images: one as mask (the diagonal lines) and the other the image and text themselves (the mask and image+text are the same size):
..and I just can't get it done!
I've tried all combinations with divs and z-indeces, opacity and background-image.. (should mention I'm noob to html).
Here's one shot I got at it (with only the mask and an image):
div {
position: absolute;
top: 775px;
left: 0px;
height: 188px;
width: 272px;
background-image: url('grey-out.png');
}
img {
z-index: 1000;
}
<div></div>
<img src="41_large.png" />
Which just gives the diagonal lines themselves..
Can someone please help me out?
How do I make that "disabled" look combining the (semi-transparent) mask and the div?
Thanks!
This approach works:
<div id="pspThing" class="disabled">
<img class="disabled" src="http://i.stack.imgur.com/lCTVr.png" />
</div>
#pspThing {
background: transparent url(http://i.stack.imgur.com/WpgNy.jpg) 0 0 no-repeat;
height: 93px;
width: 273px;
border: 1px solid #000;
margin: 0 auto;
overflow: hidden;
}
#pspThing img {
display: none;
opacity: 0.5;
}
#pspThing img.disabled {
display: block;
}
JS Fiddle demo
Bearing in mind that there's no transparency in your striped png (so far as the imgur hosted image is concerned, anyway, so I'm using opacity instead). Also the JS Fiddle demo's a little more complicated than necessary, so's I could show the disabled/enabled states.
Pleass consider this simple snippet. Very universal solution. Acts and feels very much like the 'disable' attribute of input elements. See the snippet
function disable(elementId, enabling) {
el = document.getElementById(elementId);
if (enabling) {
el.classList.remove("masked");
} else
{
el.classList.add("masked");
}
}
.masked {
position: relative;
pointer-events: none;
display: inline-block;
//visibility:hidden; /* Uncomment this for complete disabling */
}
.masked::before {
position: absolute;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
visibility: visible;
opacity: 0.5;
background-color: black;
//background: url('http://i.imgur.com/lCTVr.png'); /* Uncomment this to use the image */
content: "";
}
<button onclick="alert('Now, click \'OK\' then \'Tab\' key to focus next button.\nThen click \'Enter\' to activate it.');">Test</button>
<div id="div1" style="display:inline-block" class="masked">
<button onclick="alert('Sample button was clicked.')">Maskakable</button>
<button onclick="alert('Sample button was clicked.')">Maskakable</button><br/>
<br/>
<button onclick="alert('Sample button was clicked.')">Maskakable</button>
<button onclick="alert('Sample button was clicked.')">Maskakable</button><br/>
<img src="http://i.stack.imgur.com/WpgNy.jpg">
</div>
<button>Dummy</button>
<br/>
<button id="enableBtn" onclick="disable('div1',true);disable('enableBtn',false);disable('disableBtn',true);">Enable</button>
<button id="disableBtn" onclick="disable('div1',false);disable('enableBtn',true);disable('disableBtn',false);" class="masked">Disable</button>
I built an example here.
I doubt that the position:absolute approach is the best way to handle this since you need to know the size of the image.
For doing it by z-index your both images should be in the container with img tag.