How to rotate text in pseudo-element? - html

I'm trying to rotate the double angle bracket set as the content in an :after pseudo-element using the css transform value rotate(90deg) for a tab across the top of the screen. Here's the relevant code:
.header {
-moz-transition: top .5s ease;
-webkit-transition: top .5s ease;
-o-transition: top .5s ease;
transition: top .5s ease;
position: absolute;
left: 0;
right: 0;
top: -60px;
height: 80px;
background-color: #2d2;
}
.header.in-top {
top: 0;
}
.header-tab {
position: absolute;
bottom: 0;
width: 100%;
height: 20px;
text-align: center;
color: #000;
-moz-transition: color .5s ease;
-webkit-transition: color .5s ease;
-o-transition: color .5s ease;
transition: color .5s ease;
}
.header-tab:hover {
color: #e22;
}
.header-arrow:after {
font-size: 20px;
line-height: 1;
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
}
.header .header-arrow:after {
content: "\00bb";
}
.header.in-top .header-arrow:after {
content: "\00ab";
}
<div class="header">
<div class="header-tab" data-toggle="in-top">
<span class="header-arrow"></span>
</div>
</div>
The data-toggle attribute is used in JavaScript to toggle the in-top class in order to switch the direction of the double angle bracket as well as to expose the content of the header by bringing it down. The transform properties I have specified seem to do nothing though. Any solutions?

Use display: inline-block on the pseudo-element. Alternatively, inline-table or block should also work.
See jsFiddle.
Your pseudo-element is displayed inline by default, which makes it a nontransformable element. From the CSS Transforms Working Draft specification:
transformable element
A transformable element is an element in one of these categories:
an element whose layout is governed by the CSS box model which is either a block-level or atomic inline-level element, or whose ‘display’ property computes to ‘table-row’, ‘table-row-group’, ‘table-header-group’, ‘table-footer-group’, ‘table-cell’, or ‘table-caption’

You need to set the pseudo-element as a block or inline-block element:
.header-arrow:after {
display: block;
}
The specification says rotation should work on inline elements, but in WebKit based browsers it doesn't works: https://www.webkit.org/blog/130/css-transforms/

Rotate property will apply on pseudo-element(after/before) only when you will use display:inline-block; or display:inline-block; property in your class or selector.
.className:before{
-webkit-transform: rotateZ(180deg); /* Safari */
transform: rotateZ(180deg); /* Standard syntax */
display: inline-block;
}

Related

When using the transform rotate CSS property, how can we prevent the vibrating border issue on hover transition?

I am trying to fix an element to the right side of the page, rotate it 90 degrees using the transform rotate CSS property, then on hover I want the element to slide out to the left using a slow transition. However, there is an unsightly vibrating top border when I try a basic implementation of this in Chrome.
Bug Demo Page
The issue only seems to happen when text is entered in the element, and only happens when the element is dynamically sized with that text. This leads me to believe the transform property is rounding up-and-down by a pixel during the hover transition, resulting in the element to resize erratically during ease transition.
I can work around this issue by setting a fixed width on the element, but fixing the width of the element is not an acceptable solution in this case because the text can vary within this fixed element.
Does anyone have ideas for preventing or working around this issue? Thank you!
HTML
<a id="right_fixed_element">
Fixed Side Button
</a>
CSS
#right_fixed_element {
/* vibrating border bug goes away with fixed width */
/* width: 150px; */
position: fixed;
top: 40%;
right: 0;
padding: 10px;
color: white;
background-color: red;
border: 1px solid #777;
transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
transition: all .5s ease;
-moz-transition: all .5s ease;
-webkit-transition: all .5s ease;
-o-transition: all .5s ease;
-webkit-backface-visibility: hidden;
-webkit-transform: rotate(-90deg) translateZ(0) scale(1.0, 1.0);
}
#right_fixed_element:hover {
right: 10px;
}
I believe the animation is little cleaner using transform: translateY() to move the element (instead of animating right: 10px):
#right_fixed_element {
/* vibrating border bug goes away with fixed width */
/* width: 150px; */
position: fixed;
top: 40%;
right: 0;
padding: 10px;
color: white;
background-color: red;
border: 1px solid #777;
transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
transition: all .5s ease;
-moz-transition: all .5s ease;
-webkit-transition: all .5s ease;
-o-transition: all .5s ease;
-webkit-backface-visibility: hidden;
}
#right_fixed_element:hover {
transform: rotate(-90deg) translateY(-10px);
-ms-transform: rotate(-90deg) translateY(-10px);
-moz-transform: rotate(-90deg) translateY(-10px);
-webkit-transform: rotate(-90deg) translateY(-10px);
}
<!-- When you hover over this transform-rotated element with the slow transition speed, a buggy vibrating behavior appears at the top of the element.
If you set a fixed width on the element, then the vibrating behavior will go away.
How can we prevent the vibrating bug, without setting a fixed width, while still acheiving the transform on this fixed element?
-->
<a id="right_fixed_element">
Fixed Side Button
</a>

CSS3 Transition Keeps Resetting Rotation [duplicate]

This question already has an answer here:
CSS animation on hover stay at last keyframe when using transform: rotate
(1 answer)
Closed 8 years ago.
I have a CSS3 Transition but right at the end of the transition my rotation resets to normal state. The HTML and CSS are simple:
HTML
<span></span>Test
CSS
a {
text-decoration: none;
}
a span {
display: inline-block;
width: 25px;
}
a span:before {
content:'>';
font-size: 10px;
font-weight: bold;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
-ms-transition: all 0.5s;
-o-transition: all 0.5s;
transition: all 0.5s;
}
a:hover span:before {
margin-left: 55%;
-webkit-transform: rotate(-90deg);
}
The transition goes as expected except at the very end of the animation the rotation resets to normal state instead of persists. I've created a JSFiddle as an example. How do I keep my rotation to persist?
Try adding display: inline-block
like this:
a:hover span:before {
margin-left: 55%;
-webkit-transform: rotate(90deg);
display: inline-block;
}
fiddle.
Explanation.
The pseudo elements, like :before or :after are inline, by default, so they have issues with being transformed, thus you need to set them to display: block or display: inline-block.
Its Working Use this Method
Don't use margin for animation use translate istead.
for better smooth transitions
Demo
html
<span>></span>Test
css
a {
text-decoration: none;
}
a span {
display: inline-block;
width: 25px;
}
a span{
font-size: 10px;
font-weight: bold;
-webkit-transition: all 0.5s linear;
-moz-transition: all 0.5s linear;
-ms-transition: all 0.5s linear;
-o-transition: all 0.5s linear;
transition: all 0.5s linear;
}
a:hover span{
-webkit-transform: rotate(-90deg) translateX(50%);
-moz-transform: rotate(-90deg) translateX(50%);
-ms-transform: rotate(-90deg) translateX(50%);
-o-transform: rotate(-90deg) translateX(50%);
transform: rotate(-90deg) translateX(50%);
}

Can not center text on image hover

I am setting up a new homepage for my website. It will have a 2x2 grid of four images that change size with the window and they'll all have a hover text. I was able to do everything so far but I got stuck at one point, which possibly have an easy answer that I can't find. When I hover over the image, I want to make the text centered, no matter what the size of the window is. But I can not find the proper way to do it. The methods I've tried either don't center it both vertically and horizontally or the text goes off center when I resize the window. Any help would be appreciated. Thank you!
Here's my code: jsfiddle
HTML
<section id="photos">
<img src="image1"><span>GALLERY ONE</span>
<img src="image2"><span>GALLERY TWO</span>
<img src="image3"><span>GALLERY THREE</span>
<img src="image4"><span>GALLERT FOUR</span>
</section>
CSS
#photos {
/* Prevent vertical gaps */
line-height: 0;
margin-left:150px;
-webkit-column-count: 2;
-webkit-column-gap: 0px;
-moz-column-count: 2;
-moz-column-gap: 0px;
column-count: 2;
column-gap: 0px;
}
#photos img {
/* Just in case there are inline attributes */
width: 100% !important;
height: auto !important;
}
a.darken {
display: inline-block;
background: black;
padding: 0;
position:relative;
}
a.darken img {
display: block;
-webkit-transition: all 0.2s linear;
-moz-transition: all 0.2s linear;
-ms-transition: all 0.2s linear;
-o-transition: all 0.2s linear;
transition: all 0.2s linear;
}
a.darken:hover img {
opacity: 0.3;
}
a.darken span{visibility:hidden; font-size:16px;}
a.darken:hover span{color:#fff; visibility:visible;
-webkit-transition: all 0.2s linear;
-moz-transition: all 0.2s linear;
-ms-transition: all 0.2s linear;
-o-transition: all 0.2s linear;
transition: all 0.2s linear;
}
This wont work in older browsers, but you can use a combination of "translate" and absolute positioning to vertically and horizontally align the text. Just add the following:
a.darken span{
visibility:hidden;
font-size:16px;
/* new styles below: */
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
line-height: 100%;
}
Here is an example:
http://jsfiddle.net/bk2Sd/2/
You need to add these styles to the <span>:
position: absolute;
top: 50%;
left: 35%;
You can play with these values until you get it where you want. Here is a working example.
Since your a.darken selector already has relative positioning enabled, you can enable absolute positioning on the span attribute.
http://jsfiddle.net/EfrainReyes/bk2Sd/4/
a.darken span {
display: block;
height: 100%;
width: 100%;
visibility:hidden;
position: absolute;
top: 50%;
font-size:16px;
}
I added display: block and full height and width so I could use text-align: center on the a.darken selector.
I propose something little more generic.
Since the size of the images is not known we can center horizontally the text using the text-align property and then centre it vertically by using an absolutely positioned element with top set to 50%.
Code to add:
a.darken span {
width: 100%;
text-align: center;
top: 50%;
left: 0
position: absolute;
}
http://jsfiddle.net/bk2Sd/5/

Pseudo element not appearing in IE 8

I have an :after pseudo element on a element that should be working correctly.
My styles look like this:
.featured-video-link {
display: block;
max-width: 100%;
margin: 0 auto;
position: relative;
}
.featured-video-link:after {
content: " ";
display: block;
position: absolute;
-webkit-transition: opacity .2s;
-moz-transition: opacity .2s;
-o-transition: opacity .2s;
-ms-transition: opacity .2s;
transition: opacity .2s;
z-index: 20;
left: 50%;
top: 50%;
margin-left: -51px;
margin-top: -51px;
width: 102px;
height: 101px;
opacity: .5;
background: url(img/play-large.png);
}
.featured-video-link:hover:after {
opacity: 1;
}
And my HTML looks like this:
<div class="featured-video">
<a href="http://www.google.com" class="featured-video-link">
<img src="featured-video.jpg" class="featured-video-image" alt="Characteristics of a Design Engineer">
</a>
<div class="featured-video-title">Characteristics of a Design Engineer</div>
</div>
In the IE 8 developer tools the height attribute is somehow getting mangled into being in the same line as the background attribute and the content and top attributes share a line as well. If I remove the top attribute, the element appears, but obviously in the wrong position and there is no reason for the top attribute to get placed where it is. The z-index seems to be factoring in as well.

Flickering div when using CSS transform on hover

I'm making a div on top of the tweet (and also the Facebook like) button. I want it to move up as soon as I hover above the div (button) so you can actually press the real tweet button. I've tried the following.
HTML:
<div class="tweet-bttn">Tweet</div>
<div class="tweet-widget">
Tweet
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
</div>
CSS:
.tweet-bttn{
position: relative;
top: -30px;
left: -10px;
display:block;
opacity: 1;
width: 80px;
padding: 10px 12px;
margin:0px;
z-index:3;}
.tweet-bttn:hover{
-webkit-animation-name: UpTweet;
-moz-animation-name: UpTweet;
-o-animation-name: UpTweet;
animation-name: UpTweet;
-webkit-animation-duration:.5s;
-moz-animation-duration:.5s;
animation-duration:.5s;
-webkit-transition: -webkit-transform 200ms ease-in-out;
-moz-transition: -moz-transform 200ms ease-in-out;
-o-transition: -o-transform 200ms ease-in-out;
transition: transform 200ms ease-in-out;}
#-webkit-keyframes UpTweet {
0% {
-webkit-transform: translateY(0);
}
80% {
-webkit-transform: translateY(-55px);
}
90% {
-webkit-transform: translateY(-47px);
}
100% {
-webkit-transform: translateY(-50px);
}
... and all other browser pre-fixes.
}
I'm not sure what's going wrong. It looks like that as soon as I hover, it moves, but if I move the cursor one more pixel, it has to do a new calculation which causes the flickering.
I don't know why you need animations for this when you can simply achieve the above using transitions
The trick is to move the child element on parent hover
Demo
div {
margin: 100px;
position: relative;
border: 1px solid #aaa;
height: 30px;
}
div span {
position: absolute;
left: 0;
width: 100px;
background: #fff;
top: 0;
-moz-transition: all 1s;
-webkit-transition: all 1s;
transition: all 1s;
}
div span:nth-of-type(1) {
/* Just to be sure the element stays above the
content to be revealed */
z-index: 1;
}
div:hover span:nth-of-type(1) { /* Move span on parent hover */
top: -40px;
}
Explanation: Firstly we wrap span's inside a div element which is position: relative;
and later we use transition on span which will help us to smooth the flow of the animation, now we use position: absolute; with left: 0;, this will stack elements on one another, than we use z-index to make sure the first element overlays the second.
Now at last, we move the first span, we select that by using nth-of-type(1), which is nothing but first child of it's kind which is nested inside div, and we assign top: -40px; which will transit when the parent div is hovered.