Animate width of 3 columns so that they always occupy entire space - javascript

I have a simple page containing 3 divs within a container like this:
<body>
<div id="mainContainer">
<div id="mainColumn1" class="bgColumn"></div>
<div id="mainColumn2" class="bgColumn"></div>
<div id="mainColumn3" class="bgColumn"></div>
</div>
</body>
They are meant to be 3 even columns that occupy entire page. Whenever you hover one of them it expands to 50%, and the others shrink to 25%.
It's hard to explain where the problem is so here's jFiddle:
http://jsfiddle.net/FWcC5/2/
If you move cursor quickly all over the place, you will notice white space appear on the right side. It happens in Firefox. Oddly enough in Chrome it behaves exactly as it should.
I tried using the same thing with flex-grid, which worked but the performance dropped drastically in Chrome.
Any help would be appreciated.

I'm not sure what the problem is with Firefox though I tried and can confirm there is an issue, however there is a better and less procedural way of achieving what you're currently doing.
You can shorten your javascript massively to:
$(document).ready(function () {
$('.bgColumn').hover(function(){
$('.bgColumn').width("25%").not($(this));
$(this).width("50%");
});
});
see fiddle

$(document).ready(function () {
$('.bgColumn').hover(function(){
$(this).width('50%');
$('.bgColumn').not(this).width('25%');
},
function(){
$('.bgColumn').width('33.3%');
});
});
html, body {
height: 100%;
margin: 0;
padding: 0;
background-repeat: no-repeat;
}
div {
position: relative;
background-position: center;
}
#mainContainer {
width: 100%;
height: 100%;
overflow: hidden;
white-space:nowrap;
}
.bgColumn {
position: relative;
background-repeat: no-repeat;
transition: all 0.1s linear;
height: 100%;
width: 33.333%;
display: inline-block;
}
#mainColumn1 {
background-color: gray;
float:left;
}
#mainColumn2 {
background-color: white;
float:left;
}
#mainColumn3 {
background-color: black;
float:right;
}

Related

An expandable div?

I want to create a div where one of the children is visible and one is out of the div, I've been using overflow:hidden for this, however whatever i try i can't seem to get this to work, I've tried positioning one absolute and that works, but as soon as I extend the div to reveal the extention it will overlap it obviously. Any help would be great, here are some pictures of the main concept.
Before Being Clicked
After Being Clicked
note: I am using react js to develop this, if you could make a codepen or something in vanilla javscript just as a concept of the main functionality and then I will convert it to react.
Thanks in advance :)
Here is one way:
.expandable {
position: relative;
}
.expandable>div {
width: 200px;
transition: all 1s;
overflow: hidden;
background-image: url('https://via.placeholder.com/200');
background-repeat: no-repeat;
min-height: 200px;
border: 1px solid black;
}
.expandable>div>img {
position: absolute;
width: 200px;
}
.expandable>input { display: none; }
.expandable>label {
position: absolute;
top: 90px;
left: 210px;
transition: all 1s;
background-image: url('https://img.icons8.com/flat_round/64/000000/arrow--v1.png');
width: 20px;
height: 20px;
background-size: cover;
background-repeat: no-repeat;
transform: rotate(0deg);
}
.expandable>input:checked+label {
left: 410px;
transform: rotate(180deg);
}
.expandable>input:checked~div {
width: 400px;
}
.expandable>div>div {
width: 200px;
padding-left: 200px;
}
<div class="expandable">
<input type=checkbox id='ex1'>
<label for='ex1'></label>
<div>
<div>
<!-- right side content -->
<h1>Stuff here</h1>
<p>lorem ipsum</p>
</div>
</div>
</div>
This uses the label as the button. When clicked, it triggers the input to be checked/unchecked. We then use the status of the checkbox to change our CSS, and we use transitions so that it is smooth, works across all modern browsers, and is very battery efficient for mobile devices.

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;
}

Make image fill div completely without stretching

I have large images of varying dimensions that need to completely fill 240px by 300px containers in both dimensions. Here is what I got right now, which only works for one dimension:
http://jsfiddle.net/HsE6H/
HTML
<div class="container">
<img src="http://placehold.it/300x1500">
</div>
<div class="container">
<img src="http://placehold.it/1500x300">
</div
CSS
.container {
height: 300px;
width: 240px;
background-color: red;
float: left;
overflow: hidden;
margin: 20px;
}
img {
max-width: 100%;
height: auto;
}
The proportions should stay the same. Essentially, wide images should be cut off in width, while high images need to be cut off in height. So just zooming in as much as is needed to fill the container.
Not sure why I can't get it to work, do I need JavaScript for this?
Edit: To be clear. I need everything red on the fiddle gone. The images coming in are dynamic, therefore I can't use background-images. I'm open to using JavaScript. Thanks! :)
Auto-sizing Images to Fit a Div - Making the CSS Work
Here is one way of doing it, start with the following HTML:
<div class="container portrait">
<h4>Portrait Style</h4>
<img src="http://placekitten.com/150/300">
</div>
and the CSS:
.container {
height: 300px;
width: 240px;
background-color: red;
float: left;
overflow: hidden;
margin: 20px;
}
.container img {
display: block;
}
.portrait img {
width: 100%;
}
.landscape img {
height: 100%;
}
and the demo fiddle: http://jsfiddle.net/audetwebdesign/QEpJH/
When you have an image oriented as a portrait, you need to scale the width to 100%. Conversely, when the image is landscape oriented, you need to scale the height.
Unfortunately, there is no combination of selectors in CSS that targets the aspect ratio of the image, so you can't use CSS to pick out the correct scaling.
In addition, you have no easy way of centering the image since the top left corner of the image is pinned to the top left corner of the containing block.
jQuery Helper
You can use the following jQuery action to determine which class to set based
on the aspect ratio of the image.
$(".container").each(function(){
// Uncomment the following if you need to make this dynamic
//var refH = $(this).height();
//var refW = $(this).width();
//var refRatio = refW/refH;
// Hard coded value...
var refRatio = 240/300;
var imgH = $(this).children("img").height();
var imgW = $(this).children("img").width();
if ( (imgW/imgH) < refRatio ) {
$(this).addClass("portrait");
} else {
$(this).addClass("landscape");
}
})
For each image in .container, get the height and width, test if width<height and then set the appropriate class.
Also, I added a check to take into account the aspect ratio of the containing block.
Before, I had implicitly assumed a square view panel.
For anyone looking to do this that doesn't have dynamic images, here's an all-CSS solution using background-image.
<div class="container"
style="background-image: url('http://placehold.it/300x1500');
background-size: cover; background-position: center;">
</div>
<div class="container"
style="background-image: url('http://placehold.it/1500x300');
background-size: cover; background-position: center;">
</div>
The "background-size: cover" makes it so that the image scales to cover all of the div while maintaining the aspect ratio. The CSS could also be moved to a CSS file. Although if it's dynamically generated, the background-image property will have to stay in the style attribute.
Taking out the line: max-width:100% in your CSS file seems to do the trick.
.container {
height: 300px;
width: 240px;
background-color: red;
float: left;
overflow: hidden;
margin: 20px;
}
img {
height: auto;
}
Also you can add > to your closing div in your HTML file could make the code neater.
<div class="container">
<img src="http://placehold.it/300x1500">
</div>
<div class="container">
<img src="http://placehold.it/1500x300">
</div>
Here is a working JSFiddle link: http://jsfiddle.net/HsE6H/19/
Here is another solution I found, that no need to seperate portraid or landscape or scripting.
<div class="container">
<img src="http://placehold.it/500x500" class="pic" />
</div>
CSS
.container{
position: relative;
width: 500px;
height: 300px;
margin-top: 30px;
background: #4477bb;
}
.pic{
max-width: 100%;
width: auto;
max-height: 100%;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
Here it is, it works well...
https://jsfiddle.net/efirat/17bopn2q/2/
Background can do this
set image as background
2.
div {
-webkit-background-size: auto 100%;
-moz-background-size: auto 100%;
-o-background-size: auto 100%;
background-size: auto 100%;
}
or
div {
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
You should try this:
img {
min-width:100%;
min-height:100%;
}
I used this plugin that accounts for any ratio. It also requires imagesloaded plugin to work. This would be useful for numerous images across a site needing this treatment. Simple to initiate too.
https://github.com/johnpolacek/imagefill.js/
It works if you add the following to the parent div for img styling;
https://jsfiddle.net/yrrncees/10/
.container img {
position: relative;
vertical-align: middle;
top: 50%;
-webkit-transform: translateY(-50%);
min-height: 100%;
min-width: 100%;
object-fit:cover;
}
This could do the job:
.container {
float: left;
height: 300px;
width: 240px;
background-color: red;
margin: 20px;
}
img {
width:240px;
height:300px;
}
We went down the path with an Angular app of using a variation on the jQuery approach above. Then one of our bright colleagues came up with a pure CSS approach. See this example here: https://jsfiddle.net/jeffturner/yrrncees/1/.
Basically using line-height solved the problem for us. For those not wanting to hit the fiddle, the code fragments are:
.container {
margin: 10px;
width: 125px;
height: 125px;
line-height: 115px;
text-align: center;
border: 1px solid red;
}
.resize_fit_center {
max-width:100%;
max-height:100%;
vertical-align: middle;
}
The key is in using line-height and setting the container to do the same.
I came across this topic because I was trying to solve a similar problem. Then a lightbulb went off in my head and I couldn't believe it worked because it was so simple and so obvious.
CSS
.container {
height: 300px;
width: 240px;
background-color: red;
float: left;
overflow: hidden;
margin: 20px;
}
img {
min-width:100%;
min-height:100%;
}
Just set the min-width and min-height to 100% and it will always automatically resize to fit the div, cutting off the excess image. No muss no fuss.
Using an image as Div background has many disadvantages (like missing ALT for SEO). Instead of it, use object-fit: cover; in the image tag style!
The following solution is very short and clean if you need to insert img tag into div tag:
.container, .container img
{
max-height: 300px;
max-width: 240px;
}
Try to open every image into another page you will notice that originals are all different sized but none is streched, just zoomed:
<p></p>
<div class="container"><img src="https://www.gentoo.org/assets/img/screenshots/surface.png" /></div>
<p></p>
<div class="container"><img src="https://cdn.pixabay.com/photo/2011/03/22/22/25/winter-5701_960_720.jpg" /></div>
<p></p>
<div class="container"><img src="https://cdn.arstechnica.net/wp-content/uploads/2009/11/Screenshot-gnome-shell-overview.png" /></div>
<p></p>
<div class="container"><img src="http://i.imgur.com/OwFSTIw.png" /></div>
<p></p>
<div class="container"><img src="https://www.gentoo.org/assets/img/screenshots/surface.png" /></div>
<p></p>
<div class="container"><img src="https://freebsd.kde.org/img/screenshots/uk_maximignatenko_kde420-1.png" /></div>
<p></p>
<div class="container"><img src="https://i.ytimg.com/vi/9mrOgkYje0s/maxresdefault.jpg" /></div>
<p></p>
<div class="container"><img src="https://upload.wikimedia.org/wikipedia/commons/5/59/Linux_screenshot.jpg" /></div>
<p></p>
Also, if you don't need to use a div you can just write an even shorter css:
img
{
max-height: 300px;
max-width: 240px;
}

Difficulties causing html div to slide horizontally

I'm having trouble animating this item using PHP and CSS and Javascript (with jQuery).
I want a div that slides out from the left side of the screen when its tab bar is hovered over.
I have three divs: the container, the contents, and the tab.
Here's the Javascript and HTML:
<div id="LeftSidebar">
<div id="LeftSidebarTab" class="">
Left sidebar tab
</div>
<div id="LeftSidebarContents" class="">
Left sidebar contents
</div>
<script type="text/javascript">
$("#LeftSidebar").mouseenter(function()
{
$("#LeftSidebar").animate(
{
left: 0px
});
});
$("#LeftSidebar").mouseleave(function()
{
$("#LeftSidebar").animate(
{
left: -100px
});
});
</script>
</div>
Here's the CSS:
#LeftSidebar
{
position: absolute;
display: block;
z-index: 12;
top: 220px;
left: 0px;
background-color: green;
height: 500px;
}
#LeftSidebarTab
{
float: right;
background-color: red;
width: 20px;
height: 100%;
}
#LeftSidebarContents
{
background-color: blue;
width: 100px;
height: 100%;
}
I'm new to Javascript, HTML, and et al.
The code isn't doing what I expect it to do.
I expect it to, when hovered over, gradually move the 'left' CSS property to 0px, and when the mouse moves off of the contents, move the 'left' CSS property to -100px.
When I hover over it, I see no visible change to the div. I can't even tell if the 'mouseenter()' or 'mouseleave()' functions are even being triggered.
Questions:
1) How can I check if the function is being triggered or not? Can I output some text or something, using Javascript? Maybe pop up a dialog box for debugging?
2) Will mouseenter/mouseleave be triggered for 'LeftSidebar', even though LeftSidebarContents and LeftSidebarTab completely cover every pixel of LeftSidebar?
3) Am I making any obvious mistakes in the above code that's causing it not to work as I expect?
You probably want to put some single quotes around the 0px.
Check this: http://api.jquery.com/animate/
Copy their example and get theirs working them modify it to your needs.
As for alerts to check if the event is being triggered:
alert("Thanks for visiting!");
Use ff with firebug or chrome to debug your script. Put a pointer on the functions, this will cause the browser to pauze execution of your script so you can step over it and see what happens.
A quick and dirty test to figure out if an event is being triggered is to use the alert function. For example:
$("#LeftSidebar").mouseenter(function()
{
alert("Mouse Enters Region");
});
Also this is how I would do your css file:
#LeftSidebar
{
position: fixed;
display: block;
z-index: 12;
top: 220px;
left: -100px;
background-color: green;
width:120px;
height: 500px;
}
#LeftSidebarTab
{
position:absolute;
background-color: red;
width: 20px;
height: 500px;
left:100px;
top:0px;
}
#LeftSidebarContents
{
background-color: blue;
position:absolute;
left:0px;
top:0px;
}
I would recommend learning more about the CSS Box Model and probably just reading up on HTML/CSS in general.

child div overlapping rounded (with radius) container when at width of 2%

I have a long rectangle shape container with a radius.
And I also have 3 child divs, in the container.
Here it is:
As you can see in the picture above, the first child container (white) and the third (red) have also been set a radius to match to containers radius.
Now, the child containers width will be dynamic (changeable by the user). So the user will be able to change the widths of all three child containers to meet their needs.
But take a look at what happens when I give the third container a width of 2%:
the same thing happens when i do the same to the first child (it overlaps the containers rounded borders).
Child container 1 (white) is floating to the left and child container 3 (red) is floating to the right.
I need a way to stop the overlapping from happening.
I am able to use JS and JQuery incase your wondering.
Thanks
EDIT:
CSS:
.parent {
border: 1px solid #5B5B5B;
height: 30px;
width: 80%;
right: 0%;
position: relative;
margin-right: auto;
margin-left: auto;
<? set_radius("25px",true);
set_box_shadow("1px","1px","#F8F8F8");?>
overflow: hidden;
z-index: 3;
}
.child_class {
display: inline-block;
position: relative;
width: auto;
height: 100%;
margin: 0px;
border-right-width: 1px;
border-right-style: solid;
border-right-color: #5C5C5C;
box-sizing: border-box;
}
#child1 {
width: 33.33;
background-repeat: repeat-x;
background-position: center center;
<? set_radius("25px",false,false,true,false,true);?>
float: left;
background-color: #fff;
}
#child2 {
width: 33.33;
background-repeat: repeat-x;
background-position: center center;
background-color: #0CF;
}
#child3 {
<? set_radius("25px",false,true,false,true,false);?>
background-repeat: repeat-x;
background-position: center center;
width: 33.33;
float: right;
background-color: #F00;
}
HTML:
<div class="parent">
<div class="child_calss" id="child1"></div><div class="child_calss" id="child2"></div><div class="child_calss" id="child3"></div></div>
In your CSS:
parent{
overflow: hidden;
}
Then you won't have to bother with matching the border-radius on the children, either.
Edit
I've created this jsfiddle to demonstrate:
Not needing border-radius on the children
overflow: hidden rounds the children when they overlap
Unnecessary background- properties on the children are removed
Expected behavior at small percentages
Update
Another note on this:
If you want the CSS/HTML to perform logic for you (not drop the last element out of the bar), you have a clear misunderstanding of what CSS and HTML do.
I've updated the jsfiddle to provide a sort of patch-fix to that issue. The third child is positioned absolutely at the far right, so that it will always stay in the bar.
Update
Finally, here's the bug in Webkit that doesn't correctly clip the background. It appears there's nothing you can do right now except possibly something like this:
<div class="hasBorder hasBorderRadius">
<div class="hasBorderRadius hasHiddenOverflow">
<div class="containsContent">
</div>
</div>
</div>
have you tried giving them a z-index so they have a stack order? also what about an overflow hidden on the parent?

Categories

Resources