How to create a slanted Progress Bar using CSS? - css

I'm making progress bar with CSS. I want to make the end of the section inside the bar oblique. How can I do as pictured?
.progress-bar{
height: 34px;
background: #0C0C0C;
display: flex;
flex: 1 auto;
width: 100%;
position: relative;
}
.progress-bar div{
width: 69%;
background: #1EA614;
height: 100%;
}
.progress-bar div span{
position: absolute;
font-size: 24px;
width: 100%;
left: 0;
justify-content: center;
align-items: center;
display: flex;
height: 100%;
}
<div class="progress-bar">
<div>
<span>Level 5</span>
</div>
</div>

Here is a simplified version with less of code where you can easily control the curve, the color and the percentage of the progress
.progress-bar {
--s:20px; /* define the curve (make bigger to increase the curve, smaller to reduce)*/
--p:50; /* percentage of the progress without unit */
--c:#1EA614; /* color */
height: 34px;
line-height:34px;
background:
linear-gradient(to bottom right,var(--c) 49%,transparent 50%)
calc(1%*var(--p) + var(--p,0)/100*var(--s)) 0 / var(--s) 100%,
linear-gradient(var(--c) 0 0)
0 / calc(1%*var(--p)) 100%,
#0C0C0C;
background-repeat:no-repeat;
text-align: center;
font-size: 24px;
color:#fff;
margin:5px;
}
<div class="progress-bar">
Level 5
</div>
<div class="progress-bar" style="--p:30;--c:red;--s:10px">
Level 5
</div>
<div class="progress-bar" style="--p:70;--c:lightblue;--s:40px">
Level 5
</div>
<div class="progress-bar" style="--p:100;--s:40px">
Level 5
</div>

You could use a gradient to accomplish this, as I do below.
The only line that I've changed is
background-image: linear-gradient(105deg, #1EA614 0%, #1EA614 85%, transparent 85%);
Essentially, we declare a gradient background that's on an angle which roughly lines up with the photo you gave. Then, we set the stops like so:
At 0% (all the way to the left) it's fully green;
85% of the way through we ensure that it's still fully green. This means that there is no graduation between the original green and the black, and thus that we get a sharp transition.
85% of the way through (so directly after) we make it black. Because this is so close to the previous stop, the transition between them is instant, and we get the effect you're looking for.
Note that this number, 85%, does need some tweaking to make sure that the cutoff is the same all of the way through.
Here's your demo again, but with this code added in. I've also added an animation, so that you can see it works at all width stages of the bar.
.progress-bar{
height: 34px;
background: #0C0C0C;
display: flex;
flex: 1 auto;
width: 250px;
position: relative;
}
.progress-bar div{
width: 100%;
background-size: cover;
background-position: -250px 0;
background-repeat: no-repeat;
background-image: linear-gradient(105deg, #1EA614 0%, #1EA614 96%, transparent 96%);
height: 100%;
animation: bar 2s linear infinite;
}
.progress-bar div span{
position: absolute;
font-size: 24px;
width: 100%;
left: 0;
justify-content: center;
align-items: center;
display: flex;
height: 100%;
}
#keyframes bar {
0% {
background-position: -250px 0;
}
100% {
background-position: 0 0;
}
}
<div class="progress-bar">
<div>
<span>Level 5</span>
</div>
</div>
If you're having issues with it not filling the entire bar, you could try just moving the gradient across the bar, rather than changing the bar's width. I've updated my example to do this.
References:
https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient

.progress{
height: 34px;
background: #0C0C0C;
display: flex;
flex: 1 auto;
width: 100%;
position: relative;
}
.progress .progress-bar{
width: 60%;
background: #1EA614;
height: 100%;
position: relative;
overflow: hidden;
}
.progress span{
position: absolute;
font-size: 24px;
width: 100%;
left: 0;
justify-content: center;
align-items: center;
display: flex;
height: 100%;
}
.progress .progress-bar:after{
content: "";
position: absolute;
top: -1px;
right: -6.5px;
height: 115%;
width: 13px;
background: #0C0C0C;
transform: rotate(20deg);
}
<div class="progress">
<div class="progress-bar"></div>
<span>Level 5</span>
</div>

Related

how to make css background with round shapes

I wanted to make a format divided into two parts with the shape of curves, only the background visual, with different colors and without affecting the position of any element.
EXAMPLE
I wanted to do something like this, I remember having seen something similar using linear or radial gradient but I can't find it, it's just for the background without applying any kind of division or border
I think you can make something like
wave background but just rotate it.
<section>
<!-- content here -->
<div class="curve"></div>
</section>
section {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
min-height: 400px;
padding-top: 100px;
background: #3c31dd;
}
.curve {
position: absolute;
height: 250px;
width: 100%;
bottom: 0;
text-align: center;
}
.curve::before {
content: '';
display: block;
position: absolute;
border-radius: 100% 50%;
width: 55%;
height: 100%;
transform: translate(85%, 60%);
background-color: hsl(216, 21%, 16%);
}
.curve::after {
content: '';
display: block;
position: absolute;
border-radius: 100% 50%;
width: 55%;
height: 100%;
background-color: #3c31dd;
transform: translate(-4%, 40%);
z-index: -1;
}

Opacity for only a part of background image - CSS

Do you maybe know how (and if) I can add an opacity for the background image but only to PART of it?
The effect should be like this one: https://i.stack.imgur.com/HYvaU.png.
I have only added the image as a background but I cannot find any solution for this oppacity.
My HTML:
<header>
<img src="images/logo.svg" />
<h1>A history of everything you copy</h1>
<p>
Clipboard allows you to track and organize everything you copy.
Instantly access your clipboard on all your devices.
</p>
</header>
And CSS:
body {
font-family: "Bai Jamjuree", sans-serif;
text-align: center;
}
#media (min-width: 1200px) {
header {
width: 100%;
background-image: url(images/bg-header-desktop.png);
background-size: 100%;
background-repeat: no-repeat;
padding-top: 50px 150px;
}
}
h1 {
color: hsl(210, 10%, 33%);
font-size: 35px;
margin-bottom: 15px;
}
header > p {
color: hsl(201, 11%, 66%);
font-size: 18px;
}
Thank you in advance!
I have tried to use mask-image but it didn't work:
#media (min-width: 1200px) {
header {
width: 100%;
background-image: url(images/bg-header-desktop.png);
mask-image: linear-gradient(180deg, rgba(0, 0, 0, 1), transparent 74%);
background-size: 100%;
background-repeat: no-repeat;
padding-top: 50px 150px;
}
}
Do you have maybe any idea if I can give an opacity only for the bottom part of this background image using CSS?
With more than 1 background, you can put image in 1 and opacity on the other.
You can change 2nd background color as you want. It's opacity value is given by the RGBA background color (here 0.75 in the snippet).
body {
margin: 0;
padding: 0;
}
.wrapper {
position: absolute;
width: 100vw;
height: 50vh;
top: 50%;
transform: translateY(-50%);
font-size: 10em;
font-weight: bold;
font-family: sans-serif;
background: url("https://picsum.photos/id/22/1280/600");
}
.wrapper1 {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
clip-path: inset(50% 0 0 0);
background-color: rgba(255, 255, 255, 0.75);
display: flex;
justify-content: center;
align-items: center;
}
.wrapper2 {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 2;
}
<div class="wrapper">
<div class="wrapper1"></div>
<div class="wrapper2">Hello World!</div>
</div>
Look at the snipper in full scree, for this demo I put width 100vw, so in small result is "strange"

Are there any way to change color of part of a string?

I'am beginner at frontend, and got some design-layout to train. Designer expects that on hover part of string or even letter will change color Example
I thought about CSS 'clip', but doubt
I change the snippet. Play with font-size.
body {
margin: 0;
padding: 0;
}
.wrapper {
position: absolute;
width: 100vw;
height: 50vh;
top: 50%;
transform: translateY(-50%);
font-size: 3em;
font-weight: bold;
font-family: sans-serif;
background-color: red;
}
.wrapper1 {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
clip-path: inset(0 50% 0 0);
background-color: blue;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper2 {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
clip-path: inset(0 0 0 50%);
background-color: green;
display: flex;
justify-content: center;
align-items: center;
}
<div class="wrapper">
<div class="wrapper1">Hello World!</div>
<div class="wrapper2">Hello World!</div>
</div>
As G-Cyrillus has pointed out, background-clip with value text can be used, it will 'cut out' characters from the background.
In this simple snippet the background is half white, half black and the blue/white background is supplied in a pseudo before element.
Note that the property requires a -webkit- prefix in some browsers.
* {
margin: 0;
}
div::before {
background-image: linear-gradient(to right, blue 0 50%, white 50% 100%);
content: '';
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: -1;
}
div {
position: relative;
width: 100vw;
height: 500px;
font-size: 50px;
text-align: center;
rmix-blend-mode: difference;
rcolor: white;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
background-image: linear-gradient(to right, white 0 50%, black 50% 100%);
}
<div>Hello how are you?</div>
So, Thanks for your help, A Haworth , G-Cyrillus! I think, I've found the solution. I experimented with background-clip:text, but in my case it was excess, but I used mix-blend-mode, thanks. I've found an article Taming Blend Modes: difference and exclusion, where explained filter:invert(1). Tried to show in snippet. When hover the cell part of title change color to white. But color of title and hovering background should be the same.My realized layout from designer
.block {
width: 100%;
height: 200px;
padding-top: 10px;
position: relative;
filter: invert(1);
}
h1 {
position: relative;
color: #091C91;
text-align:center;
font-size: 2rem;
z-index: 5;
mix-blend-mode:difference;
filter: invert(1);
}
.list {
display: flex;
justify-content: center;
border: 1px solid red;
height: 130px;
width: 100%;
position: absolute;
top: 0;
left: 0;
}
.column {
color: white;
flex: 0 1 25%;
border: 1px solid black;
filter: invert(1);
}
.column:hover {
background: #091C91;
}
<div class="block">
<h1>Snippet for Inverting colores</h1>
<div class="list">
<div class="column">Column 1</div>
<div class="column">Column 2</div>
<div class="column">Column 3</div>
<div class="column">Column 4</div>
</div>
</div>

Skewed Edges for multiple lines in headline

I ran into a little css problem. I'm trying to get skewed edges for a headline, which also workes for multiple lines (see in added screen). Important: The skewed edge should appear on every single line.
I already tried following solutions which didn't work 100%:
:after, :before Elements as Triangles or parallelogram (https://css-tricks.com/examples/ShapesOfCSS/)
.element {
background: red;
line-height: 30px;
width: 100px;
margin-right: 50px;
position: relative;
display: inline-block;
clear: both;
}
.element:after {
background: #f00;
content: "";
display: block;
height: 100%;
transform: skew(-20deg);
position: absolute;
right: -5px;
top: 0;
width: 30px;
}
<div class="element">Headline 1</div>
<div class="element">Headline 2 veeery long</div>
--> doesn't work for multiple line because it needs to meet the bottom-right top-left corner
Multi-Line Padded Text (https://css-tricks.com/multi-line-padded-text/) with skewed edges
--> doesn't work to make it skewed on the edges without pseudo-element. same problem like above.
Can you help me with a solution for this problem?
This should work with display inline:
body {
background: black;
}
div {
max-width: 300px;
}
h1 {
line-height: 46px;
color: #fff;
background-image: linear-gradient(110deg, transparent 50%, red 53%), linear-gradient(110deg, red 50%, transparent 53%), linear-gradient(to left, red, red);
background-size: 16px 100%, 16px 100%, calc(100% - 32px) 100%;
background-position: left, right, center;
background-repeat: no-repeat;
display: inline;
padding: 0 16px;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
}
<div><h1>Some dynamic text on several lines with no special meaning...</h1></div>
No Edge support for now as "box-decoration-break" is not supported (yet?).
Hope this helps you out. Here just applied linear gradient to in before and after element and positioned them absolute. Its height will increase according to the height of relative div.
In case you want to increase the curved area you just need to update width and position them left and right as per the amount of given width. As done in example.
.element {
line-height: 30px;
width: 100px;
margin-right: 50px;
position: relative;
display: inline-block;
clear: both;
psdding: 10px;
background: #f00;
padding: 10px;
}
.element:after, .element:before {
content: "";
width: 10px;
position:absolute;
height: 100%;
}
.element:before {
top: 0px; background: linear-gradient(to top left, #ff0000 50%, transparent 50%);
left: -10px;
}
.element:after {
top: 0px; background: linear-gradient(to bottom right, #ff0000 50%, transparent 50%);
right: -10px;
}
<div class="element">Headline 1</div>
<div class="element">Headline 2 veeery long</div>
Looking at you link provided,
This according to me is best answer... ( hope so )
Increasing the element width as I did in below code snippet ,
width: 200px;
Will work fine with the way you want Sample Here
View Code snippet in full screen
.element {
background: red;
line-height: 30px;
padding : 10px ;
width: 200px;
position: relative;
display: inline-block;
clear: both;
}
.element:after {
background: #f00;
content: "";
display: block;
height: 100%;
transform: skew(-10deg);
position: absolute;
right: -5px;
top: 0;
width: 50px;
}
.element:before {
background: #f00;
content: "";
display: block;
height: 100%;
transform: skew(-10deg);
position: absolute;
left: -5px;
top: 0;
width: 10px;
}
<div class="element">Headline 1</div>
<div class="element">Headline 2 veeery long</div>
<div class="element">Headline</div>
<div class="element">Another Headline</div>
You can use multiple background and rely on the repeat:
.element {
background: red;
margin:10px;
line-height: 30px;
width: 100px;
padding:0 30px;
display: inline-block;
position:relative;
background:
linear-gradient(to bottom right,red 50%,transparent 0)100% 0/30px 30px repeat-y,
linear-gradient(to top left,red 50%,transparent 0)0 0/30px 30px repeat-y,
linear-gradient(red,red)30px 0/calc(100% - 60px) 100% no-repeat;
}
<div class="element">Headline 1</div>
<div class="element">Headline 2 veeery long</div>
<div class="element">Headline 2 veeery long veeery long veeery long</div>

CSS: adding an image to a circle with text

I would like to add an image to a circle that is created by CSS and has text inside. I know how to create a circle with text, for example, this StackOverflow question and answer shows how to do it. Here is the circle definition in css:
circle {
background: #f00;
width: 100px;
height: 100px;
border-radius: 50%;
display: inline-block;
text-align: center;
line-height: 100px;
margin-right:5px;
}
and here is what I will have in html:
<circle>THIS IS THE TEXT</circle>
Now I want to be able to add a background image to the circle and if possible add an opacity of 0.5. So basically I want an image with a shape of circle and text on top of it. Here is an example:
The "THIS IS THE TEXT" is the text that can be written in the html code on top of the image.
How can this be done?
It's not hard to find how to do a circle with text. The <circle> is used for SVG, so it's not what you want here. Use a plain <div> instead. The solution here gives the background image a opacity.
body {
background-color: #121212;
}
.circle {
position: relative;
height: 300px;
width: 300px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.circle:hover:after {
opacity: 0.5;
}
.circle:after {
content: "";
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-image: url(https://buyersguide.caranddriver.com/media/assets/submodel/280_8204.jpg);
background-size: cover;
background-repeat: no-repeat;
z-index: -1;
opacity: 1;
transition: opacity 300ms;
}
.circle__text {
padding: 10px;
background-color: yellow;
}
<div class="circle">
<span class="circle__text">random text</span>
</div>
if you want an alternate solution here is what i use
.story_shape {
width: 15rem;
height: 15rem;
-webkit-shape-outside: circle(50% at 50% 50%);
shape-outside: circle(50% at 50% 50%);
clip-path: circle(50% at 50% 50%);
position: relative;
}
.story_img {
height: 100%;
transform: translateX(-4rem);
backface-visibility: hidden;
}
.story_caption {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
text-transform: uppercase;
font-size: 1.7rem;
text-align: center;
backface-visibility: hidden;
}
<figure class="story_shape">
<img src="https://orig00.deviantart.net/6afd/f/2015/182/4/f/croatia_nature_pack___sample__1___proref_org_by_proref-d8zgqmh.jpg" alt="person on a tour" class="story_img">
<figcaption class="story_caption">mary smith</figcaption>
</figure>

Resources