Gap between border-image after using transform: rotate - css

I am trying to create a box with a jagged edge, that can actually be used as a HTML element should be, and can resize etc.
Finally got my head around border-image, got it looking nice, and then when I rotate it, it gets a gap between the border-image and the main fill:
I googled it, and found an answer on SO telling someone to set
-webkit-backface-visibility: hidden;
This cleared it up, but obviously only in webkit browsers.
I tried using -moz-backface-visibility as well, but it didn't clear the issue up in Firefox.
Any suggestions?
jsFiddle
e: I actually thought I may be able to fix it by setting a background color, and then setting the background-clip to padding-box, but honestly it just left me in the same position.

One trick that fixes the problem both in Webkit and FF is setting perspective (instead of backface visibility)
.box.one {
-webkit-transform: perspective(999px) rotate(1deg);
-moz-transform: rotate(1deg);
-ms-transform: rotate(1deg);
-o-transform: rotate(1deg);
transform: perspective(999px) rotate(1deg);
}
fiddle

Adding an after pseudo class with negative margin seems to fix the Firefox issue.
.rough:after {
content: "";
display: block;
margin: -1px;
height: 302px;
background: black;
}
Fiddle demo: http://jsfiddle.net/Wkk7W/3/
Note that the display:block seems to be an essential part of my hack/fix.
Update: Depending on your plans for content inside the div, that exact example might not suit. However, I think the concept could be tweaked depending on your requirements - e.g. using a 3px wide black border instead of a background fill, and using position:absolute to allow other text to be layered on top of the box.

Gonna answer myself, because this solution actually covers my needs of it being "as a html element should be, and can resize etc", even though I developed this solution from Grants answer.
http://jsfiddle.net/Wkk7W/6/
Set the element to position:absolute, then give it a pseudo element with:
content: "";
display: block;
position: absolute;
top: 0;
width: 102%;
margin: -1px 0 0 -1%;
height: 102%;
background: black;
z-index: -1;
This way it keeps the elements width and height, z-index: -1 to put it behind the text. It might not require the display:block, i didn't check.
There are still a few tiny gaps but they are basically impossible to cover and I am happy with it the way it is.

Related

How to avoid the text jerk by using css transitions

I try to rotate the text by using, text-transform with transition. In firefox browser a slight jerk get happened. Check the below link, by mouse overing the text, end of the rotation you can see the slight jerk, how to avoid this?
.rot_pos{
margin:100px auto;
text-align:center;
}
.rotate{
font-size:30pt;
font-weight:bold;
display:inline-block;
transform:rotate(0deg);
-moz-transition:1s;
transition:1s;
}
.rotate:hover{
transform: rotate(-180deg);
-moz-transform: rotate(-180deg);
}
<div class="rot_pos">
<div class="rotate">Sample Text</div>
</div>
http://jsfiddle.net/es86wh1p/
Any other solution??
This happens only in firefox.
I had a small play with your code in js-fiddle, it almost appears to be a bug in firefox. A quick debugging tip for things like this is to enable borders and set different colors.
I was able to find a solution, but it is so incredibly hackey that this reminds me of the 90's and the fact that mozilla firefox rose from the ashes of the netscape codebase.
First I set a parent/child tag which "Should" have caused the text to rotate when the mouse entered the rot_pos div. This still caused the text to 'trap' when the mouse hit the box that was rotating ( when causing the mouse to leave quickly, you can test this by removing the padding from rot_pos )
Setting the Z-Order of rotate to -2 shows that the rotate:hover trigger is not being triggered when it is 'behind' another div. So the quick lazy fix would be to expand the size of rot_pos so it completely covers the rotating text.
Which leads me to:
http://jsfiddle.net/rwa1pq2v/
.rot_pos{
margin:100px auto;
text-align:center;
border: 1px solid black;
padding: 100px 20px 100px 20px;
}
.rot_pos > .rotate {
font-size:31pt;
font-weight:bold;
display:inline-block;
transform:rotate(0deg);
transition:1s;
border: 1px solid black;
background: green;
}
.rot_pos:hover > .rotate {
transform: rotate(-180deg);
-moz-transform: rotate(-180deg);
}
.rotate {
z-index: -2;
}
.rotate:hover {
background: pink;
}
The issue with this is that the rotation is being triggered when the mouse enters the outer-area. So with the knowledge that a div which is "above" according to the z-order will prevent the trigger of the div below I dropped a further 2 div's over the top which can be seen as red and blue with a opacity of 0.5 in the example below:
http://jsfiddle.net/non45qy2/
With some lazy hand fiddling of sizes to ensure that they completely cover the trigger area we have my final solution..
To improve on this we could also drop a further 2 div's to cover up the 2 leftover white area's (and fix up the padding on the covered up areas) so you don't have to offset by such a large amount.
if it wasn't 1:40am I would be raising this issue as a bug with mozilla and hoping it gets fixed in the next release.

CSS - "position: fixed" acting like "absolute" in Firefox

I've been building a website in Safari, and I've just tested it in Firefox and my fixed navigation elements are behaving as if they're position is absolute.
#navigation {
display: block;
width: 100%;
height: 50px;
position: fixed;
left: 0px;
bottom: 0px;
text-align: center;
z-index: 99000;
}
This is the CSS I have for the primary navigation wrapper (it's a bottom nav.). In Webkit, it works perfectly: that is, it sticks to the bottom of the window regardless. In firefox, it positions itself at the end of the tags, so, for example, on a long page, I'd have to scroll down just to see it. It is acting as if it's absolute.
I also have a sidebar navigation.
.slidebar {
display: block;
position: fixed;
left: -1px;
top: -1px;
width: 1px;
height: 100%;
overflow: hidden;
-webkit-transition: all 300ms ease;
-moz-transition: all 300ms ease;
-o-transition: all 300ms ease;
-ms-transition: all 300ms ease;
transition: all 300ms ease;
z-index: 99998;
}
This sidebar is also acting as if it's absolute - that is, it is positioning itself off the screen properly, but it's elongating <body> and thus the horizontal scrollbar appears. The height: 100%; is also responding to the <body> height and not the window height, so, for example, my <header> has a top margin of 20px, and the slidebar observes that margin too (the body has 0 margin). Likewise, instead of the height: 100%; ending at the bottom of the window, it ends at the bottom of the <body>, factoring in the footer's bottom margin.
I cannot understand for the life of me why this is happening. Element inspection shows all the properties are loading fine, and in Chrome and Safari it works. It worked initially, and it worked the last time I even edited either navigation, but it has since stopped working since I built other, irrelevant, parts of the site.
http://www.upprise.com/demo.php - click the Envelope icon to see the sidebar
I had the exact same problem, turns out the following CSS property of a parent element was causing the problem.
transform: translate3d(0px, 0px, 0px);
Through the process of elimination I was able to determine that having the following in my body was causing all the problems with fixed divs in Firefox:
-o-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
I had originally added this code to prevent flickering in certain CSS transitions throughout the site, but I guess I'll have to add it to each individual class now.
It appears that some browsers will will apply fixed positioning relative to the window, while Firefox is applying it relative to the <body />. You need to make your body 100% tall:
body {
height: 100%;
}
But the margin from your .header is collapsing outside of the body element. Change this:
margin: 25px auto;
to this:
margin: 0 auto; /* updated - thanks JoshC */
padding: 25px auto;
I solved the issue by moving the element that uses position: fixed; out of its original parent element that uses transform: translateX(-50%);.
Thus...
<div class="transformed-container">
<div="fixed-element"></div>
</div>
...became...
<div class="transformed-container"></div>
<div class="fixed-element"></div>
Two things led me to this conclusion:
#Pankaj's answer shows that the translate value can cause an issue.
#Wildhoney's comment to another answer references an explanation of the underlying cause: http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/
The problem seems to be in your body, i've added width:100%; height:100%; and overflow:hidden; to it in my fire fox and it looked just fine, except for the bottom menu-bar that went half of it's height over the bottom.
Not sure why the browsers were rendering differently, though the solution is pretty simple. You need to give the parent elements (html/body) a height of 100% in order to fill the entire page. It seems like FF rendered the fixed elements at the bottom of the contents as opposed to the bottom of the window. Adding the following will make it work across browsers:
html, body {
height: 100%;
}
In addition, you should also use padding on .header element as opposed to a margin. This will solve another issue.
.header {
margin: 0 auto; /* use a value of 0 rather than 25px */
padding: 25px 0;
}
I tested all this in the browser, it will work in FF now. It should also render properly in Chrome and others.
I needed to remove some css classes from the superior container of the fixed-on-scroll element that had a transition, from the animateCSS library.
$(window).on('scroll', function () {
if (distance <= 65) {
$('#my-contaniner').removeClass('animated fadeInLeft'); //delete problematic classes for FF
Add your code
});
Maybe it helps
After 5 hours of debugging, if you are using tailwindcss and you have drop-shadow-* (pay attention it's not shadow-*) class on one of your parent elements, it will cause the fixed elements within that element to act like they're absolute positioned.
Not sure why that is happening, maybe due to fact that tailwindcss is using lots of combined CSS variables.
Here's an example of what gets generated with tailwindcss drop-shadow-* utility, seems like filter property on one of the parent elements causes the same unexpected behaviour as transforms:
.drop-shadow-lg {
--tw-drop-shadow: drop-shadow(0 10px 8px rgba(0, 0, 0, 0.04)) drop-shadow(0 4px 3px rgba(0, 0, 0, 0.1));
filter: var(--tw-filter);
}

Unwanted outline on border when parent is transformed

I am using borders on some content. However, I am finding an unwanted 1px outline the same color as the background color is being added around the border when the parent is transformed (at least with scale and rotate). This occurs on pseudo-elements of the children as well
.container {
transform:rotate(-45deg);
}
.child {
border:3px solid white; background:green;
}
jsFiddle to work with
I have tested on the newest Chrome and IE, the problem is on both
How can I get rid of this outline without using box-shadow or removing the transform?
Add a translateZ(1px)
.container {
position:absolute;
top:50%; left:50%;
-webkit-transform:translateZ(1px) rotate(-45deg);
transform:rotate(-45deg);
}
(not really sure why does this work ...)
fiddle
Seems that IE needs more fixing...
.container {
position:absolute;
top:50%; left:50%;
-webkit-transform:translateZ(1px) rotate(-45deg);
transform:perspective(999px) translateZ(1px) rotate(-45deg);
}
fiddle2
Not a great fix, but adding backface-visibility: hidden; which determines if the element should be visible or not when it's faced away from the screen, commonly used when you "flip" and element, seems to fix it, at least in Chrome. I haven't got the possibility to test in IE though.
The reason I tried it is because this "hack" has solved simliar issues that I've had before. But I'm not really sure why it works ...
jsFiddle
In chrome you should be able to use -webkit-backface-visibility: hidden; to fix this. I'm not too sure about IE, I don't have anything to test that on right now.
http://jsfiddle.net/ayFbD/4/

Align Top of Background with Bottom of Element with CSS

I want to align the top of a background image with the bottom of an element using CSS (so that I can make it transition in upon hover or in an animation, in case you were wondering). This element does not have a set height; I don't know what the height of the element is. Does anybody know how to do this? The solution does not have to be IE compatible; it only has to work in the latest versions of Chrome and Firefox.
EDIT: I'll award the bounty to an answer that also works for the <body> element if there is such an answer by the time that the bounty ends.
Sorry about the trouble. Gotta love CSS right? Anyhow I have two solutions for you: One just stays within the realms of using background positioning and achieves it... for the MOST part; The other one goes outside of the immediate solution, adds just a little bit extra, but is rock solid and works with any height at all. Both work with any width.
So the first one:
This works by setting the background-position to the keyword value center for the xpos and the percentage value 1000% for the ypos. Of course the % value can vary, but I just went with 1000% to be safe. In reality you could make this just big enough to push it off screen. But here's the fiddle:
http://jsfiddle.net/D5QME/
The problem with this one is that if you make the height of the parent element the exact height of the background image... it quits working. And if the height of the parent element shrinks below the height of the image, it reverse the pattern. So if you're confident that the parent element will always be taller than the BG image, this is pretty solid.
Now the second one:
This one is straight up rock solid but adds an extra element. This extra element can either be a placeholder element, like a div or whatever, or just the straight img itself. This:
1) Uses position: relative and overflow: hidden on the parent to turn it into a container
2) Uses position: relative, margin: 0 auto, and top: 100% to position the image in the center and push it just below the parent
3) and uses .parent:hover .backgroundImage to make the image transition to top: 0% when the user hovers over the parent element.
Here's the fiddle:
http://jsfiddle.net/Fwf6p/
Even though this adds an extra element, it is pretty rock solid.
Anyhow, hope this helps!
-J Cole Morrison
Another modification of J Cole's answer, but seems to work with the body tag. May also work with Hephistocles modification but haven't tested that.
CSS:
.example{
border: 1px solid red;
/* Change the height to anything you want! */
height: 400px;
/* Change the width to anything you want! */
width: 500px;
position: relative;
}
.example:hover .backgroundImage{
height: inherit;
top: 0%;
}
.backgroundImage{
background: url("http://img.gadgetian.com/Angry-Birds-Space-021-300x300.png") no-repeat top center;
position:relative;
margin: 0 auto;
top: 100%;
-webkit-transition: 1s ease all;
-moz-transition: 1s ease all;
transition: 1s ease all;
height: 0px;
}
HTML:
<body class="example">
<div class="backgroundImage"></div>
</body>
JSFiddle
To take J Cole's second answer a bit further - if you want to avoid inserting an extra element you could always use pseudo-elements. For example:
.myElm {
position: relative;
overflow: hidden;
}
.myElm:after{
content:"";
background: url("myimage.png") no-repeat top left;
top:100%;
position: absolute;
}
.myElm:hover:after {
top:0;
}
If you know the height of your element in pixels, you may be able to set its background position to be: background-position:0 npx;. Not sure otherwise. If there's a maximum height, you could always just use that. Or have a reasonable estimate/limit. The transitions may not 'ease' very uniformly, however.
There was an excellent JSFiddle in another answer just now, but it's been deleted :(

When using CSS Scale in Firefox, element keeps original position

When using scale in Firefox, the scaled element dóes get scaled properly. The problem is, that it's positioned as if it isn't scaled.
This works fine in Chrome, and probably also in IE, Safari and Opera. These browsers all support the CSS zoom property, where Firefox doesn't. For Firefox I'm using -moz-transform: scale(0.3);.
This is my CSS:
#overview .page-content {
zoom: 0.3;
-moz-transform: scale(0.3);
}
This is what it should look like (as in Chrome):
This is what it shouldn't look like (as in Firefox):
Does anybody know how to fix this? Or maybe a workaround?
As thirtydot mentioned:
position: absolute;
-moz-transform-origin: 0 0;
This will do the trick.
I added -transform-origin: 0 0; and it still did not work.
Somehow in Chrome it collapsed to -webkit-transform-origin: 0;
So I changed it to -transform-origin: top left; and it works fine now.
Full code:
-moz-transform: scale(50%);
-moz-transform-origin: top left;
-o-transform: scale(50%);
-o-transform-origin: top left;
-webkit-transform: scale(50%);
-webkit-transform-origin: top left;
If absolute positioning is not an option - and aware of according browser support - display: table-cell with a min-width definition, should needs be, might do the trick as well.
E.g. this helped me to get a row with customer logos scaling well across different screen resolutions.

Resources