In a Rails 3.2 app I am displaying user avatars using a responsive, flippable CSS circle. But due to padding needed on a parent element, the avatar is not centered in the circle.
How can I center this circle? Where possible, I would prefer to keep this semantically marked up with an img tag, rather than as a background image on a div.
Also, can this be optimized? I've a lot of nested divs at present!
The code is below, and a jsfiddle here.
<div class='responsive-container'>
<div class='responsive-inner'>
<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
<div class="flip-inner">
<div class="front">
<div class="circle">
<div class="circle-inner">
<%= image_tag #user.avatar %>
</div>
</div>
</div>
<div class="back">
<div class="circle">
<div class="circle-inner">
<%= #user.name %>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.responsive-container{
position: relative;
width: 50%;
}
.responsive-container:before{
content: "";
display: block;
padding-top: 100%;
}
.responsive-inner{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.flip-container {
perspective: 1000;
-webkit-perspective: 1000; /* Safari and Chrome */
}
/* flip the pane when hovered */
.flip-container:hover .flip-inner, .flip-container.hover .flip-inner {
transform: rotateY(180deg);
-ms-transform:rotateY(180deg); /* IE 9 */
-webkit-transform:rotateY(180deg); /* Safari and Chrome */
}
.flip-inner {
transition: 0.6s;
-webkit-transition: 0.6s; /* Safari */
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d; /* Safari and Chrome */
position: relative;
}
.front, .back {
backface-visibility: hidden;
-webkit-backface-visibility:hidden; /* Chrome and Safari */
-moz-backface-visibility:hidden; /* Firefox */
-ms-backface-visibility:hidden; /* Internet Explorer */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.front {
z-index: 2;
}
.back {
transform: rotateY(180deg);
-ms-transform:rotateY(180deg); /* IE 9 */
-webkit-transform:rotateY(180deg); /* Safari and Chrome */
}
.circle {
width: 100%;
height: 0;
padding: 50% 0; //padding top & bottom must equal width
border-radius: 50%;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
overflow: hidden;
border: 1px #000 solid;
}
.circle-inner {
display: table;
width:100%;
}
.circle-inner img {
height: auto;
width: 100%;
}
.circle-inner p {
display: table-cell;
vertical-align: middle;
text-align: center;
}
</style>
why dont you use border-radius instead of circle? will be much easier i think.
http://bavotasan.com/2011/circular-images-with-css3/
Related
I have some flip cards and when you hover over the flip card, the card flips and enlarges (scales). However I don't want to the text inside the hovered card to scale so I put the text inside a child div. (I only want the parent card background to scale).
How can I stop my text and content from scaling and going blurry? I've tried to reset my child div to 1/2 of the scale size to reset it but it does not work.
HTML
<div class="c-flip-card">
<div class="c-flip-card__inner">
<div class="c-flip-card__front"><img src="img_avatar.png" alt="Avatar"</div>
<div class="c-flip-card__back">
<h1>John Doe</h1>
<p>Architect & Engineer</p>
<p>We love that guy</p>
</div>
</div>
</div>
SASS
.c-flip-card {
background-color: transparent;
width: 180px;
height: 200px;
border: 1px solid #f1f1f1;
perspective: 1000px;
/* Do an horizontal flip when you move the mouse over the flip box container */
&:hover {
z-index: 10;
position: relative;
}
&:hover .c-flip-card__inner {
transform: rotateY(180deg) scale(1.4);
}
/* This container is needed to position the front and back side */
.c-flip-card__inner {
cursor:pointer;
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
/* Position the front and back side */
.c-flip-card__front, .c-flip-card__back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
/* Style the front side (fallback if image is missing) */
.c-flip-card__front {
background-color: #bbb;
color: black;
}
/* Style the back side */
.c-flip-card__back {
background-color: red;
color: white;
transform: rotateY(180deg);
}
.abc{
transform: scale(0.7);
h1, p{
color:#000;
}
}
}
jsfiddle
Edit
I think I found a workaround : Don't use scale() !
.c-flip-card .c-flip-card__inner {
transition: all 0.8s;
}
.c-flip-card:hover .c-flip-card__inner {
transform: rotateY(180deg) translate3d(40px,-40px,0);
/* Just change the width and height to 140% and have them transition
I used translate3d to position the card the same way scale() does */
width: 140%;
height: 140%;
}
And if you want to get the same positioning as scale() produce, you can add something like translate3d(40px,-40px,0) to your transform.
This way you don't have to manage the size of the text, the effect is the same (except for a little transition on the text position), and there is no bluriness.
.c-flip-card {
margin: 50px;
background-color: transparent;
width: 180px;
height: 200px;
border: 1px solid #f1f1f1;
perspective: 1000px;
}
.c-flip-card:hover {
z-index: 10;
position: relative;
}
.c-flip-card:hover .c-flip-card__inner {
transform: rotateY(180deg) translate3d(40px,-40px,0);
width: 140%;
height: 140%;
}
.c-flip-card .c-flip-card__inner {
cursor: pointer;
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: all 0.8s;
transform-style: preserve-3d;
}
.c-flip-card .c-flip-card__front,
.c-flip-card .c-flip-card__back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.c-flip-card .c-flip-card__front {
background-color: #bbb;
color: black;
}
.c-flip-card .c-flip-card__back {
background-color: red;
color: white;
transform: rotateY(180deg);
}
<div class="c-flip-card">
<div class="c-flip-card__inner">
<div class="c-flip-card__front">
<img src="img_avatar.png" alt="Avatar" style="width:300px;height:300px;">
</div>
<div class="c-flip-card__back">
<h1>John Doe</h1>
<p>Architect & Engineer</p>
<p>We love that guy</p>
</div>
</div>
</div>
Original
Putting the content of your back card inside a div and applying scale(0.7) on it seems to work but it really doesn't look good on the first hover.
<div class="c-flip-card__back">
<div class="notScale">
<h1>John Doe</h1>
<p>Architect & Engineer</p>
<p>We love that guy</p>
</div>
</div>
.c-flip-card:hover .notScale {
transform: scale(0.7);
}
So instead of applying transform on your text, since it's only shown on hover, why not simply change the font size for exemple using calc() and variables :
/* define variables for p and h1 */
body {
--sizeP : 16px;
--sizeH1 : calc(2.5 * var(--sizeP));
}
/* apply those variable one "regular" h1 and p */
h1 {
font-size: var(--sizeH1);
}
p{
font-size: var(--sizeP);
}
/* "scale" down the text for the backside by a factor of .7 */
.c-flip-card .c-flip-card__back h1{
font-size: calc(.7 * var(--sizeH1));
}
.c-flip-card .c-flip-card__back p{
font-size: calc(.7 * var(--sizeP));
}
For the blury part I did get some imporvement (though it's not enough for chrome) by adding :
.c-flip-card {
-webkit-filter: blur(0);
filter: blur(0);
}
body {
--sizeP: 16px;
--sizeH1: calc(2.5 * var(--sizeP));
}
h1 {
font-size: var(--sizeH1);
}
p {
font-size: var(--sizeP);
}
/* The flip card container - set the width and height to whatever you want. We have added the border property to demonstrate that the flip itself goes out of the box on hover (remove perspective if you don't want the 3D effect */
.c-flip-card {
margin: 50px;
background-color: transparent;
width: 180px;
height: 200px;
border: 1px solid #f1f1f1;
perspective: 1000px;
/* Do an horizontal flip when you move the mouse over the flip box container */
/* This container is needed to position the front and back side */
/* Position the front and back side */
/* Style the front side (fallback if image is missing) */
/* Style the back side */
-webkit-filter: blur(0);
filter: blur(0);
}
.c-flip-card:hover {
z-index: 10;
position: relative;
}
.c-flip-card:hover .c-flip-card__inner {
transform: rotateY(180deg) scale(1.39);
}
.c-flip-card .c-flip-card__inner {
cursor: pointer;
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.c-flip-card .c-flip-card__front,
.c-flip-card .c-flip-card__back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.c-flip-card .c-flip-card__front {
background-color: #bbb;
color: black;
}
.c-flip-card .c-flip-card__back {
background-color: red;
color: white;
transform: rotateY(180deg);
}
.c-flip-card .c-flip-card__back h1 {
font-size: calc(.7 * var(--sizeH1));
}
.c-flip-card .c-flip-card__back p {
font-size: calc(.7 * var(--sizeP));
}
<div class="c-flip-card">
<div class="c-flip-card__inner">
<div class="c-flip-card__front">
<img src="img_avatar.png" alt="Avatar" style="width:300px;height:300px;">
</div>
<div class="c-flip-card__back">
<h1>John Doe</h1>
<p>Architect & Engineer</p>
<p>We love that guy</p>
</div>
</div>
</div>
For chrome I tried every solution from here and here but wasn't able to get a descent result.
The only one that worked for the blury part on chrome was :
#supports (zoom : 140%) {
.c-flip-card:hover {
zoom : 140%;
transform: translate3d(-40px,-40px,0);
}
.c-flip-card:hover .c-flip-card__inner {
transform: rotateY(180deg) scale(1);
}
.c-flip-card .c-flip-card__back h1{
font-size: calc(var(--sizeH1));
}
.c-flip-card .c-flip-card__back p{
font-size: calc(var(--sizeP));
}
}
But I wasn't able to transition the property zoom so the effect isn't great.
I followed Amarjits solutions and added scale:1.1 to .c-flip-card__back and this is the best result, however it is blurry using Saffari
.c-flip-card__back {
background-color: red;
color: white;
transform: rotateY(180deg) scale(1.1);
}
I found a better solution. Just don't use scaling on the back card, so the animation just tweens as the front card fades out it just shows the back card
This transitions around half way creates the illusion of it scaling when in fact it's just showing a div at set height and width.
It works in Chrome and Saffari and text is not blurry
.mycont{
/* How pronounced should the 3D effects be */
perspective: 500;
-webkit-perspective: 500;
-moz-perspective: 500;
-ms-perspective: 500;
-o-perspective: 500;
width:100%;
height:245px;
position:relative;
/*Some UI */
border-radius:6px;
-webkit-border-radius:6px;
-moz-border-radius:6px;
-ms-border-radius:6px;
-o-border-radius:6px;
font-size:28px;
line-height:150px;
vertical-align:middle;
cursor:pointer;
}
.box-front,.box-back{
/* Enable 3D transforms */
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
-o-backface-visibility: hidden;
width:100%;
height:100%;
position:absolute;
background-color:#0090d9;
/* Animate the transitions */
-webkit-transition:0.8s; text-align:center;
-moz-transition:0.8s; text-align:center;
-ms-transition:0.8s; text-align:center;
-o-transition:0.8s; text-align:center;
transition:0.8s; text-align:center;
color:#FFF;
border-radius:5px;
-webkit-border-radius:6px;
-moz-border-radius:6px;
-ms-border-radius:6px;
-o-border-radius:6px;
}
.box-back{
/* The back side is flipped 180 deg by default */
transform:rotateY(180deg);
-webkit-transform:rotateY(180deg);
-moz-transform:rotateY(180deg);
-ms-transform:rotateY(180deg);
-o-transform:rotateY(180deg);
background-color:#f35958;
}
.mycont:hover .box-front{
/* When the mycont is hovered, flip the front side and hide it .. */
transform:rotateY(180deg);
-webkit-transform:rotateY(180deg);
-moz-transform:rotateY(180deg);
-ms-transform:rotateY(180deg);
-o-transform:rotateY(180deg);
}
.mycont:hover .box-back{
/* .. at the same time flip the back side into visibility */
transform:rotateY(360deg);
-webkit-transform:rotateY(360deg);
-moz-transform:rotateY(360deg);
-ms-transform:rotateY(360deg);
-o-transform:rotateY(360deg);
margin-left: -0%;
margin-top: -10%;
width: 300px;
height:430px;
}
<div style="width:300px; margin-top:100px; margin-left:100px;">
<div class="mycont">
<div class="box-front">Front :)</div>
<div class="box-back">
rtrtrtrt
</div>
</div>
</div>
I am trying to use the parallax effect on a site that has a fixed nav bar at the top of the page. Due to the way the parallax effect deals with overflows, the scroll bar appears to sit underneath the fixed nav bar at the top of the page.
I have included a fiddle to demonstrate this.
I have tried placing the fixed navbar div inside the parallax container. This moves the navbar beneath the scrollbar but also results in the navbar not fixing to the top of the page.
Here is my code so far...
HTML
<div class="navbar">NavBar</div>
<div class="parallax">
<div class="parallax_layer parallax_layer_back">
<img class="backgroundImage" src="https://images.pexels.com/photos/131212/pexels-photo-131212.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb">
</div>
<div class="parallax_layer parallax_layer_base">
<div class="title">Title</div>
<div class="content">Content area</div>
</div>
</div>
CSS
.parallax {
height: 100vh;
overflow-x: hidden;
overflow-y: initial;
perspective: 1px;
-webkit-perspective: 1px;
}
.parallax_layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.parallax_layer_base {
transform: translateZ(0);
-webkit-transform: translateZ(0);
}
.parallax_layer_back {
transform: translateZ(-1px);
-webkit-transform: translateZ(-1px);
}
.parallax_layer_back { transform: translateZ(-1px) scale(2); }
.parallax_layer_deep { transform: translateZ(-2px) scale(3); }
/* Example CSS for content */
* {
margin: 0;
padding: 0;
}
.title {
position: absolute;
left: 10%;
top: 30%;
color: white;
font-size: 300%;
}
.backgroundImage {
width: 100%;
height: auto;
}
.content {
margin-top: 100vh;
width: 100%;
height: 800px;
background-color: #e67e22;
}
.navbar {width:100%; position: fixed; z-index: 999; background-color: red;}
Based on your source code, I have made a few changes. I'll explain step by step.
Assume that your NavBar's height is 50px, I lower .parallax class 50px down by using margin-top:50px;.
Also, we need to change your NavBar's position property from fixed to absolute.
Now there will be 2 scrollbar, one for the body and one for the .parallax contents. To hide the body's scrollbar, which is unnecessary, we can use overflow:hidden; for body tag.
This time, you will see that your NavBar won't cover the scrollbar, but the bottom of the scrollbar is unfortunately unseeable since the contents is shifted 50px from to top. To solve this I use a simple Jquery code to set .parallax height equal to the remaining window's height.
You can have a look at the snippet.
$(document).ready(function(){
$(".parallax").css("height",$(window).height()-50);
});
.parallax {
margin-top:50px;
overflow-x: hidden;
overflow-y: initial;
perspective: 1px;
-webkit-perspective: 1px;
}
.parallax_layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.parallax_layer_base {
transform: translateZ(0);
-webkit-transform: translateZ(0);
}
.parallax_layer_back {
transform: translateZ(-1px);
-webkit-transform: translateZ(-1px);
}
/* Depth Correction */
.parallax_layer_back { transform: translateZ(-1px) scale(2); }
.parallax_layer_deep { transform: translateZ(-2px) scale(3); }
/* Example CSS for content */
* {
margin: 0;
padding: 0;
}
.title {
position: absolute;
left: 10%;
top: 30%;
color: white;
font-size: 300%;
}
.backgroundImage {
width: 100%;
height: auto;
}
.content {
margin-top: 100vh;
width: 100%;
height: 800px;
background-color: #e67e22;
}
.navbar {
width:100%;
position: absolute;
top:0;
z-index: 999;
background-color: red;
height:50px;
}
body{
overflow:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navbar"> NavBar </div>
<div class="parallax">
<div class="parallax_layer parallax_layer_back">
<img class="backgroundImage" src="https://images.pexels.com/photos/131212/pexels-photo-131212.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb">
</div>
<div class="parallax_layer parallax_layer_base">
<div class="title">Title</div>
<div class="content">Content area</div>
</div>
</div>
For some reason my vertical alignment code is blurring some but not all child elements in Chrome and Safari.
Whats causing it is the translateY(-50%), if I remove this then blurriness is gone however the vertical centring effect is lost.
/* #group Center all the things */
.center-wrapper {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.center-wrapper .center {
position: relative;
overflow: hidden;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
/* This fixes the blurred buttons but breaks centering
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
transform: translateZ(0);*/
}
/* #end */
Tried and tested methods such as below work but they break the vertical centring:
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
transform: translateZ(0);
Faced the same issue while trying to position buttons in the middle, but the button appeared on hover of the parent element and each time text inside was randomly cut.
The solution is:
.positioned-button {
transform: translateY(-50%) scale(1);
filter: blur(0);
line-height: 1;
}
Breaks nothing, fixes Chrome :)
The only way around this blurry issue, from what I could see was to change the vertical alignment method and use display: table instead. Here's how I did it:
1) Keep HTML markup the same
<div class="center-wrapper">
<div class="center">
<p>Centered content here</p>
</div>
</div>
2) Change CSS to the following:
/* #group Center all the things */
.center-wrapper {
min-height: 100%;
padding: 0;
display: table;
width: 100%;
}
.center-wrapper .center {
display: table-cell;
vertical-align: middle;
}
/* #end */
You can see the display table in action here.
.center-wrapper {
min-height: 200px;
padding: 0;
display: table;
width: 100%;
background: black;
}
.center-wrapper .center {
display: table-cell;
vertical-align: middle;
color: white;
}
.center-wrapper .center div {
height: 40px;
background: red;
width: 50%;
margin: 0 auto;
}
<div class="center-wrapper">
<div class="center">
<div>Centered content here</div>
</div>
</div>
I've followed this How to make vertically rotated links in HTML? but I've to improve this solution.
I need to have a vertical menu that fits the entire height of the windows and divides it in three part (cause I've three menu links to show).
How can I update the code suggested in that solution?
Try this:
CSS
#container {
overflow: hidden;
width: 50px;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: table;
}
.section {
position: relative;
height: 33.33333%;
display: table-row;
background: #ccc;
text-align: center;
}
.section .link {
display: table-cell;
vertical-align: middle;
line-height: 50px;
white-space:nowrap;
max-width:50px;
-webkit-transform: rotate(270deg);
-moz-transform: rotate(270deg);
-ms-transform: rotate(270deg);
-o-transform: rotate(270deg);
}
.section:hover { background: #ddd }
HTML
<div id="container">
<div class="section">aaa</div>
<div class="section">bbb</div>
<div class="section">ccc</div>
</div>
DEMO JSFiddle
My suggestion is to use display: table CSS property as follow:
EDITED
HTML
<div class="container">
<div class="container-child">row 1</div>
<div class="container-child">row 2</div>
<div class="container-child">row 3</div>
</div>
CSS
html, body {
text-align: center;
width: 100%;
height: 100%;
}
.container {
display: table;
width: 100%;
height: 100%;
}
.container-child {
display: table-row;
-ms-transform:rotate(270deg); /* IE 9 */
-moz-transform:rotate(270deg); /* Firefox */
-webkit-transform:rotate(270deg); /* Safari and Chrome */
-o-transform:rotate(270deg); /* Opera */
}
CODE
the transform: rotate() allows you to rotate the orientation of the text.
i m flipping an image through CSS and its wirking in mozila.but in all other browsers its not working.i m unable to know what i m missing here.
Here is my code for image:
<div id="f1_container">
<div id="f1_card" class="shadow">
<div class="front face">
<img src="http://placehold.it/300x300"/>
</div>
<div class="back face center">
<p>This is nice for exposing more information about an image.</p>
<p>Any content can go here.</p>
</div>
</div>
</div>
and Here is my CSS:
#f1_container {
position: relative;
margin: 10px auto;
width: 450px;
height: 281px;
z-index: 1;
}
#f1_container {
perspective: 1000;
}
#f1_card {
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: all 1.0s linear;
}
#f1_container:hover #f1_card {
transform: rotateY(180deg);
box-shadow: -5px 5px 5px #aaa;
}
.face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.face.back {
display: block;
transform: rotateY(180deg);
box-sizing: border-box;
padding: 10px;
color: white;
text-align: center;
background-color: #aaa;
}
</style>
You are using bleeding edge CSS properties.
transform, for example, only works unprefixed in IE 10, Firefox and Opera.
You can get support in webkit based browsers by duplicating the property with a -webkit- prefix (since the implementation is still considered experimental in that engine).
See also: can I use