I am trying to evenly increase and then decrease the font size of anchor text inside a paragraph without moving the paragraph text. This way the anchor text will look as if it is coming toward the user and then receding back into its original place. The font-size also appears as if it is growing from the lower left corner as opposed to what I want which is evenly from all sides.
HTML:
<p>
<a>[D]</a>I've been workin' on the railroad,
<a>[G]</a>all the live long <a>[D]</a>day.
<a>[D]</a>I've been workin' on the railroad,
just to <a>[E]</a>pass the time a<a>[A]</a>way.
</p>
CSS:
p {
white-space: pre-wrap;
}
a {
-webkit-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
-ms-transition: all .5s ease-in-out;
-o-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
color:red;
}
.increase-font {
font-size: 30px;
background:#FFF;
}
Jquery/Javascript:
$('a').on('click',function(e){
e.preventDefault();
var el = this;
$(el).addClass('increase-font');
setTimeout(function(){
$(el).removeClass('increase-font');
},1000);
});
Here is the fiddle:
https://jsfiddle.net/scooke/ro2tyf6h/
To achieve this, the anchor texts need to be somewhat independent from the parent. Inserting the anchor text with CSS :before or :after selectors will solve the problem. See my example and adjust as needed.
$('a').on('click', function(e) {
e.preventDefault();
var el = this;
$(el).addClass('increase-font');
setTimeout(function() {
$(el).removeClass('increase-font');
}, 1000);
})
p {
white-space: pre-wrap;
padding-left: 30px;
display: inline-block;
width: 100%;
position: relative;
}
a {
-webkit-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
-ms-transition: all .5s ease-in-out;
-o-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
color: red;
display: inline-block;
position: relative;
width: 30px;
height: 10px;
}
a:before {
content: "[D]";
position: absolute;
left: 0;
text-align: center!important;
width: 100%;
top: -5px;
}
.increase-font {
font-size: 30px;
background: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> <a></a>I've been workin' on the railroad,</p>
<p><a></a>all the live long <a></a>day.</p>
<p><a></a>I've been workin' on the railroad, just to <a></a>pass the time a<a></a>way.</p>
Suggestions:
Restructuring your HTML will be a good start
Adding a background to the :hover state will help keep it clean
and distinguishable.
It's relatively simple - just wrap the anchor tags in span tags:
<p><a><span>[D]</span></a>I've been workin' on the railroad,</p>
<p><a><span>[G]</span></a>all the live long <a><span>[D]</span></a>day.</p>
<p><a><span>[D]</span></a>I've been workin' on the railroad, just to <a><span>[E]</span></a>pass the time a<a><span>[A]</span></a>way.</p>
Set the anchor's position to relative (with a margin to give its children spans room), whilst also setting span tags to absolute:
a {
position: relative;
max-height: 0px;
max-width: 0px;
margin-right: 25px;
}
span {
position: absolute;
top: 0;
left: 0;
}
Then just swap the jQuery event handler from registering on all anchor tags to all span tags:
$('span').on('click',function(e){
e.preventDefault();
var el = this;
$(el).addClass('increase-font');
setTimeout(function(){
$(el).removeClass('increase-font');
},1000);
})
Seeing as absolute elements are removed from the DOM flow, resizing the spans doesn't effect the elements around it. Full code here:
https://jsfiddle.net/ro2tyf6h/5/
Related
For some reason when I add the second click function it stops working completely. I was wondering if anybody could help pin point what the issue might be?
What I'm trying to do:
The default state is "day" and when "night" is clicked, it removes the day class and adds the night class. Which changes the background image. Which works... Sort of. However, when I add the function for the day button to add the day class and remove the night class is breaks and doesn't work.
Here's a fiddle of what I have: http://jsfiddle.net/790hqykq/3/
$(document).ready(function () {
$('.night').click(function () {
$('#room').addClass('night');
$('#room').removeClass('day');
});
$('.day').click(function () {
$('#room').addClass('day');
$('#room').removeClass('night');
});
});
Thanks!!
Edit: Also - Is there any way to fade this class change? Similar to fadeIn/fadeOut? Thanks!
jsFiddle Demo
The problem with your fiddle is that the #room element has the class day. So does the anchor element. When the event handler is setup
$('.day').click(function () {
It is also assigned to the room element, and as a result of that, #room ends up also having the event handler attached to it. This causes day to always be selected as the element's class, even when night is clicked.
You should consider changing the class name to something like daycolor and nightcolor
<div id="room" class="daycolor">
and
#room.daycolor {
background: #00CCFF;
}
The element with ID room has the class day, as one of the elements within it.
When you attach the handler, it's being attached to both elements.
This should solve your problem:
$(document).ready(function () {
$('.timeButton.day').click(function () {
$('#room').addClass('day').removeClass('night');
});
$('.timeButton.night').click(function () {
$('#room').addClass('night').removeClass('day');
});
});
As per your complement about fading, you can use CSS 3 to achieve this:
#room {
-webkit-transition: background 0.5s linear;
-moz-transition: background 0.5s linear;
-ms-transition: background 0.5s linear;
-o-transition: background 0.5s linear;
transition: background 0.5s linear;
}
Demo
Change the classnames on your children elements and use that selector for your events.
jsFiddle
HTML:
<div id="container">
<div id="room" class="day">
<a class="timeButton day1">Day</a>
<a class="timeButton night1">Night</a>
</div>
</div>
JS:
$(document).ready(function () {
$('.night1').click(function () {
$('#room').addClass('night');
$('#room').removeClass('day');
});
$('.day1').click(function () {
$('#room').addClass('day');
$('#room').removeClass('night');
});
});
Style:
#container {
width: 300px;
margin: 0 auto;
}
#container a, #container div {
float: left;
display: block;
}
#room {
width: 300px;
height: 200px;
position: relative;
}
#room.day {
background: #00CCFF;
}
#room.night {
background: #0000CC;
}
#room .day1 {
left: 30px;
border: 1px solid black;
}
#room .night1 {
right: 30px;
border: 1px solid black;
}
#room .timeButton {
position: absolute;
width: 80px;
height: 25px;
top: 30px;
cursor: pointer;
text-align: center;
}
#room .timeButton:hover {
background: #fff;
}
Here is another solution, where I just change the css-style via jquery.
Javascript:
$(document).ready(function () {
$('.day').click(function () {
$('#room').css("background-color", "#00CCFF");
});
$('.night').click(function () {
$('#room').css("background-color", "#0000CC");
});
});
Also you need to add a background-color to #room:
background: #00CCFF;
Fiddle:
http://jsfiddle.net/790hqykq/7/
In your script, you reference to ".night" instead ".nightButton".
$('.nightButton').click(function () {
$('#room').addClass('night');
$('#room').removeClass('day');
});
$('.dayButton').click(function () {
$('#room').addClass('day');
$('#room').removeClass('night');
});
To achieve the transition, you can add this CSS propertie to #room.
-webkit-transition: background 2s; /* For Safari 3.1 to 6.0 */
transition: background 2s;
http://jsfiddle.net/790hqykq/13/
you can add css3 for the transitions from day to night.
it wont working in older IE browsers 9 and under but is excellent in all modern browsers.
browser support. You can use this generator to make the code faster.
#room {
width: 300px;
height: 200px;
position: relative;
-webkit-transition: background 1000ms ease-in-out;
-moz-transition: background 1000ms ease-in-out;
-ms-transition: background 1000ms ease-in-out;
-o-transition: background 1000ms ease-in-out;
transition: background 1000ms ease-in-out;
}
Demo jsfiddle
Is there a way to animate display:none to display:block using CSS so that the hidden div slides down instead of abruptly appearing, or should I go about this a different way?
$(document).ready(function() {
$('#box').click(function() {
$(this).find(".hidden").toggleClass('open');
});
});
#box {
height:auto;
background:#000;
color:#fff;
cursor:pointer;
}
.hidden {
height:200px;
display:none;
}
.hidden.open {
display:block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="box">
Initial Content
<div class="hidden">
This is hidden content
</div>
</div>
And a JSFiddle
Yes, there is a way:
http://jsfiddle.net/6C42Q/12/
By using CSS3 transitions, and manipulate height, rather than display property:
.hidden {
height: 0px;
-webkit-transition: height 0.5s linear;
-moz-transition: height 0.5s linear;
-ms-transition: height 0.5s linear;
-o-transition: height 0.5s linear;
transition: height 0.5s linear;
}
.hidden.open {
height: 200px;
-webkit-transition: height 0.5s linear;
-moz-transition: height 0.5s linear;
-ms-transition: height 0.5s linear;
-o-transition: height 0.5s linear;
transition: height 0.5s linear;
}
More here: Slide down div on click Pure CSS?
Since you're already using jQuery, the simplest thing is just to use slideDown(). http://api.jquery.com/slidedown/
There's also slideToggle().
Then you don't need to manually do all the browser-specific transition css.
I like the idea of CSS transitions, but it's still very jumpy. Sometimes the max-height has to be set to a very high number because of dynamic content which renders the transition useless as it's very jumpy. So, I went back to jQuery, but it had its own faults. inline elements are jumpy.
I found this to work for me:
$(this).find('.p').stop().css('display','block').hide().slideDown();
The stop stops all previous transitions.
The css makes sure it's treated as a block element even if it's not.
The hide hides that element, but jquery will remember it as a block element.
and finally the slideDown shows the element by sliding it down.
What about
$("#yourdiv").animate({height: 'toggle'});
Toggle will switch your div on/off, and the animate should make it appear from below. In this scenario, you don't need the specific CSS to "hide" it.
We can use visibility: hidden to visibility: visible instead of display: none to display: block property.
See this example:
function toggleSlide () {
const div = document.querySelector('div')
if (div.classList.contains('open')) {
div.classList.remove('open')
} else {
div.classList.add('open')
}
}
div {
visibility: hidden;
transition: visibility .5s, max-height .5s;
max-height: 0;
overflow: hidden;
/* additional style */
background: grey;
color: white;
padding: 0px 12px;
margin-bottom: 8px;
}
div.open {
visibility: visible;
/* Set max-height to something bigger than the box could ever be */
max-height: 100px;
}
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
</div>
<button
onclick="toggleSlide()"
>
toggle slide
</button>
I did this workaround for the navigation header in my React site.
This is the regular visible css class
.article-header {
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
}
This is the class that is attached to the div (when scrolled in my case)
.hidden {
top: -50px !important;
transition: top 0.5s ease-in-out;
}
You can use also
$('#youDiv').slideDown('fast');
or you can tell that the active div goes up then the called one goes down
$('.yourclick').click(function(e) {
var gett = $(this).(ID);
$('.youractiveDiv').slideUp('fast', function(){
$('.'+gett).slideDown(300);
});
});
Something like that.
My CSS:
a:hover {
position: relative;
}
a:hover:after {
z-index: -1;
content: url(icon.jpg);
display: block;
position: absolute;
left: 0px;
bottom: 20px;
}
This displays an icon when I hover over an anchor, from this post:
Make image appear on link hover css
I am trying to apply this:
-webkit-transition: all 0.3s ease-in;
-moz-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
So that the image fades in, but I cant get it to work.
WebKit (Chrome, Safari) does not support transitions on pseudo elements. It should work in Firefox.
see this q/a
To accomplish your need you could apply the background image for the link and in hover you could apply the transition by setting the background-position. You can also use an extra span inside the a tag instead of using :before pseudo class.
You could do a background image.
a {
-webkit-transition: all 0.3s ease-in;
-moz-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
}
a:hover {
position: relative;
background:url(icon.jpg);
}
The code is just an example, you would need to position the background image as well, since I dont know the dimensions of your design I can't tell you the exact position.
Webkit currently support transitions and animations
http://css-tricks.com/transitions-and-animations-on-css-generated-content/
a:hover {
position: relative;
}
a:after{
-webkit-transition: all 0.3s ease-in;
-moz-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
transition: all 0.3s ease-in; /*never forget the standard*/
}
a:hover:after {
z-index: -1;
content: url(icon.jpg);
display: block;
position: absolute;
left: 0px;
bottom: 20px;
}
And the example used before:
http://jsfiddle.net/d2KrC/88/
The example using image
http://jsfiddle.net/d2KrC/92/
There are some css "tricks" that can help you, maybe using css keyframes, but the best way to perform this in a compatibility way is using jQuery (a jquery version that matches your compat needs).
As some people asked you on css, where webkit actually support this kind of transitions, and this question could grow if we start talking on standards, the best you can do at first is update all your browsers and check.
If you need or want to keep compat on older browser versions, you'll need to catch the hover event with javascript and then do whatever you want (as javascript can work directly with the DOM) and with CSS is pre-loaded and the most you can do is change the properties. i.e.
load image with display: none, then change this property with an event.
example on jquery:
$('.link').click(function(){
$('.foo').fadeIn();
});
$('.link2').click(function(){
$('.foo2').fadeToggle();
if($('.link2').text() == 'show or hide') $('.link2').text('click again');
else $('.link2').text('show or hide');
});
.foo, .foo2{display: none; width: 100px; height: auto;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<img class="foo" src="http://joelbonetr.com/images/root.jpg" alt="">
<a class="link" href="#">show it!</a>
</p>
<p>
<img class="foo2" src="http://joelbonetr.com/images/root.jpg" alt="">
<a class="link2" href="#">show or hide</a>
</p>
I want the little hover grey arrows to be display block and not animate when hovering over the thumbnail navigation. You can see the demo here. I have been wading through the javascript for the plugin and cannot for the life of me work out where it is animating the arrows. If I could, I would just comment out that code. So can anyone else?
This confused me for a little while, but it turns out the arrow animation isn't actually in the plugins javascript. It's in the CSS using -webkit-transition: all .3s ease;. If you look at the default CSS file and go to line 52 you need to remove the above out of .flex-direction-nav a. So the line should look like the below.
.flex-direction-nav a {
width: 30px;
height: 30px;
margin: -20px 0 0;
display: block;
background: url(images/bg_direction_nav.png) no-repeat 0 0;
position: absolute;
top: 50%;
z-index: 10;
cursor: pointer;
text-indent: -9999px;
opacity: 0;
}
I recently ran into this issue and solved it (with the help of this question/answer) by overriding the following styles:
.flex-direction-nav a {
...
-webkit-transition: all .3s ease;
-moz-transition: all .3s ease;
transition: all .3s ease;
}
with these styles in my own css:
.flexslider .flex-direction-nav a.flex-prev,
.flexslider .flex-direction-nav a.flex-next {
...
-moz-transition: none;
-webkit-transition: none;
transition: none;
}
I'm a big fan of not modifying source code provided by a library, so I think this is a better and more complete solution.
It is very simple, just change the following css code like this:
.flexslider .flex-direction-nav .flex-next {
right: 5px; /* adjust offset to match the hover style */
opacity: .8; /* adjust opacity to match the hover style */
}
.flexslider .flex-direction-nav .flex-prev {
left: 5px; /* adjust offset to match the hover style */
opacity: .8; /* adjust opacity to match the hover style */
}
Make your own arrows: disable directionNav and use manualControls.
I was wondering if you can offer me a better way of achieving the effect Ive created in this fiddle: http://jsfiddle.net/YLuKh/1/
Basically I would like to animate the background colour of the anchor tag revealing an image which I've done by positioning an anchor tag on top of a span on top of an image and then on hover animate the width of the span. Can anyone suggest a more straight forward way of doing this?
HTML
<ul id="test">
<li>
This is the link
<span class="bg"></span>
<img src="http://www.ritaxxii.org/wp-content/uploads/Luxury-Bedroom-Furniture-1.jpg" />
</li>
</ul>
JS
$(document).ready(function() {
var li_width = $('#test').find('li').width();
console.log(li_width);
$('#test').find('li').on('mouseover', function() {
$(this).find('.bg').stop().animate({
width: '0'
}, 200);
}).on('mouseout', function() {
$(this).find('.bg').stop().animate({
width: li_width
}, 200);
});
});
As I mentioned in the comments you can use the background position to do the animation. Here's a simple one using only background image positioning ( http://jsfiddle.net/3PESX/ )
$('a').mouseenter(function() {
$(this).stop().animate({ 'background-position-x': '-700px'}, 300);
});
$('a').mouseleave(function() {
$(this).stop().animate({ 'background-position-x': '0'}, 300);
});
a {
display: inline-block;
height: 50px;
width: 300px;
background: transparent url(http://jtrujillo.net/digital-photo-tutorials/8vs16bit/dgr1.jpg) 0 top no-repeat;
color: grey;
text-decoration: none;
line-height: 50px;
}
This is a link text
Beware that the background-position property is a composition of the x and y version. You cannot animate composite properties, you'll need to animate the X and Y version seperately. Alternatively you can use a css hook plugin that makes it possible. You can find those here: https://github.com/brandonaaron/jquery-cssHooks
You can get a referance from this : http://snook.ca/archives/javascript/jquery-bg-image-animations
May I suggest a CSS3-only means of achieving what I think you're trying to do:
li {
border: 1px solid #f90;
width: 504px; /* width of the image, adjust to taste */
overflow: hidden;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
}
li a {
display: block;
position: relative;
width: 100%;
height: 2em;
line-height: 2em;
color: #fff;
background-color: #000;
-webkit-transition: width 1s linear;
-moz-transition: width 1s linear;
-o-transition: width 1s linear;
-ms-transition: width 1s linear;
transition: width 1s linear;
}
li:hover a {
width: 0;
-webkit-transition: width 1s linear;
}
li a::after {
content: url(http://www.ritaxxii.org/wp-content/uploads/Luxury-Bedroom-Furniture-1.jpg);
position: absolute;
top: 0;
right: 0;
left: 100%;
bottom: 0;
}
JS Fiddle demo.
If you're going to have a lot of list items, you might want to consider event delegation to the #test element so you dont have to attach a bunch of different event listeners to each li tag
//attach one event listener for 'mouseover' and one for 'mouseout' on the test element
$('#test').on('mouseover', 'li', function(){
//'this' is still the li element
console.log( $(this));
$(this).find('.bg').stop().animate({width: '0'},200);
}).on('mouseout', 'li', function(){
$(this).find('.bg').stop().animate({width: li_width},200);
});