CSS: Opacity Issue - css

Ok, so in my page I am showing a background image with this css:
.heroarea {
background:url(/static/images/mrd_hero_01.jpg) no-repeat;
height:450px;
}
and the copy placed over it and the container the copy is in have these styles:
.main-panel {
position: absolute;
top: 130px;
left: 380px;
background: #fff;
width: 560px;
height: 340px;
padding: 30px 30px 20px 30px;
/* CSS3 standard */
opacity:0.5;
/* for IE */
filter:alpha(opacity=50);
}
.main-panel h1 {
background: transparent;
color:#39372f;
text-align: center;
/* CSS3 standard */
opacity:1;
/* for IE */
filter:alpha(opacity=100);
}
Generally, everything is as expected. That is, the image shows where I expect it to show. main-panel shows a white back ground with a transparent background. However, the text in the h1 tag is also transparent. I can see the image from underneath showing through. How can I make this so that the h1 tag content is not opaque?
Thanks!

Opacity applies to the element, not it's background.
You either need to use a translucent image, or an rgba background colour.
There is an explanation about how to do this in a backwards compatible way. (Disclosure: My site)

Use rgba and/or transparent png. Alternatively, move the content to a separate sibling div as the background:
<div id="parent">
<div id="opacity"></div>
<div id="child">text</div>
</div>

If you use transparency on a block element it makes the child element inside transparent as well.This is how css works ! I do not think there is any way to hack out of it. What you can do it to absolutely position h1 without making it a child or use a translucent image

It looks like your text is a child of .main-panel. It will take on 50% opacity. Even though you state the text is opacity 100% will only make it 100% of 50%. You will need to layer it outside of .main-panel and place it on top.

You have to move it outside of its .main-panel parent. There's no way to override the 50% opacity that's being applied there.
Alternatively, if you're only using 50% opacity to make the mrd_hero_01.jpg background image transparent, you could convert it to a .png with 50% opacity and then you wouldn't need to set the opacity on .main-panel.

Related

Masked SVG flickering when changing currentColor

To supplement my icon set, I'm using SVG's and currentColor.
However, I'm seeing some issues with flickering when the (font)color changes or there's animation on the page.
Example of color change on hover causes flicker
body{
color:green;
font-size:50px;
}
.dynamicSVG {
/*
Allows us to colour SVGs using mask, the colour will follow the text colour
NOTE: doesn't work well with SVG's with lots of colors as you lose the contrast
*/
height: 1em;
min-width: 1em;
display: inline-block;
-webkit-mask: var(--src) no-repeat 50% 50%;
mask: var(--src) no-repeat 50% 50%;
-webkit-mask-position: left;
mask-position: left;
-webkit-mask-size: contain;
mask-size: contain;
background-color: currentColor;
vertical-align: middle;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.dynamicSVG > img {
/*
Here I use an child img element inside the i.dynamicSVG.
It uses the style SRC variable to remove the need to set the URL twice in HTML, a nice CSS hack.
We do this to load in the image and ensure the dynamic SVG is the correct size and dimensions...
Which it wouldn't have been as we're using background + mask for the dynamic icon
It does mean the image will be called twice, but due to caching it shouldn't be an issue and isnt visible to the user
*/
content: var(--src);
height: 100%;
visibility: hidden;
/*Ensure the max height isn't overridden*/
max-height: 100% !important;
vertical-align:top;
}
.dynamicSVG:hover{
color:red;
}
<div class="dynamicSVG" style="--src:url('http://upload.wikimedia.org/wikipedia/fr/c/c8/Twitter_Bird.svg')"><img /></div>
<span>< Hover Me</span>
I've read some articles which suggest -webkit-translate-3d, -webkit-backface-visibility,-webkit-transform-style, none of which resolves my issue.
Essentially I use a CSS mask to colorise the SVG to my font colour.
The child img allows it to size correctly relative to the height.
However, during transitions or in particular changing the font colour (and in turn the mask colour when using currentColor, the image is either hiding completely until the transition is complete or flickers.
The question is firstly, is there a better way of linking to an SVG (without embedding the XML) and using CSS to set the colour, or if there's no better solution, how can we stop the flickering / hiding during transitions.
I've mainly noticed it in chrome in my application, but in this example we can see it occur in modern edge too.

Button out of 3 graphic parts with fluid mid-part

I have an image:
with 3 parts:
, and
I want a button with a repeating part2, so the button text (centered) is variable.
But the button text should range 50% into the other pieces.
Part1 and part3 need a min width I think, unfortunately I have no useful example.
:before and :after didn't work very well (with position:absolute or similar), because the repeat part have to be fluid between the outer parts.
Any ideas? Greetz.
A modern posibility would be using border-image.
But if you want a wider support, do it with backgrounds.
The problem is that a repeating bkg is difficult to size . So, it's best to handle it in a pseudo element
.test {
min-width: 200px;
text-align: center;
line-height: 90px;
display: inline-block;
margin: 20px;
height: 100px;
padding: 0px 20px;
font-size: 30px;
color: white;
background-image: url('//i.stack.imgur.com/mYxcX.png'), url('//i.stack.imgur.com/TlpN0.png');
background-size: auto 100%;
background-repeat: no-repeat;
background-position: left top, right top;
position: relative;
}
.test:after {
content: "";
position: absolute;
background-image: url('//i.stack.imgur.com/GMhMi.png');
background-size: auto 100%;
left: 90px;
right: 100px;
top: 0px;
bottom: 0px;
z-index: -1;
}
<div class="test">TEST</div>
<div class="test">long test</div>
<div class="test">much longer test</div>
And the same, using border image. Using this image
we will get this: (note the trick about height:0px to allow for a single image in all the left and right sides.)
.test {
display: inline-block;
margin: 20px;
height: 0px;
font-size: 30px;
border-width: 50px;
border-image-source: url(http://i.stack.imgur.com/oXiA6.png);
border-image-slice: 50% 49% 50% 50% fill;
border-image-repeat: repeat repeat;
}
<div class="test">TEST</div>
<div class="test">long test</div>
<div class="test">much longer test</div>
UPDATED and totally Changed:
Thanks to #vals comment below which let me had the "idea bulb" above my head, hence the "unless.." part in the comment.
This new solution is much cleaner in CSS and HTML, less code, no need to worry about position:absolute, no need for extra mess, just simply uses "multiple backgrounds" (1) as well as calc()(2) function with min-width too techniques. but first here's the code and comments will explain:
JS Fiddle
.test-class {
/* so that div can expand to contain the text as well as the padding */
width:auto;
/* min width = 173px left image width + 199px right image width */
/* without this it'll collapse */
min-width:372px;
padding:0 20px 0 10px; /* just to give it breathign space on sides */
line-height: 148px;
color: white;
font-size:24px;
/* no color background because the images are PNGs with alpha */
background-color: transparent;
/* setting multiple images having the middle "extendable" one as third background */
background-image: url('//i.stack.imgur.com/mYxcX.png'),
url('//i.stack.imgur.com/TlpN0.png'),
url('//i.stack.imgur.com/GMhMi.png');
/* set no repeat to all, even the extendable otherwise it'll appear behind the
other two images, instead we don't repeat it but control its size later */
background-repeat: no-repeat, no-repeat, no-repeat;
/* position each image to its corresponding position, the 46.5% for the middle
image is because the left-side image has less width than the one on the right */
background-position:left center, right center, 46.5% 50%;
/* finally giving the images on the sides their exact-pixel size, while for the
one on the middle we make use of calc() function, so the width size of the middle
image = full div size (100%) - the width values of the left and right image (173+199) */
background-size: 173px 148px, 199px 148px, calc(100% - 372px) 148px;
display: inline-block;
text-align:center;
}
<div class="test-class">Home</div>
<div class="test-class" style="margin-left:200px;">about company</div>
<div class="test-class">example dummy text for demo only</div>
Alternatively, as I commented, you can use the CSS Sliding Door technique which was so practical and used a lot before CSS border-radius and CSS shadow presented and simplified interfaces. another example perfect CSS sprite sliding doors button
This JS Fiddle 2 shows how to implement the sliding door method for achieving such task, while it looks kind too much wide for this images set, since the right side image has 199px width, it could be used for images with less width values.
And this JS Fiddle 3 is similar to sliding door but with :before and :after but with one issue that it has to have display:block which make it not workign for horizontal alignment but could be fixed with javascript after settign it's display to inline-block.
Also there's another way, using SVG as background image which is better first because it is scale-able especially for non linear images like the blue ink circle used in the great example by #vals .
Second benefit of using SVG is using inline SVG and because SVG is made of groups and element could be targeted with CSS just like targeting other DOM elements.
https://css-tricks.com/using-svg/
----------------------------------------------------------------------------
(1). Resources:
caniuse - Multiple backgrounds
MDN - Using CSS multiple backgrounds
(2). Resources:
caniuse CSS calc()
MDN - calc()
CSS-Tricks - A couple of use cases for calc

CSS: Extend an image

I have an image that looks like this:
Is it possible to extend this image (perhaps inside a div) so that it would look something like this:
Thanks!
You can create a div of the same color using the CSS background-color property (I believe the hex should be ~#999). Then, position the image as a background-image within the div using the background-position: right property.
HTML
<div class="arrow">Home</div>​
CSS
#arrow {
background-color: #999;
background-image: url('http://i.stack.imgur.com/QDCz4.png');
background-position: right;
background-repeat: no-repeat;
/* sets div dimensions/text styles */
height: 24px;
color: white;
text-align: center;
line-height: 24px;
float: left;
padding-left: 20px;
padding-right: 30px; /* slightly longer to account for background image /*
}
JS Fiddle: http://jsfiddle.net/fbBsz/14/
Get a vertical slice of the gray part of very top left of the arrow with having width:1px. Take that one px slice image and repeat it on -x.
Here is something you can practice with
Since your image does not have a gradient, you have a better chance of matching the color(s) you want with just using background color.
you can set it as a background to a div
#elem {
display:block;
width:200px;
height:20x;
background: url(/filepath/to/image.gif) right top no-repeat #ccc;
}
Just make sure the background color is the same as the dark grey on the gif
No, this is not possible in CSS. You must set the width of the containing element, set the background image's url and set the x-position to right and set the repeat to no-repeat. Then set the background color to the same as the button's foreground color. If the button foreground is a pattern, you will have to use another image as the background.
No, not with that image at least :-)
Looks like you could make use the "sliding doors" technique – see http://www.alistapart.com/articles/slidingdoors/ for a good article about it

CSS3 does ::after inherit the height and margin of the origin element in IE9?

I have this HTML:
<div class="demo">hello world</div>
and this CSS:
.demo { width: 100px;
height: 50px; margin-bottom: 50px;
background-color: red; position: relative;
z-index:-1;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorStr=#40ffffff,EndColorStr=#12ffffff);zoom: 1;}
.demo::after {
width: 95px;
height: 95px;
position: absolute; left: 0; top: 0; border: 5px solid blue; content:"";
background-color: yellow; opacity: .75;}
I wanted the pseudo element to completely cover the origin element (which contains a 50% gradient for IE7,8 - therefore height: 50%, margin-bottom: 50%;)
However in IE9... the ::after element only covers 50%, although I specifically set the height to be 44px. Is this because of the use of filter? Any idea how to override it?
Here is a JSBin of the example.
Thanks for help.
UPDATE
Here is an example of the whole thing:
Example
Notes:
see comments in the background.css file
I can't change the element structure or assign gradient to any other element than .ui-icon
The gradient should cover 50% of the footer. Footer is 44px so gradient stops at 22px
IE7+8 cannot do this (or color stops), so I making .ui-icon height 22px plus filter-gradient
using ::before I add the gradient for all other browsers sitting on top of .ui-icon
Problem 1 = IE9+ renders ::before - I use z-index:-1, so .ui-icon sits behind ::before = OK
Problem 2 = on IE9+ the ::before background is cut off by .ui-icon.
Question: How can I avoid the gradient in ::before being cut off?
Is this because of the use of filter? Any idea how to override it?
Yes, it's because of the filter. Using filter causes an overflow:hidden-esque effect.
You might be aware that :after is rendered inside the element, like this:
<div class="demo">hello world<div:after></div:after></div>
If you add overflow: hidden, then all browsers are equally broken: http://jsbin.com/otilux/3
So, how to fix it? One option is to use ::before to handle drawing the thing that has filter.
See: http://jsbin.com/otilux/4
That looks the same as it did before in Chrome/Firefox, and now also looks the same in IE9.
Due to using ::after instead of :after, I can see you're not trying to support IE8. So, another option would be to use an SVG gradient instead of filter.

Make a background image transparent using CSS

I have a scenario where I need a transparent background image but I have no control over the dynamically generated images I use. For that reason Transparent PNG is out of the question. All child elements within the same div should NOT be effected and should be fully visible.
I know how to apply transparency to background colours and block level elements but can you do this for a background image?
Setting the opacity of the element with the background is a good start, but you'll see that any elements within the one whose opacity is changed will also be transparent.
The way around that is to have an element that contains the background and is transparent (opacity:0.6; filter:alpha(opacity=60)), and then float or position the container with the actual content over it.
Here's a sample of how this approach would work:
#container {
width: 200px;
postiion: relative;
}
#semitrans {
width: 100%; height: 100px;
background: #f00;
opacity: 0.6;
filter:alpha(opacity=60);
}
#hello {
width: 100%; height: 100px;
position: absolute;
top: 20px; left: 20px;
}
<div id="container">
<div id="semitrans"></div>
<p id="hello">Hello World</p>
</div>
No. Not technically. You'd have to apply a background-color in order to get this to work because you'd be fading the color and image, rather than just the image. Remember that a background image is not styleable content.
You could probably hack it by using an image instead of a background image and there a mixture of relative and absolute positioning with some z-indexing on top. But that's the only way I can think of!
IE uses filter:alpha(opacity=50); while others use opacity:.5
Just include them both.

Resources