css3 arrow with drop shadow - html

Hey currently I have this css to produce a css arrow but I cannot seem to get a drop shadow on it any ideas
.arrow {
width: 0px;
height: 0px;
border-style: solid inset;
border-width: 10px 78px 0 78px;
border-color: #000 transparent transparent transparent;
z-index: 1;
}
I have dabbled with :after and :before but with no success

Since your arrow is going to be placed under a solid rectangle, this can help you
.demo {
position: absolute;
top: 50px;
left: 0px;
width: 200px;
height: 50px;
clip: rect(0px 400px 100px 0px);
}
.demo:after {
content: "";
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: black;
-webkit-transform: translate(-90px, -45px) skew(80deg) rotate(-5deg);
-moz-transform: translate(-90px, -45px) skew(80deg) rotate(-5deg);
transform: translate(-90px, -45px) skew(80deg) rotate(-5deg);
box-shadow: 30px 1px 6px blue;
}
fiddle compared with your original arrow
The problem is that the shadow can not go upwards, but usually this design wouldn't need that anyway.
Also, the base div is highly distorted, so you will need to set the shadow by trial and error.

http://css-tricks.com/triangle-with-shadow/
I think that's what you're looking for, it explains two methods to get a shadow on arrows with CSS.
One is to use a unicode triangle character and apply a shadow to that, the other is using CSS trickery with the :after selector and CSS transform.

Related

Center text over a responsive triangle?

I have to center text on top of (or inside of) a triangle, which is bleeding off the right side. Ideally I'd like it to be responsive, but all I could get to work was fixed pixel widths/margins on both the triangle and the content. Like so:
View my Demo
.triangle-down:after {
content: "";
border-style: solid;
position: absolute;
right: 0;
top: 0;
margin-left: -450px;
border-width: 550px 450px 0 450px;
border-color: red transparent transparent transparent;
}
You can see what I'm trying to accomplish better if you look at it wider than 960px. (It will just be a red rectangle below 768px.) I suppose I can work with this if there's no other choice because I can make sure the text inside the triangle will always be roughly the same word count.
But is there a better way to accomplish this layout in a responsive design without having to use fixed pixels?
Use this,
Html code :
<div class="up">
<p>some information text goes here<p>
</div>
Css code :
.up {
width: 0px;
height: 0px;
border-style: inset;
border-width: 0 100px 173.2px 100px;
border-color: transparent transparent #007bff transparent;
float: left;
transform:rotate(360deg);
-ms-transform:rotate(360deg);
-moz-transform:rotate(360deg);
-webkit-transform:rotate(360deg);
-o-transform:rotate(360deg);
}
.up p {
text-align: center;
top: 80px;
left: -47px;
position: relative;
width: 93px;
height: 93px;
margin: 0px;
}
Working Demo is here :
http://jsfiddle.net/markus85/TRuQc/

Applying a mock bottom-border to a rotated div

I'm currently using the CSS3 rotate value to give the appearance of an arrowhead for modal boxes. I'm now in a situation where I need to create an full arrowhead with a bottom border. Since this is just a div that's rotated at a 45° angle, applying another border to either of the two sides wouldn't solve the problem.
My first thought was to apply some styling the div's :after pseudo selector and vertically center it. For some reason though it's inheriting the rotate value. I've tried setting the value to none and tried to manually adjusting the rotation angle but to no avail. Any idea on how to get this border to reset horizontally straight?
Through Harry's suggestion I set the angle of the :after selector to -45deg and top value to 50%. The only problem now is that it doesn't fully expand to the left and right of the div. Any ideas?
.arrow {
background-color: transparent;
border-top: 2px solid #c7c7c7;
border-left: 2px solid #c7c7c7;
position: relative;
height: 18px;
width: 18px;
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.arrow:after {
content: "";
background: #c7c7c7;
display: inline-block;
position: absolute;
top: 50%;
height: 2px;
width: 100%;
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
<div class="arrow"></div>
Using CSS Transforms:
You can create a full arrowhead with bottom border using the approach adopted in the below snippet. Here, the arrowhead is created by the :after element while the line at the bottom is created using the parent container. The rotation axis is fixed using the same transform-origin for parent & child.
The shape created using this approach should be able to adapt itself to all dimensions without needing any tweaks to the positioning (hover the arrow in snippet to see it in action).
.arrow {
position: relative;
height: 25px;
width: 25px;
border-bottom: 2px solid #c7c7c7;
}
.arrow:after {
position: absolute;
content: "";
bottom: -1px; /* half of border top */
left: -2px; /* equal to border left */
height: calc(100% / 1.414); /* division by 1.414 because parent has to be larger */
width: calc(100% / 1.414);
border-top: 2px solid #c7c7c7;
border-left: 2px solid #c7c7c7;
transform-origin: left bottom;
transform: rotate(45deg);
}
/* Just for demo */
.arrow { transition: all 1s; }
.arrow:hover { height: 50px; width: 50px; }
<div class="arrow"></div>
Using SVG:
You could also have a look at using SVG for creating such shapes because it is much more easier to do so and the output is also responsive. All we need is one path element which creates the shape by connecting the coordinates provided within the d attribute. The M command moves the pen to the specified coordinate whereas the L command draws line from the previous point to the one specified after the command.
svg {
width: 25px;
height: 18px;
}
path {
stroke: #c7c7c7;
stroke-width: 2;
fill: transparent;
}
/* Just for demo */
svg{ transition: all 1s; }
svg:hover{ width: 50px; height: 36px; }
<svg viewBox='0 0 50 50' preserveAspectRatio='none'>
<path id='arrowhead' d='M0,48 L25,2 50,48z' vector-effect='non-scaling-stroke'/>
</svg>
Using Gradients:
The below approach using linear-gradient which would also work and would require only a single element but it has lesser browser support and is suited only for fixed size containers. Because the gradients use percentage values, bottom border tends to get thicker as container's dimensions change (thus rendering it useless for responsive designs).
.arrow {
position: relative;
height: 18px;
width: 18px;
border-top: 2px solid #c7c7c7;
border-left: 2px solid #c7c7c7;
background: linear-gradient(to left top, transparent 50%, #c7c7c7 50%, #c7c7c7 60%, transparent 60%);
transform: rotate(45deg);
}
/* Just for demo */
.arrow { transition: all 1s; }
.arrow:hover { height: 50px; width: 50px; }
<div class="arrow"></div>

Why does IE apply opacity to border-style: dotted?

The title says it all, I've just discovered that IE (9 - 11) automatically applies about 50% opacity to any element's border with border-style: dotted.
The weirdest thing is, it only happens on dotted in particular, solid and dashed are fine.
You can test it yourself: http://jsfiddle.net/ptv74f4q/1/
Any ideas?
This appears to be due to IE anti-aliasing the dotted border. If you make the border-width bigger than 1px (say 5px) the border will appear white again.
One way to get around this would be to overlay some pseudo elements with the same dotted border on top to counteract the opacity:
div {
width: 200px;
height: 200px;
background: #000;
}
span {
transform: rotate(0deg);
display: inline-block;
width: 180px;
height: 85px;
line-height: 85px;
text-align: center;
margin: 8px 8px 0 8px;
border: #fff 1px solid;
color: #fff;
position: relative;
}
span.dotted {
border-style: dotted;
}
span.dotted::before, span.dotted::after {
border: #fff 1px dotted;
content: "";
height: 100%;
left: -1px;
position: absolute;
top: -1px;
width: 100%;
}
<div>
<span>I'm with normal border</span>
<span class="dotted">I'm with dotted border</span>
</div>
JS Fiddle: http://jsfiddle.net/oyrbLyjc/1/
Alternative method
Alternatively you could try using border-image. There are online tools (e.g. https://developer.mozilla.org/en-US/docs/Web/CSS/Tools/Border-image_generator) that would be able to help you generate a similar border using this method.

CSS Shapes with only a Border

I have found information on how to create various shapes, such as trapezoids and hearts, using only CSS; however, they are solid shapes. Is there a way to create a shape, such as a trapezoid, that is transparent and only displays an outline/border?
By making two shapes and overlapping them, with one larger than the other, it is possible to make it appear to have this effect, but that would only work if the background behind the shape is a solid color, which may not always be the case. Thus the reason for the transparency.
For examples of the CSS shapes: link; look at the triangles, for example.
Thank you.
This is usually done with border tricks, and those are not really helpful for this
You need others techniques for that.
For instance, see this CSS
body {
background: linear-gradient(90deg, lightblue, yellow)
}
.trapezoid {
left: 50px;
top: 50px;
position: absolute;
height: 100px;
width: 500px;
background-color: transparent;
}
.trapezoid:before {
content: '';
width: 57%;
height: 100%;
left: -4%;
position: absolute;
border-color: red;
border-style: solid;
border-width: 3px 0px 3px 3px;
-webkit-transform: skewX(-20deg);
}
.trapezoid:after {
content: '';
width: 59%;
height: 100%;
right: -4%;
position: absolute;
border-color: red;
border-style: solid;
border-width: 3px 3px 3px 0px;
-webkit-transform: skewX(20deg);
}
fiddle
The base element has the background transparent, as per your request. I have set a gradient in the body to verify it.
The you add 2 pseudo elements, that have the borders set (except the inner one), and that are skewed to achieve the trapezoid
You can set background color to transparent
background-color: transparent;
The way that these shapes are typically done in css is through border manipulation. When you have a transparent trapezoid it's just a rectangle with the sides lopped off by a border. Because of this, there is no way to use a uniform border and maintain the same shape.
What's your current code look like? You should just be able to add a border to it and no background color. Example: http://jsfiddle.net/tBBkg/
Overlapping transparent shapes (with border):
#square {
width: 140px;
height: 140px;
border: 2px solid blue;
position: absolute;
}
#circle {
position: absolute;
height: 100px;
width: 100px;
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
border-radius: 50px;
border: 2px solid pink;
}
Perhaps I'm not understanding the question properly, in which case could you clarify?

Dynamic shapes with CSS

I'm working on a creative project whereby I want to add 'triangles' to box elements to get a speech bubble effect and still apply an opacity to each element as shown below:
I can get the blocks to display correctly with a 1px boarder on the right and bottom of each element. This, however, does not include the arrows on the heading element. When I add the arrows, using .heading:before, the result is as shown below:
As you can see, the original border remains, breaking the arrow and its corresponding element.
My HTML is as follows:
<li class="heading">
<div class="text_contain_head">
<h1>Heading</h1><p>Subheading</p>
</div>
</li>
<li class="options">
<div class="text_contain">
<h2>Option 1</h2><p>Description</p>
</div>
</li>
<li class="options">
<div class="text_contain">
<h2>Option 2</h2><p>Description</p>
</div>
</li>
<li class="options">
<div class="text_contain">
<h2>Option 3</h2><p>Description</p>
</div>
</li>
<li class="options">
<div class="text_contain">
<h2>Option 4</h2><p>Description</p>
</div>
</li>
and here's the CSS for .options:
.options {
position: relative;
padding-bottom: 25%;
height: 0;
width: 25%;
background-color: rgba(0, 0, 0, 0.25);
border-right: 1px solid #FFF;
border-bottom: 1px solid #FFF;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
float: left;
}
and here's the CSS for .heading:
.heading {
position: relative;
padding-bottom: 25%;
width: 75%;
background-color: rgba(0, 0, 0, 0.6);
border-right: 1px solid #FFF;
border-bottom: 1px solid #FFF;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding-left: 40px;
padding-right: 40px;
float:left;
}
.heading:before {
content: "\0020";
display: block;
border: solid 20px transparent;
border-right-color: rgba(0, 0, 0, 0.6);
position: absolute;
top: 50%;
right: -40px;
margin-top: -20px;
z-index: 1002;
transform:scale(1,1.5);
-ms-transform:scale(1,1.5);
-webkit-transform:scale(1,1.5);
}
P.S. I use :after to add a white triangle with a 1px offset underneath the :before to replicate the border around the triangles.
In the end, I want to be able to keep the elements' opacities (due to the background image) and still be able to 'remove' the original border where the arrows overlap.
I'm stumped, as such any and all advice would be most apreciated
here is a jsfiddle of what I have so far: http://jsfiddle.net/N2nZ6/1/
I have put up a fiddle of my own: http://jsfiddle.net/Pevara/8WBcQ/
It was not easy, but i think i got away with it, but with some limitations:
- I had to add two empty nodes inside your .heading for the arrows. I know it isn't pretty, but I tried without them and just couldn't get it to work.
- I had to set a fixed width. It might be possible to do with percentages, but as it requiers very exact positioning, I did not even try... (percentages and exact postioning are a no go in my experience)
How does it work:
- I turn the extra nodes into a square and rotate them 45deg to make them look like an arrow point
- I position them absolute over the edge of the .heading, to cover up the border.
- I set them to overflow hidden to prevent the :after and :before overflowing
- I set the background image on the :before, counter rotate 45deg, and position exactly to line up with the background image of the ul
- I add another :after with a the same semi-transparent background color as the .heading to make the backgrounds match exactly.
It is not exactly clean, and it will take some fiddling with the positioning, but it works (in chrome, other browsers might need some prefixes). I don't dare to look at the result in older IE's. Might not be useable in a real life website, but as a proof of concept...
In real life I would probably go for a sprite image with the borders and arrows already in place, and position the li's on top of them.
And because SO insists, here is a part of the css:
.arrow-down {
position: absolute;
display: block;
overflow: hidden;
width: 50px;
height: 50px;
-webkit-transform: rotate(45deg);
top: 200px;
left: 300px;
background-color: rgba(0, 0, 0, .5);
margin-left: -25px;
z-index: 5;
border: 1px solid #fff;
border-left: none;
border-top: none;
}
.arrow-down:after {
content:' ';
display: block;
width: 300px;
height: 300px;
-webkit-transform: rotate(-45deg);
background-repeat: no-repeat;
background-image: url(http://www.placekitten.com/900/600);
background-position: -114px -77px;
z-index: 1;
position: absolute;
top: -100px;
left: -150px;
}
.arrow-down:before {
content:'';
background-color: rgba(0, 0, 0, .5);
z-index: 2;
position: absolute;
top: -5px;
left: -5px;
bottom: -5px;
right: -5px;
}
I think that achieving this effect is a bit complicated which can be done by making the triangle opaque and keeping the same background image(using appropriate position) for the triangles which would cover the border.