CSS3 - 3D Cube- IE transform-style: preserve-3d workaround - html

After looking through IE10's developer blog I have found that they do not support the preserve-3d setting.
I found this cube originally made by Paul Hayes which is working with touch screens and quite popular.
Altough preserve-3d setting is a known issue, I couldn't achieved suggested work around because it seems there is no transform property in the parent to maually apply to the child elements.
Here is the link that I simplified so far: http://jsfiddle.net/cC4Py/1/
CSS:
.viewport {
perspective: 800px;
perspective-origin: 50% 200px;
transform: scale(0.75,0.75);
-webkit-perspective: 800;
-webkit-perspective-origin: 50% 200px;
-webkit-transform: scale(0.75,0.75);
-moz-perspective: 800;
-moz-perspective-origin: 50% 200px;
-moz-transform: scale(0.75,0.75);
}
.cube {
position: relative;
margin: 0 auto;
height: 400px;
width: 400px;
transition: transform 50ms linear;
transform-style: preserve-3d;
-webkit-transition: -webkit-transform 50ms linear;
-webkit-transform-style: preserve-3d;
-moz-transition: -moz-transform 50ms linear;
-moz-transform-style: preserve-3d;
}
.cube > div {
position: absolute;
height: 360px;
width: 360px;
padding: 20px;
background-color: rgba(50, 50, 50, 1);
font-size: 1em;
line-height: 1em;
color: #fff;
border: 1px solid #555;
border-radius: 3px;
transition: -webkit-transform 50ms linear;
}
.cube > div:first-child {
transform: rotateX(90deg) translateZ(200px);
-webkit-transform: rotateX(90deg) translateZ(200px);
-moz-transform: rotateX(90deg) translateZ(200px);
}
.cube > div:nth-child(2) {
transform: translateZ(200px);
-webkit-transform: translateZ(200px);
-moz-transform: translateZ(200px);
}
.cube > div:nth-child(3) {
transform: rotateY(90deg) translateZ(200px);
-webkit-transform: rotateY(90deg) translateZ(200px);
-moz-transform: rotateY(90deg) translateZ(200px);
text-align: center;
}
.cube > div:nth-child(4) {
transform: rotateY(180deg) translateZ(200px);
-webkit-transform: rotateY(180deg) translateZ(200px);
-moz-transform: rotateY(180deg) translateZ(200px);
}
.cube > div:nth-child(5) {
transform: rotateY(-90deg) translateZ(200px);
-webkit-transform: rotateY(-90deg) translateZ(200px);
-moz-transform: rotateY(-90deg) translateZ(200px);
}
.cube > div:nth-child(5) p {
text-align: center;
font-size: 2.77em;
margin: 40px;
line-height: 60px;
}
.cube > div:nth-child(6) {
transform: rotateX(-90deg) rotate(180deg) translateZ(200px);
-webkit-transform: rotateX(-90deg) rotate(180deg) translateZ(200px);
-moz-transform: rotateX(-90deg) rotate(180deg) translateZ(200px);
}
object {
opacity: 0.9;
}
object:hover {
opacity: 1;
}
HTML:
<body class="experiment">
<div class="viewport">
<section class="cube" style="transition: 500ms; -webkit-transition: 500ms;">
<div>MELABA!</div>
<div>
<h2>3D cube</h2>
<time>28th September 2010</time>
<p>By Paul Hayes</p>
<p>3D cube built using css, webkit-perspective and webkit-transform. Rotation via webkit-transition.</p>
<p>Use arrow keys to navigate, or click and hold mouse. On touch screens, use one finger to rotate. Press ESC to reset.</p>
<p>Read more »</p>
</div>
<div>
<object width="360" height="360"><param name="movie" value="http://www.youtube.com/v/MY5PkidV1cM?fs=1&hl=en_GB&rel=0"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/MY5PkidV1cM?fs=1&hl=en_GB&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="360" height="360">
</object>
</div>
<div>
<h2>Learn how to make a cube</h2>
<time>17th July 2009</time>
<p>By Paul Hayes</p>
<p>“A 3D cube can be created solely in CSS, with all six faces.”</p>
<p>Article: Cube explanation</p>
</div>
<div>
<p>I design and build websites in Brighton</p>
</div>
<div>
<small>Nothing down here.</small>
</div>
</section>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="http://www.paulrhayes.com/experiments/cube-3d/js/experiment.js?13"></script>
</body>
I created copies of every property without -webkit- prefix. Am I doing anything wrong? What should I do next?

First of all, dragging and interaction in general usually means JavaScript. Yes, there are CSS hacks and I've used and abused them myself, but in this case it would be absolutely insane not to use JS.
So that means that you need to chain all the transforms from the ancestors (that means the rotation of the cube itself and the perspective you'd normally set on the parent of the cube) onto the faces of the cube via JavaScript.
You can do this in a few ways. In this case, I've used the style property of the face element, but you can also insert the styles into a style element.
Anyway...
demo
Relevant HTML:
<div class='cube'>
<div class='face'></div>
<!-- five more faces -->
</div>
Relevant CSS:
Since I'll be changing transform values via JS, I didn't bother setting them in the CSS.
.cube, .cube * {
position: absolute;
top: 50%; left: 50%;
}
.face {
margin: -8em;
width: 16em; height: 16em;
}
JS:
The code below is quick and dirty and can be improved.
var faces = document.querySelectorAll('.face'),
n = faces.length,
styles = [],
_style = getComputedStyle(faces[0]),
factor = 3,
side = parseInt(_style.width.split('px')[0], 10),
max_amount = factor*side,
unit = 360/max_amount,
flag = false,
tmp, p = 'perspective(32em) ';
for(var i = 0; i < n; i++) {
tmp = ((i < 4) ? 'rotateY(' + i*90 + 'deg)' :
'rotateX(' + Math.pow(-1, i)*90 + 'deg)') +
' translateZ(' + side/2 + 'px)';
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
styles.push(tmp);
}
var drag = function(e) {
var p1 = { 'x': e.clientX - p0.x, 'y': e.clientY - p0.y },
angle = {'x': -p1.y*unit, 'y': p1.x*unit};
for(var i = 0; i < n; i++) {
tmp = 'rotateX(' + angle.x + 'deg)' +
'rotateY(' + angle.y + 'deg)' + styles[i];
faces[i].style.transform = p + tmp;
faces[i].style['-webkit-transform'] = p + tmp;
}
};
window.addEventListener('mousedown', function(e) {
var t = e.target;
if(t.classList.contains('face')){
p0 = { 'x': e.clientX, 'y': e.clientY };
flag = true;
window.addEventListener('mousemove', drag, false);
}
else {
flag = false;
}
}, false);
window.addEventListener('mouseup', function(e) {
if(flag) {
for(var i = 0; i < n; i++) {
_style = faces[i].style;
tmp = _style.transform || _style['-webkit-transform'];
styles[i] = tmp.replace('perspective(32em) ', '');
}
}
flag = false;
window.removeEventListener('mousemove', drag, false);
}, false);

Personally, I prefer using CSS #keyframes, and setting up animations that way, to using JS. JS tends to introduce jank and freeze up pages. CSS, especially in Firefox, but also in Chrome, is very fast and smooth for 3d vizualization and animation. IE has a problem by not including preserve-3d. Until it does, I won't worry about whether things look as intended in IE. Just try to make sure there's an acceptibly graceful degredation if you have to support IE.

Related

Vertical Carousel in Bootstrap 5

I'm trying to create a vertical carousel on bootstrap 5. I'm using this code for reference. I understand it was built on a different version of bootstrap but I can't seem to translate it to bootstrap 5. I have this so far. When ran, the website is blank. I'm also not sure if I've linked the CSS and JS properly in my html.
HTML
<html lang="en">
<head>
<!-- Latest compiled and minified CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Latest compiled JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script type="text/javascript"src="{{ url_for('static', filename='js/scripts.js')}}"></script>
<link rel="stylesheet/less" type="text/css" href="{{ url_for('static', filename='less/mystyles.less')}}">
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<div class="carousel slide vertical" id="carousel-vertical" data-bs-ride="carousel">
<ol class="carousel-indicators">
<li data-bs-target="#carousel-vertical" data-bs-slide-to="0" class="active"></li>
<li data-bs-target="#carousel-vertical" data-bs-slide-to="1"></li>
<li data-bs-target="#carousel-vertical" data-bs-slide-to="2"></li>
</ol>
<div class="carousel-inner" role="listbox">
<div class="item active"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
</body>
</html>
JS
$(document).ready(function() {
var delta = 0;
var scrollThreshold = 5;
// detect available wheel event
wheelEvent = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
"DOMMouseScroll"; // let's assume that remaining browsers are older Firefox
// Bind event handler
$(window).on(wheelEvent, function (e) {
// Do nothing if we weren't scrolling the carousel
var carousel = $('.carousel.vertical:hover');
if (carousel.length === 0) return;
// Get the scroll position of the current slide
var currentSlide = $(e.target).closest('.item')
var scrollPosition = currentSlide.scrollTop();
// --- Scrolling up ---
if (e.originalEvent.detail < 0 || e.originalEvent.deltaY < 0 || e.originalEvent.wheelDelta > 0) {
// Do nothing if the current slide is not at the scroll top
if(scrollPosition !== 0) return;
delta--;
if ( Math.abs(delta) >= scrollThreshold) {
delta = 0;
carousel.carousel('prev');
}
}
// --- Scrolling down ---
else {
// Do nothing if the current slide is not at the scroll bottom
var contentHeight = currentSlide.find('> .content').outerHeight();
if(contentHeight > currentSlide.outerHeight() && scrollPosition + currentSlide.outerHeight() !== contentHeight) return;
delta++;
if (delta >= scrollThreshold)
{
delta = 0;
carousel.carousel('next');
}
}
// Prevent page from scrolling
return false;
});
})
CSS(less)
.carousel .item {
padding-bottom: 720/1280 * 100%;
background-size: cover;
&:nth-child(1) { background-image: url('https://via.placeholder.com/1280x720?text=Slide 1'); }
&:nth-child(2) { background-image: url('https://via.placeholder.com/1280x720?text=Slide 2'); }
&:nth-child(3) { background-image: url('https://via.placeholder.com/1280x720?text=Slide 3'); }
}
.carousel.vertical .carousel-inner > .item {
-webkit-transition: .6s ease-in-out top;
-o-transition: .6s ease-in-out top;
transition: .6s ease-in-out top;
}
#media all and (transform-3d),
(-webkit-transform-3d) {
.carousel.vertical .carousel-inner > .item {
-webkit-transition: -webkit-transform .6s ease-in-out;
-ms-transition: -ms-transform .6s ease-in-out;
-o-transition: -o-transform .6s ease-in-out;
transition: transform .6s ease-in-out;
-ms-backface-visibility: hidden;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-ms-perspective: 1000;
-webkit-perspective: 1000;
perspective: 1000;
}
.carousel.vertical .carousel-inner > .item.next,
.carousel.vertical .carousel-inner > .item.active.right {
top: 0;
-ms-transform: translate3d(0, 100%, 0);
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
}
.carousel.vertical .carousel-inner > .item.prev,
.carousel.vertical .carousel-inner > .item.active.left {
top: 0;
-ms-transform: translate3d(0, -100%, 0);
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
.carousel.vertical .carousel-inner > .item.next.left,
.carousel.vertical .carousel-inner > .item.prev.right,
.carousel.vertical .carousel-inner > .item.active {
top: 0;
-ms-transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.carousel.vertical .carousel-inner > .active {
top: 0;
}
.carousel.vertical .carousel-inner > .next,
.carousel.vertical .carousel-inner > .prev {
top: 0;
height: 100%;
width: 100%;
}
.carousel.vertical .carousel-inner > .next {
left: 0;
top: 100%;
}
.carousel.vertical .carousel-inner > .prev {
left: 0;
top: -100%
}
.carousel.vertical .carousel-inner > .next.left,
.carousel.vertical .carousel-inner > .prev.right {
top: 0;
}
.carousel.vertical .carousel-inner > .active.left {
left: 0;
top: -100%;
}
.carousel.vertical .carousel-inner > .active.right {
left: 0;
top: 100%;
}
.carousel.vertical .carousel-indicators,
.carousel-indicators-vertical {
right: 20px;
top: 50%;
transform: translate(-50%);
bottom: auto;
left: auto;
width: auto;
margin: 0;
padding: 0;
li {
display: block;
margin: 5px 0;
}
}
1) Getting the right setup for Bootstrap :
you have 2 ways of using the framework -> download the files OR link the files
which one should you use ? I like downloading the files better so I can go and see what's going on. It also allows me to modify the things I want from the source code and not do "orders / counter-orders" with my own CSS / JS files.
where to get those links -> in Bootstrap "Getting Started" section (homepage - link here)
where to download the files ? -> in Bootstrap download section (here)
where should you place the links / scripts ? -> Links are in the head section of HTML but I really suggest putting the script right before the end of the body. Why ? So your HTML structure/elements are loaded, and THEN only you can put eventlisteners and modifiers on those loaded elements.
2) How to make the carousel vertical ?
how does it currently work ? The carousel works in horizontal mode using Bootstrap Framework. If you go into their CSS files, you will understand how it works. It mainly uses a float: left, display:none and transform: translateX(...) properties to make it work horizontally.
what must you do to make it vertical ? Well, you need to get the float:left off the code and you need to change the transform-:translateX(...) to a transform-:translateY(...)
transitions, awful ? I know, it doesn't look great. One thing you can do, first, to make it a little less "jumpy", is set a fixed height to the carousel-inner class.
If you want the buttons (next / previous) to be vertical, you will need to work on their positionning (currently, their classes are in left: 0 / right: 0 .
The classes are : .carousel-control-prev /.carousel-control-next
3) Illustrated idea:
What vertical CSS modifications look like :
More info on the "Getting the right setup for Bootstrap" :
The link files of Bootstrap :
The download section of Bootstrap :
The .zip files for CSS, example :
Don't forget to "link" the download files into your html.
Example for CSS : <link rel="stylesheet" href="./bootstrap.css">

Element transforms when active (half click)

I was following a Youtube tutorial to create a Memory Card game. Halfway through I started to tinker to see if I could figure out the steps myself. I have a div that looks like this:
<div class="memory-card">
<img class="front-face" src="img/aurelia.svg" alt="Aurelia">
<img class="back-face" src="img/js-badge.svg" alt="JSBadge">
</div>
The CSS for this div looks like this
.memory-card {
width: calc(25% - 10px);
height: calc(33.33% - 10px);
position: relative;
margin: 5px;
transition: transform 0.2s;
}
.memory-card:active {
transform: scale(0.97);
transition: transform 0.2s;
}
.flip {
transform: rotateY(180deg);
transition: transform 0.2s;
}
The class "flip" is added to the div by toggling on the classList of the memory-card element when a click occurs. Essentially what this does is that when the memory-card is clicked and held it becomes active and scales to 0.97 and when released it is rotated by 180 degrees around the Y-axis (class="memory-card flip").
Before click
However, when I click again (and hold) it rotates again without waiting for the click to be released. As per my understanding (which has a hole that I hope you can fill), the card (which the div represents btw) should rotate only after I release the click. Can anybody help? This seems like an issue that must have been answered before but for the life of me, I could not find it.
Try like this:
var memorycard = document.querySelector('.memory-card');
memorycard.onclick = function(e) {
memorycard.classList.toggle('flip');
};
.memory-card {
width: calc(25% - 10px);
height: calc(33.33% - 10px);
position: relative;
margin: 5px;
transition: transform 0.2s;
}
.memory-card:active {
transform: scale(0.97);
}
.memory-card.flip:active {
transform: rotateY(180deg) scale(0.97);
}
.flip {
transform: rotateY(180deg);
}
img {
width: 100%;
height: auto;
}
<div class="memory-card">
<img class="front-face" src="https://i.stack.imgur.com/esMJU.png" alt="Aurelia">
<img class="back-face" src="https://i.stack.imgur.com/xR2ZZ.png" alt="JSBadge">
</div>
.flip has this CSS property: transform: rotateY(180deg);. However, as soon as the click begins, .memory-card:active is applied, so that property gets overwritten as transform: scale(0.97);. The solution is to specify that when the .flip class is present, both transform functions should be applied:
.memory-card.flip:active {
transform: rotateY(180deg) scale(0.97);
}

This 3d banner does not working correctly on Internet Explorer

This sample of rolling 3D cube does not work correctly on Internet Explorer.
There is must be rotation on 360 degrees like in other browsers.
Which of vendor prefixes are missing?
random text for submitting post insted of more details
random text for submitting post insted of more details
random text for submitting post insted of more details
random text for submitting post insted of more details
random text for submitting post insted of more details
random text for submitting post insted of more details
random text for submitting post insted of more details
/* animation speed */
.container {
-webkit-animation: rotate 18s infinite linear;
animation: rotate 18s infinite linear;
}
/* native */
.cube { transform:scaleX(.7) scaleY(.7); }
* { margin:0; padding:0; outline:none; box-sizing: border-box; }
.stage { width:240px; height:360px; overflow:hidden; }
.cube {
width:240px;
height:400px;
margin-top:-20px;
-ms-perspective:1000px;
-webkit-perspective: 1000px;
perspective: 1000px;
-ms-perspective-origin: center center;
-webkit-perspective-origin: center center;
perspective-origin: center center;
}
.container {
display:block;
width: 240px;
height: 400px;
-ms-transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.side {
display:block;
position: absolute;
width: 240px;
height: 400px;
background-position:center center;
background-repeat:no-repeat;
background-size:cover;
}
.face1 {
-webkit-transform: translateZ(120px);
transform: translateZ(120px);
background-color: green;
}
.face2 {
-webkit-transform: translateX(120px) rotateY(90deg);
transform: translateX(120px) rotateY(90deg);
background-color: red;
}
.face3 {
-webkit-transform: translateZ(-120px) scale(-1, 1);
transform: translateZ(-120px) scale(-1, 1);
background-color: teal;
}
.face4 {
-webkit-transform: translateX(-120px) rotateY(90deg) scale(-1, 1);
transform: translateX(-120px) rotateY(90deg) scale(-1, 1);
background-color: black;
}
#-webkit-keyframes rotate { 100% { -webkit-transform: rotateY(-360deg); transform: rotateY(-360deg); } }
#keyframes rotate { 100% { -webkit-transform: rotateY(-360deg); transform: rotateY(-360deg); } }
</style>
</head>
<body cz-shortcut-listen="true">
<div class="stage">
<div class="cube">
<a class="container" href="">
<span class="face1 side"></span>
<span class="face2 side"></span>
<span class="face3 side"></span>
<span class="face4 side"></span>
</a>
</div>
</div>
</body></html>
Have a look here : https://caniuse.com/#search=perspective
As they say for perspective, it is partially supported by ie :
Partial support in IE refers to not supporting the transform-style: preserve-3d property. This prevents nesting 3D transformed elements.
You will have to use another method for ie.
Related post : Transform-Style preserve-3d in internet explorer CSS not working
Hope this help
As it is already suggested by other community member that transform-style preserve-3d is not supported in IE.
You can Work around this by manually applying the parent element's transform to each of the child elements in addition to the child element's normal transform.
Reference:
Internet Explorer Preserve 3D fix

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.

Cube rotation with css

I am having a bit of an issue with rotation of a cube. I want to make it cross-browser so I am transforming every side of the cube. When I am rotating from left to right the sides align perfectly on all browsers Chrome, Firefox and IE, BUT when the cube is rotated from top to bottom, the sides align only on Chrome (If I make the animation slower on Chrome the sides are broken the same way as the other browsers, so I think working properly is a bug :D). I have provided an example on jsfiddle:
http://jsfiddle.net/0n9bnxe5/
HTML:
<div class="flip-card-content">
<div class="flip-card-side-a" style="background:red">
FRONT
</div>
<div class="flip-card-side-b" style="background:green">
BACK
</div>
<div class="flip-card-side-c" style="background:aqua">
LEFT
</div>
</div>
<button id="button">Flip-top</button>
<button id="button2">Filp-right</button>
CSS:
.flip-card-content {
position: relative;
margin: 100px;
width: 200px;
height: 200px;
transform-style: preserve-3d;
perspective:1000px;
}
.flip-card-side-a,
.flip-card-side-b,
.flip-card-side-c{
width: 100%;
position: absolute;
height: 100%;
backface-visibility: hidden;
transform-origin:50% 50% 0px;
transition: all .5s ease-in-out;
}
.flip-card-side-a {
transform: rotateY(0deg) translateZ(100px);
z-index: 1;
}
.flip-card-side-b {
transform: rotateX(90deg) translateZ(100px);
}
.flip-card-side-c {
transform: rotateY(-90deg) translateZ(100px);
}
.flip .flip-card-side-a {
transform: rotateX(-90deg) translateZ(100px);
}
.flip .flip-card-side-b {
display:block;
transform: rotateY(0deg) translateZ(100px);
z-index: 1;
}
.flip-right .flip-card-side-a {
transform: rotateY(90deg) translateZ(100px);
}
.flip-
right .flip-card-side-b {
display:none;
}
.flip-right .flip-card-side-c {
transform: rotateY(0deg) translateZ(100px);
z-index:1;
}
JQUERY:
$("#button").on('click', function(){
$(".flip-card-content").removeClass("flip-right");
setTimeout(function(){
$(".flip-card-content").toggleClass("flip");
},500);
});
$("#button2").on('click', function(){
$(".flip-card-content").removeClass("flip");
setTimeout(function(){
$(".flip-card-content").toggleClass("flip-right");
},500);
});
Any advice is welcomed!
Your translateZ doesn't quite work in the way you expect. Have look at how I've positioned the faces on the cube here and compare it to your own. Ultimately, I find the easiest way to rotate items such as cubes etc. is to position all the elements and then just rotate the container.
Also for nice scaling of fonts, images etc. its preferable to leave the front face at its natural size rather than scale up (i.e. move everything backward in 3d space):
.box {
height: 100%;
position: relative;
transform: rotateX(0deg);
transform-origin: 50% 50% -100px;
transform-style: preserve-3d;
transition: all 1s;
width: 100%;
}
.box--rotate-top {
transform: rotateX(-90deg);
}
.box--rotate-left {
transform: rotateY(90deg);
}
.box__face {
backface-visibility: hidden;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.box__face--front {
background: #f90;
}
.box__face--top {
background: #369;
transform: rotateX(90deg) translateZ(200px);
transform-origin: 0 100% 0;
}
.box__face--left {
background: #867;
transform: rotateY(-90deg) translateZ(200px);
transform-origin: 100% 0 0;
}
Here is the fiddle.
Transition in 3d space are tricky, and different browsers can handle them differently.
Here you have your fiddle corrected.
Your best bet is to leave nothing to the browser imagination
so, instead of changing
transform: rotateY(0deg) translateZ(100px);
to
transform: rotateX(-90deg) translateZ(100px);
make the change happen from
transform: rotateX(0deg) rotateY(0deg) translateZ(100px);
to
transform: rotateX(-90deg) rotateY(0deg) translateZ(100px);
Notice that I didn't change the transform from a mathematical point of view; but now every property matches a similar one.
Note just in case you want to know, in the first case IE is making the followng transition: change the angle of rotation from 0 to -90deg. At the same time, change the axis of rotation from Y to X. So, at the middle of the transition, the rotation is wrong (from your point of view), but in a mathematic sense, both ways of understanding the transition make sense.