How do I mask a div to its parent dimensions? - css

I have a rounded rectangle as a background and would like to place another shape on top. The overlaying shape should mask the underlying shape, preferably without any weird coloring at the edges.
I tried to make this work by matching up the shape dimensions, but the border-radius property does not align perfectly with the darker background where the rounded edges overlap.
Imperfect coloring to the left:
body {
margin: 100px;
}
#outer-shape {
height: 25px;
width: 100%;
border-radius: 12.5px;
background-color: #191932;
}
#inner-shape {
height: 25px;
width: 50%;
border-radius: 12.5px 0 0 12.5px;
background-color: #fa6400;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Overlapping Shapes</title>
</head>
<body>
<div id="outer-shape">
<div id="inner-shape"></div>
</div>
</body>
</html>
Is there a way to have my child div remain a rectangle and then clip the parent div? The point is to hide anything that falls outside the boundaries of the underlying shape.
Is it possible to clip the rectangle to the parent shape?
body {
margin: 100px;
}
#outer-shape {
height: 25px;
width: 100%;
border-radius: 12.5px;
background-color: #191932;
}
#inner-shape {
height: 25px;
width: 50%;
opacity: 25%;
background-color:rgba(250, 100, 0, 0.75);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Overlapping Shapes</title>
</head>
<body>
<div id="outer-shape">
<div id="inner-shape"></div>
</div>
</body>
</html>
Edit:
Perhaps, I should have mentioned that the point is to convert the design into a progress bar; meaning that I will need to update the width of the overlaying shape (orange). It should be possible to set a width from 0% up to 100%, while still displaying a distinct separation between the two shapes (no gradient transition).
Besides this, I seek to answer my original question: Is it possible to clip the rectangle to the parent shape?
If you look closely, shape 1) and shape 2) are slightly different at the edges. The first one has an underlying darker background color, which can be seen by looking at the somewhat rougher edge. The second image is simply the same shape, without any layers beneath. This is really nitpicking, but I cannot avoid seeing the imperfect edge in the first example where the rounding is applied.
Is there a way to keep the underlying darker color and have the smooth rounded edge as seen in the second example?

Try adding overflow: hidden to the parent element
body {
margin: 100px;
}
#outer-shape {
height: 25px;
width: 100%;
border-radius: 12.5px;
background-color: #191932;
overflow: hidden;
}
#inner-shape {
height: 25px;
width: 50%;
background-color: #fa6400;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Overlapping Shapes</title>
</head>
<body>
<div id="outer-shape">
<div id="inner-shape"></div>
</div>
</body>
</html>

Use multiple background for this where you can easily control the size using background-size
.outer-shape {
height: 25px;
margin: 10px;
border-radius: 12.5px;
background:
linear-gradient(#fa6400, #fa6400) left/50% 100% no-repeat,
#191932;
}
<div class="outer-shape"></div>
<div class="outer-shape" style="background-size:20% 100%"></div>
<div class="outer-shape" style="background-size:60% 100%"></div>

overflow:hidden on the parent will lead to the same imperfect coloring.
But you can use:
body {
margin: 100px;
}
#outer-shape {
height: 25px;
width: 100%;
border-radius: 12.5px;
overflow:hidden;
background: linear-gradient(90deg, #fa6400 50%, #191932 50%);
}
https://jsfiddle.net/fmvsk8g9/5/
Side by Side
https://jsfiddle.net/8nzL17mp/1/

Related

How can apply custom css to the background image

I've got this example from w3school.
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-image: url("paper.gif");
display: flex;
align-items: center;
background-size: 705px;
background-repeat: no-repeat;
background-position: 95% 50%;
}
</style>
</head>
<body>
<h1>The background-image Property</h1>
<p>Hello World!</p>
</body>
</html>
What I want to do is to add some border around the image which position has been changed by background-position property.
https://www.w3schools.com/cssref/tryit.asp?filename=trycss_background-image
Try this:
<!DOCTYPE html>
<html>
<head>
<style>
section{
position: relative;
}
div {
background-image: url("paper.gif");
display: flex;
align-items: center;
background-size: 705px;
background-repeat: no-repeat;
background-position: 95% 50%;
position: absolute;
height: 600px;
width: 700px;
border-bottom: solid;
border-left: solid;
top: 0;
right: 0;
}
</style>
</head>
<body>
<section>
<div><div/>
<section/>
</body>
</html>
It will look like this in the "Try It Editor" on W3Schools website:
First of all as you know you can add border; the property border is a shorthand it will apply a border to all sides, so go for border-bottom and border-left.
With this said you can use the :after selector to put any kind of styles or effects such a responsive animation, motion transitions, borders > glow borders or better yet borders with neon glow blurry effect.
If you are interested on going deep with these kind of animations i would suggest you to try a library specialized on animation, such as anime.js or framer-motion.

Creating div with width equal to height

I've been stuck on this for awhile now. I have an answers-container div that's going to contain 4 rows, each with a checkbox and a button like this.
The problem is, I can't figure out how to get the width of the checkbox to be the same as the height, since if I set answers-container to be a grid and do grid-template-rows: 25% 25% 25% 25% the height of each answer will be correct but there's no way to set the width to be the same as the height. I know it's possible to do this in Jquery by manually grabbing the value of the height, but if possible I would like to find a solution in CSS.
I saw an answer that used a dummy div with padding set to a percentage which inherits that percentage from the parent, but I couldn't figure out a way to get that method to work while still keeping the button divs next to the checkboxes.
I don't have much code to share because I've deleted and rewritten this so many times, but this is the codepen:
https://codepen.io/TheNomadicAspie/pen/QWvWOgz
And this is what I'm trying to do:
.answers-container {
grid-columns: 2/3;
position: relative;
background-color: blue;
height: 100%;
}
.answer {
}
.checkbox {
}
.button {
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.container {
background-color: red;
position: relative;
width: 50%;
padding-top: 50%;
/* 1:1 Aspect Ratio */
}
.text {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
text-align: center;
font-size: 20px;
color: white;
}
</style>
</head>
<body>
<div class="container">
<div class="text">
1:1 Aspect ratio<br/> width and height are always equeal
</div>
</div>
</body>
</html>

background-image not loading [duplicate]

This question already has answers here:
Percentage Height HTML 5/CSS
(7 answers)
Closed 4 years ago.
For some reason it was working before, but I haven't changed anything in these files, and the background-image stopped loading. I mocked up a codepen to re-produce the problem:
https://codepen.io/jamespagedev/pen/WYNPYv
HTML5:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>UI Project Wk - Home</title>
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700" rel="stylesheet">
</head>
<body>
<div class="coming-soon">
<div class="notice">
<h1>COMING SOON</h1>
<hr>
<p id="countdown-clock" style="font-size:30px"></p>
</div>
</div>
</body>
</html>
CSS:
.coming-soon {
background-image: url('https://www.w3schools.com/w3images/forestbridge.jpg');
height: 100%;
background-position: center;
background-size: cover;
position: relative;
color: white;
font-family: "Courier New", Courier, monospace;
font-size: 25px;
}
.notice {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
hr {
margin: 50px auto;
width: 40%;
}
Can anyone tell me why background-image isn't showing up?
To use height: 100%; the parent element must have a defined height. In the codepen, adding this works:
html, body {
height: 100%;
}
Height of Html and body tag is not define. That's why your image is not render properly.
you need to add height of html and body tag.
html,body {
height:100%;
}
You can check updated codepen. link
seems you have given height:100% for .coming-soon class. Give the height value in px or pt instead of giving value in %.
For example.
.coming-soon {height:700px}
.coming-soon {height:100vh} /*Background will be applied for the whole vieport height.*/

css border-style double 1px gap chrome

3px double border on the left or right side of a div, however in chrome it is leaving a 1px gap at the top of the border. I have tried looking extensively to see if this is a browser bug or for some kind of solution.
http://jsfiddle.net/QSm2Z/2/
If you view the code in firefox/ie you get continuous black bar, in chrome and on my phone/tablet I am getting a 1px gap at the top of each div which breaks the black bar
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style type="text/css">
.test {
height: 100px;
width: 100px;
border-right: 3px double #c7c7c7;
border-left: 3px double #c7c7c7;
background-color: #06F;
padding: 0px;
margin: 0px;
border-bottom-style:
}
</style>
</head>
<body>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
</body>
</html>
Observations
There appears to be a glitch in the corner-shaping algorithm that leaves a mitered edge in preparation of meeting a border on a perpendicular edge even though there is not one.
I doubt this is the intended behavior, even though the spec states that:
This specification does not define how borders of different styles
should be joined in the corner.
You can see evidence of the mitered join with a 2 pixel solid border (screenshot):
If you look very closely, you can see the manifestation of another potential problem: the edges of the top and side borders don't touch (screenshot):
Workaround
This is complex/inelegant by comparison, but one way to fix the problem is to hide both the top and bottom edge of the offending elements. You'll need to adjust the dimensions for your actual site.
Example: http://jsfiddle.net/QSm2Z/10/
.test{
position: relative;
height: 100px;
width: 152px;
overflow: hidden;
}
.test:after {
width: 100px;
height: 102px;
content: "";
top: -1px;
position: absolute;
background-color: #06F;
border-left: 26px double #000;
border-right: 26px double #000;
}
Looks like a browser bug - it doesn't happen with regular solid borders - check this out: http://jsfiddle.net/QSm2Z/8/
Maybe related to this bug: https://code.google.com/p/chromium/issues/detail?id=61702

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