I am trying to do this shape in HTML/CSS for my mobile app:
https://embed.plnkr.co/9k8jbJyzUiSMSoSHlOti/
.boundary {
width: 100.13723%;
padding-bottom: 5.24078%;
position: relative;
overflow: hidden;
background-color: white;
}
.boundary:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: top left;
transform: rotate(3deg);
background-color: green;
}
.inner {
height: 100%;
width: 100%;
background-color: green;
}
<div class="boundary"></div>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis auteirure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
In my browser, when I inspect the element and change the zoom (to 75%), there is a gap between 2 <div>
. When I deploy my application in my device, I can see this same gap.
What is going on ?
This is how I make the shape:
I create a first div to do the inclined line. I make a responsive triangle (I picked some information from this Question)
1) In my div, I insert a first pseudo-element and give it 100% width and height of parent. I apply a rotation : I define a transform origin in the top left, and rotate the pseudo element 3 degrees clockwise with transform: rotate(3deg)
2) I have to adjust width and height: I use percentages and padding-bottom
to maintain the aspect ratio (more information here) so:
[rectangle height] : padding-bottom = tan(3deg) * 100% = 100.13723% (100% is the screen width)
[hypotenuse of triangle = new rectangle width] : width = tan(3deg) * 100% / sin(3deg) = 5.24078%.
3) To hide the unwanted parts of the pseudo element (everything that overflows the <div>
with the red border) I set overflow: hidden
on the container.
- I make a second
<div>
after the first inclined <div>
. This <div>
is simple, without special transformation, and contains Lorem ipsum.
This usually happens while transforming elements because browser starts doing antialiasing with elements' edges.
Antialiasing is something of an unsung hero in web graphics; it’s the
reason we have clear text and smooth vector shapes on our screens.
While zooming out/in browser doesn't rescale element properly, e.g. if you zoom out an element of 1px
height to 0.75%
, browser should redraw element to 0.75px
but browser cannot draw 0.75px
, it either can create it 1
or it will try to make edges smooth with making pixel blur or 50% opacity.
In above picture you can see the same triangle being drawn, but on the left it has antialiasing enabled and on the right it’s been disabled. As you can see, when antialiasing is enabled the pixels are shades of gray when the triangle only passes through part of the pixel. When disabled, however, the pixel is filled in as either solid black or solid white and the shape looks jagged.
Using backface-visibility: hidden;
or overlapping elements with negative margins while scaling/transforming is the better option to avoid this issue.
Demo without using backface-visibility: hidden;
html,
body {
transform: scale(.8);
}
.boundary {
width: 100.13723%;
padding-bottom: 5.24078%;
position: relative;
overflow: hidden;
background-color: white;
}
.boundary:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: top left;
transform: rotate(3deg);
background-color: green;
}
.inner {
height: 100%;
width: 100%;
background-color: green;
}
<div class="boundary"></div>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
Demo with using backface-visibility: hidden;
html,
body {
transform: scale(.8);
}
.boundary {
width: 100.13723%;
padding-bottom: 5.24078%;
position: relative;
overflow: hidden;
background-color: white;
}
.boundary:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: top left;
transform: rotate(3deg);
background-color: green;
}
.inner {
height: 100%;
width: 100%;
background-color: green;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
<div class="boundary"></div>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
Demo provided by OP in comment solved by using backface-visibility: hidden;
and overlapping elements with negative margin
html,
body {
transform: scale(.75);
}
.inner {
height: 100%;
width: 100%;
background-color: green;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.inner-2 {
background-color: red;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.inner-3 {
background-color: blue;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.boundary {
width: 100.13723%;
padding-bottom: 5.24078%;
position: relative;
overflow: hidden;
background-color: white;
margin-top: -2px;
}
.boundary:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: top left;
transform: rotate(3deg);
background-color: green;
backface-visibility: hidden;
}
.boundary-2 {
background-color: green;
}
.boundary-2:before {
transform-origin: top right;
transform: rotate(-3deg);
background-color: red;
}
.boundary-3 {
background-color: red;
}
.boundary-3:before {
transform-origin: top left;
transform: rotate(3deg);
background-color: blue;
}
<div class="boundary"></div>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="boundary boundary-2"></div>
<div class="inner inner-2">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="boundary boundary-3"></div>
<div class="inner inner-3">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
PS: Don't forget to use viewport meta
tag for responsiveness.
Source Antialiasing-101
I think I have fixed it by using skew and adding a border and a negative margin at the top.
Here's a CodePen and below is my CSS:
.boundary {
padding-bottom: 5.24078%;
position: relative;
overflow: hidden;
background-color: white;
}
.boundary:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 105%;
height: 105%;
transform-origin: top left;
background-color: green;
transform: skew(0, 3deg);
z-index: 10;
}
.inner {
height: 100%;
width: 100%;
background-color: green;
color: #fff;
z-index: 50;
position: relative;
border-top: 1px solid green;
margin-top: -1px;
}
Gap is still there even if you do not apply any transformation.
.boundary {
width: 100.13723%;
padding-bottom: 5.24078%;
position: relative;
overflow: hidden;
background-color: white;
}
.boundary:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
/*transform-origin: top left;*/
/*transform: rotate(3deg);*/
background-color: green;
}
.inner {
height: 100%;
width: 100%;
background-color: green;
}
<div class="boundary"></div>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis auteirure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
So transform:rotate()
or something are not causing any troubles.
Now your problem can be solved by
.inner {
margin-top: -2px;
/* experiment different value or unit for different zoom levels*/
height: 100%;
width: 100%;
background-color: green;
}
For me it is rendering problem. If you change
top: 0px;
to
top: 1px;
everything should be fine.