Create ribbon-like badge with CSS - html

I have a small box with a slanted corner, that looks like this:
The slanted corner was done with the help of this snippet: https://codepen.io/myf/pen/FLzva. But just in case the link dies, I'll put my scss code here:
.product-info {
position: relative;
padding: $spacer * .5;
padding-right: $spacer * 2;
overflow: hidden;
&-link {
display: block;
a {
color: $gray-dark;
transition: color $animation-fast;
&:hover {
color: $brand-primary;
text-decoration: none;
}
}
}
&-price {
color: $brand-primary;
}
&:before,
&:after {
position: absolute;
content: "";
left: 0;
z-index: -1;
background-color: $gray-lighter;
border-color: $gray-lighter;
}
&:before {
top: 0;
right: 0;
bottom: 35px;
}
&:after {
top: auto;
right: -5px;
bottom: 0;
border-style: solid;
border-width: 35px 35px 0 0;
background-color: transparent;
border-right-color: transparent;
}
}
I now need to be able to add a badge to this box. I thought about doing it with a data attribute; <div class="product-info" data-badge="New">...</div> and if div.product-info has the data attribute, the badge will appear. The badge has to look like this:
I have no idea how to achieve this, unfortunately. A push to the right direction would be much appreciated!

I managed to do it myself with CSS. I don't know how good the solution is and how reusable my code is, but it works for my case. I didn't do it with a data-attribute, as I first intended, because I feel like this would've been even more a pain in the ass. I created separate elements and I just have to be careful where to put it in the HTML structure. Here is the whole SCSS code with comments:
.product-badge-wrapper { /* I needed the wrapper for positioning the badge */
position: absolute;
bottom: 0;
right: 0;
.product-badge { /* This is the actual badge */
position: relative;
width: 100px;
overflow: hidden;
&.red {
/* I need the badge in two versions, a gray version and a red version.
* The .red class just deals with some colors and can be ignored. */
&:before,
&:after {
border-color: $brand-primary;
background-color: transparent;
}
&:after {
background-color: transparent;
border-left-color: transparent;
}
.product-badge-content {
&:before {
border-color: darken($brand-primary, 10%);
border-left-color: transparent;
border-right-color: transparent;
}
}
}
/* These next few :befores and :afters are for the general shape
of The badge. This is just the rectangle with the 45deg slant*/
&:before,
&:after {
content: "";
position: absolute;
left: 0;
background-color: transparent;
border-color: $gray-light;
}
&:before {
top: 20px;
right: 0;
bottom: 0;
}
&:after {
bottom: auto;
left: -1px;
top: -10px;
border-style: solid;
border-width: 0 0 75px 75px; /* This is where the main magic for the slant happens */
background-color: transparent;
border-left-color: transparent;
width: 100px;
}
/* Now for the little fold I needed an extra class to attach a
:before to. This class seems really bloated and could be trimmed
down probably. A lot of it is just positioning and text stuff */
.product-badge-content {
height: 43px;
padding-right: 5px;
padding-left: 22px;
display: flex;
justify-content: flex-end;
align-items: center;
text-align: right;
text-transform: uppercase;
font-weight: 700;
position: relative;
z-index: 10;
color: $white-base;
&.text-small {
font-size: .7rem;
font-weight: 400 !important;
}
/* This is where the fold is created */
&:before {
content: "";
position: absolute;
left: 11px;
bottom: 0;
display: block;
border-style: solid;
border-color: $gray-dark;
border-left-color: transparent;
border-right-color: transparent;
border-width: 10px 10px 0 10px; /* Magic happens here. We create a downward arrow */
}
}
}
}
And here is how I place it in the HTML code
<div class="product-info-wrapper">
<div class="product-info">
<!-- Gray box with product name and price -->
</div>
<!-- Badge here -->
<div class="product-badge-wrapper">
<div class="product-badge">
<div class="product-badge-content text-small">
nicht<br>auf lager
</div>
</div>
</div>
</div>
There are a lot of absolutely set dimensions, which is what I meant with "I don't know how reusable my code is". You'd have to play around with the numbers, if you need something like this. There probably are better solutions, but for now it works for the project I'm working on.

Related

How to customize tooltip arrow to look curved (Normal Distribution) in react

I am currently facing a issue with the tool tip, The arrow for tooltip as per design is not a triangle but look like a normal distribution curve, I was wondering if it is possible to make a div for tooltip arrow and make the div look like the curve shown below.
If not possible I would be making an svg of the curve, but not sure how to proceed with it.
code for my tool tip
/* Tooltip container */
.tooltip {
position: relative;
display: inline-block;
z-index: 1111111111;
}
/* Tooltip text */
.tooltip.show .tooltiptext {
display: block;
opacity: 1;
min-width: 240px;
max-width: 308px;
background-color: #555;
color: #fff;
text-align: center;
padding: 16px;
/* padding-top: 0px; */
border-radius: 6px;
position: absolute;
z-index: 1;
bottom: 120%;
left: 50%;
transform: translateX(-50%);
transition: opacity 0.3s;
}
.tooltip.hide .tooltiptext {
display: none;
}
.tooltip .tooltiptext .tooltipArrow {
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
Can anybody help? below is the design for tool tip

CSS technique for a horizontal line with words in the middle plus vertical borders

I'm trying to move the entire border "up" so the bottom border lines up with the middle of the text. Very similar to this question, but I want to keep the left and right borders (they must be pushed up too). The reason for this is the text relates to the information above it.
https://jsfiddle.net/8c039kzy/
My jsfiddle is close but the left / right borders don't go high enough. So I want something like this:
|--------Info above is Important!--------|
(But the bottom of the left / right borders don't leak down past the horizontal border)
Use a :before pseudo element to draw the horizontal line instead.
h5 {
width: 100%;
text-align: center;
border-left: 1px solid #000;
border-right: 1px solid #000;
margin: 10px 0 20px;
position: relative;
}
h5:before, h5:after {
content: '';
position: absolute;
}
h5:before {
top: 50%;
background: #000;
height: 1px;
left: 0; right: 0;
}
h5:after {
background: #fff;
top: calc(50% + 1px);
bottom: 0;
left: -1px; right: -1px;
}
span {
background: #FFF;
padding: 0 10px;
position: relative;
z-index: 1;
}
<h5><span>Refer to Info above</span></h5>
I think you want this :
h5 {
position: relative;
text-align: center;
border-left: 1px solid #000;
border-right: 1px solid #000;
}
h5 span {
background: white;
padding: 0 15px;
position: relative;
z-index: 1;
}
h5:before {
background: black;
content: "";
display: block;
height: 1px;
position: absolute;
top: 50%;
width: 100%;
}
h5:before {
left: 0;
}
<h5><span>Refer to Info above</span></h5>
I created a sides line and I used just right and left borders, is this that you want?
h5 span:before, h5 span:after {
display:inline-block;
content: "";
vertical-align: bottom;
height: .5em;
border-top: 1px solid #000;
width: 200px;
}
<h5><span>Refer to Info above</span></h5>
other way to do this :) but with lines of given width

Align pentagon shapes which have text in them

I'm trying to make a bar which holds the navigation stack.
For example: Here I am on the client page
And then when I click on a clients name I go to a new page and it adds onto the bar:
Here is what I have so far: http://jsbin.com/bahaqebiga/edit?html,css,js,output
All that needs to be done is change of shape and I'd think some how to manage the z-index as the next arrow should always be under the previous one. I have tried with svg but couldn't get it right because of the text and there was a weird padding I couldn't get rid of, and also with pure html/css but also failed.
Note: position absolute can NOT be used
Any ideas?
Thanks
You can have a pure css solution for that. No need for svg/js.
Use the :after pseudo-selector to create an arrow, and color it based on it's position:
.stack-arrow p:after {
content: "";
width: 0;
height: 0;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
border-left: 25px solid blue;
top: 0;
margin-left: 14px;
position: absolute;
}
.stack-arrow:nth-child(2) {
background: red;
}
.stack-arrow:nth-child(2) p:after{
border-left-color: red;
}
.stack-arrow:nth-child(3) {
background: green;
}
.stack-arrow:nth-child(3) p:after{
border-left-color: green;
}
.stack-arrow:nth-child(4) {
background: blue;
}
.stack-arrow:nth-child(4) p:after{
border-left-color: blue;
}
Check this example:
http://jsbin.com/jusuwihize/1/edit?html,css,js,output
Here is a working example (after react):
.top-nav {
display: flex;
align-items: center;
position: absolute;
top: 0;
height: 50px;
width: 100%;
z-index: 1000;
background-color: #222;
}
.top-nav img {
cursor: pointer;
}
.stack-arrow {
cursor: pointer;
height: 50px;
color: white;
background-color: blue;
font-family: sans-serif;
padding: 0px 15px;
margin: 0.5px;
}
.stack-arrow {
padding-left: 25px;
}
.stack-arrow p:after {
content: "";
width: 0;
height: 0;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
border-left: 25px solid blue;
top: 0;
margin-left: 14px;
position: absolute;
}
.stack-arrow:nth-child(2) {
background: red;
}
.stack-arrow:nth-child(2) p:after{
border-left-color: red;
}
.stack-arrow:nth-child(3) {
background: green;
}
.stack-arrow:nth-child(3) p:after{
border-left-color: green;
}
.stack-arrow:nth-child(4) {
background: blue;
}
.stack-arrow:nth-child(4) p:after{
border-left-color: blue;
}
<div class="top-nav" data-reactid=".0"><img height="50px" src="http://skihighstartups.com/wp-content/uploads/2015/07/logo-placeholder.jpg" data-reactid=".0.0"><div class="stack-arrow" data-reactid=".0.1"><p data-reactid=".0.1.0">Clients</p></div><div class="stack-arrow" data-reactid=".0.2"><p data-reactid=".0.2.0">Name</p></div><div class="stack-arrow" data-reactid=".0.3"><p data-reactid=".0.3.0">Extra</p></div></div>

Link with border and down triangle transparent

I can't find what I need. I have this code
<hgroup id="subheader">
<h1>lorem ipsum</h1>
<h2>ipsum lorem</h2>
read More
</hgroup>
I want the link to have a border with a down triangle at the bottom. But it has to be transparent, because it goes in front of an image. Is that possible?
The shape given in question is a bit complex to achieve with full transparency because of the area cut by the arrow having to be transparent too. Because of this, the techniques that are generally used for creating such tool-tip like shapes cannot be used as-is here. However, there is a still a way to achieve it using CSS and it is as follows:
Use the parent hgroup for the shape with borders on top, left and right and add border-radius. Don't add any border to the bottom because then cutting the space for the arrow would be tough.
Use two pseudo elements (:before and :after) which have the same height as the parent but lesser width such that they produce a tiny gap when positioned absolutely with respect to parent. Add border-bottom alone to these pseudo-elements.
Add a pseudo-element for the arrow on the arrow-down element (a) and create the arrow using rotate(45deg) transforms instead of using the border trick. The transform method is very helpful for creating transparent arrows. Position this arrow again absolutely with respect to the parent.
As we are dealing with transforms, triangle shapes etc the position values need to be calculated based on Math theorems.
* {
box-sizing: border-box;
}
.container {
height: 300px;
width: 500px;
background: url(http://lorempixel.com/500/300/nature/2);
padding: 10px;
}
#subheader {
position: relative;
width: 400px;
height: auto;
border: 1px solid black;
border-bottom: none;
border-radius: 12px;
padding: 10px;
}
.arrow-down{
display: inline-block;
}
.arrow-down:after {
position: absolute;
content: '';
bottom: -10px; /* half the height of the element */
left: 50px; /* some aribitrary position */
height: 20px;
width: 20px;
transform: rotate(45deg);
transform-origin: 50% 50%; /* rotate around center which is at 60px from left */
border-right: 1px solid black;
border-bottom: 1px solid black;
}
#subheader:after {
position: absolute;
content: '';
left: 74px; /* center point of arrow + 1/2 of hypotenuse */
height: 100%;
width: calc(100% - 74px); /* 100% - value of left */
bottom: 0px;
border-bottom: 1px solid black;
border-bottom-right-radius: inherit; /* same border-radius as parent */
}
#subheader:before {
position: absolute;
content: '';
height: 100%;
width: 46px; /* center point of arrow - 1/2 of hypotenuse */
left: 0px;
bottom: 0px;
border-bottom: 1px solid black;
border-bottom-left-radius: inherit; /* same border-radius as parent */
}
<div class='container'>
<hgroup id="subheader">
<h1>lorem ipsum</h1>
<h2>ipsum lorem</h2>
Read More
</hgroup>
</div>
Here is a working version of what you're after.
HTML
<div style="display:none" class="tri-down">Your Content will go into this fancy tri-down</div>
CSS --- I ADDED a background img to show that its transparent as you said that you were going to be having an image behind it.
body {
background: #333 url("http://a2.files.readwrite.com/image/upload/c_fit,cs_srgb,dpr_1.0,q_80,w_620/MTIyMzI3NDY5NDAyMzg1Njg5.jpg") fixed;
}
.tri-down {
/* Styling block element, not required */
position: relative;
margin-bottom: 2em;
padding: 1em;
width: 75%;
border: 1px solid #999;
background: #f3f3f3;
border-radius:5px;
opacity: 0.5;
/*you may want to set the z-index level of your tri-down box.
z-index: 100;
*/
}
/* Required for Down Triangle */
.tri-down:before, .tri-down:after {
content: "";
position: absolute;
width: 0;
height: 0;
border-style: solid;
border-color: transparent;
border-bottom: 0;
}
/* Stroke */
.tri-down:before {
bottom: -16px;
left: 21px;
/* If 1px darken stroke slightly */
border-top-color: #777;
border-width: 16px;
}
/* Fill */
.tri-down:after {
bottom: -15px;
left: 22px;
border-top-color: #f3f3f3;
border-width: 15px;
}
JSFIDDLE HERE
http://jsfiddle.net/LZoesch/dk43s2qz/
You will want to hide the DIV that is going to house your content. I added it to the above HTML code.
style="display:none"
Then you want to call the link on click and toggle the div class tri-down on/off
<script type="text/javascript">
$(function(){
$('#').click(function(){
$('#').toggle();
$('#').toggle();
});
});
</script>
Here is your orignal code.
<hgroup id="subheader">
<h1>lorem ipsum</h1>
<h2>ipsum lorem</h2>
read More
</hgroup>
If you dont want to set the opacity if your div, you can also try this below.
body {
background: url(http://a2.files.readwrite.com/image/upload/c_fit,cs_srgb,dpr_1.0,q_80,w_620/MTIyMzI3NDY5NDAyMzg1Njg5.jpg);
font-family: sans-serif;
text-align: center;
}
body > div {
color: #000;
margin: 50px;
padding: 15px;
position: relative;
}
.tri-down {
border: 5px solid #000;
content: "";
position: absolute;
}
you can try this one:
.tri-down {
/* Styling block element, not required */
position: relative;
margin-bottom: 2em;
padding: 1em;
border: 1px solid #999;
background: #f3f3f3;
border-radius:5px;
}
/* Required for Down Triangle */
.tri-down:before, .tri-down:after {
content: "";
position: absolute;
width: 0;
height: 0;
border-style: solid;
border-color: transparent;
border-bottom: 0;
}
/* Stroke */
.tri-down:before {
bottom: -16px;
left: 21px;
/* If 1px darken stroke slightly */
border-top-color: #777;
border-width: 16px;
}
/* Fill */
.tri-down:after {
bottom: -15px;
left: 22px;
border-top-color: #f3f3f3;
border-width: 15px;
}
DEMO
You may need to overlay two images and absolutely position them. Like something along the lines of:
body{
padding:2em;
}
#subheader h1{
font-size:1.5em;
margin-top:0;
}
#subheader h2{font-size:1.2em;}
#subheader
{
position: relative;
max-width:300px;
min-height:1.5em;
padding: 20px;
background: #FFFFFF;
border: #dedede solid 2px;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px;
}
#subheader:after
{
content: "";
position: absolute;
bottom: -19px;
height:13px;
widht:12px;
left: 10%;
border-style: solid;
border-width: 20px 13px 0;
border-color: #FFFFFF transparent;
display: block;
width: 0;
z-index: 1;
}
#subheader:before
{
content: "";
position: absolute;
bottom: -22.5px;
left: calc(10.5% - 3px) ;
border-style: solid;
border-width: 23px 15px 0px;
border-color: #dedede transparent;
display: block;
width: 0;
z-index: 0;}
Like in this pen

How can I make Twitter Bootstrap tooltips look like the popovers (without the title line)?

I'd like to replace the Twitter Bootstrap tooltip styles with the popover styles. How can I do that?
Tooltips look like this by default:
Popovers look like this by default:
I'd like my tooltips to be white, with a gray border, just like the popovers.
Can you help?
If you want to change the style for the tooltip itself you would have to edit the .tooltip-inner class in bootstrap's css file or override the .tooltip-inner class with a class of your own.
An example for the border would be:
.tooltip-inner {
border: solid 1px #ccc;
}
Here's how I got it to work:
Add to variables.less
#tooltipArrowOuterWidth: #tooltipArrowWidth + 1;
#tooltipArrowOuterColor: rgba(0,0,0,.25);
Add to custom LESS file
// Tooltip
// --------------------------------------------------
.tooltip.in { .opacity(100); }
.tooltip-inner {
background:#popoverTitleBackground;
color:#gray;
}
.tooltip .arrow {
border-width: #tooltipArrowOuterWidth;
}
.tooltip {
position: absolute;
top: 0;
left: 0;
z-index: #zindexPopover;
display: none;
max-width: 276px;
padding: 1px;
text-align: left; // Reset given new insertion method
background-color: #popoverBackground;
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.2);
.border-radius(6px);
.box-shadow(0 5px 10px rgba(0,0,0,.2));
// Overrides for proper insertion
white-space: normal;
// Offset the popover to account for the popover arrow
&.top { margin-top: -10px; }
&.right { margin-left: 10px; }
&.bottom { margin-top: 10px; }
&.left { margin-left: -10px; }
}
.tooltip-inner {
margin: 0; // reset heading margin
padding: 4px 8px;
font-size: #baseFontSize * 0.9;
font-weight: normal;
line-height: 18px;
background-color: #popoverTitleBackground;
border-bottom: 1px solid darken(#popoverTitleBackground, 5%);
.border-radius(5px 5px 0 0);
&:empty {
display: none;
}
}
// Arrows
//
// .arrow is outer, .arrow:after is inner
.tooltip .tooltip-arrow,
.tooltip .tooltip-arrow:after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.tooltip .tooltip-arrow {
border-width: #tooltipArrowOuterWidth;
}
.tooltip .tooltip-arrow:after {
border-width: #tooltipArrowWidth;
content: "";
}
.tooltip {
&.top .tooltip-arrow {
left: 50%;
margin-left: -#tooltipArrowOuterWidth;
border-bottom-width: 0;
border-top-color: #999; // IE8 fallback
border-top-color: #popoverArrowOuterColor;
bottom: -#tooltipArrowOuterWidth;
&:after {
bottom: 1px;
margin-left: -#tooltipArrowWidth;
border-bottom-width: 0;
border-top-color: #tooltipArrowColor;
}
}
&.right .tooltip-arrow {
top: 50%;
left: -#tooltipArrowOuterWidth;
margin-top: -#tooltipArrowOuterWidth;
border-left-width: 0;
border-right-color: #999; // IE8 fallback
border-right-color: #tooltipArrowOuterColor;
&:after {
left: 1px;
bottom: -#tooltipArrowWidth;
border-left-width: 0;
border-right-color: #tooltipArrowColor;
}
}
&.bottom .tooltip-arrow {
left: 50%;
margin-left: -#tooltipArrowOuterWidth;
border-top-width: 0;
border-bottom-color: #999; // IE8 fallback
border-bottom-color: #tooltipArrowOuterColor;
top: -#tooltipArrowOuterWidth;
&:after {
top: 1px;
margin-left: -#tooltipArrowWidth;
border-top-width: 0;
border-bottom-color: #tooltipArrowColor;
}
}
&.left .tooltip-arrow {
top: 50%;
right: -#tooltipArrowOuterWidth;
margin-top: -#tooltipArrowOuterWidth;
border-right-width: 0;
border-left-color: #999; // IE8 fallback
border-left-color: #tooltipArrowOuterColor;
&:after {
right: 1px;
border-right-width: 0;
border-left-color: #tooltipArrowColor;
bottom: -#tooltipArrowWidth;
}
}
}
JQuery UI is interfering with bootstrap.
They aren't really compatible with each other as they overlap in a lot of functionality.
I had this problem a few weeks back and found this page but I didn't want to start adding custom css for something that should 'just work'. After removing JQuery UI today (for another reason) I noticed the tool-tips started looking as intended. I know this is an old question but I would have found this answer useful a few weeks ago.
JS
$(function() {
$('[title]').attr("data-rel", "tooltip");
$("[data-rel='tooltip']")
.attr("data-placement", "top")
.attr("data-content", function() {
return $(this).attr("title")
})
.removeAttr('title');
var showPopover = function() {
$(this).popover('show');
};
var hidePopover = function() {
$(this).popover('hide');
};
$("[data-rel='tooltip']").popover({
trigger: 'manual'
}).click(showPopover).hover(showPopover, hidePopover);
});
And simple HTML
<h1 title="This is title">What is this</h1>
Here is what worked for me on a right-side tooltip.
I just took a CSS triangle of the same size as the arrow, and then pulled it away from the Bootstrap triangle by the same distance as the width of the border. Adapt as needed, and you can refer to this awesome article for reference on how to make a triangle pointing in any direction:
http://css-tricks.com/snippets/css/css-triangle/
.tooltip .tooltip-inner {
background: white;
color: black;
border: 3px solid black;
padding: 10px;
line-height: 1.65em;
}
.tooltip.right .tooltip-arrow {
top: 50%;
left: 0;
margin-top: -15px;
border-right-color: white;
border-width: 15px 15px 15px 0;
}
.tooltip.right .tooltip-arrow:after {
content: " ";
position: absolute;
z-index: -1;
width: 0;
height: 0;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
border-right: 15px solid black;
top: -15px;
left: -3px;
}
Since the best answer was hiding in the comments to the question and wasn't visible at first, I've ended up finding out the solution on my own. It was easiest way in my case to use popover instead of tooltip with triggering it on hover event. In order to do that you have 2 options:
You may use attribute 'data-trigger':
<td id="3" data-content="Tooltip text" data-placement="bottom" data- container="body" data-trigger="hover" data-original-title="" title="">This tooltiped</span></td>
or use option 'trigger' on popover initialization:
$('.payment').popover({
trigger: "hover",
})