How to make a border around clip path shape? [duplicate] - html

This question already has answers here:
Hexagon shape with a border/outline
(7 answers)
Closed 3 years ago.
I am trying to create hexagon shaped buttons that have a transparent background and white 1px solid border around the hexagon I created with clip path. However, when I apply a border part of it is cut off. How can I achieve this look?
Here is my code:
.project-button div{
position: relative;
display: inline-block;
padding: 1rem;
margin: 0 1rem 1rem 1rem;
color: #d9d9d9;
font-size: 1rem;
font-weight: 700;
border: 1px solid white;
-webkit-clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
background-repeat: no-repeat;
transition: background-size .5s, color .5s;
}
.to-top {
background-position: 50% 100%;
background-size: 100% 0%;
}
.project-button div:hover {
background-size: 100% 100%;
background-image: linear-gradient(white, white);
color: #51d0de;
}
<div class="project-button">
<div class="to-top>View Code"></div>
</div>

This is what i Got so far,
I've used filter: drop-shadow()
For your transparent background you can use same color as parent
.hexagon{
background: white;/*giving color is important*/
padding: 40px;
width: 20%;
text-align: center;
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}
/* main code */
.container{
filter: drop-shadow(0px 0px 1px black);
}
<div class="container">
<div class="hexagon">Button</div>
</div>
I hope it helps.
Note: filter is used on parent div.

Related

Changing shape of arrows in progress bar

I am working on angular application in which I am making a progress bar. My code is as follows:
CSS:
.progressbar {
height: 56px;
background: lightgray;
box-shadow: inset 0px -2px 5px rgba(0, 0, 0, 0.5);
animation: change 1s linear infinite;
margin: 5px -10px;
clip-path: polygon(95% 0%, 100% 50%, 95% 100%, 0% 100%, 5% 50%, 0% 0%);
}
.progressbar:first-child {
margin-left: 0;
clip-path: polygon(0% 0%, 95% 0%, 100% 50%, 95% 100%, 0% 100%);
}
.progressbar:last-child {
margin-right:0;
}
.bar {
display:flex;
gap:20px; /*You can use now this property to play with the separation between the bars*/
}
.progressbar.active{
background:
linear-gradient(to right, red 0%, yellow 50%, green 34%)
left/var(--p, 100%) fixed,
lightgray;
box-shadow: inset 0px -2px 5px rgba(0, 0, 0, 0.5);
}
HTML:
<div class="bar">
<div class="progressbar active" style="width:100%;"></div>
<div class="progressbar" style="width:100%;"></div>
<div class="progressbar" style="width:100%;"></div>
</div>
With this I am getting a progress bar like this . This is very near to my desired result. But with this code arrow shape of bars is not proper. The shape of arrow I want is . How can I change shape of my bars exactly as same that of required as shown in image.
Add negative right margin to your tabs (+ the desired gap size)
Add a positive margin-right to the parent wrapper (of the same size)
Easily achievable with just two CSS variables --d and --gap. Edit their values to achieve the desired result:
/*Quick Reset*/
* { margin: 0; box-sizing: border-box; }
body {
font: 1rem/1.3 sans-serif;
}
/*
* Progressbar
*/
.bar {
--d: 1rem; /* arrow depth */
--gap: 0.3rem; /* arrow thickness, gap */
display: flex;
margin-right: var(--d);
}
.bar-step {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
padding: 0.6rem var(--d);
margin-right: calc(var(--d) * -1 + var(--gap));
background: #d9e3f7;
color: #23468c;
clip-path: polygon(
0% 0%,
calc(100% - var(--d)) 0%,
100% 50%,
calc(100% - var(--d)) 100%,
0% 100%,
var(--d) 50%
);
}
.bar-step:first-child {
clip-path: polygon(
0% 0%,
calc(100% - var(--d)) 0%,
100% 50%,
calc(100% - var(--d)) 100%,
0% 100%
);
}
.bar-step.active {
background: #23468c;
color: #fff;
}
<div class="bar">
<div class="bar-step active">Step 1</div>
<div class="bar-step">Step 2 text</div>
<div class="bar-step">Step 3</div>
<div class="bar-step">Step 4</div>
</div>

How can I combine a circle in a polygon using clip-path and add a shadow

I am new to using the css property clip-path and have created a shape that almost fits the requirement I have.
I am looking to create the following shape however struggling to convert the squares I have to circles.
.ticket {
background-color: blue;
height: 100px;
width: 200px;
border-radius: 10px;
box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 15%);
clip-path: polygon(
0 0,
0% 42%,
5% 42%,
5% 58%,
0 58%,
0 100%,
100% 100%,
100% 58%,
95% 58%,
95% 42%,
100% 42%,
100% 0
);
}
<div class="ticket"></div>
Is this possible using this property? If not, how could I achieve this using a SVG instead? Is it also possible to add a drop shadow to this clipped mask? As you can see in the snippet the shadow doesn't really work.
If it's only a solid coloration, background can do it:
.ticket {
background:
radial-gradient(20px at right, #0000 97%,blue) right,
radial-gradient(20px at left , #0000 97%,blue) left;
background-size: 51% 100%;
background-repeat: no-repeat;
height: 100px;
width: 200px;
border-radius: 10px;
filter: drop-shadow(0 0.5rem 0.2rem rgb(0 0 0 / 50%));
}
<div class="ticket"></div>
It is possible to 'cut holes' using the mask-image property and radial-gradients.
This snippet uses your code but replacing the clip-path with circle radial-gradient masks. Obviously you can change the percentages depending on hole-size required.
body {
background: cyan;
}
.ticket {
background-color: blue;
height: 100px;
width: 200px;
border-radius: 10px;
box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 15%);
--mask1: radial-gradient(circle at 0 50%, transparent 0, transparent 5%, black 5%, black 90%, transparent 90%, transparent);
--mask2: radial-gradient(circle at 100% 50%, transparent 0, transparent 5%, black 5%, black 90%, transparent 90%, transparent);
/* webkit needed for Chrome */
-webkit-mask-image: var(--mask1), var(--mask2);
mask-image: var(--mask1), var(--mask2);
}
<div class="ticket"></div>
(body has been given a background just to prove that holes have been cut rather than white circles drawn which is what would have happened with pseudo elements).
The box shadow is more problematic as it gets masked (or clipped as in the question's code). Box-shadow on element with -webkit-mask-image has ideas on putting a shadow on a containing element which has the mask image(s) as background images(s) but putting a shadow into the holes is still a problem. Perhaps just putting a slightly bigger container with gradient gray/transparent backgrounds would do enough, with the 'holes' varying transparent grays rather than just transparent. Seems hacky though.
Here is my solution for both contained and outlined coupons with mask-image and radial-gradient .
In order to draw an outlined coupon, I use two backgrounds and masks, each of which is only a half part to avoid overlapping of radial-gradient.
.wrapper {
display: flex;
gap: 30px;
--coupon-side-radius: 6px;
--coupon-background-color: #c39f76;
--coupon-border-color: #c39f76;
--coupon-border-width: 1px;
}
.coupon {
width: 100px;
height: 100px;
border: var(--coupon-border-width, 1px) solid var(--coupon-border-color);
border-radius: 6px;
box-sizing: border-box;
background: radial-gradient(
circle at center left,
transparent 0px var(--coupon-side-radius),
var(--coupon-border-color) var(--coupon-side-radius)
calc(var(--coupon-side-radius) + var(--coupon-border-width, 0.5px)),
var(--coupon-background-color) calc(var(--coupon-side-radius) + var(--coupon-border-width) + 0.5px)
)
border-box,
radial-gradient(
circle at center right,
transparent 0px var(--coupon-side-radius),
var(--coupon-border-color) var(--coupon-side-radius)
calc(var(--coupon-side-radius) + var(--coupon-border-width, 0.5px)),
var(--coupon-background-color) calc(var(--coupon-side-radius) + var(--coupon-border-width, 0.5px) + 0.5px)
)
border-box;
background-size: 50% 100%, 50% 100%;
background-position: 0% 100%, 100% 100%;
background-repeat: no-repeat, no-repeat;
-webkit-mask-image: radial-gradient(
circle at center left,
transparent 0,
transparent var(--coupon-side-radius),
#000 calc(var(--coupon-side-radius) + 0.5px)
),
radial-gradient(
circle at center right,
transparent 0,
transparent var(--coupon-side-radius),
#000 calc(var(--coupon-side-radius) + 0.5px)
);
-webkit-mask-size: 50% 100%, 50% 100%;
-webkit-mask-position: 0% 100%, 100% 100%;
-webkit-mask-repeat: no-repeat, no-repeat;
}
.coupon1 {
--coupon-side-radius: 6px;
--coupon-background-color: #c39f76;
--coupon-border-color: #c39f76;
--coupon-border-width: 1px;
}
.coupon2 {
--coupon-side-radius: 6px;
--coupon-border-color: red;
--coupon-border-width: 1px;
--coupon-background-color: #c39f76;
}
.coupon3 {
--coupon-side-radius: 6px;
--coupon-background-color: transparent;
--coupon-border-color: red;
--coupon-border-width: 1px;
}
.coupon4 {
--coupon-side-radius: 6px;
--coupon-background-color: transparent;
--coupon-border-color: red;
--coupon-border-width: 2px;
}
.coupon5 {
--coupon-side-radius: 6px;
--coupon-background-color: transparent;
--coupon-border-color: red;
--coupon-border-width: 0.5px;
border: none !important;
position: relative;
}
.coupon5::before{
content: "";
position: absolute;
top: 0px;
left: 0px;
box-sizing: border-box;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
border: 1px solid red;
border-radius: 16px;
opacity: 0.7;
}
.coupon-demo {
width: 100px;
height: 100px;
border: 2px solid red;
border-radius: 15px;
background: radial-gradient(
circle at center left,
transparent 0px 6px,
red 6px 8px,
#fff 9px
)
border-box,
radial-gradient(
circle at center right,
transparent 0px 6px,
red 6px 8px,
#c39f76 9px
)
border-box;
background-size: 51% 100%, 50% 100%;
background-position: 0% 100%, 100% 100%;
background-repeat: no-repeat, no-repeat;
-webkit-mask-image: radial-gradient(
circle at center left,
transparent 0,
transparent 6px,
red 7px
),
radial-gradient(
circle at center right,
transparent 0,
transparent 6px,
red 7px
);
-webkit-mask-size: 50% 100%, 50% 100%;
-webkit-mask-position: 0% 100%, 100% 100%;
-webkit-mask-repeat: no-repeat, no-repeat;
}
<div class="wrapper">
<div class="coupon coupon1">1. Contained</div>
<div class="coupon coupon2">2. Contained + Outlined</div>
<div class="coupon coupon3">3. Outlined</div>
<div class="coupon coupon4">4. Border 2px</div>
<div class="coupon coupon5">5. Border 0.5px </div>
<div class="coupon-demo">6. For debug purpose </div>
<div>

Diagonal split of 2 images with transition

I was wondering if it was possible to split a screen into 2 parts diagonally as shown on the picture. Once I'd hover over Picture A, the diagonal line would shift a bit to the right, revealing more of picture A while hiding a bit of picture B (I'm thinking transition?), and when I'd hover over picture B the opposite would happen.
Thanks in advance,
Martin
The diagonal image transition effect is unique request. I tried my best, Can you please check revealing effect.
section {
border: 1px solid black;
display: flex;
width: 400px;
box-sizing: border-box;
}
.diagonalHover {
position: absolute;
width: 66%;
height: 200px;
transition: all 0.3s ease-out;
}
.diagonalHover.first,
.diagonalHover.second {
background-image: url(https://cdn.pixabay.com/photo/2016/07/20/22/33/vajdahunyadvar-1531470_960_720.jpg);
background-repeat: no-repeat;
background-size: cover;
}
.diagonalHover.second {
background-image: url(https://cdn.pixabay.com/photo/2020/02/05/22/17/vendetta-4822543__340.jpg);
}
.diagonalHover.first:hover {
width: 75%;
z-index: 1;
}
.diagonalHover.second:hover {
width: 75%;
z-index: 1;
}
.diagonalHover.first:hover + .second {
}
.diagonalHover.first {
left: 0;
top: 0;
-webkit-clip-path: polygon(0 0, 100% 0%, 50% 100%, 0% 100%);
clip-path: polygon(0 0, 100% 0%, 50% 100%, 0% 100%);
}
.diagonalHover.second {
right: 0;
top: 0;
-webkit-clip-path: polygon(50% 0, 100% 0%, 100% 100%, 0% 100%);
clip-path: polygon(50% 0, 100% 0%, 100% 100%, 0% 100%);
}
<section>
<div class="diagonalHover first">
</div>
<div class="diagonalHover second">
</div>
</section>

How to get a border around this polygon?

I have created a shape with 5 corners using polygon as shown below.
This is the css needed to make it:
div {
width: 280px;
height: 280px;
background: #1e90ff;
-webkit-clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 0 48%, 0% 0%);
clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 0 48%, 0% 0%);
border: 3px solid black;
border-bottom-left-radius: 15px;
border-top-left-radius: 15px;
}
Unfortunately I cannot get it to add a black border all around the shape (it is missing on the right side). How would I do that?
I have created a fiddle here.
The border property goes around the outside of an element, and the clip-path property applies a mask to an element. So, as far as other CSS rules are concerned, you're still dealing with a rectangle. Because of this, you can't simply apply a border.
It's not impossible to get very close to the effect you want, however. Using (and abusing) CSS pseudo-elements, borders, and filters you can create the same shape plus an outline with only a single HTML div.
div {
position: relative;
width: 210px;
height: 280px;
background: #1e90ff;
border-bottom-left-radius: 15px;
border-top-left-radius: 15px;
filter:
drop-shadow( 0px 3px 0 black)
drop-shadow( 0px -3px 0 black)
drop-shadow( 3px 0px 0 black)
drop-shadow(-3px 0px 0 black);
-webkit-filter:
drop-shadow( 0px 3px 0 black)
drop-shadow( 0px -3px 0 black)
drop-shadow( 3px 0px 0 black)
drop-shadow(-3px 0px 0 black);
}
div::after {
position: absolute;
display: block;
content: '';
width: 0;
height: 0;
left: 210px;
top: 0;
border-left: 70px solid #1e90ff;
border-right: 70px solid transparent;
border-top: 140px solid transparent;
border-bottom: 140px solid transparent;
}
<div>
</div>
So, what's going on here?
The main div element is just the rectangular portion of the shape (with rounded top-left and bottom-left corners). It also has an ::after pseudo-element which creates the triangle shape. The triangle shape is done using the CSS border-triangle hack.
Okay, so that creates the shape without having to mask off any of the element, but a border still can't be applied directly, since I've already (ab)used the border to create the triangle. Using a CSS outline or box-shadow would be the next logical choice, but both properties go all the way around the element's bounding-box... ignoring features like rounded corners or hacky transparent borders.
Enter the CSS filter property. This provides a family of post-processing filters. The important thing to note is that they treat the element as a transparency mask when being applied, rather than respecting the element's bounding-box... and there is a drop-shadow filter!
Unfortunately, it's not quite as flexible as the box-shadow property in that it doesn't have a "spread" parameter which can be used to create solid shapes that are larger than the element. To get around this, we need to cast a drop-shadow in every direction: up, down, right, and left. That's where this monstrosity comes in:
filter:
drop-shadow( 0px 3px 0 black)
drop-shadow( 0px -3px 0 black)
drop-shadow( 3px 0px 0 black)
drop-shadow(-3px 0px 0 black);
Ta-da!
Expanding on this: this works on any shape you can manage to create (as long as it done without clipping). Just apply a drop-shadow filter to the element, or to a parent/wrapper div (if it's a multi-element shape) to get a border.
I'm on a bit of a pseudo kick here, but You can always recreate the element with a black color and throw it behind the original, giving the impression of an outline. Suitable for most purposes, the proposal is demonstrated in this codepen: http://codepen.io/anon/pen/MeJorM
CSS in the codepen has been changed up a bit. Your original is ".orig".
div.orig {
position:relative;
width: 280px;
height: 280px;
background: #1e90ff;
-webkit-clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 0 48%, 0% 0%);
clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 0 48%, 0% 0%);
border: 1px solid black;
border-bottom-left-radius: 15px;
border-top-left-radius: 15px;
display:block;
}
div.abc {
position:relative;
width: 280px;
height: 280px;
background: #000;
-webkit-clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 0 48%, 0% 0%);
clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 0 48%, 0% 0%);
border: 1px solid black;
border-bottom-left-radius: 15px;
border-top-left-radius: 15px;
display:block;
}
div.abc div.def{
top:-0.02em;
left:-0.2em;
position:absolute;
display:block;
width: 278px;
height: 280px;
background: #1e90ff;
-webkit-clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 0 48%, 0% 0%);
clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 0 48%, 0% 0%);
border: 1px solid black;
border-bottom-left-radius: 15px;
border-top-left-radius: 15px;
}

How can I render country flags as a ribbon, using CSS only?

I need to present some data. Each block of data needs a country flag. I would like to display the country flag, using a nice little hanging banner, like this:
This image is edited in paint, and the example I've used, comes from this page
This link right here, shows how to display flags of Europe++ in pure CSS. In my system, I only need Nordic flags, which are all represented by a cross.
From the codepen example:
#function cross($back, $main, $detail: $back){
#return linear-gradient(90deg, transparent 28%, $main 28%, $main 34%, transparent 34%),
linear-gradient(transparent 42%, $detail 42%, $detail 46%, $main 46%, $main 58%, $detail 58%, $detail 62%, transparent 62%),
linear-gradient(90deg, $back 25%, $detail 25%, $detail 28%, $main 28%, $main 34%, $detail 34%, $detail 37%, $back 37%);
}
If I derive this (and rotate it 90deg to fit my preferred orientation, I can get something like this:
HTML:
<div class="norway"></div>
CSS:
.norway{
background: linear-gradient(180deg, transparent 28%, blue 28%, blue 34%, transparent 34%),
linear-gradient(90deg, transparent 42%, white 42%, white 46%, blue 46%,
blue 58%, white 58%, white 62%, transparent 62%),
linear-gradient(180deg, red 25%, white 25%, white 28%, blue 28%, blue 34%,
white 34%, white 37%, red 37%);
height: 600px;
width: 400px;
}
The hanging banner example however, is not really displaying the element itself, merely its border. I like the split in the bottom, So I would like to be able to set the linear gradients on the different border sides individually, or somehow otherwise solve the problem. I have tried a few approaches, but I can't seem to make the gradients work on individual border sides.
Does anyone know how I can display my flags as split end ribbons, using only CSS?
By the way, the Czech Republic is easy...
UPDATE:
I was able to render a Norwegian version, but I had to make two elements. One displaying the flag in the background of an element, and another element over it, displaying only the bottom border, in the same color as the block background. It seems like a pretty fragile solution, though...
https://jsfiddle.net/azjctc1y/
Note: After looking at Joseph's answer, I'd suggest you to go with that but this is another way.
Instead of using border to create the flag, we can use background with linear-gradient images like in the below snippet.
/* Latest compiled and minified CSS included as External Resource*/
html {
margin: 20px;
}
/* Optional theme */
#import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
body {
margin: 10px;
}
.test-container {
background-color: lightgrey;
border: 1px solid black;
position: relative;
padding: 10px;
margin: 10px;
min-height: 100px;
}
.close-ribbon {
position: absolute;
top: 0;
right: 1em;
z-index: 1;
color: #eee;
font-size: 2em;
}
.close-ribbon:before {
content: "";
font-size: 0.5em;
position: absolute;
border-style: solid;
border-color: transparent transparent #B71C1C transparent;
top: -1em;
right: 3em;
border-width: 0 0 1em 0.7em;
z-index: -1;
}
.close-ribbon:after {
position: absolute;
content: "";
top: -1em;
right: 0;
height: 5em;
width: 3em;
background: linear-gradient(to bottom right, transparent 48%, lightgrey 52%), linear-gradient(to bottom left, transparent 48%, lightgrey 52%), linear-gradient(180deg, transparent 38%, blue 38%, blue 44%, transparent 44%), linear-gradient(90deg, transparent 40%, white 40%, white 46%, blue 46%, blue 56%, white 55%, white 62%, transparent 62%), linear-gradient(180deg, red 35%, white 35%, white 38%, blue 38%, blue 44%, white 44%, white 47%, red 47%), linear-gradient(to bottom right, red 50%, lightgrey 55%), linear-gradient(to top right, lightgrey 45%, red 50%);
background-size: 1.6em 1.4em, 1.45em 1.4em, 3em 4em, 3em 4em, 3em 4em, 1.2em 1.1em, 1.2em 1.1em;
background-position: 0% 100%, 100% 100%, 0% 0%, 0% 0%, 0% 0%, 0% 100%, 100% 100%;
background-repeat: no-repeat;
font-size: 0.5em;
z-index: -1;
-webkit-transition: height 0.5s;
transition: height 0.5s;
}
<div class="container">
<div class="row">
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
<div class="test-container">
<a class="close-ribbon"></a>
Czech Republic is easy...
</div>
</div>
</div>
</div>
Original Answer:
It is not 100% like the image provided in question or the ouput of your fiddle because the blue cross doesn't have the small triangular cut because I was trying create a cut that was transparent (so that you can use it on top of an element with any background). But if it is always going to be a grey background then that can also be done.
The below is the code that I have added:
.close-ribbon:after {
position: absolute;
content: "";
top: -1em;
right: 0;
height: 5em;
width: 3em;
background: linear-gradient(180deg, transparent 28%, blue 28%, blue 34%, transparent 34%), linear-gradient(90deg, transparent 40%, white 40%, white 46%, blue 46%, blue 58%, white 58%, white 62%, transparent 62%), linear-gradient(180deg, red 25%, white 25%, white 28%, blue 28%, blue 34%, white 34%, white 37%, red 37%), linear-gradient(to bottom right, red 50%, transparent 55%), linear-gradient(to top right, transparent 45%, red 50%);
background-size: 3em 4em, 3em 4em, 3em 4em, 1.25em 1em, 1.2em 1em;
background-position: 0% 0%, 0% 0%, 0% 0%, 0% 100%, 100% 100%;
background-repeat: no-repeat;
/* other styles */
}
/* Latest compiled and minified CSS included as External Resource*/
/* Optional theme */
#import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
body {
margin: 10px;
}
.test-container {
background-color: lightgrey;
border: 1px solid black;
position: relative;
padding: 10px;
margin: 10px;
min-height: 100px;
}
.close-ribbon {
position: absolute;
top: 0;
right: 1em;
z-index: 1;
color: #eee;
font-size: 2em;
}
.close-ribbon:before {
content: "";
font-size: 0.5em;
position: absolute;
border-style: solid;
border-color: transparent transparent #B71C1C transparent;
top: -1em;
right: 3em;
border-width: 0 0 1em 0.7em;
z-index: -1;
}
.close-ribbon:after {
position: absolute;
content: "";
top: -1em;
right: 0;
height: 5em;
width: 3em;
background: linear-gradient(180deg, transparent 28%, blue 28%, blue 34%, transparent 34%), linear-gradient(90deg, transparent 40%, white 40%, white 46%, blue 46%, blue 58%, white 58%, white 62%, transparent 62%), linear-gradient(180deg, red 25%, white 25%, white 28%, blue 28%, blue 34%, white 34%, white 37%, red 37%), linear-gradient(to bottom right, red 50%, transparent 55%), linear-gradient(to top right, transparent 45%, red 50%);
background-size: 3em 4em, 3em 4em, 3em 4em, 1.2em 1em, 1.2em 1em;
background-position: 0% 0%, 0% 0%, 0% 0%, 0% 100%, 100% 100%;
background-repeat: no-repeat;
font-size: 0.5em;
z-index: -1;
-webkit-transition: height 0.5s;
transition: height 0.5s;
}
<div class="container">
<div class="row">
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
<div class="test-container">
<a class="close-ribbon"></a>
Czech Republic is easy...
</div>
</div>
</div>
</div>
You have a great base to go on. It just needs a few tweaks here and there. (Making individual styles for flags is going to be a colossal pain though). There's just a few places you could improve it. In most cases when using absolute positioning, you may want to have whatever you are positioning align with some edge of the parent element. For that you can use negative values like left: -1em or whatever, but a lot of times, it's more robust to leave left auto and set the right attribute to 100%. You also set the bottom border to right:0. In throwing it in this answer I discovered that the font size difference caused it to be aligned incorrectly. One way you can fix that is to give it a left:50% with a negative margin equal to the left border. In this case it's 1.5em. A few changes, but it's all about understanding and leveraging top, right, bottom, and left to their fullest potential, which includes percent based values.
Hope it helps!
body {
padding: 2em;
}
/* Latest compiled and minified CSS included as External Resource*/
/* Optional theme */
#import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
body {
margin: 10px;
}
.test-container{
background-color: lightgrey;
border: 1px solid black;
position: relative;
padding: 10px;
margin: 10px;
min-height: 100px;
}
.ribbon {
position: absolute;
top: 0;
right: 1em;
z-index: 1;
color: #eee;
font-size: 2em;
}
.norway {
position: absolute;
top: -0.5em;
right: 1em;
z-index: 1;
font-size: 2em;
height: 70px;
width: 42px;
background: linear-gradient(180deg, transparent 28%, blue 28%, blue 34%, transparent 34%),
linear-gradient(90deg, transparent 40%, white 40%, white 46%, blue 46%, blue 54%, white 54%, white 60%, transparent 60%),
linear-gradient(180deg, red 25%, white 25%, white 28%, blue 28%, blue 34%, white 34%, white 37%, red 37%);
}
.ribbon:before {
content: "";
font-size: 0.5em;
position: absolute;
border-style: solid;
border-color: transparent transparent #B71C1C transparent;
top: 0;
right: 100%;
border-width: 0 0 1em 0.7em;
z-index: -1;
}
.ribbon:after {
content: "";
font-size: 0.5em;
position: absolute;
height: 5em;
border: 1.5em solid #F44336;
z-index: -1;
bottom: 0;
border-top-width: 1.5em;
border-bottom-color: lightgrey;
border-right-color: transparent;
border-left-color: transparent;
border-top-color: transparent;
left: 50%;
margin-left: -1.5em;
-webkit-transition: height 0.5s;
transition: height 0.5s;
}
<div class="container">
<div class="row">
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
<div class="test-container">
<a class="norway ribbon"></a>
Norway
</div>
</div>
</div>
</div>
Inserted a div into the anchor tag and styled a before and after content to display the blue cross. Used a + symbol to display the white underneath cross.
jsfiddle.net/8g1w5va9/4
EDIT
Just saw your fiddle. Looks good! Was just going to suggest something like that but decided to at least build somewhat of a working model.