CSS to create arrowhead aligned with arrow body - css

I need to draw a lot of precisely positioned horizontal arrows that point either left, right, or both. I don't want to use HTML canvas. it will all be done dynamically with JQuery, but the css parameters will be the roughly the same as below, including arrowhead size and arrow thickness.
This code works pretty well...
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style >
.ArrowHead {
position: absolute;
width: 0;
height: 0;
border-top: 4px solid transparent;
border-bottom: 5px solid transparent;
border-right: 12px solid black;
top:46px;left:52px;
}
.Arrow {
border-top:solid 1px black;
position: absolute;
top:50px;left:50px;
width:100px;height:1px
}
</style>
</head>
<body>
<div id="Arrow" class="Arrow"></div>
<div id="ArrowHead" class="ArrowHead"></div>
</body>
</html>
...but the tip of the arrowhead is slightly above the body of the arrow, and it just looks aligned properly on the right of the arrowhead because the bottom of the arrowhead is larger than the top (easier to see at 400%). Nice illusion, however, I was hoping to find out if there was some way that the arrowhead could be vertically symmetric and still be lined up exactly horizontally with the arrow body.

You won't be able to center the arrow vertically while the line is 1px in height, as you can't measure in half pixels. If you are willing to increase the line's width to two pixels, it's easy, though. It's also better to position the arrow heads relative to the line rather than to the viewport (using relative/absolute positioning). E.g.
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
.arrow {
background: black;
width:100px;
height:2px;
position: relative;
}
.arrow::before {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-right: 12px solid black;
top:-4px;
left:-3px;
}
.arrow::after {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 12px solid black;
top:-4px;
right:-3px;
}
</style>
</head>
<body>
<div class="arrow"></div>
</body>
</html>

Related

Border bottom to Display Under Side Borders

Ok, so for the sake of argument i have a box with a grey left and right border with an 8 pixel border bottom with a different colour.
The way borders display is showing the bottom border inside the left and right border. Ive done some research but i cannot find a way that is possible for the bottom border to display under the side borders as apposed to inside them. Sorry if i have not explained this too well please feel free to ask if you need any more information. Please follow the link below to a quick fiddle i have created.
<div class="bg">
<div class="box">
Box
</div>
</div>
.bg {
background-color: #fff;
width: 72%;
float: left;
height: 100%;
padding: 100px;
}
.box {
background-color: #fff;
height: 200px;
width: 200px;
float: left;
margin-left: 100px;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
border-bottom: 8px solid black;
}
http://jsfiddle.net/L06s4k50/
Thanks in advance people.
I think the best way of going about this is to forgo the border-bottom completely, and instead use a box-shadow property:
.box {
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
box-shadow: 0px 8px black;
}

Box with darkened corners without using images

Is it possible to recreate a box like this without using background images and only one element?
Ideally, I'd be able to control which corners are darkened by adding a class, so the above image might be class="box dark-top dark-left dark-bottom dark-right". I can darken two by using :before and :after, but am having problems thinking of a good way to darken three or four corners without adding additional markup.
Here's a way to darken all four corners with one element, though I haven't figured out how to darken specific corners yet. But my theory was to have the original border as the dark border, and then /lighten/ the sides of the box with pseudo-elements.
Fiddle: http://jsfiddle.net/KZSLH/
.box {width:236px; height:236px; border:1px solid #333; position:relative;}
.box:before {content:""; display:block; width:200px; height:236px; position:absolute; top:-1px; left:18px; border-top:1px solid #ccc; border-bottom:1px solid #ccc;}
.box:after {content:""; display:block; width:236px; height:200px; position:absolute; top:18px; left:-1px; border-left:1px solid #ccc; border-right:1px solid #ccc;}
It's far from perfect, but this is the only way I could think of to do something like that... You'll want to play around with the border thickness, border radius and which borders are rounded to really have it suit your needs
The only thing I couldn't figure out is how to get the edges of the corners to be sharp rather than tapering off... Maybe someone could contribute that part?
First, start off with two overlapping div elements:
<div id="thick" />
<div id="thin" />
Then, use rounded corners and relative positioning to taper off and create the "bold" corners.
#thick {
position:absolute;
top:50px;
left:50px;
height:100px;
width:100px;
background-color:white;
border:3px solid black;
}
#thin {
position:relative;
top:-2px;
left:-2px;
height:104px;
width:104px;
background-color:white;
border-radius: 15px;
}
Here is a fiddle: http://jsfiddle.net/bGrdA/
And credit to this post for giving me the idea.
I think I figured it out. The key is that there must be content inside of the box in it's own element, which will always be the case my scenario.
Example: http://jsfiddle.net/n7pgP/
The classes that can be added to the box are:
dtl = darken top left
dtr = darken top right
dbl = darken bottom left
dbr = darken bottom right
Some thing this can be tried out for two elements
http://jsfiddle.net/V8jmR/
#content {position:relative;width:400px;height:300px;}
#content:before, #content:after, #content>:first-child:before, #content>:first-child:after {
position:absolute;
width:80px; height: 80px;
border-color:red; /* or whatever colour */
border-style:solid; /* or whatever style */
content: ' ';
}
#content:before {top:0;left:0;border-width: 1px 0 0 1px}
#content:after {top:0;right:0;border-width: 1px 1px 0 0}
#content>:first-child:before {bottom:0;right:0;border-width: 0 1px 1px 0}
#content>:first-child:after {bottom:0;left:0;border-width: 0 0 1px 1px}
Original answer
CSS - show only corner border
The only possibility I know is in using additional elements:
<div class="box">
<span class="darkTopLeft"></span>
<span class="darkTopRight"></span>
<span class="darkBottomLeft"></span>
<span class="darkBottomRight"></span>
</div>
.box {
background-color: #fff;
border: 1px solid #ccc;
height: 100px;
position: relative;
width: 100px;
}
.box > span {
height: 10px;
position: absolute;
width: 10px;
}
.darkTopLeft {
border-left: 1px solid #000;
border-top: 1px solid #000;
left: -1px;
top: -1px;
}
.darkTopRight {
border-right: 1px solid #000;
border-top: 1px solid #000;
right: -1px;
top: -1px;
}
.darkBottomLeft {
bottom: -1px;
border-bottom: 1px solid #000;
border-left: 1px solid #000;
left: -1px;
}
.darkBottomRight {
bottom: -1px;
border-bottom: 1px solid #000;
border-right: 1px solid #000;
right: -1px;
}
http://jsfiddle.net/cM7xU/

How can I set a specific border around an element?

I want to put a specific border like below around my element.
How can I do this with css.
I use this css for showing a border around an element:
.ui-selected {
-moz-box-shadow: 0 0 1px 1px black;
-webkit-box-shadow: 0 0 1px 1px black;
box-shadow: 0 0 1px 1px black;
}
But I want to show border like in the image. Is this possible?
I want to put those eight square around an element.
I use $('#element').addClass('ui-selected') to add
and $('#element').removeClass('ui-selected') to remove.
I want css classes, is it possible
Here is the solution:
box-shadow: 2px 2px 1px 0 #666;
border-top: 1px solid white;
border-left: 1px solid white;
You can see on JSFiddle.
You can specify a different colour for each side, using the border-(top|lef|right|bottom)-color property to add the highlights/shadows. The corners will be mitred accordingly.
Border-top-color
You may then try to use individual CSS3 border images placed at the corners to acheive the black squares.
border images
For the drag handles: although you could place them there with CSS, you would not be able to attach event handlers to them, nor change the mouse cursor when it goes over them.
To get both of these, you need the dots to be actual elements. See this example for one way to position corner elements. Cached for StackOverflow posterity (in the unlikely event that my site is down):
<html lang="en"><head>
<title>Positioning Images</title>
<style type="text/css">
.compass { position:relative }
.compass .north,
.compass .south,
.compass .east,
.compass .west,
.compass .center { width:15px; height:15px; position:absolute; left:50%; margin-left:-8px; top:50%; margin-top:-8px; cursor:pointer }
.compass .north { top:0; margin-top:0 }
.compass .south { bottom:0; top:auto; margin-top:0 }
.compass .east { right:0; left:auto; margin-left:0 }
.compass .west { left:0; margin-left:0 }
</style>
</head><body>
<div class="compass">
<!-- your element here -->
<img class="north west" src="c1.png" alt="resize">
<img class="north east" src="c2.png" alt="resize">
<img class="south east" src="c3.png" alt="resize">
<img class="south west" src="c4.png" alt="resize">
<img class="north" src="up.png" alt="resize">
<img class="south" src="dn.png" alt="resize">
<img class="east" src="rt.png" alt="resize">
<img class="west" src="lt.png" alt="resize">
</div>
</body></html>
You could experiment with pseudo elements:
div:after {
content: '\25A0\25A0\25A0 \25A0\25A0\25A0 \25A0\25A0\25A0';
position: absolute;
top: -37px;
left: -5px;
width: 100%;
height: 100%;
text-align: center;
line-height: 75px;
letter-spacing: 67px;
}
​This looks good in Webkit, and is a few pixels off in Firefox.
Demo

CSS Border Meeting point

I am hoping someone can help me with a css problem...
I am using a listview to display some results, there is required to be a concept of grouping, to achieve this i am using 2 background colors alternating between groups. I am trying to add a border to these elements, but as the border-top and the border-left may be different colors, is there any way of removing the triangle where they meet?
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
p
{
border-top:10px solid red;
border-left:10px solid white;
border-bottom-style:dotted;
border-left-style:solid;
}
</style>
</head>
<body>
<p>2 different border styles.</p>
</body>
</html>
You can write like this:
p{
width:200px;
height:200px;
background:red;
border-left:5px solid pink;
-moz-box-shadow:inset 0 5px green;
box-shadow:inset 0 5px green;
}
Check this http://jsfiddle.net/nRWux/1/
box-shaow not work in IE8 & below.
Here's a solution compatible with IE8+ using :before pseudo:
Fiddle http://jsfiddle.net/PhilippeVay/hXrW5/
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
p {
position: relative;
border-top:10px solid red;
border-bottom-style:dotted;
border-left-style:none;
}
p:before {
content: '';
display: block;
width: 10px;
position: absolute;
top: -10px; /* top: 0; if you want red over blue (top over left) */
bottom: 0;
background: blue;
}
</style>
</head>
<body>
<p>2 different border styles.</p>
</body>
</html>
You can use box-shadow for the border-top,
In your example: http://jsfiddle.net/C7jnJ/
margin-top:10px;
box-shadow:0 -10px 0 10px red;
Instead of border-top. The margin-top is added because the shadow is displaying outside the 'p', If you would like it inside, then it would be: http://jsfiddle.net/C7jnJ/1/
box-shadow:inset 0px 10px 0px red;
No, it is not possible to remove the triangle where they meet. borders are implemented that way and there is no way around.

:after pseudoclass on IE7

I have this code, that shows a little triangle using pure CSS, and it works on all modern browsers, including IE8-IE9:
<html>
<head>
<style>
.arrow:after {
display: inline-block;
width: 0;
height: 0;
margin: 4px 0 0 4px;
vertical-align: top;
text-indent:-9999px;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid black;
content: "↓";
}
</style>
</head>
<body>
<div class="arrow">testing</div>
</body>
</html>
The problem is that it is not working on IE7, it just does not display the arrow.
I have seen people suggesting to use ie8.js, but it doesn't work either.
Does anyone know how to make it work on IE7?
Yes, this is possible in IE7 without the use of JS plugins. Don't let the naysayers fool you. Here's your updated code:
<html>
<head>
<style type="text/css">
.arrow:after {
display: inline-block;
width: 0;
height: 0;
margin: 4px 0 0 4px;
vertical-align: top;
text-indent:-9999px;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid black;
content: "↓";
}
.arrow {*zoom: expression( this.runtimeStyle.zoom="1", this.appendChild( document.createElement("i")).className="ie-after" );}
.arrow .ie-after {*zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '↓');}
</style>
</head>
<body>
<span class="arrow">testing</span>
</body>
</html>​
style .arrow in conditional comments specifically for ie7. ie7 doesn't understand :after,:before,:content or display:inline-block for that matter. without looking at the site, it's hard to offer a solid fix. offhand, i'd make it display:block; with a text-indent and use background-image.
Have you tried using CSS3Pie
http://css3pie.com/
http://code.google.com/p/ie7-js/ project claims support for :after, :before and content. You would use the IE8.js part of it.
Test page: http://ie7-js.googlecode.com/svn/test/index.html

Resources