center psuedo element content - html

I have a little "caret" that is put on my currently hovered menu item ,and I now realize the caret created it not centered. I have a bunch of dynamically sized menu items.
The class menu-caret is applied when hovered by a little bit of jquery, and I have some css like so :
.menu-caret::before {
content:"";
position: absolute;
margin-left: 20px;
bottom: 0;
width: 0%;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid black;
}
See a quick example here - https://jsfiddle.net/keL4zhky/3/.
Is it possible to have the carets be centered on the bottom? Thanks!
EDIT: is it possible to do this without relative? I have a full width sub menu that if i change the ul/li to relative will lose it's effect - See example here http://codepen.io/ajmajma/pen/KgGxWL

Just make the parent position: relative; and add left: 50%; and margin-left: -5px; to the pseudo element:
ul {
width: 100%;
position: relative;
display: inline-block;
list-style-type: none;
}
li {
padding: 20px;
float: left;
position: relative;
}
.menu-caret::before {
content: "";
position: absolute;
left: 50%;
bottom: 0;
width: 0%;
margin-left: -5px;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid black;
}
<ul>
<li class="menu-caret">one</li>
<li class="menu-caret">larger</li>
<li class="menu-caret">larrrrger</li>
</ul>
Instead of left: 50%; and margin-left: -5px;you can also just use left: calc(50% - 5px);

The li has to have position:relative to provide positioning context.
The pseudo-element is then positioned absolutely 50% left and then pulled back 50% of it's own width by the transform. This will work for any size caret and does not require any magic numbers.
ul {
width: 100%;
position: relative;
display: inline-block;
list-style-type: none;
}
li {
padding: 20px;
float: left;
}
.menu-caret {
position: relative;
}
.menu-caret::before {
content: "";
position: absolute;
transform: translateX(-50%);
left: 50%;
bottom: 0;
width: 0%;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid black;
}
<ul>
<li class="menu-caret">one</li>
<li class="menu-caret">larger</li>
<li class="menu-caret">larrrrger</li>
</ul>

Instead of absolute positioning and float, I prefer:
ul {
width: 100%;
position: relative;
display: inline-block;
list-style-type: none;
}
li {
padding: 20px;
text-align:center;
display: inline-block;
}
.menu-caret::after {
text-align: center;
display: block;
content: "";
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid black;
clear: both;
width: 1px;
margin: 0 auto;
}
<ul>
<li class="menu-caret">one</li>
<li class="menu-caret">larger</li>
<li class="menu-caret">larrrrger</li>
</ul>

Related

How to center dropdown based on size of parent

I have a dropdown-component that when you click the button and dropdown is shown.
I want the triangle on the dropdown to always point to the center of the button that opened it regardless of how big it was.
Is this possible using css?
In the example below I am using a css-variable to achieve this. But in my real scenario I am unable to do this since the width of the container/button is decided by its contents.
Is it possible to reference the width of the container in any other way? I see that percentages used in left-positioning and the transform is based on the width of the menu it self. So that doesn't really help.
body {
margin: 2rem 50%;
--button-size: 100px;
}
.container {
position: absolute;
display: inline-block;
}
.button {
position: relative;
width: var(--button-size);
border: 1px solid black;
}
.button:after {
display: block;
position: absolute;
content: "";
width: 1px;
height: 200%;
top: 0;
left: 50%;
transform: translateX(-50%);
background: red;
}
.item {
white-space: pre;
padding: 1rem;
}
.item + .item {
border-top: 1px solid black;
}
.menu {
padding: 0;
list-style: none;
position: absolute;
border-radius: 4px;
border: 1px solid black;
left: 100%;
transform: translateX(calc(-75% - var(--button-size)/2));
}
.menu:after,
.menu:before {
content: "";
position: absolute;
left: 75%;
transform: translateX(-50%);
width: 0;
height: 0;
border-style: solid;
border-width: 8px;
border-color: transparent;
}
.menu:before {
border-bottom-color: black;
top: -17px;
}
.menu:after {
border-bottom-color: white;
top: -16px;
}
<div class="container">
<div class="button">Centered on me(but using css-variables)</div>
<ul class="menu">
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>
</div>
I think using a margin: auto; on the element that you want in the center could be useful as it automatically adjusts and places it's element in the center depending on the space available to it in any given situation.

Centre an image on top of a CSS shape?

I am trying to center an image on to a Hexagon made using CSS.
The code I currently have is:
.img-social {
width: 25px;
height: 25px;
}
.hexagon {
position: relative;
width: 35px;
height: 20.21px;
background-color: #525555;
margin: 10.10px 0;
}
.hexagon:before,
.hexagon:after {
content: "";
position: absolute;
width: 0;
border-left: 17.5px solid transparent;
border-right: 17.5px solid transparent;
}
.hexagon:before {
bottom: 100%;
border-bottom: 10.10px solid #525555;
}
.hexagon:after {
top: 100%;
width: 0;
border-top: 10.10px solid #525555;
}
<li class="img-social-container">
<div class="hexagon"></div>
<a><img class="img-social" src="icons/logo-github.png" alt="github"></a>
</li>
I also want the image to be ontop of the hexagon which is another problem I am having.
Just move it? I'm somewhat sure it's not the best solution, but still.
.img-social {
width: 25px;
height: 25px;
position: relative;
bottom: 32.5px;
left: 5px;
margin: 0;
}

How best to create this arrow shaped div/button?

first post on Stack. I've been asked to recreate this design for a project and I'm not entirely sure how best to approach recreating this div/button with an arrowed bottom side.
I'm fairly comfortable with most CSS conventions but for custom styles like this, I'm a bit lost as to a starting point. If anybody could point me in the right direction I would be much appreciated.
Thanks very much,
Nathan
.button
{
position: relative;
background-color: rgb(128,250,128);
padding: 10px 0px;
width: 60px;
text-align: center;
}
.button::after
{
display: block;
position: absolute;
bottom: -10px;
content: "";
width: 0px;
border-color: rgb(128,250,128) transparent;
border-style: solid;
border-width: 10px 30px 0px 30px; /*10 is the height and 30 is half of parent width*/
}
<div class="button">
button
<div>
Here is the CSS you need to make a div/button angled downwards:
.menu {
background-color: #0b0;
border: 1px solid #000;
float: left;
height: 50px;
line-height: 50px;
margin: 0;
position: relative;
text-align: center;
width: 150px;
}
.menu.active {
background-color: #0d0;
}
.menu.active::after {
border-top: 10px solid #0d0;
border-left: 75px solid transparent;
border-right: 75px solid transparent;
bottom: -10px;
content: "";
left: 0;
position: absolute;
}
.menu.active::before {
border-top: 10px solid #000;
border-left: 75px solid transparent;
border-right: 75px solid transparent;
bottom: -11px;
content: "";
left: 0;
position: absolute;
}
<div class="menu">
HOME
</div>
<div class="menu active">
MORE REVIEWS
</div>
<div class="menu">
ABOUT
</div>

Creating a div with a pointed side

I want to create a div with an image and text in it that looks like this.
I've managed to get something that looks like this here:
JSFiddle of pointed div
.triangle-down {
background: white;
display: inline-block;
height: 125px;
margin-left: 20px;
margin-bottom: 55px;
position: relative;
width: 200px;
cursor: pointer;
border: red solid 2px;
}
img {
margin: 10px;
}
.triangle-down:before {
border-top: 20px solid red;
border-left: 101px solid transparent;
border-right: 101px solid transparent;
content: "";
height: 0;
left: -1px;
position: absolute;
top: 127px;
width: 0;
}
.triangle-down:after {
border-top: 20px solid white;
border-left: 100px solid transparent;
border-right: 100px solid transparent;
content: "";
height: 0;
left: 0;
position: absolute;
top: 125px;
width: 0;
}
<div class="triangle-down">
<img src="http://placehold.it/180x105">
</div>
The issues I have are:
(1) The curser turns to a pointer outside the shape when it crosses the transparent borders that help create the point. I'd prefer it if the pointer appeared only when inside the visible outline of the shape.
(2) Is there a better way of doing this? I looked at trying to rotate a div to create the point as I thought this would solve the pointer issue but I can't work out how to create an isosceles triangle shape with the correct proportions this way. This would also allow me to apply a border to create the outline rather than overlay two triangles as I have in the JSFiddle. See this post for more on this - Speech bubble with arrow
Here is a version using transform: rotate
/*Down pointing*/
.triangle-down {
background: white;
display: inline-block;
height: 125px;
margin-left: 20px;
margin-bottom: 55px;
position: relative;
width: 200px;
cursor: pointer;
border: red solid 2px;
}
img {
position: relative;
margin: 10px;
z-index: 1
}
.triangle-down:before,
.triangle-down:after {
border-bottom: 2px solid red;
background: white;
content: '';
height: 50px;
left: 5px;
position: absolute;
top: 98px;
width: 54%;
transform: rotate(22deg);
z-index: 0;
}
.triangle-down:after {
left: auto;
right: 5px;
transform: rotate(-22deg);
}
<div class="triangle-down">
<img src="http://placehold.it/180x105">
</div>

How can I create a non-repeated outside border image?

I'm trying to figure out how to create a border image for separate divs in the screenshot, yet I can't seem to find a way to do so. Can anyone offer some guidance on how to make these outside border images work?
This is about as close as I can get it. No images required:
.has_tab {
border: 1px solid #e6e6e6;
border-left: none;
width: 33.33%;
height: 300px;
box-sizing: border-box;
display: block;
float: left;
position: relative;
text-align: center;
}
.has_tab:first-child {
border-left: 1px solid #e6e6e6;
}
/* the important bit... */
.has_tab:after {
content: "";
display: block;
width: 10px;
height: 100px;
background: #FFF;
border: 1px solid #e6e6e6;
border-left: none;
border-radius: 0 20px 20px 0;
position: absolute;
top: 50%;
margin-top: -50px;
right: -11px;
}
.has_tab:last-of-type:after {
display: none;
}
<div class="has_tab">Lorem ipsum</div>
<div class="has_tab">Lorem ipsum</div>
<div class="has_tab">Lorem ipsum</div>
Fiddle version
here is how i do it
first you need to cut this image
and then you can use it as background of after element
<div class="borderd-div"></div>
and the css:
.borderd-div{
height: 334px;
width:334px;
border: 1px solid #f1f1f1;
position: relative;
}
.borderd-div:after{
content:" ";
display: block;
position: absolute;
width: 20px;
height: 145px;
right:-19px;
top:83px;
background: url(Djyods1.png) no-repeat 0 0;
}