Add polygon as css background - css

I want to have a div where the upper part has a black background and is a polygon(0 0, 100% 0, 100% 780px, 0 670px). The other part of the background of this div should be white. How can I do that?

When you say polygon, do you mean a clip-path polygon?
Maybe something like this? I made the DIV 1000x1000 arbitrarily.
.polygon-bg
{ width: 1000px;
height: 1000px;
position: relative;
}
.polygon-bg::before
{ background-color: Lime;
content: "";
clip-path: polygon(0 0, 100% 0, 100% 780px, 0 670px);
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.polygon-bg .content
{ position: relative;
z-index: 2;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="polygon-bg">
<div class="content">
<h1>Some text...</h1>
</div>
</div>
</body>
</html>

For a simple shape like this you could use linear-gradients in an background-image CSS declaration as you can have as many ‘images’ as you like, separated by commas, and each with its own positioning.
Your shape is a rectangle with a triangle beneath. Instead of using different colors to merge into one another we can just use black for both the start and end colors.
So here is the snippet to create a class called polygon which will make the background color of the div white and overlay one black polygon.
.polygon {
width:400px;/* set these as required */
height:1024px;
background:
linear-gradient(black,black) top/100% 670px,
linear-gradient(to bottom left,black 50%,transparent 50%) 0px 670px /100% 110px;
background-color:white;
background-repeat:no-repeat;
}
<div class="polygon"></div>

Related

Background image with a colored curved border at the bottom

I am trying to achieve this with css3, I tried using border-radius with percent values and it's not the same always, I always got a rounded corners and the border will start disappearing on the corners too.
I want it to be exactly the same as the example image:
EDIT:
this is my html code :
<div class='container-fluid'>
<section class='section-1'>
<div class='container'>
</div>
</section>
And this is my css:
.section-1 {
background-image: url('../images/bg.png');
background-size: cover;
background-repeat: no-repeat;
position: relative;
background-position: 50%;
}
If you want, you can accomplish this using only CSS by creating a <div> that would be used only as a mask. You can create the round effect with the border-radius property, but you need to do it bigger than the part that will be visible, then crop the result to show only the curvy part that you want. And you must compensate the imagem position.
Check my example below:
.oval-header {
width: 100%;
height: 150px;
overflow: hidden;
position: relative
}
.oval-header--mask {
width: 200%; /* Mask width 2x the size of the header */
height: 200%; /* Mask height 2x the size of the header */
transform: translate(-25%, -51%); /* This compensates the size of the image and places the curvy part that you want on the certer of the mask, it's a translate that negativates half it's width and half it's height */
border: 6px solid yellow;
border-radius: 0 0 50% 50%;
overflow: hidden;
border-top: 0;
background-image: url('http://www.placecage.com/3000/1500');
background-size: cover
}
<div class="oval-header">
<div class="oval-header--mask">
</div>
</div>

Some-size some-colour square in background of div without resizing div or editing html

I have a div spanning the whole height of the viewport, while being horizontally center-aligned through use of margins, and would like to center a red square of, say, a 100px by 100px in that div just using CSS. Background-color: red wouldn't work, because that will span the whole div, which will be bigger than 100 pixels. I currently have the following solution:
div {
background-image: linear-gradient(to right, red, red);
background-size: 100px 100px;
background-repeat: no-repeat;
background-position: center;
}
It works, because there's no shift in gradient, but using linear-gradient in this way seems sort of hackish, which makes the solution less useable. Is there any way to generate a purely red square of some size smaller than the div without resorting editing the HTML of the page, or resizing the div with CSS? Preferably, I would also like to avoid scaling up an image of 1 red pixel (I wouldn't easily be able to change the colour).
Thanks for reading!
You could use the :after pseudo selector to add a block with these dimensions. If you position it absolute you can center it using left, top and a transform.
.box {
position: relative;
}
.box:after {
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
}
Or see http://codepen.io/ckuijjer/pen/CbduL
try this
html
<body>
<div id="div0">
<div id="div1"></hr>
</div>
</body>
css
#div1 {
width:100px;
height:100px;
background-color:red;
top: 50%;
transform: translateY(50%);
margin-right:auto;
margin-left:auto;
}
#div0{
height:500px;
width:100%;
background:white;
}

Adding a CSS gradient to an image--NOT a background image

This is a page that uses a carousel (I believe flexslider). The images in this carrousel are NOT background images. I need to add a gradient to the image, going from the bottom up, and from dark to zero opacity, so that I can make the text more legible. Is this possible?
http://hungersolutionsny.magadev.net
Personally I am not a big fan of adding markup just for styling. I would go for a pseudo element :before or :after
The code would look something like this:
HTML
<div class='slideshow-wrapper'>
<img src='http://www.placekitten.com/800/300'/>
<h2 class='title'>Some title</h2>
</div>
CSS
.slideshow-wrapper {
position:relative;
float: left;
}
.title {
position: absolute;
left: 0;
right: 0;
text-align: center;
z-index: 2;
}
.slideshow-wrapper:before {
content: '';
position:absolute;
top:0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%);
z-index: 1;
}
And an example: http://jsfiddle.net/VrGeM/
Overlay the image with an absolutely positioned <div> that's the same size as the slider. Give that <div> the gradient. Ensure that it's above the images but below the text on top of the images.
It's also pretty easy to create a transparent PNG to use rather than a CSS gradient, which will have the advantage of working in older versions of IE.
The way I ususally do this is via an absolutely-positioned DIV which sits on top of the images and contains the text. Then I give that an opacity like so:
background-color: rgba(0, 0, 0, 0.56);
If you want a gradient with opacity, this is a good tool which makes that easy: http://www.colorzilla.com/gradient-editor/
There are a number of ways to tackle this. Mainly targeting the background CSS property. If you're looking to target the text that is overlapping the image you could use something simple like this:
body.front #region-content #flexslider-1 ul.slides .views-field-field-banner-statement {
background-color:rgba(0, 0, 0, 0.5);
}
It doesn't apply a gradient but it does supply a black background with 50% opacity.
I usually don't use a gradient in this way... when faced with this problem in the past I have always used an inset box-shadow on a div wrapped around the image. Something like this...
<div class="img-wrap">
<img src="" />
</div>
And then in CSS apply the box-shadow to a pseudo selector...
.img-wrap {
display: block;
position: relative;
}
.img-wrap:before {
display: block;
content: '';
position: absolute;
width: 100%;
height: 100%;
-webkit-box-shadow: inset 0 -100px 80px 0px rgba(0,0,0,0.4);
}
img {
display: block;
width: 100%;
height: auto;
}
Check out this CodePen if you want to see it live... http://cdpn.io/qGwLe

how to handle 'double opacity' of two overlapping divs

I have two divs, both with 0.6 opacity. I need them to overlap but retain their opacity and not create a new combined opacity level. I can't use an image.
EDIT -- The little circle is supposed to have a canvas element in it. Not sure if pseudo-elements would be the best solution.
Is there anyway to do this with CSS, or should I just use canvas?
example -
http://dabblet.com/gist/1566209
HTML:
<div id="foo">
<div id="bar">
</div>
</div>
CSS:
/**
* Double Opacity
*/
body{background:green;}
#foo{
height:150px;
width:250px;
background:rgba(0, 0, 0, 0.6);
position:absolute;
left:40%;
top:20%;
}
#bar{
height:40px;
width:40px;
background:rgba(0, 0, 0, 0.6);
border-radius:40px;
position:absolute;
top:-15px;
left:-15px;
}
SUMMARY:
Depending on what is needed it can be tricky but the basic approach is pretty straight forward.
This approach is a little different from my first thought... but this has the same result.
I made a black/transparent pattern for the circle and set it to
:before.
The circle is then transformed rotate(180deg) and moved to fit on
the corner of the <div>.
Then I set the opacity of that circle to 0.6.
The <div> itself is not affected by the opacity.
Next I added the :after element and put an image as background
(you can control this via js if needed)
I added some effects to the image (border-radius, box-shadow,
border) to show how easily and independent this element can be
controlled.
I used a lighter background and set the opacity to 0.3 to show
the result
HERE'S THE FIDDLE: http://jsfiddle.net/pixelass/nPjQh/4/
Look at this version for some crazy results: http://jsfiddle.net/pixelass/nPjQh/5/
each of these examples only use a single div element
Basic rules. (these rules "could" be used to create a dynamic behavior with js)
position = absolute;
top = circleHeight / -2;
left = circleHeight / -2; //(left = top)
rotation = 180deg;
opacity = valueAofBackground;
bgColor = valueRGBofBackground;
#inner {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: -1;
background-color: rgba(0, 0, 0, 0.3);
padding:20px;
border-radius: 20px;
border-top-left-radius: 0;
}
#inner:before {
content: "";
background-image: -webkit-linear-gradient(transparent 50%, rgb(0, 0, 0) 50%, rgb(0, 0, 0)),
-webkit-linear-gradient(0deg, transparent 50%, rgb(0, 0, 0) 50%, rgb(0, 0, 0));
height: 40px;
width: 40px;
border-radius: 40px;
position: absolute;
top: -20px;
left: -20px;
-webkit-transform: rotateZ(180deg);
opacity:0.3;
}
#inner:after {
content: "";
background: url('http://lorempixel.com/10/10/sports/1/') no-repeat;
background-position:0;
height: 10px;
width: 10px;
border-radius: 10px;
position: absolute;
top: -6px;
left: -6px;
-webkit-box-shadow: 0 0 10px rgb(255,255,255);
border: 1px rgb(255,255,255) solid;
}
Better explanaition
Original commented version
http://jsfiddle.net/pixelass/nPjQh/10/
see the comments in the code below
#inner {
background: rgba(0,0,0,0.5) /*this is the full color-code of the div (with alpha)*/
}
#inner:before {
/*the solid color of the circle = rgbValue of the div*/
background-image: -webkit-linear-gradient(transparent 50%, rgb(0, 0, 0) 50%, rgb(0, 0, 0)),
-webkit-linear-gradient(0deg, transparent 50%, rgb(0, 0, 0) 50%, rgb(0, 0, 0));
/*opacity of the circle = alpha of the div*/
opacity: 0.5;
}
This example has a full transparent div ...the circle is a "pacman"- shape: http://jsfiddle.net/pixelass/nPjQh/14/
Managing the offset of the circle
Look at these examples that handle the offset of the circle (NOT USING PSEUDEO-ELEMENTS)
1:1 copy of the OP's code (15px offset): http://jsfiddle.net/pixelass/nPjQh/12/
With a lot smaller offset (5px): http://jsfiddle.net/pixelass/nPjQh/13/
(the content has the same opacity as the circle)
How does the offset work?
Control the background-size vs. the top and left
Rules:
top = left;
background-size = elementHeight * 2 + top * 2;
Look at the flower (it is also only one <div> with pseudo-elements)
the background-size is bigger than the circle. which creates the green leaves on the bottom
http://jsfiddle.net/pixelass/nPjQh/15/
CURRENT PROBLEM
See this fiddle: http://jsfiddle.net/pixelass/nPjQh/16/
If not using another layer as seen in the examples at the top of the post the content will be transparent. So if you only need an image inside the circle the above examples will work fine.
HOW TO SOLVE THIS ISSUE
If you need a canvas or another div inside the circle you would have to put the circle on the div and layer the needed div over the circle
See this fiddle: http://jsfiddle.net/pixelass/nPjQh/17/
change around a little and it will work fine. GET THE CODE FROM THE FIDDLE
Different shape /advanced Styling
If you use a different shape with flat sides, you could even put a border around the sum of the two divs.. or even add a box shadow
still using the simple markup of....
<div id="foo">
<div id="bar">
</div>
</div>
See the fiddle for the box-shadow: http://jsfiddle.net/pixelass/nPjQh/21/
Apply a border to the circle
Using -webkit-mask-image we could add a border to the circle.
http://jsfiddle.net/pixelass/nPjQh/24/
More examples:
Four circles around the div
http://jsfiddle.net/pixelass/nPjQh/25/
Markup:
<div id="foo">
<div id="bar1"></div>
<div id="bar2"></div>
<div id="bar3"></div>
<div id="bar4"></div>
</div>
Using this technique to make a tooltip
http://jsfiddle.net/pixelass/nPjQh/31/
Markup:
<div id="foo">
<div id="bar"></div>
I am a pure css tooltip with a semi-transparent background and a black border. <br/>
My width is static an my height is dynamic...
</div>
I think the only way would be to do the opacity separately,
e.g.
http://dabblet.com/gist/1566278
How about this: http://jsfiddle.net/rudiedirkx/TqRCw/
(Dabble's editor sucks!!)
It can't be done with only pseudo elements sadly =(
It can be done with only pseudo elements! See pixelass' answer. CSS3 is a requirement though.
Revised Answer
This fiddle is compatible with IE9 and resolves the duplication of background needed in my original answer. It does use pseudoelements to generate the circle. This solution spins off pixelass's "pacman" idea, only instead of using the newer background gradient css to generate, it uses the older (and little used or understood) clip property to make the circle in two parts. This solved the issue of your circle not being "centered" at the corner.
#foo {
height:150px;
width:250px;
background: rgba(0, 0, 0, 0.6);
position:absolute;
left:40%;
top:20%;
}
#bar {
height:40px;
width:40px;
position:absolute;
top:-15px;
left:-15px;
line-height: 40px;
}
#bar:before,
#bar:after {
content: '';
display: block;
background: rgba(0, 0, 0, 0.6);
border-radius: 40px;
width: 100%;
height: 100%;
position: absolute;
z-index: -1;
top: 0;
left: 0;
}
#bar:before {
clip: rect(0 40px 15px 0);
}
#bar:after {
clip: rect(15px 15px 40px 0);
}
Original Answer
You can do this (see fiddle). It pushes the circle below and "overlays" the portion that overlaps with a pseudoelement to reestablish the background color of the body:
body{background:green;}
#foo{
height:150px;
width:250px;
background:rgba(0, 0, 0, 0.6);
position:absolute;
left:40%;
top:20%;
}
#bar{
height:40px;
width:40px;
background:rgba(0, 0, 0, 0.6);
border-radius:40px;
position:absolute;
top:-15px;
left:-15px;
z-index: -1;
}
#bar:after {
content: '';
display: block;
background: green;
position: absolute;
right: 0;
bottom: 0;
width: 25px;
height: 25px;
}
I have created a Q/A to handle this scenario along with the 'hover' of such overlapped elements.
Overlapped elements with opacity and handling the 'hover' on those.
The solution is basically to set the opacity in the parent level instead directly on the children elements and to toggle those while hover, with JS.
HTML
<div class="wrapper">
<div class="first"></div>
<div class="second"></div>
</div>
JS
$(".first, .second").hover(function() {
$(".wrapper, .first, .second").not(this).toggleClass("add-opacity");
});
CODEPEN
Hope this helps.

CSS progress bar text color for contrast filled and empty backgrounds?

I want to have XHTML+CSS progress bar with contrast colors between filled and empty background areas.
I have a problem with text color. Because filled and empty backgrounds are too contrast (this is a requirement), to remain readable the text should be double-colored to be contrast to both of them. The image should explain it better than words:
Progress bar with dark blue filled area and white empty background http://drdaeman.pp.ru/tmp/20090703/progress-bar-text-example.png
Example of the problem http://drdaeman.pp.ru/tmp/20090703/progress-bar-text-problem.png
My current progress bar implementation is trivial, but as example above shows, the text can be hard to read in some cases, which is exactly a problem I want to solve.
My current (simplified) implementation attempt (fails, because overflow: hidden does not work without positioning div.progress which I cannot position because of inner span's width):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Progress bar test</title>
<style type="text/css">
div.progress_bar {
border: 1px #ccc solid; position: relative;
text-align: center; height: 32px;
}
div.progress_bar .progress {
height: 32px;
overflow: hidden; /* This does NOT work! */
}
div.progress_bar .progress div {
position: absolute; width: 100%; height: 32px;
z-index: 30; overflow: hidden;
background-color: #44a;
}
div.progress_bar span {
position: absolute; top: 0; left: 0; width: 100%;
z-index: 20;
color: #000;
}
div.progress_bar .progress span {
position: absolute; top: 0; left: 0; width: 100%;
z-index: 40;
color: #eee;
}
</style>
</head>
<body>
<!-- Can be of any (unknown) width. Think of "width: auto".
The 400px value is just to keep it small on a big monitor.
DON'T rely on it! -->
<div id="container" style="width: 400px;">
<div class="progress_bar">
<!-- div.progress is a dark filled area container -->
<div class="progress" style="width: 51%;">
<!-- Actually dark filled area -->
<div style="width: 51%;"></div>
<!-- Text (white).
Does not clip, even with overflow: hidden on parent! -->
<span>This is a test</span>
</div>
<!-- Text (black) -->
<span>This is a test</span>
</div>
</div>
</body>
</html>
Live version of the above: http://drdaeman.pp.ru/tmp/20090703/test2.html
Previous attempt: http://drdaeman.pp.ru/tmp/20090703/test.html
The images are GIMP edited prototypes, and not exactly what this code displays.
Add: Thank you all, especially Meep3D, Nosredna and Lachlan! However I still have a problem — in my case progress bar should have no fixed width and take all horizontally available space (width: auto; or width: 100% are acceptable). But without width: 400px rule Lachlan's code breaks. And I'd still like to avoid using JavaScript, if that's possible.
As per Meep3D's suggestion, take 2 copies of the text.
Wrap each in a div of the same width as the container. The "upper" div is wrapped with another div which clips at the desired percentage.
Update: removed the fixed widths.
The "upper" div is sized to the inverse percentage of its wrapper.
<html>
<head>
<style type="text/css">
#container {
position: relative;
border: 1px solid;
text-align: center;
width: 400px;
height: 32px;
}
.black-on-white {
height: 32px;
color: #000;
}
.white-on-black {
height: 32px;
color: #fff;
background-color: #44a;
}
.wrapper {
width: 53%;
overflow: hidden;
position: absolute;
top: 0; left: 0;
}
.black-on-white {
width: 100%;
}
.white-on-black {
width: 188.7%;
}
</style>
</head>
<body>
<div id="container">
<div class="wrapper">
<div class="white-on-black">
<span>This is a test</span>
</div>
</div>
<div class="black-on-white">
<span>This is a test</span>
</div>
</div>
</body>
</html>
What about putting a second copy of the progress bar text inside the div, and set the div's overflow to hidden, so it reveals with it?
--
Update: I am also not a javascript expert, but I am sure that you can find out the width of an object and then set the offset based upon that if the width is flexible as you say.
You could:
Find a grey which suits
Use JavaScript to change the colour between white and black dynamically, depending on where it is
Make the middle colour of the background gradient closer to white, and always use dark text
Put the progress outisde the box:
[######### ] 50 %
You could use a text shadow for your "percentage" text. The only downside to this is that it would only work in the latest browsers. Only Firefox 3.5, Safari (all versions), and Chrome 2+ support it.
Here is a demo of using text-shadow in a way that would make your progress readable.
http://www.w3.org/Style/Examples/007/text-shadow#white
If you're willing to use more JavaScript, you could try this jQuery plugin:
http://kilianvalkhof.com/2008/javascript/text-shadow-in-ie-with-jquery/
The article says it works in IE only, however it works in Chrome 3 (what I'm using), Firefox 3.5, Internet Explorer, and Safari. It may work in older browsers but I haven't tested it.
Meep3D has the correct answer. Two versions of the box. Reveal n% of the top one.
More options:
Put a translucent box under the
number that either darkens the area
for a white number or lightens the
area for a black number.
Use red and white as backgrounds and
a black number. (Problem here is red
is associated with error, so you can
play with other combinations of three
colors that are all high contrast
against each other.)
You need 2 values styled differently. And fixed width
let counter = 0
const increment = () => {
counter++
}
let interval = setInterval(() => {
increment();
document.querySelectorAll('.value').forEach(node => {
node.textContent = `${counter}`
});
document.querySelector('.progress-bar').style.width = `${counter}%`
if (counter >= 100) clearInterval(interval);
}, 50)
.progress-wrapper{
margin: 20px auto;
width: 400px;
height: 20px;
background-image: linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 50%, #ccc 50%, #ccc 75%, transparent 75%, transparent);
animation: progress-bar-stripes 2s linear infinite;
background-size: 40px 40px;
position: relative;
border-radius: 5px;
overflow: hidden;
}
.progress-bar{
z-index: 3;
overflow: hidden;
position: absolute;
height: 20px;
background-color: #8178d9;
text-align: center;
transition: width 0.5s ease;
}
.progress-value-1, .progress-value-2{
margin: 0;
position: absolute;
width: 400px;
color: #8178d9;
text-align: center;
z-index: 2;
font-weight: bold;
}
.progress-value-2{
color: #fff;
z-index: 1;
}
#keyframes progress-bar-stripes {
from {
background-position: 40px 0;
}
to {
background-position: 0 0;
}
}
<div class="container">
<div class="progress-wrapper">
<div class="progress-bar">
<p class="progress-value-2">
<span class="value"></span>%
</p>
</div>
<p class="progress-value-1">
<span class="value"></span>%
</p>
</div>
</div>
https://codepen.io/kosachevlad/pen/dypEjBa
This answer with the use of clip-path: inset(0 0 0 50%); is great.
The use of a background linear gradient with a background-clip as described in this answer is also interesting.

Resources