make css box rotate from all sides - html

I want to make a css box with rotation. here is the image that I'd like:
Can anyone help me to make the same? Here is the code that I have used.
.yr_highlights
{
background: none repeat scroll 0 0 #000000;
height: 30px;
margin: 24px auto 0;
text-align: center;
transform: skewY(-7.4deg);
width: 20%;
}
<div class="yr_highlights"></div>

See this Fiddle
.box {
background: red;
width: 200px;
height: 50px;
-webkit-transform: skewY(-7deg) skewX(-17deg);
-moz-transform: skewY(-7deg) skewX(-17deg);
transform: skewY(-7deg) skewX(-17deg);
margin: 50px 0 0 50px;
}

.yr_highlights {
transform: rotate(-10deg);
}

Related

Combining and aligning multiple divs into a single shape

I am trying to create a hexagon using CSS. There are a number of questions about this already, but in my specific case I need it composed of 3 identical shapes that are different colors.
There are 2 specific requirements:
The overall size of the hexagon must be controllable by a single value. In my case that is the width of the .hexagon-wrapper class
The hexagon shape must be centered horizontally and vertically within it's parent (.hexagon-wrapper), and that wrapper must also be centered horizontally and vertically within its parent (the outermost div)
You'll notice there are some problems with my attempt:
The 3 pieces that make up the hexagon arent tightly aligned,
and the overall shape starts to break apart when you change
.hexagon-wrapper width
I'm using some magic numbers to translate the individual pieces, and they don't guarantee that the pieces will stick together after resizing, nor do they really guarantee that the elements are perfectly centered horizontally and vertically
Is there an easier way to do this, or some simple math that I'm missing? Basically, how do I keep the pieces together, and how do I ensure everything is centered?
I did consider creating a 3D cube and using transform3d to ensure everything sticks together, but I do not want to go with this approach because I have had many anti-aliasing issues when using transform3d and want to avoid that altogether
.hexagon-wrapper {
display: flex;
position: relative;
background-color: green;
width: 40%;
height: 100%;
margin: auto;
}
.hexagon-part-red {
position: relative;
width: 27.85714285714286%;
padding: 0 0 32.16760145166612% 0;
transform: translate(112%, -50%) rotate(-60deg) skewY(30deg);
background: red;
margin: auto;
}
.hexagon-part-yellow {
position: relative;
width: 27.85714285714286%;
padding: 0 0 32.16760145166612% 0;
transform: translate(-49%, 25%) rotate(0deg) skewY(30deg);
background: yellow;
margin: auto;
}
.hexagon-part-blue {
position: relative;
width: 27.85714285714286%;
padding: 0 0 32.16760145166612% 0;
transform: translate(-69%, 25.1%) rotate(60deg) skewY(30deg);
background: blue;
margin: auto;
}
<div>
<span class="hexagon-wrapper">
<div class="hexagon-part-red"></div>
<div class="hexagon-part-yellow"></div>
<div class="hexagon-part-blue"></div>
</span>
</div>
Here is an easier idea where you don't need any complex calculation and a lot of transform:
.hexagon-wrapper {
position: relative;
background-color: green;
width: 40%;
margin: auto;
display: flex;
justify-content: center;
}
.hexagon-part-red,
.hexagon-part-yellow,
.hexagon-part-blue {
width: 30%;
display: inline-flex;
}
.hexagon-part-red:before,
.hexagon-part-yellow:before,
.hexagon-part-blue:before {
content: "";
padding-top: 115.47%; /* 100/cos(30deg) */
}
.hexagon-part-red {
position: absolute;
top: -50%;
height: 100%;
width: 60%;
background: red;
clip-path: polygon(0 50%, 50% 0, 100% 50%, 50% 100%);
}
.hexagon-part-yellow {
transform: skewY(30deg);
transform-origin: left;
background: yellow;
}
.hexagon-part-blue {
transform: skewY(-30deg);
transform-origin: right;
background: blue;
}
body {
margin: 0;
display: flex;
height: 100vh;
}
<div class="hexagon-wrapper">
<div class="hexagon-part-red"></div>
<div class="hexagon-part-yellow"></div>
<div class="hexagon-part-blue"></div>
</div>

If I have two identical elements, one scaled to 2x, how scale down it's inner element and place it where it would be at 1x?

I have two identical elements. The top one, I'm scaling to double the size and then centering over the normal-sized one. I want its inner element to then be scaled back down to normal size and placed exactly where the normal sized element's inner element is placed.
This seems to be impossible. There seems to be no logic in the scaling + translation of position.
How would I do this?
https://jsfiddle.net/0urdrvao/
HTML:
<div class="top">
<div class="inner">
Inner
</div>
</div>
<div class="bottom">
<div class="inner">
Inner
</div>
</div>
CSS:
body, html
{
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}
.top,
.bottom
{
position: relative;
top: 0px;
left: 0px;
width: 300px;
height: 300px;
background-color: gray;
z-index: 0;
}
.top
{
position: fixed;
transform-origin: 0 0 0;
transform: translate(-150px, -150px) scale(2);
opacity: .5;
z-index: 1;
}
.inner
{
position: relative;
top: 20vh;
left: 0px;
width: 100px;
height: 40px;
background-color: red;
}
.top .inner
{
/* This doesn't work */
transform: translate(150px,150px) scale(.5);
/* This also doesn't work (doing half)*/
/*transform: translate(75px,75px) scale(.5);*/
/* This also doesn't work (doing double)*/
/*transform: translate(300px,300px) scale(.5);*/
transoform-origin: 0 0 0;
background-color: yellow;
}
Since the top: 20vh will be scaled times 2, the transform-origin should be 0 -20vh.
When reverse a scale/translate you need to go backwards and start with scale and then the translate
.top{
position: fixed;
transform-origin: 0 0;
transform: translate(-150px, -150px) scale(2);
opacity: .5;
z-index: 1;
}
.top .inner{
transform: scale(.5) translate(150px, 150px);
transform-origin: 0 -20vh;
background-color: yellow;
}
Updated fiddle
Or one could do like this, setting origin to 0 0 and transform: scale(.5) translate(150px,150px) translateY(-20vh);
Updated fiddle

How to add that slant line?

I would like to add that line in border property, not create new div.
Is it possible?
http://i.stack.imgur.com/9SsYo.png
You can use CSS3 transform style to do that. You can use jQuery aswell: How to rotate a div using jQuery
If you choose to use CSS3 transform style, you need to set border of your div and rotate it. If you have something (image, text, etc) in your div, it will rotate with the div, so you need to un-rotate them using the same method.
If this doesn't help you, paste your code in jsFiddle and it will be way easier to help you. Good luck.
Not sure, but if you are looking to clip:
-webkit-clip-path: polygon(28% 0, 100% 0, 100% 81%, 74% 100%, 0 100%, 0 19%);
clip-path: polygon(28% 0, 100% 0, 100% 81%, 74% 100%, 0 100%, 0 19%);
You can use css pseudo classes to do this.
https://jsfiddle.net/L87jf1d8/2/
Use :before and :after to the box class
<div class="box">
Name
</div>
Css:
.box{
padding:30px;
text-align:center;
width:200px;
border:1px solid #000;
}
.box:after,.box:before{
content: " ";
width: 55px;
height: 1px;
transform: rotate(-45deg);
background: #000;
position: absolute;
}
.box:after{
margin-left: 64px;
margin-top: 29px;
}
.box:before{
margin-left: -120px;
margin-top: -12px;
}
Define a slant class like the following and apply it to any div regardless of its size:
Note that you should also set overflow: hidden; on main element;
.box1, .box2, .box3 {
width: 100px;
height: 100px;
background-color: white;
border: 1px solid black;
overflow: hidden;
margin-top: 10px;
}
.box2 {
width: 200px;
}
.box3 {
width: 300px;
}
.slant:before, .slant:after {
content: '';
border: 1px solid tomato;
display: inline-block;
transform: translate3d(-50%, -50%, 0) rotate(45deg);
position: relative;
top: 0;
right: 0;
width: 30px;
height: 30px;
}
.slant:after {
transform: translate3d(-150%, -50%, 0) rotate(45deg);
top: 100%;
left: 100%;
}
<div class="box1 slant"></div>
<div class="box2 slant"></div>
<div class="box3 slant"></div>

How to set ribbon on image by stacking it in a div?

I currently have an ng-repeat that looks like this:
<div class="repeaterDiv" data-ng-repeat="item in itemArray">
<div class="wrapper">
<img class="imageClass" ng-src="{{item.image}}"/>
<div class="corner-ribbon bottom-right sticky green shadow">Changed</div>
</div>
</div>
Here is the CSS pulled from this codePen:
.corner-ribbon{
width: 200px;
background: #e43;
position: absolute;
top: 25px;
left: -50px;
text-align: center;
line-height: 50px;
letter-spacing: 1px;
color: #f0f0f0;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.sticky{
position: fixed;
}
.corner-ribbon.shadow{
box-shadow: 0 0 3px rgba(0,0,0,.3);
}
.corner-ribbon.bottom-right{
top: auto;
right: -50px;
bottom: 25px;
left: auto;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.green{background: #2c7;}
I am trying to figure out how to get the ribbon to be restricted to the wrapper class. Does anyone know how I can do that? so I'm still using the same ribbon, but instead of being in the bottom right of the screen, it is at the bottom right of the image for which it applies?
you need to use relative/absolute position and reset display of .wrapper to shrink on image. Then add overflow:hidden to cut off edges of ribbon:
.corner-ribbon {
width: 200px;
background: #e43;
position: absolute;
top: 25px;
left: -50px;
text-align: center;
line-height: 50px;
letter-spacing: 1px;
color: #f0f0f0;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.sticky {
position: absolute;
}
.corner-ribbon.shadow {
box-shadow: 0 0 3px rgba(0, 0, 0, .3);
}
.corner-ribbon.bottom-right {
top: auto;
right: -50px;
bottom: 30px;
left: auto;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.green {
background: #2c7;
}
.wrapper {
position: relative;
display: table-cell;/* or inline-block or float */
overflow: hidden;
}
img {
display: block;
}
<div class="repeaterDiv" data-ng-repeat="item in itemArray">
<div class="wrapper">
<img class="imageClass" ng-src="{{item.image}}" src="http://lorempixel.com/300/200" />
<div class="corner-ribbon bottom-right sticky green shadow">Changed</div>
</div>
</div>
The class has fixed positioning.
.corner-ribbon.sticky{
position: fixed;
}
So for exact css you may not be able to attach ribbon to each img, rather ribbon would go to specific place in window only. However, you can adjust css a bit. Make wrapper class relative, and .corner-ribbon.sticky absolute position. Then adjust your css fot top/bottom/left/right properties to align them.
.wrapper{
position: relative;
}
.wrapper .corner-ribbon.sticky{
position: absolute;
/* put top/bottom/left/right values here*/
}

Preventing blurry rendering with transform: scale

I'm scaling a div up with the transform property, but I want to keep its children (which have 1px width or height) the same size. I counter-scaled them by .5, with the expected result that an element of 1px scaled by 2, and then .5, should end up back at 1px, but they wind up a blurry 2px.
Here's the box before scaling it:
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
}
.outlineRight {
right: 0px;
}
.outlineBottom {
bottom: 0px;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>
As you can see, the elements at the edges are a clear, dark 1px blue. Here's what the box looks like after scaling, though:
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
transform: scale(2);
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
transform: scale(.5);
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
transform: scale(1,.5);
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
transform: scale(.5,1);
}
.outlineRight {
right: 0px;
}
.outlineBottom {
bottom: 0px;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>
And here's a post-scaled render from Chrome 41.0.2272.89 Mac, which is what I'm running.
Adding transform-3d(0, 0, 0) didn't appear to help. A solution was found using the zoom property, but since zoom isn't well supported I'd like to avoid that. Adding filter: blur(0px); didn't appear to have any effect either.
It was posited in chat that perhaps the children are first scaled to .5 and then doubled in size, causing them to be scaled down to .5px and then back up from there. Is there any way to ensure the order that they're rendered in causes them to first be scaled up to 2px and then halved? Against my better judgement, I tried forcing the render order with JS, but unsurprisingly, that didn't have any effect (though, interestingly, the bottom element did maintain its original color).
Failing that, are there any other solutions floating around out there? I can't be the only one who's run into this problem.
It is to do with the default transform-origin on the scaled elements. It defaults to 50% 50% for any element being transformed, but this has issues when scaling down 1px values as it has to centre the scale on a half pixel and the rendering of the elements has issues from here on out. You can see it working here with the transform-origin moved to the relevant extremes for each item.
A bit of playing about shows that this same blurring happens on scaled elements for any dimension where the scaling ends up halving a pixel.
body {
padding: 1em;
}
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
transform: scale(2);
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
transform: scale(1, 0.5);
}
.outlineBottom {
bottom: 0;
transform-origin: 0 100%;
}
.outlineTop {
transform-origin: 0 0;
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
transform: scale(.5,1);
}
.outlineRight {
right: 0px;
transform-origin: 100% 0;
}
.outlineLeft {
left: 0px;
transform-origin: 0 0;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>