I have a header that changes size when a user scrolls past a certain point via JavaScript.
When a user scrolls beyond 50px, the class .smaller is added to the header, which affects the child elements, including the logo.
However, when the logo DIV element is resized, the quality of the image seems to change; the edges seem much more jagged and sharper.
This is how it looks normally:
And scrolled:
Here is the CSS:
div#header div.logo {
width: 400px;
height: 90px;
margin: 5px;
background: url(../img/logo.png) no-repeat center center;
background-size:contain;
float:left;
padding:0 !important;
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
-ms-transition: all 0.3s;
-o-transition: all 0.3s;
transition: all 0.3s;
}
div#header.smaller div.logo {
width:262px;
height:40px;
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
-ms-transition: all 0.3s;
-o-transition: all 0.3s;
transition: all 0.3s;
}
Relevant JavaScript:
window.onload = init();
function init() {
//header resize on scroll
window.addEventListener('scroll', function(e){
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 50,
header = document.querySelector("#header");
if (distanceY > shrinkOn) {
classie.add(header,"smaller");
} else {
if (classie.has(header,"smaller")) {
classie.remove(header,"smaller");
}
}
});
}
Why is there such a noticeable change in image quality, and how can this be avoided?
The image got blurry when navigator resize your image on the fly. SVG image will not blur your logo.
e.g. virtuehost.net/clients/go2markets check this site and try to resize this logo.
Related
I have several divs, each containing an icon and a tooltip-type image:
The container is square, height=135px and width=135px.
The icon div is mostly square, has height=135px, width=auto, it's image height=100% and width=autoto keep aspect ratio. The width is smaller than the height.
The tooltip is rectangular, height=135px, width=auto, it's image height=100% and width=auto. The width is usually at least two times larger than the height.
The images are aligned with Bootstrap 4 classes.
Together, the container divs form up a kind of mosaic of services. When each icon image is hovered, the corresponding tooltip-like image appears with a "book opening" animation, from the center of the icon. What I mean is, the child div has width:0; until the parent is hovered, then it animates to width:[width of contained image];. The markup is as follows:
<!-- container div -->
<div class="int_Sicon mx-2 my-2">
<!-- div containing the icon -->
<a href="corresponding service page">
<div class="d-block dLarge">
<img height="100%" src="the icon url">
</div>
</a>
<!-- div containing the tooltip -->
<div class="int_Stooltip dLarge">
<img height="100%" src="the tooltip url">
</div>
</div>
I had a buggy css animation doing what I wanted for a specific "tooltip" image, for layout testing purposes (the following css code), but it all broke apart when I finished testing and started adding the rest of the images. I had specific widths set, and utilized the left property to achieve what I intended, but right now I'm finishing development and wanted to allow the user to change images without breaking the layout. Each tooltip is a different image with the same height but varying widths. This is the CSS I have right now:
.dLarge { height: 135px; }
/* for different viewports I also have different heights for the icons and tooltips, but for the sake of clarity, let's focus on "dLarge" - 135px height */
.int_Sicon { position:relative; }
.int_Sicon .int_Stooltip {
visibility: hidden;
position: absolute;
z-index: 1;
overflow: hidden;
pointer-events: none;
top:0;
left: 0;
margin:0;
-webkit-transition: width 0.3s ease-out, left 0.3s ease-out;
-moz-transition: width 0.3s ease-out, left 0.3s ease-out;
-o-transition: width 0.3s ease-out, left 0.3s ease-out;
transition: width 0.3s ease-out, left 0.3s ease-out;
}
.int_Sicon .int_Stooltip::after {
content: "";
position: absolute;
}
.int_Sicon:hover .int_Stooltip {
visibility: visible;
left: -100%;
}
So I started messing around with javascript and this is where I ended up, unsucessfully:
var getWidth = $('.int_Stooltip>img').outerWidth();
$('.int_Stooltip').css({'width' : 0});
$('.int_Sicon').hover( $('.int_Sicon>.int_Stooltip').css({'width' : getWidth}); );
I looked everywhere for a solution, but nothing I find quite suits what I want to accomplish.
I based myself on this StackOverflow question: Expand div from the middle instead of just top and left using CSS
Essentially, I wanted to make something on the lines of this https://codepen.io/wintr/pen/wWoRVW except with an image covering the button instead of a background animation.
I'm using Bootstrap 4.0 beta 2 and Jquery 3.2.1.
I'm self taught, and eager to learn more. What am I missing? Or at least, where should I look?
If your trying to achieve the effect in the code pen example. You'll want to have your tooltip centered by default with a width of 0. You can center an absolutely positioned element by setting its top, right, bottom, and left properties to 0, then setting its margins to auto. Then when you hover, the width should change to 100%. Check out the code below. I added some colors and text just to help visualize it since there were no actual images.
.int_Slogo {position:relative; display:inline-block;}
.int_Slogo .int_Stooltip {
width: 0;
position: absolute;
z-index: 1;
pointer-events: none;
overflow: hidden;
top:0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
-webkit-transition: width 0.3s ease-out, left 0.3s ease-out;
-moz-transition: width 0.3s ease-out, left 0.3s ease-out;
-o-transition: width 0.3s ease-out, left 0.3s ease-out;
transition: width 0.3s ease-out, left 0.3s ease-out;
}
.int_Slogo:hover .int_Stooltip {
width: 100%;
}
<div class="int_Slogo mx-2 my-2">
<a href="Services">
<div class="d-block dLarge">
<img src="http://lorempixel.com/400/200/sports/1/Dummy-Text/">
</div>
</a>
<div class="int_Stooltip dLarge">
<img src="http://lorempixel.com/400/200/sports/Dummy-Text/">
</div>
</div>
I woke up especially inspired this morning and came up with the solution. The answer wasn't in defining the widths of the divs, but specifying css for the images themselves. This is what I came up with.
Markup:
<div class="dLarge int_Sicon mx-2 my-2">
<a href="corresponding service page">
<div class="d-block">
<img class="dLargeImg m-auto d-block" src="imgsrc">
</div>
</a>
<div class="int_Stooltip">
<img class="dLargeImgs m-auto d-block" src="imgsrc">
</div>
</div>
Styles:
.dLarge {
height: 135px;
width: 135px;
}
.dLargeImgs { height:135px; }
.int_Sicon {
position:relative;
display: inline-block;
}
.int_Sicon .int_Stooltip {
position: absolute;
top:0;
right:0;
bottom:0;
left: 0;
margin:0;
z-index: 1;
pointer-events: none;
overflow: hidden;
-webkit-transition: left 0.3s ease-in-out, right 0.3s ease-in-out;
-moz-transition: left 0.3s ease-in-out, right 0.3s ease-in-out;
-o-transition: left 0.3s ease-in-out, right 0.3s ease-in-out;
transition: left 0.3s ease-in-out, right 0.3s ease-in-out;
}
.int_Sicon:hover .int_Stooltip {
left:-50%;
right:-50%;
}
.int_Sicon .int_Stooltip img {
width:0;
-webkit-transition: width 0.3s ease-in-out;
-moz-transition: width 0.3s ease-in-out;
-o-transition: width 0.3s ease-in-out;
transition: width 0.3s ease-in-out}
.int_Sicon:hover .int_Stooltip img { width:100%; }
I've been experimenting with Ace Editor and I've been trying to automatically "hide" (= not use the system defaults) the vertical/horizontal scrollbars, when not in use.
Is there a way? Any ideas?
Just add overflow:auto css to the right element. I think that could be .ace_scroller. Give me example with scrollers or find by yourself using Object Inspector (Ctrl + Shift + I ; Chrome, FF, Opera).
Edit:
There is your code:
body .ace_scrollbar-v {
overflow-y: auto;
}
body .ace_scrollbar-h {
overflow-x: auto;
}
Edit2:
Hide scrollbar If editor isn't hovered:
body .ace_scrollbar {
display: none;
}
body .ace_editor:hover .ace_scrollbar {
display: block;
}
Or with animation:
body .ace_scrollbar {
-webkit-transition: opacity .3s ease-in-out;
-moz-transition: opacity .3s ease-in-out;
-ms-transition: opacity .3s ease-in-out;
-o-transition: opacity .3s ease-in-out;
transition: opacity .3s ease-in-out;
opacity: 0;
}
body .ace_editor:hover .ace_scrollbar {
opacity: 1;
}
You may want to set the word wrap too.
editor.getSession().setUseWrapMode(true)
I have a header that appears when the page scrolls down. I am trying to add css transitions to make it fade in and out because I've read that using javascript for fading is not as efficient.
.header-wrapper {
top:0;
left:0;
right:0;
position: fixed;
display:none;
height: 60px;
border-top: 1px solid #000;
background: red;
z-index: 1;
}
.header-wrapper.active {
display:block;
}
.header {
background-color:#000;
height:80px;
}
Here is the js fiddle
$(window).scroll(function () {
var y = $(window).scrollTop();
// if above 300 and doesn't have active class yet
if (y > 300 && !$('.header-wrapper').hasClass('active')) {
$('.header-wrapper').addClass('active');
// if below 300 has still has active class
} else if(y <= 300 && $('.header-wrapper').hasClass('active')) {
$('.header-wrapper').removeClass('active');
}
});
Transitions are added with the css3 property transition.
One common reason for confusion: you can only transition properties that accept numeric values. Thus, you can't transition between display: block and display: none.
However you can transition between opacity: 0 and opacity: 1 with:
transition: 0.5s opacity
That would look something like this:
.bottomMenu {
...
opacity: 0;
transition: 0.5s opacity;
...
}
.bottomMenu.active {
opacity: 1;
}
For your particular case, I might recommend transitioning the height between 0 and 60px.
For that you can use:
transition: 0.5s height
So:
.bottomMenu {
...
height: 0;
transition: 0.5s height;
...
}
.bottomMenu.active {
height: 80px;
}
To animate the opacity the element must be visible. So remove the display:none and make it fully transparent (opacity:0). You can then use CSS transitions to animate the opacity when the classname changes:
.bottomMenu {
...
display:block;
opacity: 0;
transition: opacity .25s ease-in-out;
-moz-transition: opacity .25s ease-in-out;
-webkit-transition: opacity .25s ease-in-out;
}
.bottomMenu.active {
opacity:1
}
http://jsfiddle.net/oL9ro4gL/6/
Furthermore, you're not restricted to just animating the opacity:
.bottomMenu {
...
transition: all .25s ease-in-out;
}
.bottomMenu.active {
opacity:1;
height: 60px;
background-color: blue;
transform:rotate(180deg);
color:white;
font-size:40px;
etc...
}
http://jsfiddle.net/oL9ro4gL/8/
Unfortunately, you can't animate the display property. See this question and its suggestions for workarounds.
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.
I'm using the following code.
By clicking on div id="popUpPane", the div and it's childs should appear and slowly fade in.
By clicking on the div again, it should slowly fade out and then disappear.
Firefox and Chrome (which is webkit too) behave that way and I know Safari did in an earlier version, too. But right know on Safari and on Safari Mobile nothing happens at all when I click on "popUpPane".
Is this a bug in Safari or is there something I could change to come back to the intended behaviour?
One addition: If I set -webkit-transition to -webkit-transition: opacity .5s ease-in-out; it works fine but the transition only appears on the first click. There's no transitions after that first one... If I delete the opacity-part in the java-script the opo-up works but there's no transition.
All other transitions on my site are working. But they all use only opacity and no visibility.
Here's my code:
CSS:
#popUpPane {
white-space:normal;
position:fixed;
width:100%;
height:100%;
top:0;
left:0;
text-align:center;
vertical-align:middle;
visibility:hidden;
z-index:90;
}
#greyOut {
position:fixed;
width:100%;
height:100%;
top:0;
left:0;
background-color:#000;
opacity:0;
}
#popUpPicCanvas {
position:relative;
top:50%;
margin-top:-325px;
display:inline;
opacity:0;
z-index:100;
}
.fade {
-webkit-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
-o-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
}
HTML:
<div id="popUpPane" onClick="noPopUp()">
<div id="greyOut" class="fade"> </div>
<canvas id="popUpPicCanvas" width="1000" height="650" title="Bastian Beuttel" class="fade"></canvas>
</div>
Javascript:
var popUpPane = document.getElementById("popUpPane"),
greyOut = document.getElementById("greyOut"),
popUpPicCanvas = document.getElementById("popUpPicCanvas"),
popCanvasContext = popUpPicCanvas.getContext("2d");
var doPopUp = function(source,x,y){
var popUpPic = document.getElementById("pic"+source);
popCanvasContext.canvas.width = x;
popCanvasContext.canvas.height = y;
popCanvasContext.drawImage(popUpPic, 0, 0,x,y);
popUpPane.style.visibility = "visible";
greyOut.style.opacity = "0.7";
popUpPicCanvas.style.opacity = "1";
};
var noPopUp = function(){
greyOut.style.opacity = "0";
popUpPicCanvas.style.opacity = "0";
popUpPane.style.visibility = "hidden";
};
I hope someone can help me.
Thanks for your responds!
Yep, there is a bug in mobile Safari with simultaneous transition for opacity+visibility.
You can fix it using something except for visibility: in your case setting the width and height to 0 would help. However you must add the delay, so they would change not instantly.
Here is a dabblet with the working example: http://dabblet.com/gist/1642110
/**
* Delayed alternative for visibility
*/
a {
display: inline-block;
background: #888;
color:#FFF;
padding: 1em;
}
div {
width: 100px;
height: 100px;
background: lime;
transition: opacity 1s;
}
a:hover+div {
width: 0;
height: 0;
opacity: 0;
transition: width 0s 1s, height 0s 1s, opacity 1s;
}
Thank you!
Since this bug is now removed from the latest releases of webkit the problem is gone for safari and chrome.
i started to have problems since the position of my div also was transitioned so I wrote it like this:
.dofade {
-webkit-transition: visibility .5s ease-in-out, opacity .5s ease-in-out;
-moz-transition: visibility .5s ease-in-out, opacity .5s ease-in-out;
-o-transition: visibility .5s ease-in-out, opacity .5s ease-in-out;
transition: visibility .5s ease-in-out, opacity .5s ease-in-out;
}