Right trapezoid outline shape (with transparency) - css

I'm trying to emulate an angled path line similar to this image.
The way I'm doing it is using two trapezoid shapes, and overlapping one with another that would be the same as the background as seen in this jsFiddle.
But I realized I want the rest of the shape to be transparent instead of being able to overlap other objects.
The core is just a little bit of CSS, an outlineMaker div inside of a rightTrapezoid div.
.rightTrapezoid {
border-bottom: 100px solid red;
border-left: 0 solid transparent;
border-right: 50px solid transparent;
height: 0;
width: 100px;
}
.outlineMaker {
border-bottom: 80px solid white;
border-left: 0 solid transparent;
border-right: 40px solid transparent;
height: 20px;
width: 80px;
}
Is there a neat and concise way to do this?

Complete example following nice using #Feng Huo tip.
HTML Markup
<div class="trapezoidLine1">
<div class="trapezoidLine2"/>
</div>
<div class="trapezoidLine3">
<div class="trapezoidLine4"/>
</div>
CSS
.trapezoidLine1 {
position: absolute;
width: 200px;
height: 2px;
background: blue;
}
.trapezoidLine3 {
position: relative;
margin-top:45px;
width: 207px;
height: 2px;
background:blue;
}
.trapezoidLine2 {
position: absolute;
width: 47px;
height: 2px;
background: blue;
left: 200px;
-webkit-transform-origin: 0% 0%;
-webkit-transform: rotateZ(80deg);
}
.trapezoidLine4 {
position: absolute;
width: 45px;
height: 2px;
background: blue;
-webkit-transform-origin: 0% 0%;
-webkit-transform: rotateZ(270deg);
}
Try the fiddle
http://jsfiddle.net/TNW63/

Instead of trying to force this way to work with a twist somehow. I gave it a couple minutes of thought and realized DUHHHHHHH, I can just do this:
<div class="trapezoidLine1">
<div class="trapezoidLine2"/>
</div>
.trapezoidLine1 {
position: absolute;
width: 200px;
height: 10px;
background: blue;
}
.trapezoidLine2 {
position: absolute;
width: 200px;
height: 10px;
background: blue;
left: 200px;
-webkit-transform-origin: 0% 0%;
-webkit-transform: rotateZ(45deg);
}
Herp a derp...

Related

How to change shape from pointing to top to point to right

I want to change the shape of the CSS from pointing to top to point to right. This is what I have now:
And this is what I want to have:
This is my current CSS:
.base {
background: red;
display: inline-block;
height: 55px;
margin-left: 20px;
margin-top: 55px;
position: relative;
width: 100px;
}
.base: before {
border-bottom: 35px solid red;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
content: "";
height: 0;
left: 0;
position: absolute;
top: -35px;
width: 0;
}
Please with below CSS
.base{
background: red;
display: inline-block;
height: 60px;
margin-left: 20px;
margin-top: 55px;
position: relative;
width: 100px;
}
.base:before {
border-left: 30px solid red;
border-top: 30px solid transparent;
border-bottom:30px solid transparent;
content: "";
height: 0;
left:100%;
position: absolute;
top:0;
width: 0;
}
It is simpler nowadays to use the CSS clip path facility rather than have to use borders and pseudo elements.
Clip path let’s you define a polygon in terms of percentages which means it is good for responsiveness, altering automatically to fit the dimensions of the element.
Here’s an example. Change the % values to suit the look you want.
.shape {
width: 200px;
height: 200px;
clip-path: polygon(0% 0%, 50% 0%, 100% 50%, 50% 100%, 0% 100%);
background: red;
}
<div class="shape"></div>
Caveat: not supported in IE

Rotated text in div corner (45deg) breaks if longer than 6 letters. How to center it forever?

I have this code https://jsfiddle.net/johnsam/wpyqt71w/
.container {
border: 1px solid gray;
position: relative;
width: 50vw;
height: 50vh;
background: #fff;
}
.triangle {
border-left: 7vmax solid red;
border-bottom: 7vmax solid transparent;
}
.triangle::after {
content: 'Hello!';
color: #ffffff;
font-size: 1.5vmax;
text-transform: uppercase;
left: 0vmax;
top: 2vmax;
position: absolute;
transform: rotate(315deg);
}
and everything works good for me.
Now I need to use another word instead of "Hello!" Maybe this word is longer or shorter. How to automatically center using also the font-size variable size?
Try this:
.container {
border: 1px solid gray;
position: relative;
width: 50vw;
height: 50vh;
background: #fff;
}
.triangle {
border-left: 7vmax solid red;
border-bottom: 7vmax solid transparent;
}
.triangle::after {
content: 'hello!123';
color: #fff;
font-size: 1.5vmax;
text-transform: uppercase;
left: 2.75vmax;
top: 1.75vmax;
position: absolute;
text-align: center;
transform: translateX(-50%) rotate(315deg);
}
<div class="container">
<div class="triangle"></div>
</div>
You don't need to use a pseudo. You can get the result with the base element alone (and this way the text is in the html).
With a somewhat complex transform, you get the element to auto adapt. Notice that the red background adapts perfectly to the borders. (If you add padding to the triangle, it will also adapt)
I have also set a shadow to fill the corners. I used a distinct color so you can easily see what is the element and waht the shadow.
.container {
border: 1px solid gray;
position: relative;
width: 50vw;
height: 100px;
background: #fff;
overflow: hidden;
}
.triangle {
background-color: red;
display: inline-block;
transform: translateX(-50%) rotate(45deg) translateX(50%) rotate(-90deg);
transform-origin: center top;
box-shadow: 0px -50px 0px 50px tomato;
}
<div class="container">
<div class="triangle">Hello</div>
</div>
<div class="container">
<div class="triangle">How are you ?</div>
</div>

How to make a trapezium with a border

I have tried to build a trapezium which has a Text-Content and a Border (white 1px line).
I found the examples with something like this:
height: 0;
width: 120px;
border-bottom: 120px solid #ec3504;
border-left: 60px solid transparent;
border-right: 60px solid transparent;
This is a png example, if i use this as background with transpartent color it would work but is kind of a hack and not as nice...
"clip-path" seems to be not supported enough, so are there other ways? would SVG be a possibility?
Thanks in Advance
You can use pseudo-element and use perspective on parent to create that shape as background.
body {
background: lightblue;
}
div {
width: 150px;
height: 40px;
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
-webkit-perspective: 130px;
perspective: 130px;
margin: 50px;
}
div:after {
position: absolute;
width: 100%;
height: 100%;
background: lightgreen;
border: 1px solid white;
content: '';
left: 0;
top: 0;
z-index: -1;
-webkit-transform: rotateX(20deg) rotateY(0deg);
transform: rotateX(20deg) rotateY(0deg);
}
<div>Some text</div>

CSS to create an acute isosceles triangle with curved edges

I am trying to create a triangle using purely CSS which has curved edges.
Is this possible without it being totally over the top?
I've added an example below of what I'm trying to achieve (the curved lines - not the straight lines).
So far I have been working with the following code but it's not quite what I'm looking for.
#inner {
transform: rotate(45deg);
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-o-transform: rotate(45deg);
-moz-transform: rotate(45deg);
background-color: silver;
width: 100px;
height: 100px;
top: 20px;
left: -50px;
position: relative;
-moz-border-radius: 20px;
border-radius: 20px;
}
#outer {
position: absolute;
width: 70px;
height: 140px;
top: 20px;
left: 50px;
overflow: hidden;
border: 1px solid red;
}
<div id="outer">
<div id="inner"> </div>
</div>
How about an svg solution?
<svg width="200" height="200" viewBox="-2 0 252 212">
<path fill="rosybrown" d="M125 0 c-81.6 60 -113.3 130 -125 200 c83.3 40 166.6 40 250 0 c-11.7 -70 -43.4 -140 -125 -200" fill="none" stroke-width="2" stroke="black" />
</svg>
Just another posibility, without using any rotation. Just clipping different circles.
.triangle {
position: relative;
width: 200px;
height: 200px;
border-radius: 50%;
background-color: lightblue;
overflow: hidden;
}
.triangle div {
position: absolute;
width: 100%;
height: 100%;
top: 31%;
left: 16%;
background-color: lightyellow;
border-radius: 50%;
overflow: hidden;
}
.triangle div:after {
content: "";
position: absolute;
width: 100%;
height: 100%;
right: 30%;
background-color: red;
border-radius: 50%;
}
<div class="triangle">
<div></div>
</div>
The light colors are there just to make the construction of the triangle more visible
solution 1: Using two elements
The first example is not perfect, but does sort of answers your question:
.wrapper{
/*overflow:hidden;*/
width:0;
border-top:100px solid transparent;
border-left:100px solid red;
position:relative;
margin:50px;
transform:rotate(135deg);
}
.triangle{
width:20px;
height:100px;
background:red;
border-radius:50%;
transform:translate(-110px);
position:absolute;
top:-100px;
left:0;
}
.triangle:after{
content:"";
width:100px;
height:20px;
background:red;
border-radius:50%;
transform:translate(0px);
position:absolute;
top:90px;
left:10px;
}
.triangle:before{
content:"";
width:140px;
height:20px;
background:red;
border-radius:50%;
transform:rotate(225deg);
position:absolute;
top:40px;
left:-10px;
}
<div class="wrapper">
<div class="triangle"></div>
</div>
Please note This isn't an equilateral triangle, more of an isosceles one and could be edited into a better one no doubt!!
Solution 2: Using a single element
I was trying to create this shape using a single div element, but i was only able to generate two sides of the triangle. So, from this, I deduced that using css along requires two elements:
Two sides Of the Triangle Shown:
div {
border-left: 100px solid transparent;
border-bottom: 126px solid blue;
border-right: 100px solid transparent;
width: 0;
border-radius:50%;
position: relative;
}
div:after,
div:before {
content: "";
position: absolute;
height: 130px;
width: 20px;
border-radius: 50%;
top: -15px;
background: blue;
}
div:after {
left: -50px;
transform: rotate(40deg);
}
div:before {
left: 30px;
transform: rotate(-40deg);
}
<div></div>
I am guessing that svg may be a better option (note: I do not know svg, that seems like #chipChocolate.pys's area of expertise). So using 'just pseudo effects', I think you're looking to use two elements (but I'd like to see be proved wrong!). The 'single element' doesn't quite seem right, but may or may not be perfect for you
Pure CSS
Using different transforms.
I created three sectors using transform: rotate(30deg); and transform-origin: 0% 100%; Then I transformed their parent containers (scaleX: -1; for the left side). Done.
This can be done with just one pair of #cont and #circ elements, but I used different tags just for demonstrating better.
#cont {
height: 300px;
width: 300px;
overflow: hidden;
position:relative;
}
#circ {
height: 300px;
width: 300px;
background: black;
border-radius: 0 300px 0 0;
transform: rotate(30deg);
transform-origin: 0% 100%;
}
#cont:nth-of-type(2){
top: -300px;
transform: scaleX(-1);
}
#cont:nth-of-type(3){
top: -600px;
transform: rotate(30deg);
transform-origin: 0% 100%;
}
#cont:nth-of-type(3) > #circ {
border-radius: 0 0 300px 0;
transform-origin: 0% 0%;
}
<div id="cont">
<div id="circ">
</div>
</div>
<div id="cont">
<div id="circ">
</div>
</div>
<div id="cont">
<div id="circ">
</div>
</div>
Note: For a real website, almost always use SVG. But creating shapes with CSS is an art which mustn't be killed.
Here is my attempt at this. I think this is the best way to do it, using 1 element and :before :after.
Using the div as the base element (the bottom) we can line up the other 2 above it keeping the size and shape equal.
div {
width: 120px;
height: 60px;
background: red;
border-radius: 50%;
position: relative;
margin: 100px;
}
div:before, div:after {
content: "";
display: block;
background: red;
border-radius: 50%;
position: absolute;
width: 60px;
height: 120px;
top: -70px;
}
div:before {
transform: rotate(30deg);
left: 8px;
}
div:after {
transform: rotate(-30deg);
right: 8px;
}
<div></div>
Edit:
Another Attempt, slight tweaking from the first.
div {
width: 100px;
height: 50px;
background: red;
border-radius: 50%;
position: absolute;
top: 10px;
left: 70px;
margin: 100px;
}
div:before,
div:after {
content: "";
display: block;
background: red;
border-radius: 50%;
position: absolute;
width: 36px;
height: 106px;
top: -65px;
}
div:before {
transform: rotate(28deg);
left: 8px;
border-right: 10px solid red;
}
div:after {
transform: rotate(-28deg);
right: 8px;
border-left: 9px solid red;
}
<div></div>
I like the challenge :)
I recently have come to love the more complex border radius variations. I'm sure with some more fiddling and decent math calculations you can get rid of the rough edges where the different sides meet. No time for it now unfortunately.
.triangle {
position: absolute;
top: 100px;
left: 100px;
border-left: 25px solid transparent;
border-bottom: 40px solid blue;
border-right: 25px solid transparent;
width: 0;
border-bottom-right-radius: 80px 70px;
border-bottom-left-radius: 0 0;
transform: rotate(160deg);
}
.triangle:after {
content: '';
position: absolute;
border-left: 25px solid transparent;
border-bottom: 40px solid CornflowerBlue;
border-right: 25px solid transparent;
width: 0;
left: -54px;
top: -12px;
border-bottom-right-radius: 80px 70px;
border-bottom-left-radius: 0 0;
transform: rotate(120deg);
}
.triangle:before {
content: '';
position: absolute;
border-left: 25px solid transparent;
border-bottom: 40px solid darkblue;
border-right: 25px solid transparent;
width: 0;
top: -30px;
left: -29px;
border-bottom-right-radius: 80px 70px;
border-bottom-left-radius: 0 0;
transform: rotate(240deg);
}
<div class="triangle"></div>

css - border on only a quarter of a circle shape?

I'm trying to create a rectangle with indented corners. So I have a relatively positioned rectangle with a colored background. I then absolutely positioned a circle in each corner, which gives the impression of indented corners on the rectangle. This works great as long as I keep the background color on the rectangle and circle are white, matching the page background.
But I'd like to have the background of the rectangle and circles both be white, matching the page background, and have borders on both of them. but when I do that, the rectangle's border appears around the circles. I've experimented with z-index, but that's not working. Any suggestions? Thank you.
Here is the relevant code:
<style>
#rect {width:200px; height: 300px;background-color: #fff;position: relative;overflow: hidden; border:1px solid #747474;}
.circle {border-radius: 50%; background-color: #fff; border: 1px solid #747474; width: 50px;height: 50px;position: absolute;}
.topleft {top: -10px;left: -10px;}
.topright {top: -10px;right: -10px;}
.bottomleft {bottom: -10px;left: -10px;}
.bottomright {bottom: -10px;right: -10px;}
</style>
</head>
<body>
<div id ="rect">
<div class ="circle topleft"></div>
<div class ="circle topright"></div>
<div class ="circle bottomleft"></div>
<div class ="circle bottomright"></div>
</div>
You can use
#rect {
border: none; // default value
}
#rect:before {
content: "";
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
border:1px solid #747474;
}
Demo
The problem is that with overflow: hidden, circles can't overlap #rect's border. Then, remove that border and add it to a pseudo-element instead.
Slightly different approach - FIDDLE.
CSS
#rect {
width:200px;
height: 300px;
position: relative;
overflow: visible;
border:1px solid #747474;
}
.circle {
border-radius: 50%;
background-color: white;
border: 1px solid white;
width: 100px;
height: 100px;
position: absolute;
z-index: 9999;
}
.topleft {
top: -52px;
left: -52px;
border-right-color: black;
transform: rotate(45deg);
}
.topright {
top: -52px;
left: 150px;
border-left-color: black;
transform: rotate(-45deg);
}
.bottomleft {
top: 250px;
left: -52px;
border-right-color: black;
transform: rotate(-45deg);
}
.bottomright {
top: 250px;
left: 150px;
border-top-color: black;
transform: rotate(-45deg);
}

Resources