Text with background color - html

I have a weird problem and honestly I have no idea how to do that.
I have a box with background image. Over the background image I have a lot of boxes with a background color and text. I would like the color of the text in every box to be transparent, so the color will be the part of the background image that text is above.
Here is an example: http://jsfiddle.net/wjdwohdd/5/
Instead of the green background, it should be an image.
<div class="box">
<div class="background">
Example text
</div>
</div>
.box {
width:200px;
height:20px;
background-color: green;
padding: 10px;
}
.background {
color: transparent;
height: 100%;
width: auto;
background-color: red;
text-align: center;
}
If I set color: transparent, the text's color becomes red and I am not sure even if it is possible to be the background image.
EDIT: I updated my jsfiddle. I would like the color of the text to be the part of the image that is behind the text.

You can do that, but you need a pretty new property: mix-blend-mode.
Even though it, support is growing: it has been supported in FF for a while, and it is supported in the latest Chrome.
To get it, you need a gray text on a red background, and set the mode to hard-light
body {
background-image: url(http://placekitten.com/1200/800);
}
.test {
font-size: 300px;
color: #888;
background-color: red;
mix-blend-mode: hard-light;
}
<div class="test">TESTING</div>

i would suggest to use a color for the font in the parent element and then in the child element inherit the font color, not sure what you really want
.box {
width:200px;
height:20px;
background-color: green;
padding: 10px;
color: blue;
}
.background {
color: inherit;
height: 100%;
width: auto;
background-color: red;
text-align: center;
}
otherwise use a rgb color for the font in the child element with a transparency then your background will be visible for example something like color: rgba(0, 0, 0, 0.5);

I dont know whether it is possible to do using CSS. Only solution that I can come up with is using Canvas. But it is too complicated and lot of coding. back canvas contains the image that you want to show and in front canvas you do background coloring and letter writing. Here goes the code:
HTML
<body>
<canvas id="back">
</canvas>
<canvas id="front">
</canvas>
</body>
CSS
#back{
position: fixed;
top: 40px;
left: 40px;
z-index: -1;
}
#front{
position: fixed;
top: 60px;
left: 60px;
z-index: 99;
}
JavaScript
window.onload = function(){
var h = new Image();
h.src = 'images/color.jpg';
var back = document.getElementById('back');
back.width = h.width;
back.height = h.height;
back.getContext('2d').drawImage(h,0,0,h.width,h.height);
var front = document.getElementById('front');
var back = document.getElementById('back');
front.width = h.width - 40;
front.height = h.height - 40;
var ctx = front.getContext('2d');
ctx.fillStyle="#ED6";
ctx.fillRect(0,0,h.width - 40,h.height - 40);
ctx.font="150px Verdana";
ctx.fillStyle= 'rgba(0,0,0,1)';
ctx.fillText("HELLO" , h.width/2 - 300 , h.height/2 - 25);
maketransparent(front,back);
};
function maketransparent(front,back){
var backimage = back.getContext('2d').getImageData(0,0,back.width,back.height);
var frontimage = front.getContext('2d').getImageData(0,0,front.width,front.height);
for(var i=0; i<frontimage.data.length; i=i+4){
var line=Math.floor(i/(4*front.width));
line=line+20;
var backi=(line*back.width*4) + 80 + (i%(front.width*4));
if(frontimage.data[i]+frontimage.data[i+1]+frontimage.data[i+2]<50){
frontimage.data[i]=backimage.data[backi];
frontimage.data[i+1]=backimage.data[backi+1];
frontimage.data[i+2]=backimage.data[backi+2];
}
}
front.getContext('2d').putImageData(frontimage,0,0);
}

Related

Tint a white-on-transparent image with CSS

I have an image that's white with a transparent background; I'd like to be able to dynamically color/tint the image on hover to another color.
My first thought was to use background-blend-mode to multiply a solid red image with my white-on-transparent image to get a red-on-transparent image. Unfortunately, this doesn't give the desired behavior and instead gives me a solid red box. Example here: https://jsfiddle.net/wcL2exa4/58/
I've looked into CSS mask but that also doesn't seem to do what I want. How can I easily turn my white image into a colored one?
thank you!
You can try using mix-blend-mode on a pseudoelement. I've used multiply and screen in the example below
document.getElementById('c').addEventListener('change', (e) => {
const mode = e.target.checked ? 'screen' : 'multiply';
document.documentElement.style.setProperty('--blend-mode', mode);
})
:root {
--blend-mode: multiply;
}
#container {
position: relative;
background: black;
width: 100%;
height: 250px;
margin-bottom: 2rem;
}
#constellation {
position: absolute;
top: 0px;
left: 0px;
width: 250px;
height: 250px;
background: url("https://storage.googleapis.com/astrology-images/constellations/aries-white.png");
}
#constellation:after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: red;
mix-blend-mode: var(--blend-mode);
}
<div id="container">
<div id="constellation" class="bg">
</div>
</div>
<input id="c" type="checkbox"><label for="c">Red Background</label>
There is a way but it's a bit weird
filter: brightness(0.5) sepia(1) hue-rotate(50deg)
Change the brightness and hue rotate till you get the colour you want.
Are all background image white ?
You may do it by changing the default image to a red version, and apply some filter to it to get it white.

Is it possible to change this div color on scroll using purely CSS?

Thanks for taking the time to read my post.
So I've started freelancing recently (CSS and HTML) and I've found my first difficulty.
Look at the green bar (Its a fixed div), its green for testing porpuses, but client wants it to be transparent when on top of this orange background...
...But switch to another color when on top of this white background (So the letters can be seen)
Is this possible to do with CSS? If so, how do I do it?
Thanks again!
Pure css does not currently have any amount of responsiveness to what is and is not onscreen. So, the short lame answer is "not with just css."
That being said, it's very easy to do this with js.
The event you'll be looking for is scroll event.
From there you can add/remove a class for styling.
Something like this:
// wait for document.addEventListener("DOMContentLoaded");
const myHeader = document.getElementById("MyHeader");
window.addEventListener("scroll", () => {
const scrollPos = window.scrollY;
if (scrollPos ... add your logic here) {
myHeader.classList.add("scrollIsThing"); // this is the css class you'll target
} else {
myHeader.classList.remove("scrollIsThing");
}
});
Sorry there's no good css way to do this.
It is "kind of" possible to do this just with css if you can accept some html markup duplication. You can split the fixed header into two layers, one for white text, one for background, and using z-index you can sandwich the content between these two header layers (in case of a colorful content), in which case only the white text would be visible, and position the white content below the header background. A sample of such behavior is shown below:
.header {
height: 50px;
background: transparent;
position: fixed;
top: 0;
width: 100%;
color: white;
font-family: sans;
text-align: center;
line-height: 50px;
z-index: 3;
}
.header.header-background {
background: teal;
z-index: 1;
}
.body1 {
height: 120vh;
background: orange;
z-index: 2;
position: relative;
}
.body2 {
height: 120vh;
background: #eee;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
<div class="header">
White text
</div>
<div class="body1"></div>
<div class="header header-background">
</div>
<div class="body2"></div>

width on element and z-index

I am just playing a little bit around with a landing page.
I just set a red opacity background on "A CATCHY PIECE OF TEXT".
How do I set the width on that the correct way, so I also have the responsive part in mind?
How can I get the font in front, and the red background in the back?
#cathyText {
background-color: red;
padding: 10px;
opacity: 0.1;
}
<h2 class="text-center" id="cathyText">A CATCHY PIECE OF TEXT</h2>
How can I get the font in front, and the red background in the back?
Use rgba():
#cathyText {
padding: 10px;
background: rgba(255,0,0,0.3);
z-index: 1;
}
The reason it works is the first 3 numbers set the red-green-blue of the color, and the last sets the opacity.
If you want to center your <h2> element, one way is to place it in a wrapper and change the display to inline-block:
#cathyText {
background-color: red;
padding: 10px;
background: rgba(255,0,0,0.3);
width:200px;
display:inline-block;
}
.catchy-text-wrapper {
width:100%;
text-align:center;
}
<div class="catchy-text-wrapper">
<h2 class="text-center" id="cathyText">A CATCY PEICE OF TEXT</h2>
</div>
use rgba() for background color
#cathyText {
background-color: rgba(255,0,0,.1);
padding: 10px;
/* opacity: 0.1; */
z-index: auto;
}

Opaque pop up window

I have found this code from google, and it is working fine but the pop up window is transparent and I want to make it opaque. (I know that the pop up window is transparent because if I zoom in the browser I can see the pop up window overlapping with the background content and the background content is visible)
Here is the link to code:
popup window
<HTML>
<HEAD>
<TITLE>Popup div with disabled background</TITLE>
<style>
.ontop {
z-index: 9999;
width: 100%;
height: 100%;
top: 0;
left: 0;
display: none;
position: absolute;
background-color: #cccccc;
color: #aaaaaa;
opacity: .8;
filter: alpha(opacity = 80);
}
#popup {
width: 300px;
height: 200px;
position: absolute;
color: #000000;
background-color: #ffffff;
/* To align popup window at the center of screen*/
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -150px;
}
</style>
<script type="text/javascript">
function pop(div) {
document.getElementById(div).style.display = 'block';
}
function hide(div) {
document.getElementById(div).style.display = 'none';
}
//To detect escape button
document.onkeydown = function(evt) {
evt = evt || window.event;
if (evt.keyCode == 27) {
hide('popDiv');
}
};
</script>
</HEAD>
<BODY>
<div id="popDiv" class="ontop">
<table border="1" id="popup">
<tr>
<td>
This is can be used as a popup window
<br></br>
Click Close OR escape button to close it
Close
</td>
</tr>
</table>
</div>
<CENTER>
<h3>
Simple popup div with disabled background
</h3>
<br/>
Click here to open a popup div
</CENTER>
</BODY>
For some reason, I am not sure of, I couldn't make this code work in jsfiddle, but I have used the same code in one html file with tags for css and it is working fine.
Kindly help.
It works, but only if the Javascript comes before your onclick-handlers in the source code.
So you need to change the following setting in JSFiddle (the second dropdown must be set to "No wrap - in <head>":
In the updated fiddle, I also fixed the opacity issue. Your whole overlay had opacity: 0.8; and that affects also all children of that overlay. Instead, you should use slightly transparent background-color in rgba notation for overlay:
background-color: rgba(204,204,204,0.8);
https://jsfiddle.net/ppqct0dg/4/
rgba uses decimal number, in contrast to #cccccc notation, which uses hexa-decimal numbers.

Diagonal bottom on rectangle?

Thank you in advance for your help.
I have spent a good deal of time scouring the web and this forum for a solution to having a diagonal angled bottom to my navigation buttons. Here is an example:
I want to avoid using images if possible. I'm wondering how to create a box like this in the example image for each navigation choice with CSS. This navigation code will make its way into a Wordpress install. I really appreciate the expertise. Thank you again!
So good-news, bad-news...
This can be most-of-the-way done using nothing but CSS.
For sufficiently-new browsers (ie: you don't require IE<=8 to maintain all styles that Chrome 42 has) this can be done without using extra DOM elements.
This can also be done using just CSS ...wait for it...
buuuut the CSS-only version can only make the angle a set width.
It can't make the angle stretch across an arbitrary width, so either the buttons have to be the same length, or the width/height of the angle has to be the same on all buttons (meaning part of the bottom will be flat, on longer buttons).
CSS-only Solution (good enough?)
nav {
background-color: green;
padding: 20px;
}
nav > button {
background-color: rgb(60, 60, 60);
color: rgb(120, 120, 120);
position: relative;
border-radius: none;
border: none;
padding: 20px;
}
nav > button:after {
content: "";
width: 0;
height: 0;
right: 0;
bottom: 0;
position: absolute;
border-left: 60px solid transparent;
border-bottom: 15px solid blue;
}
<nav >
<button >About</button>
<button >Bios</button>
</nav>
I made the colours obvious for a reason.
For the full experience of the cheat, I'll make the solution a little more obvious, by changing the colour of the left border:
Behind the Scenes Look
nav {
background-color: green;
padding: 20px;
}
nav > button {
background-color: rgb(60, 60, 60);
color: rgb(120, 120, 120);
position: relative;
border-radius: none;
border: none;
padding: 20px;
}
nav > button:after {
content: "";
width: 0;
height: 0;
right: 0;
bottom: 0;
position: absolute;
border-left: 60px solid red;
border-bottom: 15px solid blue;
}
<nav >
<button >About</button>
<button >Bios</button>
</nav>
As you can see, the triangle that I created using the border-bottom (in blue) and border-left (transparent) is just about perfect.
The width of the border-left determines the width of this effect, and the height of the border-bottom determines the height; it just happens that the left one is invisible.
If that blue were set to the same green as the <nav> itself, then it would look like a notch was missing from the button, rather than having a corner painted over.
If you wanted to make this ES6-8 friendly, you'd just add 1 div per button (after each button or whatever), and size that and use its borders.
Really, you'd need to add a div to contain the div and the button, as well (so the container was relatively positioned, the button took up 100% of its space, and the paint-chip was absolutely positioned inside).
If you don't care about old browsers getting the exact same view, you really don't need to do this to yourself.
That's most of the way solved...
If you can say "My theme's smallest button is 60px, so a 60px triangle is okay", then great. Change the colours and you're done.
If not, there's a little more you can do.
It's not ideal, and it's not as pretty as it could be (still prettier than a lot out there), but if you can use JS to do this, and you can guarantee that all of the buttons are going to be on the page before the code runs, and their widths won't change, you can do something like:
JS + CSS (good enough!)
(function () {
var nav;
var buttons;
var style;
var styleText;
function getElWidth (el) { return el.getBoundingClientRect().width; }
function borderLeftText (width, i) {
return ["nav > button:nth-child(", i + 1, "):after { border-left: ", width, "px solid transparent; }"].join("");
}
function getStyleEntries (els) {
return els.map(getElWidth).map(borderLeftText);
}
try {
nav = document.querySelector("nav");
buttons = [].slice.call(nav.querySelectorAll("button"));
style = document.createElement("style");
styleText = getStyleEntries(buttons).join("\n");
style.textContent = styleText;
document.head.appendChild(style);
}
catch (err) {
// because the same browsers that will blow up won't support the CSS anyway;
// don't fix it, just move on
// good code shouldn't do this, but that's another story
}
}());
nav {
background-color: green;
padding: 20px;
}
nav > button {
background-color: rgb(60, 60, 60);
color: rgb(120, 120, 120);
position: relative;
border-radius: none;
border: none;
padding: 20px;
}
nav > button:after {
content: "";
width: 0;
height: 0;
right: 0;
bottom: 0;
position: absolute;
border-left: 60px solid transparent;
border-bottom: 15px solid green;
}
<nav >
<button >About</button>
<button >Bios</button>
</nav>
Here I'm basically grabbing all buttons that exist at this time, and writing my own CSS file, full of
nav > button:nth-child(1):after { /*...*/ }
nav > button:nth-child(2):after { /*...*/ }
and then appending a <style> tag to the <head> with that text inside.
There will just be one rule inside each one of those selectors; the border-left width is going to be set to the actual width of the button, in pixels.
Terms and Conditions
Now you have exactly what you wanted, but it required JS and requires that the buttons be on the page before that code runs, and requires that the widths not change (through styling, or through media-queries, et cetera). If either of those things happens, and you want to keep the corners updated, that code needs to be run again.
And if that's the case, special care should be made to cache and reuse the style tag, so that you don't have 8 tags with the same rules, on the page.
Conclusion
If you're good with mostly-fine, go CSS-only.
If you're good with knowing that the fix doesn't have to respond in real-time, or be applied to more and more buttons that are dynamically added, go JS + CSS.
If neither of those is good enough, use an .svg or .png
Transform: skewY(deg);
will skew a div up like that, you might need to build it in layers though, and then skew the text -deg to unskew the text
Simple example:
https://jsfiddle.net/uex2umac/
.wrapper{
width:500px;
height:300px;
background-color:#000;
overflow:hidden;
}
.tobeskew{
width:280px;
height:220px;
margin-bottom:0px;
background-color:#f1f;
text-align:center;
transform:skewY(-15deg);
}
p{
transform:skewY(15deg);
line-height:220px;
font-size:40px;
color:#fff;
}
<Div class="wrapper">
<div class="tobeskew">
<p>Hello</p>
</div>
</div>
Here's a solution using SVG background images. Note that using SVG requires IE9+ though...
BODY
{
background-color: #333;
}
.button
{
float:left;
float: left;
font-family: sans-serif;
font-weight: bold;
font-size: 44px;
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 115' preserveAspectRatio='none'><polygon points='0 0 100 0 100 100 0 115' fill='%23282828'/></svg>");
background-size: 100% 100%;
color: #999;
height: 110px;
line-height: 96px;
padding: 0 50px;
margin-right: 10px;
}
.button.selected
{
color: #fbac31;
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 115' preserveAspectRatio='none'><polygon points='0 0 100 0 100 100 0 115' fill='black'/></svg>");
}
<div class="button">
<div>ABOUT</div>
</div>
<div class="button selected">
<div>BIOS</div>
</div>