2d transform affect parent only - css

I'm using transform:matrix on some parent element, but i want that child element is not affected by it.
I've got something like that for parent:
transform:matrix(0.98,-0.53,0.82,0.57,0,0);
-ms-transform:matrix(0.98,-0.53,0.82,0.57,0,0);
-webkit-transform:matrix(0.98,-0.53,0.82,0.57,0,0);
and inside that element is child.
I've tried position:absolute, or fixed for the child, but that doesn't work. I can always reset matrix positions for the child by changing parameters back to normal, but it is not easy to get that exact 100% accurate.
Adding jsfiddle for full code: https://jsfiddle.net/ypvoa8Ly/

Instead of using matrix transformation that can be hard to invert on child element. You can instead use simple transformation in the same property that you can easily invert.
You may also adjust the position of the inner element to avoid some bad overflow:
.img-wrapper {
width: 300px;
height: 300px;
margin:10px auto;
overflow: hidden;
transform: rotate(45deg) skew(-20deg);
position:relative;
}
.img-wrapper img {
transform: skew(20deg) rotate(-45deg);
position:absolute;
top:-15%;
bottom:-15%;
left:-15%;
right:-15%;
}
<div class="img-wrapper">
<img class="main-img" src="http://25.media.tumblr.com/tumblr_m5nre6cxkQ1qbs7p5o1_r1_500.jpg" alt="" />
</div>
Here is also another way to achieve something like this using gradient (since you cannot use clip-path):
.image {
height: 300px;
width: 300px;
margin: auto;
background:
linear-gradient(40deg, #fff 28%, transparent 20%, transparent 75%, #fff 70%),
linear-gradient(-40deg, #fff 28%, transparent 20%, transparent 75%, #fff 20%),
url('http://25.media.tumblr.com/tumblr_m5nre6cxkQ1qbs7p5o1_r1_500.jpg') center/cover no-repeat;
}
<div class="image" ></div>

Related

Create angled triangle top and bottom of page

I'm trying to create a diagonal div with SVG and I'm having a lot of issues.
My goal is:
Create full-width map on the top left corner.
Create full-width div of text on the bottom right corner.
I have worked on it but the SVG div overlapping the map and I can't select map and if I position map higher than SVG than map overlaps entire page.
You can see in the image what I want to achieve should look like.
I would use clip-path to do the job. AFAIK it's the only think able to achieve desired effect without JS and without assumption, that rectangle with map is a square. Support, unfortunately, isn't perfect. I also found interesting creator for clip paths.
More about clip-path
The clip-path CSS property creates a clipping region that defines what part of an element should be displayed. More specifically, those portions that are inside the region are shown, while those outside are hidden.
Unfortunetely it doesn't work on IE, but here you can find some fallback workarounds.
Snippet
.container {
position: relative;
height: 250px;
width: 250px;
background: black;
}
.map {
height: 100%;
width: 100%;
background: red;
-webkit-clip-path: polygon(100% 0, 0% 100%, 0 0);
clip-path: polygon(100% 0, 0% 100%, 0 0);
}
.corner {
position: absolute;
right: 0;
bottom: 0;
height: 100%;
width: 100%;
background: green;
-webkit-clip-path: polygon(100% 0, 0% 100%, 100% 100%);
clip-path: polygon(100% 0, 0% 100%, 100% 100%);
}
<div class="container">
<div class="map"></div>
<div class="corner"></div>
</div>

How can I alter the curve of a radial gradient in CSS?

I'm trying to achieve this gradient. What I don't understand is the curvature of it and I'm not sure on how to replicate it:
What I have so far:
and my code for the gradient:
radial-gradient(at top left,#629a92 36%,#02d2a0 67%, #fff 11%)
However I'm not sure how this gets stretched to the end of the screen. I haven't used radial-gradient much before so I feel like I'm missing something. Any help would be greatly appreciated. Thank you.
You need to also adjust background-size of the gradient:
body {
height:100vh;
margin:0;
background-image:radial-gradient(at top left,#629a92 36%,#02d2a0 67%, transparent 67.5%);
background-size:120% 100%;
background-repeat:no-repeat;
}
Or adjust the radius:
body {
height:100vh;
margin:0;
background-image:radial-gradient(120% 100% at top left,#629a92 61%,#02d2a0 92%, transparent 92.5%);
background-repeat:no-repeat;
}
UPDATE
If it's a linear-gradient inside a curved shape you can try to use multiple background. The idea is to create the linear-gradient and above it you add the a radial-gradient with transparent color to be able to see the first gradient.
body {
height:100vh;
margin:0;
background-image:
radial-gradient(120% 100% at top left,transparent 92%, #fff 92.5%),
linear-gradient(135deg, #51a595 0%, #3fcfa2 100%);
}
If you look carefully it is not a radial gradient. It is a linear gradient inside a radial shape. If I were you, I would do a SVG shape—mine is just for using as example—and apply it to the gradient.
Like this:
body {
margin: 0;
}
svg {
width: 0;
height: 0;
display: block;
}
.main {
width: 100%;
height: 100vh;
position: relative;
}
.main:before {
content: '';
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
background: #51a595;
background: linear-gradient(135deg, #51a595 0%, #3fcfa2 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#51a595', endColorstr='#54bb9b',GradientType=1 );
-webkit-clip-path: url("#mask");
clip-path: url("#mask");
}
<svg>
<defs>
<clipPath id="mask">
<ellipse cx="0" cy="-1400" rx="2200" ry="1500"></ellipse>
</clipPath>
</defs>
</svg>
<div class="main"></div>
Looking at radial-gradient on mdn, it can take 2 percentages before the at top left for its size. We can make the first larger than 100% so it will extend beyond the screen on the x axis and put the second percent to 100% so it ends at the bottom.
radial-gradient(
200% 100% at top left,
#629a92 36%,
#02d2a0 67%,
#fff 11%
);
This should result in what you are looking for
.head {
width: 100%;
height: 200px;
background: radial-gradient(
200% 100% at top left,
#629a92 36%,
#02d2a0 67%,
#fff 11%
)
}
.body {
height: 200px;
width: 100%;
}
<div class="head"></div>
<div class="body"></div>

Create a shape with three vertical lines (stripes) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
How to create the 3 vertical lines as in the following image using CSS?
This is pretty easy to create with linear-gradient background images and we don't need more than one div element to create this with gradients. All we need is a couple of gradient images.
Below is an explanation of how the shape was achieved:
One linear gradient image which is 85% the size of the container in the X-axis and 75% the size of the container in the Y-axis is used to create the large white portion and it is positioned on left of the container.
One more linear gradient image which is 15% of the size of the container in X-axis and 15% of the container's size in Y-axis is used to create the three stripes at the end. The stripes are created by splitting the gradient into colored and transparent portions. The colored portions are sized equally to produce a stripe like effect.
Note: The third bar in the image in question seems to be a little lower than the others, I am assuming this to be an error in the image. If it is not, it could still be achieved with the below approach.
body {
background: yellow;
}
.shape {
height: 100px;
width: 400px;
transform: skew(-30deg);
transform-origin: left bottom;
background-image: linear-gradient(to left, rgba(255,255,255,0.5) 25%, transparent 25%, transparent 33%, rgba(255,255,255,0.75) 33%, rgba(255,255,255,0.5) 60%, transparent 60%, transparent 66%, rgba(255,255,255,1) 66%, rgba(255,255,255,0.75) 93%, transparent 93%), linear-gradient(white, white);
background-size: 15% 100%, 85% 75%;
background-position: 100% 100%, 0% 0%;
background-repeat: no-repeat;
}
<div class='shape'></div>
You could also make use of SVG path elements to create this shape.
.shape {
position: relative;
height: 100px;
width: 300px;
}
.shape svg {
position: absolute;
height: 100%;
width: 100%;
top: 0px;
left: 0px;
}
.shape svg path#white-bar {
fill: rgba(255, 255, 255, 1);
}
.shape svg path#translucent-bar-1 {
fill: rgba(255, 255, 255, 0.75);
}
.shape svg path#translucent-bar-2 {
fill: rgba(255, 255, 255, 0.5);
}
body {
background: yellow;
}
<div class='shape'>
<svg viewBox='0 0 300 100'>
<path d='M0,75 25,0 240,0, 221.5,75z M245,0 220,100 235,100 260,0' id='white-bar' />
<path d='M265,0 240,100 255,100 280,0' id='translucent-bar-1' />
<path d='M285,0 260,100 275,100 300,0' id='translucent-bar-2' />
</svg>
</div>
Note: It may well be possible to create this using a single path element and an angled gradient fill but I am not that good with SVG.
I did a fiddle.
trick is you need to transform the figure and use vertical-align property.
-webkit-transform: skew(20deg);
vertical-align: text-top;
Tweaking #Siddarth's code, this might be more suited to the above given image:
div{
display:inline-block;
vertical-align: text-top;
-webkit-transform: skew(-20deg);
-moz-transform: skew(-20deg);
-o-transform: skew(-20deg);
background: white;
}
.one{
width: 450px;
height: 100px;
}
div:not(.one){
margin-left:0px;
width: 20px;
height: 200px;
}
.two{
opacity:.8;
}
.three{
opacity:.6;
}
.four{
opacity:.4;
}
body {
background-color: rgb(255, 210, 2);
}
<body>
<div class="one">
</div>
<div class="two">
</div>
<div class="three">
</div>
<div class="four">
</div>
</body>

Skew background image without distortion?

I need to skew the shape of a div that contains a background image, without actually distorting the background image.
Right now I'm using transform: skew(-25deg)
Is it possible to do this without the distortion?
You need to add the background image on a child of the skewed element and then apply an opposite skew to the child. Here's an example:
.parent {
height: 100px;
overflow: hidden;
transform: skew(0.5rad, 0);
width: 100px;
}
.child {
background: linear-gradient(to right, red 0%, blue 100%);
height: 100%;
transform: skew(-0.5rad, 0);
width: 100%;
}
<div class="parent">
<div class="child">
etc.
</div>
</div>

part of div transparent

I would like to create a menu that consists of three layers.
The menu is supposed to stretch over the entire screen width.
The first layer is an image that contains a gradient. Since the menu is stretched over the width the amount of change/width in color depends. It looks something like this:
The second layer looks just like the first layer, but lets say blue instead of red. So it contains that same gradient. I want to overlay parts of this layer with the first to highlight a selected menu item.
The third layer contains the menu items.
Here's a jsfiddle: http://jsfiddle.net/UrVq2/9/
and it's corresponding code:
HTML:
<div id="firstLayer"></div>
<div id="secondLayer"></div>
<div id="thirdLayer">Click me</div>
CSS:
#firstLayer {
background-image:url('http://s21.postimg.org/imynbhjo7/example.jpg');
background-size: 100% 100%;
width: 100%;
height: 100px;
min-width:900px;
position:absolute;
left:0;
top:0
}
#secondLayer {
background-image:url('http://s13.postimg.org/5o17i8wwn/example2.jpg');
background-size: 100% 100%;
width: 100%;
height: 100px;
min-width:900px;
position:absolute;
left:0;
top:0
}
#thirdLayer {
position:absolute;
top: 50px;
left: 50%;
}
When something in the menu is to highlight, and to get a match between the first layer gradient and the second layer gradient, I stretch both first and second layer over the entire width of the screen. Then I try to make the parts of the second layer that are not to highlight transparent. However, I fail doing so. Is there a way to achieve it, or should I take another approach?
e.g. I have tried following https://stackoverflow.com/a/8422890/1419386, however I cannot apply 1. and 3. suggestion, due to the gradient. 2. suggestion I don't believe I can apply, I want a sudden transparency at a point in the image and not some gradient into transparency.
(just splitting the gradient off from both layers does not work for me because it actually also difuses with the color beneath it (red or blue), so it is a little bit a simplified example).
There are 3 different posibilities that I can think of to solve your problem.
All of them are based on clipping instead of transparency, so the first thing that we need to do is to change the order of the divs:
HTML:
<div id="thirdLayer">hover me</div>
<div id="secondLayer"></div>
<div id="firstLayer"></div>
I have moved also the third layer in the front so that I can use the hover state without script, but this is not important.
The first posibility uses clip. Css:
#firstLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,red,red);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
width: 100%;
height: 100px;
min-width:900px;
position:absolute;
left:0;
top:0;
clip: rect(10px,0px,80px,0px);
-webkit-transition: all 2s;
}
#secondLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,blue,blue);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
width: 100%;
height: 100px;
min-width:900px;
position:absolute;
left:0;
top:0
}
#thirdLayer {
position:absolute;
top: 110px;
left: 50%;
}
#thirdLayer:hover ~ #firstLayer {
clip: rect(10px,800px,80px,400px);
}
Most of the CSS is standard stuff. I have replaced youyr images with gradients, so that the example does not depend on the availability of them. The key issue is using
clip: rect(10px,800px,80px,400px);
To show only the part of the div that you want. The main problem with this solution is that it is not posible to use percentages in that property, so it is of limited use if you want it to be flexible.
demo 1
The second posibility is to play with the background-size:
#firstLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,red,red);
background-size: 1000% 40%, 1000% 100%;
background-repeat: no-repeat;
backgrond-position: -10% 0%;
width: 10%;
height: 100px;
position:absolute;
left:-10%;
top:0;
-webkit-transition: all 3s;
transition: all 3s;
}
#secondLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,blue,blue);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
width: 100%;
height: 100px;
position:absolute;
left:0;
top:0
}
#thirdLayer {
position:absolute;
top: 110px;
left: 50%;
}
#thirdLayer:hover ~ #firstLayer {
left: 47%;
background-position: 47% 0%, 47% 0%;
}
demo 2
Notice that to compensate that the width of the background is now 10%, the background size is now 1000%, so the porportion is the same:
There can be slight offsets in rendering, due to the different calculus, but the system is quiet good.
The third posibility is to use a clipping mask (with limited browser support)
#firstLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,red,red);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
background-position: 0% 0%;
width: 100%;
height: 100px;
position:absolute;
left:0;
top:0px;
-webkit-transition: all 3s;
transition: all 3s;
}
#secondLayer {
background-image:linear-gradient(90deg,white,black), linear-gradient(90deg,blue,blue);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;
width: 100%;
height: 100px;
position:absolute;
left:0;
top:0;
}
#thirdLayer {
position:absolute;
top: 110px;
left: 50%;
}
#firstLayer {
-webkit-mask-position: -15% 0px;
-webkit-mask-size: 84px 100%;
-webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, 1), rgba(0, 0, 0, 1));
-webkit-mask-repeat: no-repeat;
}
#thirdLayer:hover ~ #firstLayer {
-webkit-mask-position: 52% 0px;
}
We define a mask, and the only remaining issue is to set the position
demo3

Resources