Angled CSS background with bottom border. - html

I'm trying to create a CSS background that looks like this:
I've been able to create the shape, but can't figure out how to add the bottom border, and am starting to think my approach may be the problem.
So far I have the following CSS:
#top-background-flag {
border-top: 2px solid #C2C2C2;
background: linear-gradient(
to bottom right,
#5DCAD3 50%,
transparent 50.5%
)
no-repeat bottom, /* bottom part */
linear-gradient(100deg, #5DCAD3, #5DCAD3) no-repeat top;
/* top portion */
padding-bottom: 3.5rem;
border-bottom: 2px solid #C2C2C2;
background-size: 100% 3rem, 100% calc(100% - 3rem)
}
and HTML:
<div id=top-background-flag>
A fun title
</div>
and a code pen: https://codepen.io/arel/pen/PKXGmd
My problem right now is that the bottom border is a horizontal line, and I can't figure out how to have it follow the angle of the box.
Here is what I have so far:

Trying to use a linear gradient may not be the best solution here.
Appending an object with a little CSS transformation some judicious layering will accomplish what you want and will have fewer properties to adjust if you want to change the angle later.
#top-background-flag {
border-top: 2px solid #C2C2C2; /* top border on the parent */
position: relative;
padding-bottom: 3.5rem;
overflow: hidden;
}
#top-background-flag:before {
background-color: #5DCAD3;
transform: skewy(-4deg); /* angle you want */
transform-origin: bottom left;
border-bottom: 2px solid #C2C2C2; /* bottom border skews with the object */
content: ' ';
display: block;
height: 100%;
width: 100%;
position: absolute;
z-index: -1;
bottom: 0;
}
Here is a working example to play with

Add this CSS to fake a bottom border:
#top-background-flag:after {
content: "";
background-color: red;
height: 2px;
width: 100%;
position: absolute;
left: 0;
bottom: 23px;
transform: rotate(-5.5deg);
}
Here is a working fork of your codepen: https://codepen.io/anon/pen/XaojPp

I'm not sure that this is what you are looking for, but you can use the :after pseudo class with the content trick:
body {
max-width: 500px;
}
#top-background-flag {
border-top: 2px solid #C2C2C2;
background: linear-gradient(
to bottom right,
#5DCAD3 50%,
transparent 50.5%
)
no-repeat bottom, /* bottom part */
linear-gradient(100deg, #5DCAD3, #5DCAD3) no-repeat top;
/* top portion */
padding-bottom: 3.5rem;
border-bottom: 2px solid #C2C2C2;
background-size: 100% 3rem, 100% calc(100% - 3rem);
position: relative;
}
#top-background-flag:after {
content: '';
border-bottom: 1px solid red;
border-top: 1px solid red;
position: absolute;
width: 100%;
bottom: 22px;
left: 0;
transform: rotate(-5.5deg);
}
<div id=top-background-flag>
A fun title
</div>

Related

How do I add a triangle at the end of a div with opacity 0.2?

I want it to turn out like this, but unfortunately my triangle goes into the background of the next stage. I spent 3 hours on it. Help please
https://stackblitz.com/edit/angular-3llbmq?file=src/components/sales-funnel/sales-funnel.component.html
Here it is done with polygon, adapt colors yourself
div.container {
display: inline-flex;
align-items: center;
position: relative;
background: black;
width: 100%;
}
div.tangle {
height: 50px;
width: 200px;
clip-path: polygon(0% 20%,
60% 20%,
95% 20%,
100% 50%,
95% 80%,
60% 80%,
0% 80%);
}
div.tangle:nth-child(1) {
background:lightgreen;
transform: translateX(20px);
z-index:3;
}
div.tangle:nth-child(2) {
background:green;
transform: translateX(10px);
}
div.normal {
height: 30px;
width: 200px;
background: white;
}
<div class="container">
<div class="tangle"></div>
<div class="tangle"></div>
<div class="normal"></div>
</div>
This can easily be achieved with the use of ::before and ::after pseudo-elements - with one providing the background of the 'next step' and one providing the triangle with the 'current step' bg color.
Not sure if you neeed a elements in the lis - so I just did straight li's but it would not be hard to change the styling for the use of a elements.
Its best not to try to to use opacity for the step differences - its more accessible to use hex codes directly rather than the one hex code with different opacity values.
Note that the solution of preventing the bleeding color is to space the li's apart with margin and to use the before / after pseudo-elements to fill the gaps - its better to do this than overlap the element over he next step to prevent issues with clicking on areas that are covered by the triangles
ul {
display: flex;
list-style: none;
padding: 0;
border: solid 1px #d4d4d4;
background: lemonChiffon
}
li {
font-size: 16px;
line-height: 20px;
margin-right: 16px;
padding: 4px 32px 4px 8px;
position: relative;
}
.visited {
background: #AFD954;
color: #fff;
}
.visited::before {
content: '';
width: 16px;
height: 28px;
z-index: 5;
position: absolute;
top: 0;
right:-16px;
background: #9BCE29
}
.visited::after {
content: '';
width: 0;
height: 0;
border-top: 14px solid transparent;
border-bottom: 14px solid transparent;
border-left: 14px solid #AFD954;
position: absolute;
right:-14px;
z-index: 9;
top: 0
}
.active {
background: #9BCE29;
color: #fff
}
.active::before {
content: '';
width: 16px;
height: 28px;
z-index: 5;
position: absolute;
top: 0;
right:-16px;
background: lemonChiffon
}
.active::after {
content: '';
width: 0;
height: 0;
border-top: 14px solid transparent;
border-bottom: 14px solid transparent;
border-left: 14px solid #9BCE29 ;
position: absolute;
right:-14px;
z-index: 9;
top: 0
}
.not-visited {
background: lemonChiffon
}
<ul>
<li class="visited">New Deal</li>
<li class="active">Contact</li>
<li class="not-visited">Qualified</li>
</ul>
I had edited your stackbliz example. Please note the HTML and CSS changes.
Don't use opacity to lighten the color. Instead, use SCSS lighten and darken methods.
Please utilize the most of the CSS than the HTML part for the assigning styles. Utilize the classes you have.
NOTE: Please take the benefit of SCSS variables, nesting and pre-defined methods.
Added the reverse z-index to stack the previous element to place over next element.
Below 6 is the total elements
[ngStyle]="{
zIndex: 6 - i
}"
https://stackblitz.com/edit/angular-jhk6qf?file=src/components/sales-funnel/sales-funnel.component.scss

How to shorten the length of underline by reducing 30px from both ends in HTML?

I want to add an underline under my h1 heading and make it just a little short then the heading itself. 30px space should remove from both ends. how to fix this?
<h1>Heading</h1>
h1 {
border-bottom: 2px solid #000000;
width: fit-content;
}
h1 {
position: relative;
display: inline-block;
}
h1:after {
content: "";
width: calc(100% - 60px);
height: 100%;
position: absolute;
left: 30px;
border-bottom: 2px solid black;
}
<h1>Heading</h1>
One way to do it is with ::after element. Use left to shift it for 30px.
It depends a bit on what you want to do if the heading is long and overflows to another (shorter) line, but assuming you literally want just a border shortened by 60px then you can add a before pseudo element of the same height but less width.
h1 {
width: fit-content;
position: relative;
--indent: 30px;
}
h1::before {
width: calc(100% - (2 * var(--indent)));
height: 100%;
content: '';
position: absolute;
top: 0;
left: var(--indent);
;
border-bottom: 2px solid #000000;
}
<h1>Heading</h1>
This snippet defines a variable with the indent required (30px) so it will be easy for you to change it if required.
You may fake the underline via a background and shorten it via background-size:
here is an example of the idea:
h1 {
background: linear-gradient(to top, #000000 0 2px, transparent 2px) 50% 0 / calc(100% - 60px) 100% no-repeat;
width: fit-content;
}
h2 {
color: green;
margin: auto;
background: linear-gradient(to top, currentColor 0 2px, transparent 2px) 50% 0 / calc(100% - 60px) 100% no-repeat;
width: fit-content;
}
h2+h2 {
color: tomato;
line-height: 0.95em;
transition:0.25s
}
h2 + h2:hover {line-height:1.6em;}
<h1>Heading</h1>
<p>extras for infos</p>
<h2>Match colors via currentColor</h2>
<h2>move that fake underline closer or further away</h2>

Is there a CSS solution for this design?

Here's my issue:
I have a mockup from a design company that wants a text block with a 'broken' square border behind some big text that looks like this (description: there is a small white frame behind large text that is broken up by the text, and then a smaller text link below):
Image of an element on client's website,
In the design, the text is displayed accross the white square frame. The way I have implemented it right now is to make the big text's background color gray. Because the current image's background is gray the desired effect is achieved.
What is needed is to achieve that effect (of breaking the white frame) REGARDLESS of the appearance of the image. Because right now, this happens:
the gray background of the text appears like a box in front of the image -- it ought to be transparent
To further illustrate, if I set the background-color of the big text to transparent, the whole frame is shown (the desired effect is a broken frame):
background: transparent #1
More info if it helps:
The white frame element is just a div with a white border.
I am not sure exactly what to search for in this case, if there is an appropriate CSS solution (preferrable) or if I need to use SVG or maybe a PNG? Thank you for any help.
As #Temani Afif pointed out in the comments, it's not one box, but two separate shapes in CSS.
I made an example to illustrate this using flexbox.
.page {
background-color: black;
width: 400px;
height: 400px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.box-top {
width: 100px;
height: 10px;
border-color: white;
border-width: 2px;
border-style: solid;
border-bottom: none;
}
.box-bottom {
width: 100px;
height: 30px;
border-color: white;
border-width: 2px;
border-style: solid;
border-top: none;
}
.separator {
color: white;
width: 100%;
margin: 5px 0;
padding: 0;
font-size: 40px;
text-align: center;
}
<div class="page">
<div class="box-top"></div>
<p class="separator">
Headline
</p>
<div class="box-bottom"></div>
</div>
You can make a square element with a border and use a mask on it:
body {
margin: 0;
min-height: 100vh;
background: black;
box-sizing: border-box;
padding-top: 1px;
}
h2.fancy {
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 40px, 100% 40px, 100% 100%, 0 100%);
}
<h2 class=fancy>I'm a fancy title...</h2>
The advantage of this solution is that you can make it scale easily with what might change on various screen sizes. For example, with the title's font-size:
document.querySelector('input.font-size').addEventListener('input', function(e) {
document.querySelector('h2').style.fontSize = e.target.value + 'px';
})
body {
margin: 0;
min-height: 100vh;
background: url(https://picsum.photos/800) center /cover;
box-sizing: border-box;
padding-top: 1px;
}
.overlay {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.5);
}
h2.fancy {
z-index: 1;
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
display: block;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 calc(10px + 1.3em), 100% calc(10px + 1.3em), 100% 100%, 0 100%);
}
input[type=range] {
position: absolute;
bottom: 1rem;
left: 1rem;
z-index: 1;
}
<h2 class=fancy>I'm a fancy title...</h2>
<div class=overlay></div>
<input type=range min=12 max=36 class=font-size>
The disadvantage is that it doesn't work in IE or Edge lower than 18 or in Opera mini. This particular example works in IE 18, though, as it only uses polygon().

Right banner arrows purely in CSS

I'm trying to recreate these arrows in CSS for a website I'm redesigning to be responsive. These two guys were done with static images but I'd like them to be pure CSS.
This is a sprite that was used for mouseover replacement. The bottom is the mouseover state. The background behind the arrow needs to be transparent.
I thought it would be a simple div with a p or heading tag inside:
<div class="arrow_box">
<p>UTILITIES</p>
</div>
I've searched for examples everywhere and everything I've tried to modify never lets me seem to have full control of the width and height of the element. The width (with the arrow) is 114px. The height (of a single state) would be 29px.
I've played with this for the better part of an hour trying to get it properly sized but nothing seems to work. http://codepen.io/anon/pen/bpBGQL My lack of knowledge on how this works is partially to blame.
So the trick, here, is being able to control the height correctly. Here, I've got the text in a span with a line-height : 0, and padding:15px. Now, we have precisely 30px of height, and can use an ::after pseudo element to fabricate the arrow. The width will be set by the text content, but can be defined with an explicit width rule, as well.
<div class="arrow"><span>text</span></div>
.arrow{
display:inline-block;
height:auto;
background-color:orange;
}
.arrow span{
display:inline-block;
line-height:0;
padding:15px;
color:white;
}
.arrow::after{
width: 0;
height: 0;
position: absolute;
right:0
top: 0;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
border-left: 15px solid orange;
content: "";
}
Add whatever colors / hover states you require. You can see some basic rules in the working fiddle.
Fiddle
You can do this with :after pseudo element. You can change color of pseudo element on hover state like this .arrow_box:hover:after
* {
box-sizing: border-box;
}
p {
margin: 0;
padding-left: 10px;
}
.arrow_box {
background: #627680;
display: block;
color: white;
position: relative;
height: 30px;
line-height: 30px;
width: 114px;
transition: all 0.3s ease-in;
}
.arrow_box:after {
content: '';
height: 0;
width: 0;
position: absolute;
top: 0;
right:0;
transform: translateX(100%);
border-bottom: 15px solid transparent;
border-top: 15px solid transparent;
border-left: 20px solid #627680;
border-right: 15px solid transparent;
transition: all 0.3s ease-in;
}
.arrow_box:hover {
background: #2A92C2;
}
.arrow_box:hover:after {
border-left: 20px solid #2A92C2;
}
<div class="arrow_box">
<p>UTILITIES</p>
</div>
did you consider gradient backgrounds ?
body {
background: linear-gradient(45deg, gray, lightgray, gray, lightgray, gray, lightgray, gray, lightgray, gray, lightgray, gray, lightgray);
/* demo purpose only */
}
.arrow {
text-transform: uppercase;
/* optionnal */
padding: 3px 1.5em 3px 0.5em;
color: white;
background: linear-gradient(225deg, transparent 0.6em, #627680 0.6em) top no-repeat, linear-gradient(-45deg, transparent 0.6em, #627680 0.6em) bottom no-repeat;
background-size: 100% 50%;
/* each gradient draws half of the arrow */
}
.arrow:hover {
/* update gradient color */
background: linear-gradient(225deg, transparent 0.6em, #2A92C2 0.6em) top no-repeat, linear-gradient(-45deg, transparent 0.6em, #2A92C2 0.6em) bottom no-repeat;
background-size: 100% 50%;
}
<span class="arrow"> Utilities</span> <span class="arrow"> testing</span>
You may also want to take a look at Responsive Arrow Breadcrumb Navigation for breadcrumbs and imbricated arrows or Create dynamic arrow-like shape with CSS
Does this pen provide what you need?
http://codepen.io/anon/pen/dMOPmV (may require some pixel pushing to get it perfect)
It just required adjusting:
border-width: 27px;
margin-top: -35px;
and adding a hover state for the main element and before element.

Is it possible to progressively taper a CSS 'border-right' like a needle?

Edit: *old question was using images which have since expired; rewritten the same question.
I am needing to progressively taper a line in css to sub-single pixel widths. This is to mimic a design which was handed to me, imagine a single-side border with 2px width progressively thinning along a line until it's nothing.
Any tips are much appreciated!
Here, a quick example (live demo):
HTML:
<nav id="main-nav">
Link 1
Link 2
Link 3
Link 4
Link 5
</nav>
CSS:
#main-nav {
padding: 40px 20px;
width: 150px;
position: relative;
}
#main-nav a {
display: block;
}
#main-nav:after {
content: '';
position: absolute;
right: 0;
top: -10%;
width: 1px;
height: 120%;
background-image: linear-gradient(to top, #666 75%, transparent);
}
#main-nav:before {
content: '';
position: absolute;
left: -10%;
top: 0;
width: 120%;
height: 1px;
background-image: linear-gradient(to right, #666 75%, transparent);
}
You could use this. This is only any use if you a) are happy with CSS only and b) don't want any content in the div.
Think of the border-top and border-left as sort x and y coordinates.
By specifying a width and height of 0px, it allows you to shape the div purely using your borders:
div {
width:0px;
height:0px;
border-left:solid 5px rgba(0,0,0,0);
border-top:solid 50px rgba(0,0,0,0);
border-right:solid 5px blue;
border-bottom:solid 50px blue;
}
Bear in mind that this approach only allows linear tapering.