relative css only speech bubble - css

I am using this code to generate a css only speech bubble :-
li.selected{
background-color: blue;
a{
color: white;
}
}
li.selected:after{
content: "";
position: absolute;
top: 33%;
left: 390px;
border-top: 10px solid transparent;
// border-top-color: inherit;
border-left: 10px solid blue;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
}
While this works fine, the triangle gets left when I move to the next li item as it has got a fixed position, how do I move the triangle as well?
here is my html code :-
<ul>
<li class='selected'>
Credits
</li>
<div class='line-separator'></div>
<li>
Change Password
</li>
<div class='line-separator'></div>
<li>
Investor Status
</li>
</ul>

Instead of using position:absolute to the arrow, you need to change it to relative position so that the arrow would position itself relatively to the .selected menu item.
See the demo here.
Note: Replace the :hover selector with the .selected class.

you have useful this css
/* Bubble with an isoceles triangle
------------------------------------------ */
.triangle-isosceles {
position:relative;
padding:15px;
margin:1em 0 3em;
color:#000;
background:#f3961c;
/* css3 */
-moz-border-radius:10px;
-webkit-border-radius:10px;
border-radius:10px;
background:-moz-linear-gradient(top, #f9d835, #f3961c);
background:linear-gradient(top, #f9d835, #f3961c);
}
/* creates triangle */
.triangle-isosceles:after {
content:"";
display:block; /* reduce the damage in FF3.0 */
position:absolute;
bottom:-15px;
left:50px;
width:0;
border-width:15px 15px 0;
border-style:solid;
border-color:#f3961c transparent;
}

Related

How do I make an arrow with curved edges

I used border-radius but it doesn't make all the edges round. I want to make a down angle arrow.
.drop-arrow {
border: solid #FFDD00;
border-width: 0px 20px 20px 0;
display: inline-block;
padding: 40px;
transform: rotate(45deg);
}
<span class='drop-arrow'></span>
You can rely on pseudo element to curve all the edges:
.drop-arrow {
--b:20px; /* border-width */
border: solid #FFDD00;
border-width: 0px var(--b) var(--b) 0;
border-bottom-right-radius:var(--b);
display: inline-block;
padding: 40px;
transform: rotate(45deg);
margin:30px;
position:relative;
}
.drop-arrow::before,
.drop-arrow::after {
content:"";
position:absolute;
width:var(--b);
height:var(--b);
background:#FFDD00;
border-radius:50%;
}
.drop-arrow::before {
top:calc(-1*var(--b)/2);
right:0;
transform:translateX(100%);
}
.drop-arrow::after {
left:calc(-1*var(--b)/2);
bottom:0;
transform:translateY(100%);
}
<span class='drop-arrow'></span>
<span class='drop-arrow' style="--b:30px;"></span>
<span class='drop-arrow' style="--b:15px;"></span>
To add a rounded edge to the inside part, you can add a gradient coloration like below:
.drop-arrow {
--b:20px; /* border-width */
border: solid #FFDD00;
border-width: 0px var(--b) var(--b) 0;
border-bottom-right-radius:var(--b);
background:
radial-gradient(farthest-side at top left,transparent 98%,#FFDD00 100%)
bottom -0.5px right -0.5px/var(--b) var(--b) no-repeat;
display: inline-block;
padding: 40px;
transform: rotate(45deg);
margin:30px;
position:relative;
}
.drop-arrow::before,
.drop-arrow::after {
content:"";
position:absolute;
width:var(--b);
height:var(--b);
background:#FFDD00;
border-radius:50%;
}
.drop-arrow::before {
top:calc(-1*var(--b)/2);
right:0;
transform:translateX(100%);
}
.drop-arrow::after {
left:calc(-1*var(--b)/2);
bottom:0;
transform:translateY(100%);
}
<span class='drop-arrow'></span>
<span class='drop-arrow' style="--b:30px;"></span>
<span class='drop-arrow' style="--b:15px;"></span>
Your code looks like you are using a font-framework with the arrow integretated - maybe something like https://fontawesome.com/.
There is no arrow in your css described. Have a look at the font you are using to find the symbol.
To get another arrow, either the font needs to support another arrow or you'll have to use another font/build your own font.

Changing stacking order for CSS pseudo element

I am in the process of designing a 3 stage progress bar in pure CSS. My current effort is shown below.
#progBar
{
background-color:#bdbdbd;
padding:1.5vw;
position:relative;
height:9vw;
}
.progcapt
{
background-color: #526cfd;
color: transparent;
text-shadow: 0px 2px 3px #526cfd;
-webkit-background-clip:text;
font-family:'arial black';
font-size:3vw
}
#cOne
{
position:absolute;
left:calc(50% - 2.5vw);
top:calc(50% - 2.5vw);
border-radius:5vw;
height:5vw;
width:5vw;
border:1px solid #526cfd;
text-align:center;
display:flex;
align-items:center;
justify-content:center;
box-shadow:0px 0px 3vw #526cfd;
background-color:white;
}
#cOne::before
{
position:absolute;
width:50vw;
height:1vw;
background-color:rgba(82,108,253,0.5);
content:'';
/*z-index:-1; does not give the expected result*/
}
#cOneRing
{
position:absolute;
top:-calc(0.5vw + 1px);
left:-calc(0.5vw + 1px);
width:6vw;
height:6vw;
border:1px solid #526cfd;
border-radius:6vw;
}
<div id='progBar'>
<div id='cOne'>
<span class='progcapt'>1</span>
<div id='cOneRing'> </div>
</div>
</div>
The intent here is this
There will be three disc, one for each step
I am using the central disc as my "anchor"
Each disc is shown with an annular border which I create by absolutely positioning the disc and making the annulus its child.
The ::before pseudo-element for this anchor is used to create the track for the progress bar
The ensemble - the three circles and the track - are placed in an relatively positioned rectangular bar which acts as the background
The issue I have run into - I thought I would be able to send the track bar behind its parent disc element by setting its z-index attribute to -1. However, that simply causes it to disappear altogether. Clearly, I am doing something wrong here but I am unable to spot what that might be. Hopefully, someone here will be able to spot the error.
As far as I understood you need this
#progBar {z-index: -2;}
#cOne::after { z-index: -1;}
#progBar
{
z-index: -2;
background-color:#bdbdbd;
padding:1.5vw;
position:relative;
height:9vw;
}
.progcapt
{
background-color: #526cfd;
color: transparent;
text-shadow: 0px 2px 3px #526cfd;
-webkit-background-clip:text;
font-family:'arial black';
font-size:3vw
}
#cOne
{
position:absolute;
left:calc(50% - 2.5vw);
top:calc(50% - 2.5vw);
border-radius:5vw;
height:5vw;
width:5vw;
border:1px solid #526cfd;
text-align:center;
display:flex;
align-items:center;
justify-content:center;
box-shadow:0px 0px 3vw #526cfd;
background-color:white;
}
#cOne::before
{
position:absolute;
width:50vw;
height:1vw;
background-color:rgba(82,108,253,0.5);
content:'';
z-index:-1;
}
#cOneRing
{
position:absolute;
top:-calc(0.5vw + 1px);
left:-calc(0.5vw + 1px);
width:6vw;
height:6vw;
border:1px solid #526cfd;
border-radius:6vw;
}
<div id='progBar'>
<div id='cOne'>
<span class='progcapt'>1</span>
<div id='cOneRing'> </div>
</div>
</div>

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/

Arrow before and after a box with CSS

I'm trying to create in a single box, two arrows, one as a pointer and the other one into the box just behind.
Can not find the way to get the arrow right behind.
Someone can help me??
here i post the link with the sample: http://jsfiddle.net/7Esu2/
CSS:
.arrow {
width:210px;
height:40px;
background-color:#CBCBCB;
border: 1px solid #CBCBCB;
position:relative;
text-align:center;
font-size:20px;
font-weight:bold;
line-height:40px;
}
.arrow:after {
content:'';
position:absolute;
top:-1px;
left:210px;
width:0;
height:0;
border:21px solid transparent;
border-left:15px solid #CBCBCB;
}
.arrow:before {
content:'';
position:absolute;
top:-1px;
left:211px;
width:0;
height:0;
border:21px solid transparent;
border-left:15px solid #CBCBCB;
}
HTML:
<div class="arrow">
FLECHA
</div>
I prefer using inline-blocks over absolute positioning. Also, :before and :after create child elements (inside) the element you specify them on (at the beginning and end). For this, it would probably be best to have a wrapper (or inner) block, like so:
<div class="arrow">
<div class="inner-arrow">
FLECHA
</div>
</div>
Then the inner block is going to get most of the styling, as the wrapper is primarily there to contain the :before and :after. The wrapper (.arrow) needs to have font-size: 0 (or some other method to make the white-space around the inner block, .inner-arrow, go away).
.arrow {
font-size: 0;
}
.inner-arrow {
width:210px;
height:40px;
display: inline-block;
background-color:#CBCBCB;
text-align:center;
font-size:20px;
font-weight:bold;
line-height:40px;
vertical-align: middle;
}
Most of the styles for .arrow:before and .arrow:after will be the same, so we'll group those. Then specify the differences below (they have to be below to override the common styles).
.arrow:before,
.arrow:after {
content:'';
display: inline-block;
width:0;
height:0;
border:20px solid transparent;
vertical-align: middle;
}
.arrow:before {
border-top-color: #CBCBCB;
border-bottom-color: #CBCBCB;
border-right-color: #CBCBCB;
}
.arrow:after {
border-left-color: #CBCBCB;
}
This is all in the a fiddle.

CSS hover border makes elements adjust slightly

I have an unordered list full or anchors. I have a CSS :Hover event that adds borders to it but all the anchors to the left slightly adjust when i hover because it is adding 1px to the width and auto adjusting. how do i make sure the positioning is absolute?
div a:visited, #homeheader a{
text-decoration:none;
color:black;
margin-right:5px;
}
div a:hover{
background-color:#D0DDF2;
border-radius:5px;
border:1px solid #102447;
}
div li{
padding:0;
margin:0px 10px;
display:inline;
font-size:1em;
}
<div>
<ul>
<li>this</li>
<li>that</li>
<li>this again</li>
<li>that again</li>
</ul>
</div>
I made a JS Fiddle demo here.
You can add a transparent border to the non-hover state to avoid the "jumpiness" when the border appears:
http://jsfiddle.net/TEUhM/3/
#homeheader a:visited, #homeheader a{
border:1px solid transparent;
}
You can also use outline, which won't affect the width i.e. so no "jump" effect. However,support for a rounded outline may be limited.
You could use a box shadow, rather than a border for this sort of functionality.
This works because your shadow doesn't 'take size in the DOM', and so won't affect the positioning, unlike that of a border.
Try using a declaration like
box-shadow:0 0 1px 1px #102447;
instead of your
border:1px solid #102447;
on your hover state.
Below is a quick demo of this in action:
DEMO
#homeheader a:visited,
#homeheader a {
text-decoration: none;
color: black;
margin-right: 5px;
}
#homeheader a:hover {
background-color: #D0DDF2;
border-radius: 5px;
box-shadow: 0 0 1px #102447;
}
#homeheader li {
padding: 0;
margin: 0px 10px;
display: inline;
font-size: 1em;
}
<div id="homecontainer">
<div id="homeheader">
<ul>
<li>this
</li>
<li>that
</li>
<li>this again
</li>
<li>that again
</li>
</ul>
</div>
</div>
Add a margin of 1px and remove that margin on hover, so it is replaced by the border.
http://jsfiddle.net/TEUhM/4/
After taking a long time pressure i found a cool solution.
Hope that it will help others.
on the add the folloing code :
HTML
<div class="border-test">
<h2> title </h2>
<p> Technology founders churn rate niche market </p>
</div>
CSS
.border-test {
outline: 1px solid red;
border: 5px solid transparent;
}
.border-test:hover {
outline: 0px solid transparent;
border: 5px solid red;
}
Check live : Live Demo
Hope it will help.
No one has mentioned it here, but the best and simplest solution to this in my opinion is to use "box shadow" instead of borders. The magic is on the "inset" value which allows it be like a boarder.
box-shadow: inset 0 -3px 0 0 red;
You can offset the X or Y to change top/bottom and use -negative value for opposite sides.
.button {
width: 200px;
height: 50px;
padding: auto;
background-color: grey;
text-align: center;
}
.button:hover {
box-shadow: inset 0 -3px 0 0 red;
background-color: lightgrey;
}
<div class="button"> Button </div>
You can use box-shadow which does not change your box-size, unlike border.
Here is a little tutorial.
Just add the following code into your css file
#homeheader a {
border:1px solid transparent;
}
The CSS "box-sizing" attribute fixed this problem for me. If you give your element
.class-name {
box-sizing: border-box;
}
Then the width of the border is added to the inside of the box when the browser calculates its width. This way when you turn the border style on and off, the size of the element doesn't change (which is what causes the jittering you observed).
This is a new technology, but the support for border-box is pretty consistent. Here is a demo!
The easiest method I found was using 'outline' instead of 'border'.
#home:hover{
outline:1px solid white;
}
instead of
#home:hover{
border:1px solid white;
}
Works the best!
https://www.kirupa.com/html5/display_an_outline_instead_of_a_border_hover.htm
Add a negative margin on hover to compensate:
#homeheader a:hover{
border: 1px solid #102447;
margin: -1px;
}
updated fiddle
In the fiddle the margin: -1px; is a little more complex because there was a margin-right getting overridden, but it's still just a matter of subtracting the newly-occupied space.
I too was facing the same problem. The fix mentioned by Wesley Murch works! i.e. adding a transparent border around the element to be hovered.
I had a ul on which :hover was added to every li. Every time, I hovered on each list item, the elements contained inside li too moved.
Here is the relevant code:
html
<ul>
<li class="connectionsListItem" id="connectionsListItem-0">
<div class="listItemContentDiv" id="listItemContentDiv-0">
<span class="connectionIconSpan"></span>
<div class="connectListAnchorDiv">
Test1
</div>
</div>
</li>
</ul>
css
.listItemContentDiv
{
display: inline-block;
padding: 8px;
right: 0;
text-align: left;
text-decoration: none;
text-indent: 0;
}
.connectionIconSpan
{
background-image: url("../images/connection4.png");
background-position: 100% 50%;
background-repeat: no-repeat;
cursor: pointer;
padding-right: 0;
background-color: transparent;
border: medium none;
clear: both;
float: left;
height: 32px;
width: 32px;
}
.connectListAnchorDiv
{
float: right;
margin-top: 4px;
}
The hover defn on each list item:
.connectionsListItem:hover
{
background-color: #F0F0F0;
background-image: linear-gradient(#E7E7E7, #E7E7E7 38%, #D7D7D7);
box-shadow: none;
text-shadow: none;
border-radius: 10px 10px 10px 10px;
border-color: #AAAAAA;
border-style: solid;
}
The above code used to make the containing elements shift, whenever I hovered over connectionsListItem. The fix was this added to the css as:
.connectionsListItem
{
border:1px solid transparent;
}
Use :before to create the border, that way it won't modify the actual content and gives you more freedom. Check it out here:
http://codepen.io/jorgenrique/pen/JGqOMb
<div class='border'>Border</div>
<div class='before'>Before</div>
div{
width:300px;
height:100px;
text-align:center;
margin:1rem;
position:relative;
display:flex;
justify-content:center;
align-items: center;
background-color:#eee;
}
.border{
border-left:10px solid deepPink;
}
.before{
&:before{
content:"";
position:absolute;
background-color:deepPink;
width:10px;
height:100%;
left:0;
top:0;
}
&:hover{
background-color:#ccc;
&:before{
width:0px;
transition:0.2s;
}
}
}
Be careful if you also use padding.
In my case, I had a 5px padding inside the hover defn. It should be moved inside the actual class of the element you want to hover over.
Code snippet

Resources