I have a container with 2 children.
One child has dynamic width and at it's maximum width can fill the container
The other child has fixed width and starts off being hidden as it's starting point is to the right of the overflow:hidden
container
What I want is the fixed-width child to move to the left so that it exactly fits into the right of the container such that
a) If both children fit into the container - the other element should say put on the left and
b) If there is no room for both elements - the fixed-width element should push the other element to the left as much as it needs to in order to fit into the right of the container.
Here is what I tried:
.container {
width: 200px;
height: 50px;
border: 1px solid green;
overflow: hidden;
white-space: noWrap;
}
span {
height: 50px;
display: inline-block;
}
.child1 {
background: aqua;
float: right;
width: 50px;
margin-right: -50px;
transition: margin .2s;
}
.container:hover .child1 {
margin-right: 0;
}
.child2 {
background: tomato;
//width: 100%;
}
<div class="container">
<span class="child1">Fixed</span>
<span class="child2">Dynamic Width</span>
</div>
<div class="container">
<span class="child1">Fixed</span>
<span class="child2">Here is a Dynamic Width box</span>
</div>
Condition a) Succeeds but condition b) Fails
.container {
width: 200px;
height: 50px;
border: 1px solid green;
overflow: hidden;
white-space: noWrap;
}
span {
height: 50px;
display: inline-block;
}
.child2 {
background: aqua;
width: 50px;
margin: 0;
float: right;
margin-right: -50px;
transition: margin .2s;
}
.container:hover .child1 {
margin-left: -50px;
}
.container:hover .child2 {
margin: 0;
}
.child1 {
background: tomato;
transition: margin .2s;
}
<div class="container">
<span class="child1">Dynamic Width</span>
<span class="child2">Fixed</span>
</div>
<div class="container">
<span class="child1">Here is a Dynamic Width box</span>
<span class="child2">Fixed</span>
</div>
Condition a) Fails and condition b) Succeeds
Can both conditions be fulfilled with CSS alone?
PS: The markup which I provided in the demos may be modified. Also CSS3 including flexbox is also fine.
Here is a CSS only solution.
The trick is to use this basic rule:
Consider two or more inline elements rendered side by side.
If you increase the width of the first element, the second elements is pushed to the right.
The problem is that you need the elements to move to the left. I solved this by inverting the X direction to the child elements scaleX(-1)
and re-inverting again the container.
To help you better understand this, you can comment out the transform: scaleX(-1);
in the jsfiddle link below, and watch what happens.
The beauty of this is that you don't need to know the width of the .child2
. You just need to push it to the left.
.container {
width: 200px;
height: 50px;
border: 1px solid green;
overflow: hidden;
white-space: nowrap;
text-align: right;
transform: scaleX(-1);
}
span {
height: 50px;
display: inline-block;
transform: scaleX(-1);
}
.child1 {
background: aqua;
width: 50px;
margin-left: -50px;
float: left;
transition: margin-left .2s;
text-align: left;
}
.child2 {
background: tomato;
}
.container:hover .child1 {
margin-left: 0;
}
<div class="container">
<span class="child1">Fixed</span>
<span class="child2">Dynamic Width</span>
</div>
<div class="container">
<span class="child1">Fixed</span>
<span class="child2">Here is a Dynamic Width box</span>
</div>
Also on jsfiddle
Another slightly simpler solution is to use direction: rtl;
on the container. By reversing the direction of inline elements from right to left, we achieve the same effect without the need to use CSS3 transformations.
See http://jsfiddle.net/epfqjtft/12/
Since css can't do conditional statements (bar media queries), I don't think this is truly possible with css alone.
update
I have seen that it is in fact possible using CSS3 transforms (which works in modern browsers). but just in case some users might want older browser support which CSS3 transforms cant provide, i'll leave this here anyway.
Apart from that, I've used positioning instead of floats to 'clean up' the styling (and attempted the jquery):
$('.container').hover(function() {
var parentWidth = $(this).width();
var thisWidth = $(this).find(".child1").width() + 50; /*i.e. width of fixed box*/
if (parentWidth < thisWidth) { /*if it doesn't fit, move it!*/
$(this).find('.child1').addClass("moveLeft");
}
}, function() {
$(this).find(".child1").removeClass("moveLeft");
});
.container {
width: 200px;
height: 50px;
border: 1px solid green;
overflow: hidden;
white-space: noWrap;
position: relative;
}
span {
height: 50px;
display: inline-block;
}
.child2 {
background: aqua;
width: 50px;
margin: 0;
position: absolute;
top: 0;
right: -50px;
transition: all .2s;
}
.child1 {
background: tomato;
transition: all .2s;
position: absolute;
top: 0;
left: 0;
}
.container:hover .child2 {
right: 0;
}
.moveLeft:hover {
left: -50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<span class="child1">Dynamic Width</span>
<span class="child2">Fixed</span>
</div>
<div class="container">
<span class="child1">Here is a Dynamic Width box</span>
<span class="child2">Fixed</span>
</div>
As for your 'solution', you will have to test if the child + 50px
is greater than
the parent width, if so, move child1
. If not, no action is needed.
Okay, I changed LinkinTED's code a little bit. Try this: http://jsfiddle.net/epfqjtft/9/
Of course, I don't know if it's something you can work with. These types of problems should be solved with Jquery.
.container {
width: 200px;
height: 50px;
border: 1px solid green;
display: table;
table-layout: fixed;
transition: all 2s;
}
span {
height: 50px;
display: table-cell;
transition: all .2s;
}
.child1 {
background: tomato;
width: 100%;
}
.child2 {
background: aqua;
width: 0px;
overflow: hidden;
transition: all .2s;
}
.container:hover .child2 {
width: 50px;
}
<div class="container">
<div class="wrapper">
<span class="child1">Dynamic Width</span>
</div>
<span class="child2">Fixed</span>
</div>
<div class="container">
<div class="wrapper">
<span class="child1">Here is a Dynamic Width box</span>
</div>
<span class="child2">Fixed</span>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With