How to make a trapezium with a border - css

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>

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

How to give border to a shape?

I am building a testimonial component in react and I have to make a shape direction towards pic, I have done the shape exactly how I want but the testimonial div has border color when I apply the div gets a border but the shape is left outside I have tried several ways but couldn't find a solution, I have attached the picture of what I want and how it is right now.
How I want it
What I have achieved till now
Below is my CSS
#page {
background-color: lightgray;
padding: 40px;
}
.container {
position: relative;
background-color: #FFFFFF;
max-width: 600px;
height: auto;
border: 1px solid #E7E7E7;
padding: 30px;
box-sizing: border-box;
}
.container:after {
position: absolute;
width: 0;
height: 0;
border-top: 50px solid white;
border-right: 40px solid transparent;
top:101%;
left: 40%;
content: '';
transform: rotate(14deg);
margin-top: -10px;
}
<div id="page">
<div class="container">This is a test</div>
</div>
You may use a filter , choice: drop-shadow.
support ? , don't be afraid : https://caniuse.com/?search=drop-shadow All but IE 6-11 and Opera mini
here is an exemple to run:
#page {
background-color: lightgray;
padding: 40px;
}
.container {
position: relative;
background-color: #FFFFFF;
max-width: 600px;
height: auto;
filter:
/* draw borders without blur*/
drop-shadow(0 1px )
drop-shadow(1px 0px )
drop-shadow(0 -1px )
drop-shadow(-1px 0px )
/* add eventually a shadow */
drop-shadow(0 0 3px )
/*and another for demo purpose */
drop-shadow(30px 30px 3px gray );
padding: 30px;
box-sizing: border-box;
}
.container:after {
position: absolute;
width: 0;
height: 0;
border-top: 50px solid white;
border-right: 40px solid transparent;
top:101%;
left: 40%;
content: '';
transform: rotate(14deg);
margin-top: -10px;
}
<div id="page">
<div class="container">This is a test</div>
</div>
You can use a :before that's 1px bigger than your :after which uses the border colour instead and then it will be mostly covered by the :after, giving you your "fake" border. Just makes sure your z-indexing is correct so it doesn't show inside your bubble.
EDIT: Adding in example css.
I modified some colours and spacing for illustrative purposes:
#page {
background: #ffc;
padding: 40px 40px 60px;
position: relative;
z-index: 0;
}
.container {
position: relative;
background: #fff;
max-width: 600px;
height: auto;
border: 1px solid #000;
padding: 30px;
box-sizing: border-box;
}
.container:after,
.container:before {
position: absolute;
width: 0;
height: 0;
top: 101%;
left: 40%;
content: "";
transform: rotate(14deg);
margin-top: -10px;
}
.container:after {
border-top: 50px solid #fff;
border-right: 40px solid transparent;
}
.container:before {
border-top: 52px solid #000;
border-right: 42px solid transparent;
margin-left: -1px;
z-index: -1;
}
<div id="page">
<div class="container">This is a test</div>
</div>
Adding both a :before and :after is a good idea to get the effect you want. Using a CSS box-shadow or outline won't work because it actually renders a complete square around your arrow/triangle shape. A z-index is added to the before to push it to the background. In that way it's not overlapping the other objects.
Here's an example of what you might want. You can adjust the border sizes to finetune it.
.container {
position: relative;
background-color: #FFFFFF;
max-width: 600px;
height: auto;
border: 1px solid #E7E7E7;
padding: 30px;
box-sizing: border-box;
}
.container:before {
position: absolute;
width: 0;
height: 0;
border-top: 53px solid #e7e7e7;
border-right: 43px solid transparent;
top: 100%;
left: 40%;
content: '';
transform: rotate(14deg);
margin-top: -10px;
z-index: -1;
}
.container:after {
position: absolute;
width: 0;
height: 0;
border-top: 50px solid white;
border-right: 40px solid transparent;
top:101%;
left: 40%;
content: '';
transform: rotate(14deg);
margin-top: -10px;
}
<div class="container"></div>

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>

Circular effect in rectangle

I'm trying to make a design as shown in image, but main issue is that I cant use z-index there because it will effect other elements. Is there any way to achieve this ? Thank you
You can create something like this with pseudo-element.
.element {
width: 400px;
height: 45px;
position: relative;
overflow: hidden;
border: 2px solid orange;
border-bottom: none;
}
.element:after {
content: '';
width: 210%;
height: 700px;
left: 50%;
border-radius: 50%;
border: 2px solid orange;
position: absolute;
transform: translateX(-50%);
}
<div class="element"></div>

Right trapezoid outline shape (with transparency)

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...

Resources