Reveal hidden letters from the left by sliding to the right - html

I want to make the content animate so that the letters slide in to the right from the "T".
Here is a jsfiddle of the below:
.two {
width: auto;
-webkit-transition: all 1s ease;
}
.two:before {
content: "T";
width: auto;
}
.two:hover {
width: auto;
}
.two:hover:before {
display: none;
}
.two:hover:after {
content: "This is a Label";
width: auto
}
<div class="two">
</div>

Animating opacity of each letter from left to right:
You could animate each letter's opacity by combining svg's linearGradient and mask and using JavaScript for shifting the x1 and x2 attributes of the linearGradienton mouseover and mouseleave events.
var grad = document.getElementById('gradient');
// higher 'animSpeed' yeilds lower speed
var animSpeed = 20;
var two = document.getElementsByClassName('two')[0];
two.addEventListener('mouseenter', function() {
for (i = 0; i < two.offsetWidth; i++) {
var anim = setTimeout(function() {
var x1 = (parseInt(grad.getAttribute('x1').slice(0, -1), 10) + 1) + '%';
var x2 = (parseInt(grad.getAttribute('x2').slice(0, -1), 10) + 1) + '%';
grad.setAttribute('x1', x1);
grad.setAttribute('x2', x2);
}, animSpeed * i)
}
});
two.addEventListener('mouseleave', function() {
for (i = 0; i < two.offsetWidth; i++) {
var anim = setTimeout(function() {
var x1 = (parseInt(grad.getAttribute('x1').slice(0, -1), 10) - 1) + '%';
var x2 = (parseInt(grad.getAttribute('x2').slice(0, -1), 10) - 1) + '%';
grad.setAttribute('x1', x1);
grad.setAttribute('x2', x2);
}, animSpeed * i)
}
})
<svg>
<defs>
<linearGradient id="gradient" x1="-15%" y1="0%" x2="0%" y2="0%">
<stop stop-color="white" offset="0" />
<stop stop-color="black" offset="1" />
</linearGradient>
<mask id="mask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<rect width="1" height="1" fill="url(#gradient)" />
</mask>
</defs>
<foreignObject width="90px" height="100%" x="2" y="12" mask="url(#mask)">
<div class="two">This is a label</div>
</foreignObject>
</svg>
Slide from left to right:
You could transition the transform property.
Updated Fiddle
.two {
display: block;
width: 300px;
padding: 15px;
}
.two:before {
content: "T";
}
.two:hover:before {
display: none;
}
.two:after {
position: absolute;
content: "This is a Label";
transform: translateX(-150%);
transition: transform 1s ease;
}
.two:hover:after {
content: "This is a Label";
transform: translateX(0%);
}
<div class="two"></div>

Reveal letters with :before mask
If you just want to use CSS, we can create a mask which slides over the text and then is pushed to the right to reveal the text in the div.
Example
.two {
width: 100px;
position: relative;
overflow: hidden;
}
.two:before {
content: '';
position: absolute;
left: 0.6em;
top: 0;
height: 100%;
width: 100%;
background: #FFF;
transition: left 1s;
}
.two:hover:before {
left: 100%;
}
.color:before {
background: #F00;
}
<div class="two">This is a Label</div>
It looks like this (hover):
<div class="two color">This is a Label</div>

This is not possible with just the :before and :after psuedo-elements. Let me suggest another similar approach.
/* start SLIDE-IN code */
.two > .capitalT > .else {
position: relative;
left: -100px;
opacity: 0;
transition: left 0.5s, opacity 0.5s;
}
.two > .capitalT:hover > .else {
left: 0;
opacity: 1;
}
/* end SLIDE-IN code */
<div class="two"><span class="capitalT"><span class="t">T</span><span class="else">his is a Label</span></span>
</div>

CSS is not capable to animate auto values in principle. So consider either
.two:hover::after{ width: 100px;}
( http://jsfiddle.net/k2wou9eh/1/ ) or other options.

Related

CSS Animate dashed-border of div as progress bar with time that repeats

I have a div with a 2 pixel dashed boarder, and I would like to animate it so that it fills in with a different color over time until it is all filled in, and then would repeat over and over again.
I have a jsfiddle with the style that I have around my div
.widget{
height: 50px;
margin: 0px 20px 0px 0px;
display: flex;
justify-content: center;
flex-direction: column;
padding: 10px;
border: 2px dashed #E4E6EF;
border-radius: 5px;
position: relative;
}
<div class="widget">
test
</div>
https://jsfiddle.net/kqfd5jh9/
The height is fixed but the width isn't, it would depend on how many I have.
I am not to sure where to start or what method would be best to achieve this, does anyone have any ideas?
I attached a snippet that fulfills your requirements, border color will change infinitely every 10 seconds to green color. Just added an animation property on widget and the keyframes setup the initial color and ending color. Hope it helps.
For more information about CSS animations refers here.
Edit
As you requested, I made a working snippet that does what you want, I had to use an svg and javascript , to make it work. Hope it helps, the code is very straight forward.
You can see this for further research of how it works:
stroke-dasharray
stroke-dashoffset
window.onload = () => {
const border = document.querySelector('.widget rect#color');
const borderLength = border.getTotalLength();
const timeFactor = 4; // Highest number is fastest
let borderOffset = borderLength;
border.style.strokeDashoffset = borderLength;
border.style.strokeDasharray = borderLength / 2;
let initialTime;
let isColorAnimationSetted = false;
const animation = () => {
// Set the frame time only first time
if (!initialTime) {
initialTime = new Date();
} else {
!isColorAnimationSetted && setColorAnimation();
}
borderOffset -= timeFactor;
border.style.strokeDashoffset = borderOffset;
window.requestAnimationFrame(animation);
};
// We set the time for the color animation to match the progress animation to be completed
const setColorAnimation = () => {
const frameTime = new Date() - initialTime;
const framesToEnd = (2 * borderOffset) / timeFactor;
const timeToComplete = framesToEnd * frameTime;
border.style.animation = `color-change ${timeToComplete}ms linear infinite`;
isColorAnimationSetted = true;
};
window.requestAnimationFrame(animation);
};
.widget{
height: 50px;
margin: 0px 20px 0px 0px;
display: flex;
justify-content: center;
flex-direction: column;
padding: 10px;
position: relative;
}
.widget svg {
height: 100%;
width: 100%;
}
rect#color {
stroke: transparent;
stroke-width: 5;
fill: none;
border-radius: 5px;
}
rect#dash {
stroke: white;
stroke-width: 6;
fill: none;
stroke-dasharray: 5,5;
border-radius: 5px;
}
p {
position: absolute;
left: 40px;
}
#keyframes color-change {
0% {
stroke: red; /* Starting color */
}
50% {
stroke: #00FF00; /* Ending color */
}
100% {
stroke: red; /* Starting color */
}
}
<div class="widget">
<svg width="100%" height="100%" preserveAspectRatio='none'>
<rect id="color" x="0" y="0" height="50px" width="100%" />
<rect id="dash" x="0" y="0" height="50px" width="100%" />
</svg>
<p>Test<p>
</div>

Mojave Safari 14.1.2 - css animation svg disappearing during playback

Is someone able to explain a problem in Safari for this simple example:
codepen example
The logo-1 class element should animate into position from right to left. On mac it works in Firefox, Chrome and in IE11/win8 in the original bigger piece of code. In Safari during css animation the svg graphics disappears and appears only after animation is done. It only animates correctly if there is an extra dummy sibling to the svg element with a 3d transform applied to it. It needs to be on a lower z-index than the svg or the animation display fails. Ideally the svg element should be the only child of the logo-1 class element.
In the codepen example animation shows correctly for me in Safari only in the first main div that has the extra element under logo-1 element.
Any ideas?
Codepen code:
.logo-1 svg {
position: absolute;
top: 0;
left: 0;
}
.logo-1-sequence {
position: absolute;
top: 0;
left: 0;
display: block;
width: 113px;
height: 134px;
transform: scale3d(1, 1, 1) translate3d(0, 0, 0);
}
#keyframes kf-frame-1-logo-1-in {
0% {
transform: scale3d(0.47, 0.47, 1) translate3d(2078px, 20px, 0);
}
100% {
transform: scale3d(0.47, 0.47, 1) translate3d(1578px, 20px, 0);
}
}
.logo-1 {
position: absolute;
z-index: 2;
width: 93px;
height: 150px;
background-color: red;
animation: kf-frame-1-logo-1-in 0.5s 0.5s both linear 1;
}
.main {
background: green;
position: relative;
width: 900px;
height: 150px;
display: block;
overflow: hidden;
}
<div class="main">
<div class="logo-1">
<div class="logo-1-sequence"></div>
<svg class="logo-1-svg" xmlns="http://www.w3.org/2000/svg" width="93" height="150" viewBox="0 0 93 150">
<rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5" />
</svg>
</div>
</div>
<div class="main">
<div class="logo-1">
<!-- <div class="logo-1-sequence"></div> -->
<svg class="logo-1-svg" xmlns="http://www.w3.org/2000/svg" width="93" height="150" viewBox="0 0 93 150">
<rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5" />
</svg>
</div>
</div>

How can I reshape a complex shape to another shape using css or javascript?

For Example, I have a shape like this:
and would like to reshape it to something like this (in the form of animation):
How can I create these shapes and do that reshape using HTML, CSS, javascript, or jquery after that?
Regard.
Use computePath function:
const computePath = (widthTop, widthBottom, heightTop, heightBottom, radius) => {
let path = `M ${radius},0
H ${widthTop-radius}
Q ${widthTop},0 ${widthTop},${radius}
V ${heightTop-radius}`;
if (widthTop === widthBottom)
path += `Q ${widthTop},${heightTop} ${widthTop},${heightTop}
H ${widthBottom-radius}
Q ${widthBottom},${heightTop} ${widthBottom},${heightTop}`;
else
path += `Q ${widthTop},${heightTop} ${widthTop + radius},${heightTop}
H ${widthBottom-radius}
Q ${widthBottom},${heightTop} ${widthBottom},${heightTop+radius}`;
path += `
V ${heightTop + heightBottom - radius}
Q ${widthBottom},${heightTop + heightBottom} ${widthBottom-radius},${heightTop + heightBottom}
H ${radius}
Q 0,${heightTop + heightBottom} 0 ${heightTop + heightBottom - radius}
V ${radius}
Q 0,0 ${radius},0
Z`;
return path;
}
d3.select('path')
.attr('transform', 'translate(50, 20)')
.attr('d', computePath(200,200, 40, 0, 10))
.transition()
.delay(500)
.duration(1000)
.attr('d', computePath(200,300, 100, 40, 10))
path {
stroke: none;
fill: lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="300">
<path/>
</svg>
Not exactly the same shape, it's missing the radius on the inside corner, but it is almost pure HTML and CSS...
document.getElementById("shape").addEventListener("click", evt => {
evt.target.classList.toggle("open");
});
#shape {
width: 600px;
height: 60px;
position: relative;
transition: all 1s;
}
#shape::before {
content: '';
display: block;
position: absolute;
width: 400px;
height: 60px;
background-color: #eee;
border-radius: 18px;
transition: all 1s;
}
#shape::after {
content: '';
display: block;
position: absolute;
width: 400px;
height: 60px;
bottom: 0;
background-color: #eee;
border-radius: 18px;
transition: all 1s;
}
#shape.open {
height: 200px;
}
#shape.open::before {
width: 300px;
height: 200px;
}
#shape.open::after {
width: 600px;
}
<div id="shape"></div>

How to don't let the element brake if it's not the children

I'd like to make both .quote-container and #new-quote elements in the same line even if the window width is very small. For example 83pixels. Using min-width on the .quote-container element worked, however, using the same technique on the #new-quote element didn't work.
Maybe that's because #new-quote isn't the children of .quote-container? I even tried to make it a child and it was even worse (picture was taken on the desktop window size):
What I'd like to achieve in visual:
var getNewQuote = function(callback) {
var quote = {};
quote.text = 'Example';
quote.author = 'Example';
$(".loading").hide();
callback(quote);
};
var quoteContainerStartingPadding,
quoteContainerEndingPadding,
newQuoteEndingPadding;
if ($(window).width() > 648) {
quoteContainerStartingPadding = "0 2.5rem";
quoteContainerEndingPadding = "2.5rem";
newQuoteEndingPadding = "2.5rem .75rem";
} else {
quoteContainerStartingPadding = "0 1.5em";
quoteContainerEndingPadding = "1.5rem";
newQuoteEndingPadding = "1.5rem .75rem";
}
$(".quote-container").css("padding", quoteContainerStartingPadding);
getNewQuote(function(quote) {
var getRandomColor = function() {
var colors = ["#ff9966", "#7f00ff", "#396afc", "#0cebeb", "#06beb6", "#642b73", "#36d1dc", "#cb356b", "#3a1c71", "#ef3b36", "#159957", "#000046", "#007991", "#56ccf2", "#f2994a", "#e44d26", "#4ac29a", "#f7971e", "#34e89e", "#6190e8", "#3494e6", "#ee0979"],
randomNumber = Math.floor(Math.random() * colors.length);
return colors[randomNumber];
};
var updateText = function($t) {
var twitter = "https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=";
twitter += '"' + quote.text + '" ';
twitter += quote.author;
var tumblr = "https://www.tumblr.com/widgets/share/tool?posttype=quote&tags=quotes,freecodecamp&caption=";
tumblr += quote.author;
tumblr += "&content=";
tumblr += quote.text;
tumblr += "&canonicalUrl=https%3A%2F%2Fwww.tumblr.com%2Fbuttons&shareSource=tumblr_share_button";
var $icon = $("<i class='fa fa-quote-left'>").prop("aria-hidden", true);
$t.find(".quote-text").html("").append($icon, quote.text);
$t.find(".quote-author").html("- " + quote.author);
$("#tweet-quote").attr("href", twitter);
$("#tumblr-quote").attr("href", tumblr);
};
var calcNewHeight = function(q) {
var $temp = $("<div>", {
class: "quote-container temp",
}).appendTo($("body"));
$temp.append($("<div>", {
class: "quote-text"
}), $("<div>", {
class: "quote-author"
}));
updateText($temp, q);
var h = $temp.height() + 40;
$temp.remove();
return h;
};
var changeColor = function(newColor) {
$("body, .button:not(#new-quote)").animate({
backgroundColor: newColor
});
$("#new-quote").animate({
color: newColor
});
$(".quote-text, .quote-author").css("color", newColor);
if ($("#modStyle").length === 0) {
$("head").append("<style id='modStyle'>#new-quote:before {background:" + newColor + ";} .lds-eclipse {box-shadow: 0 .25rem 0 0 " + newColor + ";}</style>");
} else {
$("head style#modStyle").html("#new-quote:before {background:" + newColor + ";} .lds-eclipse {box-shadow: 0 .25rem 0 0 " + newColor + ";}");
}
};
var getQuote = function() {
var nc, nh = 0;
nc = getRandomColor();
nh = calcNewHeight(quote);
changeColor(nc);
$(".quote-container, #new-quote").animate({
height: nh / 16 + "rem",
}, {
duration: 1000,
queue: false
});
$(".quote-container").animate({
padding: quoteContainerEndingPadding
}, {
duration: 1000,
queue: false
});
$("#new-quote").animate({
padding: newQuoteEndingPadding
}, {
duration: 1000,
queue: false
});
updateText($(".quote-container"), quote);
$(".quote-container").children().not($(".loading")).fadeTo(750, 1);
};
$(".quote-container, #new-quote").css({
visibility: "visible",
height: 0
});
$("#new-quote").css("padding", "0 .75rem");
getQuote();
}
);
var two = function() {
$(".quote-container").children().not($(".loading")).hide();
$(".loading").show();
getNewQuote(function(quote) {
var getRandomColor = function() {
var colors = ["#ff9966", "#7f00ff", "#396afc", "#0cebeb", "#06beb6", "#642b73", "#36d1dc", "#cb356b", "#3a1c71", "#ef3b36", "#159957", "#000046", "#007991", "#56ccf2", "#f2994a", "#e44d26", "#4ac29a", "#f7971e", "#34e89e", "#6190e8", "#3494e6", "#ee0979"],
randomNumber = Math.floor(Math.random() * colors.length);
return colors[randomNumber];
};
var updateText = function($t) {
var twitter = "https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=";
twitter += '"' + quote.text + '" ';
twitter += quote.author;
var tumblr = "https://www.tumblr.com/widgets/share/tool?posttype=quote&tags=quotes,freecodecamp&caption=";
tumblr += quote.author;
tumblr += "&content=";
tumblr += quote.text;
tumblr += "&canonicalUrl=https%3A%2F%2Fwww.tumblr.com%2Fbuttons&shareSource=tumblr_share_button";
var $icon = $("<i class='fa fa-quote-left'>").prop("aria-hidden", true);
$t.find(".quote-text").html("").append($icon, quote.text);
$t.find(".quote-author").html("- " + quote.author);
$("#tweet-quote").attr("href", twitter);
$("#tumblr-quote").attr("href", tumblr);
};
var calcNewHeight = function(q) {
var $temp = $("<div>", {
class: "quote-container temp",
}).appendTo($("body"));
$temp.append($("<div>", {
class: "quote-text"
}), $("<div>", {
class: "quote-author"
}));
updateText($temp, q);
var h = $temp.height() + 40;
$temp.remove();
return h;
};
var changeColor = function(newColor) {
$("body, .button:not(#new-quote)").animate({
backgroundColor: newColor
});
$("#new-quote").animate({
color: newColor
});
$(".quote-text, .quote-author").css("color", newColor);
if ($("#modStyle").length === 0) {
$("head").append("<style id='modStyle'>#new-quote:before {background:" + newColor + ";} .lds-eclipse {box-shadow: 0 .25rem 0 0 " + newColor + ";}</style>");
} else {
$("head style#modStyle").html("#new-quote:before {background:" + newColor + ";} .lds-eclipse {box-shadow: 0 .25rem 0 0 " + newColor + ";}");
}
};
var getQuote = function() {
var nc = getRandomColor(),
nh = calcNewHeight(quote);
$(".quote-container").children().not($(".loading")).css("opacity", 0);
changeColor(nc);
$(".quote-container, #new-quote").animate({
height: nh / 16 + "rem",
}, {
duration: 1000,
queue: false
});
updateText($(".quote-container"), quote);
$(".quote-container").children().not($(".loading")).fadeTo(750, 1);
};
getQuote();
});
}
;
html,
body {
height: 100%;
width: 100%;
}
body {
margin: 0;
padding: 0;
background: #333;
color: #333;
font-family: sans-serif;
}
.quote-container {
width: 35%;
background: #fff;
margin: 0;
display: inline-block;
vertical-align: middle;
border-radius: 0.1875rem;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
visibility: hidden;
min-width: 15rem;
}
.quote-text {
font-size: 1.625rem;
}
.quote-text i {
margin-right: 0.6rem;
}
.quote-text p {
display: inline;
}
.quote-author {
font-size: 1rem;
margin: 0 0.4rem 2rem 0;
text-align: right;
}
.button {
padding: 0.75rem;
text-align: center;
font-size: 1rem;
color: #fff;
border-radius: 0.1875rem;
display: inline-block;
cursor: pointer;
-webkit-user-select: none;
user-select: none;
}
.button:not(#new-quote):hover {
opacity: 0.8 !important;
}
.button:not(#new-quote) {
min-width: 1rem;
min-height: 1rem;
}
.button i {
vertical-align: middle;
}
#new-quote {
white-space: nowrap;
writing-mode: vertical-lr;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
vertical-align: middle;
background: #fff !important;
margin: 0;
position: relative;
right: 0.25625rem;
color: #333;
visibility: hidden;
}
#new-quote:before {
content: "";
position: absolute;
height: 100%;
width: 0.0625rem;
bottom: 0;
left: 0;
visibility: hidden;
-webkit-transform: scaleY(0);
transform: scaleY(0);
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
#new-quote:hover:before {
visibility: visible;
-webkit-transform: scaleY(1);
transform: scaleY(1);
}
.v-align {
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.text-center {
text-align: center;
}
footer {
font-size: 0.85rem;
margin-bottom: 1rem;
}
footer a {
text-decoration: none;
color: #fff;
position: relative;
}
footer a:before {
content: "";
position: absolute;
width: 100%;
height: 0.0625rem;
bottom: 0;
left: 0;
background: #fff;
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
footer a:hover:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
/* Loading animation */
#keyframes lds-eclipse {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
50% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#-webkit-keyframes lds-eclipse {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
50% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.loading {
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.lds-eclipse {
-webkit-animation: lds-eclipse 1s linear infinite;
animation: lds-eclipse 1s linear infinite;
width: 10rem;
height: 10rem;
border-radius: 50%;
margin: auto;
}
#media (max-width: 62.5em) {
.quote-container {
width: 50%;
}
}
#media (max-width: 50em) {
.quote-container {
width: 65%;
}
}
#media (max-width: 17.96875em) {
.quote-container {
width: 40%;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="v-align text-center">
<div class="quote-container">
<div class="quote-text">
</div>
<div class="quote-author"></div>
<a id="tweet-quote" class="button"><i class="fa fa-twitter"></i></a>
<a id="tumblr-quote" class="button"><i class="fa fa-tumblr"></i></a>
<div class="loading">
<div class="lds-eclipse"></div>
</div>
</div>
<div id="new-quote" class="button">New quote</div>
<footer>
Created by LukasLSC
</footer>
</div>
EDIT 1: Codepen: https://codepen.io/Kestis500/pen/KZvXgB?editors=0110
If you want to align things in CSS you usually have two different positioning concepts you can use for this purpose:
display (flex)
float
Usually it is a good idea to put all elements you want to align in a wrapping container like a div. In this manner you can just focus on your aligning issue and forget about the general layout - means where you want to have your aligned elements in the layout eventually. You can later on just position the wrapper and do not have to worry about the elements inside.
Another best practice is to give all your elements that this container inherits from a dimension (at least width). A common mistake is that elements that should be aligned break just because the parent element does not have enough space to fit all elements on one line. If you want to know why I provide an example at the end, just follow the *.
But lets go back to the two concepts that you can use. Which one you should use depends on one hand what other attributes you need to give the respective elements and what browsers you need to support. If you only want to support newer browser versions you can go with flexbox, the more secure way to do this is use percentages for widths and float.
Flexbox
.container {
display: flex;
flex-direction: row; // this makes your elements align horizontally
}
.child1 {
flex: 1 1 auto;
}
.child2 {
flex: 0 1 auto;
}
The flex attribute determines the dimension of a child. So consider the parent as width: 100%; and the numbers you give as a first parameter to flex is the ratio of the child's dimension compared to the other children.
Float
.container {
overflow: hidden;
width: 100%; // this must be relative to the containers parent of course
}
.child1 {
width: 75%;
float: left;
}
.child2 {
width: 25%;
float: left;
}
Mind that float takes effect on the elements following in the document flow AFTER the element that you give the float attribute. Also take into account that you might need to calculate margins, paddings or borders in additionally to the elements' widths (except for paddings when using box-sizing: border-box) and that elements containing only floated elements lose their "automatic" dimensions as floated elements lose their information about height and width as well. (overflow: hidden on the container solves this issue for you)
*In a responsive design e.g. you should give the highest parent a width of 100%. If you provide to a child width: 50%; it will now have exactly 50% of the entire width. If you now give the child of the child width: 50% it will be 25% of the entire width. This is less error prone then giving the child's child directly 25%. Let's assume later on you give the child a width of 50% the width of the child's child (25%) will relate to the childs width instead of the parent. So you will end up with a width of 12.5% for the child's child relative to the entire width.

Firefox transition issues

I am trying to do this effect on my site:
http://codepen.io/anon/pen/dPzarw
<svg width="100" height="100">
<g id="cross_svg">
<rect id="Rectangle-1" x="0" y="0" width="48" height="2" fill="transparent"></rect>
<rect id="Rectangle-2" x="0" y="14" width="48" height="2" fill="transparent"></rect>
<rect id="Rectangle-4" x="0" y="28" width="48" height="2" fill="transparent"></rect>
</g>
</svg>
CSS:
svg {
width: 52px;
height: 52px;
z-index: 99999;
transition: all .3s ease;
display: block;
margin: 15% auto;
cursor: pointer;
}
svg g {
transition: all .3s ease;
width: 100px;
height: 100px;
display: block;
position: absolute;
left: 50%;
top: 50%;
margin: auto;
cursor: pointer;
}
svg rect {
transition: all .3s ease;
fill: #E04681;
}
svg g {
width: 100px;
height: 100px;
}
Javascript:
$(document).ready(function(){
var svg = $('svg');
var lines = svg.find('rect');
var line_first = $('svg rect:nth-child(1)')
var line_second = $('svg rect:nth-child(2)')
var line_third = $('svg rect:nth-child(3)')
var i = true;
svg.on('click', function(){
if (i) {
setTimeout(function(){
$(this).find("g").addClass('gotcha')
line_first.css({
'transform':'rotate(45deg)',
'left':'50%',
'top':'50%',
'width':'200px',
// This line BELONGS to #dervondenbergen :D
// Enjoy your propriety my friend.
'transform-origin': 'left bottom'
})
line_third.css({
'transform':'rotate(-45deg) translate(-50%,-50%)',
'left':'50%',
'top':'50%'
})
line_second.css('opacity','0')
},005)
} else {
setTimeout(function(){
line_first.attr('style', '');
line_third.attr('style', '');
line_second.css('opacity','1')
},005)
}
i=!i;
});
});
If that link doesn't work it is the SVG version from this page:
http://lukyvj.github.io/menu-to-cross-icon/
This works great in chrome and safari but when I tried it in firefox it was broken. In firefox it works, but its almost like it moved the line so it is an X without the bottom left leg. This is on the mobile version of firefox as well. Is there any special coding that needs to be done to allow this to work in firefox?