CSS for Line Arrow - css

Does anyone have any pointers on how I can achieve the following 2 effects (red color) using pure CSS?
I am not asking for entire code but if anybody can guide me in proper direction, that would really be great.
Thanks in advance.

For second effect you should create for image's container two pseudo-elements :before and :after with border-radius set to desired value. Element :before you should position to left bottom side of container and the element :after you should position to right bottom side. You should also specify widths for each pseudo-element (for example: 50% and 50%, 60% and 40% etc.).
Code for the second effect:
.image {
position: relative;
width: 350px;
}
img {
display: block;
padding: 0;
margin: 0;
}
.image:before {
content: '';
display: inline-block;
background: rgba(255, 0, 0, .5);
width: 30%;
height: 120px;
position: absolute;
bottom: 0;
left: 0;
border-top-right-radius: 15px;
}
.image:after {
content: '';
display: inline-block;
background: rgba(255, 0, 0, .5);
width: 70%;
height: 120px;
position: absolute;
bottom: 0;
right: 0;
border-top-left-radius: 15px;
}
<div class="image">
<img src="http://placehold.it/350x350">
</div>

OK, here is a suggestion for the proper direction.
The lower red panel looks to me like two adjoining rectangles. You need to set the widths appropriately, and then for each rectangle round off one corner using border-radius: a b c d.
The effect looks to me like two of effect number 2. The red one, and then the same in white, possibly with a z-index to make sure that it (partly) covers the other one.
I trust you already know how to make the red translucent, either by using opacity or setting the colour using rgba.
I hope that helps.

You have to use the pseudo elements :after & :before to achieve the bulge in the otherwise straight div.
You may try something like this:
div {
height: 30px;
width: 200px;
background-color: red;
position: relative;
}
div:after {
content: '';
position: absolute;
left: 0;
right: 0;
width: 0px;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #fff;
margin: auto;
}
div:before {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: -8px;
width: 0px;
height: 0;
border-left: 12px solid transparent;
border-right: 12px solid transparent;
border-top: 10px solid red;
margin: auto;
}
<div></div>

Since you didn't provide a fiddle so use below solution as a guide. CSS will produces curved edges that you join together to produce desired results.
div.arrow-curved {
width: 120px;
height: 80px;
background: red;
position: relative;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
div.arrow-curved:before {
content:"";
position: absolute;
right: 100%;
top: 26px;
width: 0;
height: 0;
border-top: 13px solid transparent;
border-right: 26px solid red;
border-bottom: 13px solid transparent;
}
For more reference for CSS shapes: https://css-tricks.com/examples/ShapesOfCSS/

Related

CSS: How to add slanted edge to right of div with complete browser cross-compatability?

I'm looking to achieve a slanted edge on my div. The problem I'm coming across is the simple code I found to accomplish this is not cross-browser compatible. In fact, it only shows in Chrome.
Can anyone advise on how to do the following so it works in ALL browsers:
clip-path:polygon(0 0, 70% 0, 100% 100%, 0 100%);
This effect would achieve:
Here's my entire CSS code:
.my-slanted-div {
position:absolute;
bottom:0;
left:0;
width:100px;
padding:10px 10px;
background-color:#eee;
font-size:20px;
clip-path:polygon(0 0, 70% 0, 100% 100%, 0 100%);
}
Can anyone help me out?
You can also skew pseudo-element, like this:
.my-slanted-div {
position:absolute;
bottom:40px;
left:0;
width:80px;
padding:10px 10px;
background-color:red;
font-size:20px;
}
.my-slanted-div:after {
width:50px;
background:red;
position:absolute;
height:100%;
content:' ';
right:-22px;
top:0;
transform: skew(45deg);
}
<div class="my-slanted-div">
TEXT
</div>
p.s. change angle, play with values...to get desired result...
Edit: Demo in context -> https://jsfiddle.net/Lbwj40mg/2/
This should do the trick using borders.
<div id="container">
<p id="text">Hello</p>
<div id="slanted"></div>
</div>
#container {
position: relative;
height: 200px;
width: 200px;
background:url(http://placehold.it/200x200);
}
#text {
position: absolute;
bottom: 15px;
left: 10px;
z-index: 1;
margin: 0;
}
#slanted {
position: absolute;
bottom: 0;
left: 0;
height: 0;
width: 0;
border-left: 75px solid #dedede;
border-right: 50px solid transparent;
border-bottom: 50px solid #dedede;
}
jsfiddle
I've made it work one way with :before and :after pseudos, you simply need to update the widths, heights and line-height to suit the size of tab you want; the rectangle must be the same height as the :before and :after bits for a clean look.
.box {
background: red;
width: 200px;
position: relative;
height: 100px;
line-height: 100px;
text-align: center;
margin-left: 50px;
color: white;
font-size: 21px;
font-family: arial, sans-serif;
}
.box:after {
position: absolute;
right: -50px;
content: '';
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
.box:before {
position: absolute;
left: -50px;
content: '';
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
<div class="box">
Text in the box
</div>
Here's a way with transform: rotate just to add to the list. Quite annoying as you will have to play with pixels for alignment and make some entries into #media rules for different screen sizes. But it should be fairly cross browser friendly (but maybe not opera mini)
body {
background-color: #333;
}
.container {
position: absolute; /* needs a position, relative is fine. abolsute just for this example */
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 200px;
background-color: #ccc;
overflow: hidden; /* required */
}
.salutations {
position: absolute;
bottom: 0;
left: 0;
padding: 0 10px 0 15px;
background-color: #fcfcfc;
height: 50px;
line-height: 50px; /* match height to vertically center text */
font-size: 30px;
}
.salutations::before {
content: '';
position: absolute;
top: 21px; /* play with this for alignment */
right: -36px; /* play with this for alignment */
height: 40px; width: 70px; /* may need to adjust these depending on container size */
background-color: #fcfcfc;
transform: rotate(60deg); /* to adjust angle */
z-index: -1; /* puts the pseudo element ::before below .salutations */
}
<div class="container">
<div class="salutations">Hello</div>
</div>
P.S. May have to adjust a pixel or two, my eyes suck.
Browser Compatability
transform: rotate
pseudo elements (::before)
Fiddle
https://jsfiddle.net/Hastig/wy5bjxg3/
It is most likely it is an SVG scaled to always fit its text which is simple and quick way of doing it; if you must use CSS then you could always:
Set a gradient to the div from color to transparent so that it takes up most of the div and the transition of color is abrupt and not smooth like how a normal gradient looks.
create another div and using borders create a triangle to touch the other main rectangular div such as doing:
.triangle {
width: 0;
height: 0;
border-style: solid;
border-width: 200px 200px 0 0;
border-color: #fff transparent transparent transparent;
}
Using css you can generate an element that takes the shape of a triangle.
Css tricks has a post on that.
By making the .slanted class position itself relative, we can position the generated content on the right side of the slanted div using absolute positioning.
It'll take some fiddling to get the perfect result you want, but here's an example.
.slanted{
background: #007bff;
color: #fff;
position: relative;
display:inline-block;
font-size: 20px;
height: 25px;
padding: 2px 4px;
}
.slanted::after {
content: " ";
display: block;
width: 0;
height: 0;
border-style: solid;
border-width: 29px 0 0 20px;
border-color: transparent transparent transparent #007bff;
position: absolute;
top: 0;
right: -20px;
}
<div class="slanted">Hello</div>

Offset border effect in pure css

I am trying to create an offset border effect. Can this be done with pure css.
These are buttons so will be different sizes and colours.
I use pseudo-element :after to create offset border effect.
body {
background: black;
padding: 30px;
}
div {
background: white;
height: 75px;
width: 175px;
position: relative;
}
div:after {
content: '';
background: transparent;
border: 1px solid white;
top: 7px;
right: 7px;
bottom: -7px;
left: -7px;
position: absolute;
z-index: -1;
}
<div></div>
Update
As web-tiki pointed out in comments on this answer, you can achieve the entire affect entirely with box-shadow. Take a look at their JSFiddle demo here: https://jsfiddle.net/5a0bvyup.
I'm going to leave my answer in the state I submitted it in because it does give some idea of how their implementation works (and if you look closely you'll see how their box-shadow differs from the one described below).
Note: In my answer I've made the foreground box red instead of white to demonstrate that this 'offset border' does not overlap the initial element. You'll need to change this back to white yourself.
The Left and Bottom Borders
You can achieve the left and bottom borders really easily with box-shadow. You simply need to create a solid shadow which matches the background colour, and then behind that add a second shadow which matches the foreground colour, offset by one pixel:
body {
background: black;
padding: 30px;
}
div {
background: red;
height: 72px;
width: 192px;
box-shadow: -2px 2px 0 5px black, -7px 7px 0 1px white;
}
<div></div>
The Top and Right Borders
You can then use pseudo-elements (::before and ::after) to fill in those extra borders:
body {
background: black;
padding: 30px;
}
div {
background: red;
height: 72px;
width: 192px;
box-shadow: -2px 2px 0 5px black, -7px 7px 0 1px white;
position: relative;
}
div::before {
background: white;
content: '';
position: absolute;
height: 1px;
width: 7px;
top: 6px;
right: 100%;
}
div::after {
background: white;
content: '';
position: absolute;
height: 7px;
width: 1px;
top: 100%;
right: 6px;
}
<div></div>

Altering one element's position with the hover state of another

I have a css triangle positioned under one of two buttons that indicates the text below it is associated with that button. When I hover over the button next to it, I would like to move that triangle to under the second button.
My triangle is a an empty div with the following styling:
.nubbin {
width: 0;
height: 0;
border-left: 2em solid transparent;
border-right: 2em solid transparent;
border-bottom: 2em solid #435C6E;
margin-left: calc(50% - 10em);
}
My buttons have classes of, "report and class". What I've tried is:
.chat:hover~.nubbing {
margin-left: calc(50% + 10em);
}
and
.chat:hover+.nubbing {
margin-left: calc(50% + 10em);
}
What am I doing wrong?
Like ralph.m mentions, you're better off the using ::after pseudo element.
Check out this example:
http://jsfiddle.net/scottmey/PhZ7x/2/
Hopefully this points you in the right direction.
.comment {
position: relative;
display: inline-block;
width: 620px;
vertical-align: top;
padding: 3px 10px;
background: #435C6E;
margin-bottom: 15px;
margin-left: 10px;
}
.comment:hover:after {
content: "";
position: absolute;
top: 5px;
left: -15px;
border-style: solid;
border-width: 10px 15px 10px 0;
border-color: transparent #435C6E;
display: block;
width: 0;
z-index: 1;
}

Avoid Border Overlap CSS

This is a simple question, I even think someone asked this before, but It never got a real answer.
What I want is to avoid border overlapping, It's that simple. Here's an example:
div{
width: 400px;
height: 150px;
border: 1px solid red;
border-bottom: 7px solid black;
}
You can see that the borders overlap in the corner.
Here's the live example: jsFiddle Example
What I really want to do is to make the bottom border cover the right and left border.
Can someone tell me what can I do here?
You can overlay a pseudo element over your div:
div {
background-color: gold;
border-top: 4px solid #172e4e;
height: 100px;
position: relative;
width: 100px;
}
div::after {
content: "";
position: absolute;
bottom: 0; top: 0px; left: 0; right: 0;
border-right:4px solid orange;
border-left:4px solid orange;
}
Example: http://jsfiddle.net/vpHW5/10/

How to make a box with arrow in CSS?

How to make a box with arrow in CSS?
Making round corner is easy. but any idea to make the arrow on left side without using image.
Is it possible to make possible with
only one elements <p>....</p>
body {
background: #ff004e;
padding: 40px
}
p {
background: white;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
width: 250px;
height: 150px
}
<p></p>
Like this :
.arrow {
border: solid 10px transparent;
border-right-color: #FFF;
}
Demo : http://jsfiddle.net/sparkup/edjdxjf2/
UPDATE :
It can also be achieved without empty elements with the css property :before
element:before {
content: "";
position: absolute;
top: 50%; // half way down (vertical center).
margin-top: -15px; // adjust position, arrow has a height of 30px.
left:-30px;
border: solid 15px transparent;
border-right-color: #FFF;
z-index: 1;
}
Demo : http://jsfiddle.net/sparkup/y89f1te0/
hope it helps
Chris Coyier has an excellent roundup of the possible shapes built in CSS using a single element (and before/afters):
http://css-tricks.com/examples/ShapesOfCSS/
Standard Tool-tip
If you want a simple arrow, then you can add a pseudo element with border-right.
body {
background:#ff004e;
padding:40px;
}
p {
background:white;
border-radius: 10px;
width:250px;
height:150px;
position: relative;
display: inline-block;
}
p:before {
content:"";
position: absolute;
height: 0px;
width: 0px;
top: 60px;
left: -29px; /* 1px buffer for zooming problems while rendering*/
border-width: 15px;
border-color: transparent white transparent transparent;
border-style: solid;
}
<p></p>
FIDDLE 1
Flat edge Tool-tip
If you want a flat edge for arrow, try this :
body {
background: #ff004e;
padding:40px;
}
p {
background:white;
border-radius: 10px;
width:250px;
height:150px;
position: relative;
display: inline-block;
}
p:before {
content:"";
position: absolute;
height: 45px;
width: 16px; /* 1px buffer for zooming problems while rendering*/
top: 50px;
left: -15px;
background: white;
}
p:after {
content:"";
position: absolute;
height: 40px;
width: 15px;
border-radius: 0 40px 40px 0;
top: 75px;
left: -15px;
background: #ff004e;
box-shadow: 0 -45px 0 0 #ff004e;
}
<p></p>
FIDDLE 2
Use this online tool and you can do it without typing lot of code
http://www.cssarrowplease.com
My answer (with no flat edge),
added some calculation formula:
.mainBox {
border: solid 1px #e0e0e0;
}
.mainBox:before {
content:"";
position: absolute;
/*The right value must be calculated with: (top value of after) - (top value of before) = (right value of before) */
/*example: (-4px) - (-7px) = 3px*/
right: 72px;
/*The `top` value must be identical to border-width*/
top: -7px;
width: 0;
height: 0;
border-style: solid;
/*The `border-width` value must be identical to top*/
border-width: 0 7px 7px 7px;
/*The border color 3rd (#e0e0e0) value must be identical to its parent border color*/
border-color: transparent transparent #e0e0e0 transparent;
/*The (z-index of before) must at least one below the (z-index of after)*/
/*Example: (z-index of before) < (z-index of after) or 9998 < 9999*/
z-index:9998;
}
.mainBox:after {
content:"";
position: absolute;
right: 75px;
top: -4px; /*suppose to be identical to border-width*/
width: 0;
height: 0;
border-style: solid;
border-width: 0 4px 4px 4px;
border-color: transparent transparent #fff transparent;
z-index:9999;
}
The basic rules are:
The before right value must be calculated with:
(after's top) - (before's top) = (before's right)
example: (-4px) - (-7px) = 3px
The before and after's top value must be identical to border-width.
The border color 3rd (#e0e0e0 in the example) value must be identical to its parent border color.
The before's z-index must at least one below the after's z-index.
example: (before's z-index) < (after's z-index) or 9998 < 9999.
The result:
a.right{ border-style: dashed;
border-color: transparent;
border-width: 0.53em;
display: -moz-inline-box;
display: inline-block;
font-size: 100px;
height: 0;
line-height: 0;
position: relative;
vertical-align: middle;
width: 0; border-left-width: 1em;
border-left-style: solid;
border-left-color: #666;
left: 0.25em; }
the above code can be used for right arrow.
You can make use of span if u don't want to use a div.
span#pointer{border:solid 10px transparent;border-right-color:#fff;position:absolute;margin:-85px 0 0 -20px;}
http://jsfiddle.net/SSKwn/

Resources