I would like to make a transparent arrow over an image. This triangle should be indented in a block and show the background image.
Desired output:
I used skewX() property that #web-tiki had explained here but I want it to display on the top of the border rather than on the bottom of image and have this issue:
A fiddle demo of my code is available here
Can anyone tell me why it's not working in my case?
As stated in the question, your case is a bit different from the example that was provided by web-tiki. In the example that you were referring to, the border with the transparent cut was included as the bottom border for the image whereas you need it as the top border of the plain text area.
The expected output can be achieved with the same skew technique described in that answer. However, it needs to be tweaked a bit to match your case.
First thing is, the skewed pseudo-elements (that produce the border) should be added to the container of plain text area and not the top section which holds the image. This part you have already done correctly.
Next, you need to position the border such that even with the border the height of your text container will be equal to the other two images placed by its side. For this, you need to position the elements that form the border within the plain text container (top: 0%) instead of above it (bottom: 100% in your code).
Then, if the text container has a non-transparent background, you need to clip it such that it is not present behind the elements that is creating the border effect. This can be achieved by adding a padding-top on the text container equal to the height of the border pseudo-elements and then setting background-clip: content-box to it.
Finally, you need to move the entire bottom part up by the same number of pixels as the height of the border in order for the top image to be seen through the transparent cut out area. This can be done by adding a negative margin-top to the bottom container.
Putting it altogether your code should be similar to the below snippet to achieve the effect that you need. (Note: Your fiddle has way too much code and so I have created a simpler sample for the demo).
.section {
height: 200px;
width: 500px;
background: url(http://lorempixel.com/500/200/nature/3);
}
.bottom-container {
margin-top: -15px;
height: 100px;
width: 500px;
}
.text,
.middle-image,
.right-image {
float: left;
height: 100%;
width: calc(100% / 3);
}
.middle-image {
background: url(http://lorempixel.com/200/100/nature/2);
}
.right-image {
background: url(http://lorempixel.com/250/100/nature/1);
}
.text {
position: relative;
box-sizing: border-box;
height: 100%;
padding-top: 15px;
text-align: center;
line-height: 85px;
background: #F7F7F7; /* Just for demo */
background-clip: content-box; /* needed only if your background is not transparent */
overflow: hidden;
}
.text:after,
.text:before {
position: absolute;
content: '';
top: 0px;
height: 15px;
background: rgb(215,182,115);
}
.text:before {
left: 0px;
width: 25%;
transform-origin: left bottom;
transform: skew(45deg);
}
.text:after {
right: 0px;
width: 75%;
transform-origin: right bottom;
transform: skew(-45deg);
}
<!-- prefix free library to avoid browser prefixes in CSS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<section class="section">
</section>
<div class="bottom-container">
<div class="text">Some text</div>
<div class="middle-image"></div>
<div class="right-image"></div>
</div>
Screenshot:
Note: The images that are displayed when the snippet is executed could be different from those in the screenshot because they are random placeholder images
Related
I've been trying to use the mix-blend-mode on a page that has contains instances of css opacity transitions. What appears to be happening is that the div containing the mix-blend-mode displays as it would without the blend mode during the transition, or rather, while the animation is in progress. I've only found it to be an issue in Chrome.
In my example, while the div is transforming the blend-mode displays correctly over the image but not over the page background. Once the transition is complete it goes back to display as it should. In other words the blended div appears as solid yellow on the black background while the animation is ongoing but since it is set to darken it should be invisible over the black background. Once the animation is finished it appears as it should. It appears normal over the image.
I've tried this is Firefox and Safari and there seems to be no issue.
Pen: http://codepen.io/anon/pen/QGGVOX
Edit - I've found another instance where this occurring that doesn't involve any animation. Weirdly it happens when the position of one div is set to fixed while the other is absolute, see here: http://codepen.io/anon/pen/wooRME If the position of the div .image is changed to absolute then the blend-mode appears normal.
body {
background: #000;
}
.blend {
height: 650px;
width: 50%;
background-color: yellow;
mix-blend-mode: darken;
position: absolute;
opacity: 1;
left: 0;
top: 0px;
z-index: 100;
}
img {
position: relative;
z-index: 0;
}
So, I think I figured the problem. During the animation, it seems like the body doesn't count as an element, thus making the yellow appear at 1 opacity. I tested with other blend mode and it always appears yellow. (when set to 'difference the expected result would be white instead of yellow)
So the fix? just add a div with 100% sizes and a black background! Then, the yellow has something to blend in and doesn't show up.
Here's the code that worked in your pen:
html - added the bg div:
<div class="bg"></div>
<div class="blend"></div>
<img src="http://lorempixel.com/500/500/">
it's css:
.bg{
background: #000;
position: absolute;
width: 100%;
height: 100%;
margin: 0;
}
body {
background: #000;
width: 100%;
height: 100%;
margin: 0;
}
I also changed the body to fill the window so the margin weren't yellow too. Alternatively, the blend div could be sized in function of the body.
tagging #chrscblls since they wanted to know if you found anything.
EDIT :
For the other codepen the problem wasn't the same tho. They were trying to darken an image and a yellow rectangle onto a gray background.
If they didn't want the yellow to show on their gray background, the solution was simply to put the image inside a div and use ::after to blend in a color. Or even just make an empty div, give it the image as background and use the ::after.
this:
<div/>
with:
body {
background: #333;
}
div{
position:fixed;
width: 500px;
height: 500px;
top:50px;
left: 50px;
mix-blend-mode: darken;
background-image: url("http://lorempixel.com/500/500/");
}
div::after {
content: "";
height: 100%;
width: 100%;
background-color: yellow;
mix-blend-mode: darken;
position:absolute;
opacity: 1;
left: 0;
top: 0;
}
or this:
<div><img src="http://lorempixel.com/500/500/"></div>
without the 'background-image' in the div css.
I need to dynamically display 2 graphic image files that represent opening and closing quotes as shown below in the sample screen shot.
The quotes need to appear just to the left and to the right of the upper content block as shown. Content block widths will vary on the page.
I have tried float and background image. Does anyone have a tip or trick to properly, dynamically and flexibly position 2 image files?
Here is what I have so far after working with #Utkanos answer:
HTML
<div class="postsPage_item_content postsPage_item_quote"><?php the_content();?></div>
CSS
div#maincontentcontainer div#primary div div.postsPage_item_content {
position: relative;
text-align: center;
}
div#maincontentcontainer div#primary div div.postsPage_item_quote::before, div#maincontentcontainer div#primary div div.postsPage_item_quote::after {
background-image: url('../images/QUOTE1.png');
content: '';
display: block;
left: 20%;
height: 28px; /* background-image natural height is 28px */
position: absolute;
top: calc(50% - 50px);
width: 36px; /* background-image natural width is 36px */
}
div#maincontentcontainer div#primary div div.postsPage_item_quote::after {
background-image: url('../images/QUOTE2.png');
left: auto;
right: 20%;
}
Display
Desired results are that (1) each of the dynamically rendered quotes align with the top of the content block, and (2) the quotes dynamically position with margin padding to the left and right of the content block as shown by the red arrows.
Pseudo elements are perfect for this sort of thing.
HTML:
<div id='my_div'>
<p>Content here.</p>
<p>Etc.</p>
</div>
CSS:
#my_div {
position: relative;
}
#my_div::before, #my_div::after {
content: '';
width: 50px;
height: 50px;
position: absolute;
display: block;
background: url('path/to/open_quote_img.png');
left: 5%;
top: calc(50% - 25px);
}
#my_div::after {
background: url('path/to/close_quote_img.png');
left: auto;
right: 5%;
}
That code assumes your quote graphics are 50px in width and height - modify as required.
Finally, to ensure your content doesn't overlay the quote images, set an appropriate padding-left and padding-right on the container (in my example, the div) so the content is sufficiently pushed in away from them.
Another possibility is using absolute positioning inside a relative container. For example:
.container { width:300px; position:relative;padding:20px}
.left-quote {position:absolute; top:10px; left:10px; font-size:30px;}
.right-quote {position:absolute; bottom:20px; right:10px; font-size:30px;}
<div class="container">
<span class="left-quote">"</span>
<span class="right-quote">"</span>
<p>is one of the smartest and most dedicated people that I know... he helped the company achieve incredible share of voice in key publications such as...</p>
</div>
In the following fiddle:
http://jsfiddle.net/6qF7Q/1/
I have a yellow content area that has a min-height set to 100% - it's the background div to all pages and should take up at least 100% of the available height. If there's overflow, it expands vertically.
Then, within that yellow container, I have another child div (red) that I would like to take up as much vertical space as its parent. It seems I can't set height because the parent element only has min-height, and setting min-height on the red element doesn't work either.
So right now, the yellow is behaving as I'd like, but the red is not expanding. How can this be achieved with CSS only?
CSS:
.browser {
background-color: blue;
height: 600px;
width: 200px;
position: relative;
}
.innercontent {
min-height: 100%;
background-color: red;
width: 100%;
color: white;
padding: 2px;
}
.content {
background-color: yellow;
width: 100%;
min-height: calc(100% - 30px);
}
.footer {
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
background-color: orange;
height: 20px;
}
HTML:
<div class="browser">
<div class="content">
<div class="innercontent">
This is the problem - I need this to take up 100% of the remaining yellow space, without setting the parent element's 'height' - only min-height is specified in the parent because I need to make sure that it takes up 100% of the height at least, but allow it to extend vertically if there's any overflow.
</div>
should not see any yellow
</div>
<div class="footer"></div>
</div>
Take a look at this
I added this
*{
box-sizing: border-box;
}
html, body {
/* Make the body to be as tall as browser window */
height: 100%;
}
and changed some attributes u can see at fiddle
If thats what you want you should read this article
http://css-tricks.com/a-couple-of-use-cases-for-calc/
I made that based in this use-cases
I think this might solve your issue?
I have changed the innercontent to position: absolute
http://jsfiddle.net/6qF7Q/7/
If you have text in the yellow section it will always show.
Also, you're going to have to do a bit of fiddling to get your footer positioned correctly since you are going to have an overflowing absolute element. I think a full body position: relative wrapper will solve it.
P.S I don't see why you would need a .content AND a .innercontent if you don't want the .content to show?
This works much better and doesn't give you footer grief: http://jsfiddle.net/6qF7Q/9/
I have the following DIV structure:
<div id="parent">
<div id="child"></div>
<div id="child2"></div>
</div>
I want to apply one half opaque background into the parent DIV, and one fully visible background to the child DIVs. However, it seems that the child will take over the parent, so, I have now no idea how to come over with this.
EDIT: Some more clarification.
I have a jQuery draggable "window" made of DIVs. Inside it, I have a progress bar with
relative position like:
position: relative;
left: 16px;
top: 16px;
This way the progress bar will be at 16-16 of the window (not the screen) and the progress bar moves correctly along with the window.
However, the progress bar has texture on the top. Take a look at this example:
<div style="background: url('texture.png'), url('empty.png'); width: 256px;">
<div style="background: url('progress.png'); width: 33%;"></div>
</div>
There's an opaque texture applied to the whole progress bar element, for example, if the percentage of this progress bar is 33%, then it looks like xxx------ where x denotes the flowing green bar and - is empty. The texture must be applied to both x and -, but currently the image of x takes place over the texture.
I can't really use Z-index and/or position absolute to position the child elem on the top, because of the relative positioned approach.
I don't know whether I understoood your question correctly, but aren't you looking for CSS3 RGBA colours?
p { color: rgba(0,0,255,0.5) } /* semi-transparent solid blue */
p { color: rgba(100%, 50%, 0%, 0.1) } /* very transparent solid orange */
Reference: 4.2.2 RGBA color values
Here is the progress bar code I use:
To change the percentage, just change the cover class' postiion (e.g. left:80%) and of course the text percentage both of which are in the HTML. Also, it uses a semi-transparent png for the bar image, so you can change the bar background color #888888 in this case to match whatever color you desire.
Note: the files are hosted on tinypic and it's been a little slow for me lately, so give it a few extra seconds to see the images.
CSS
.wrapper {
background: transparent url(http://i50.tinypic.com/2a65xtf.png) no-repeat scroll 0pt 0pt;
width: 216px;
height: 25px;
position: relative;
}
.bar {
background: #888888 url(http://i49.tinypic.com/2cdzyj9.png) repeat scroll center center;
overflow: hidden;
position: absolute;
display: block;
width: 200px;
height: 15px;
top: 6px;
left: 8px;
text-indent: -30px;
}
.cover {
background: transparent url(http://i47.tinypic.com/zyfq61.png) repeat-x scroll 0pt 0pt;
position: absolute;
display: block;
width: 200px;
height: 15px;
top: 0px;
}
.bartext {
position: absolute;
display: block;
top: -0.2em;
font-size: 12pt;
font-weight: bold;
color: #ffffff;
}
HTML
<div class="wrapper">
<span class="bar">
<em class="cover" style="left:50%">
<span class="bartext">50%</span>
</em>
</span>
</div>
Since the children are divs, they will fill to the maximum width they can, which so happens to be the width of the parent. As a result, child and child2 will cover all the area the parent fills. To get some of the parent to show around the children, try setting the size of the children to something less than that of the parent, or try adding padding to the parent.
this is the solution for IE, the bold pieces of code are the magic ones:
<style type="text/css">
#parent { background: red; opacity: .5; filter: alpha(opacity=50); width: 100px; height: 100px }
#child1, #child2 { margin: 10px; position: relative }
#child1 { background: blue }
#child2 { background: green }
</style>
<div id="parent">
<div id="child">lorem
<div id="child2">ipsum
</div>
To be cross-browser I would suggest using an alpha PNG in the parent's background, making life much easier.
What's the best way (if any) to make the inside box transparent so the image can be seen with no opacity (clear image) and the rest of the outer box opaque. So far this is what I'm doing:
<style>
#a {
background-color: black;
float: left;
} #b {
opacity : 0.4;
filter: alpha(opacity=40);
} #div {
position: absolute;
height: 30px;
width: 30px;
top: 90px;
left: 90px;
border: 1px solid #FFF;
background: transparent;
}
</style>
<div id="a">
<div id="b">
<img src="http://clagnut.com/images/ithaka.jpg" />
</div>
</div>
<div id="div"></div>
Any ideas? thx
The maximum opacity of an element is the opacity of its parent element. So if div#b has an opacity of 40%, if his children have 100% opacity in style they will also be 40% absolute opacity.
To accomplish what you're describing (at least what I think you're describing), one way could be to have both the transparent wrapper and the image children of a parent div with relative positioning. You can absolutely position both of the children inside of that wrapper so that the image shows up on top of the transparent box.
Edit: Here is the code for the effect you are describing. My example has a 480 x 320 image, and a 30-pixel border:
<style>
#back {background-image:url(mypicture.jpg);
width:480px;
height:320px;
position:relative;}
#middle {position:absolute;
width:480px;
height:320px;
background-color:#000;
opacity:0.4;
filter:alpha(opacity=40);
top:0;
left:0;}
#front {position:absolute;
width:420px; /* 30px border on left & right */
height:260px; /* 30px border on top & bottom */
background-image:url(mypicture.jpg);
background-position:-30px -30px; /* compensate for the border */
top:30px;
left:30px;}
</style>
<div id="back">
<div id="middle">
</div>
<div id="front">
</div>
</div>
If I understand you correctly, try using just one div (i.e. get rid of the outer one with ID "a") and setting a colored border around it. Or you could get more flexibility by "faking" a border using 4 divs for the left, right, top, and bottom edges and 4 more for the corners.
It's kind of hard to know what you mean without an example page, or screenshots of what you expect and what you're actually getting.
EDIT: I was about to edit in basically the same thing Rex M wrote. Here's another (although idealistically inferior) way to do it:
<style>
#a {
float: left;
position: relative;
}
div.overlay {
opacity: 0.4;
background-color: black;
position: absolute;
}
#t {
left: 0; top: 0; height: 90px; width: 450px;
}
#b {
left: 0; top: 120px; height: 218px; width: 450px;
}
#l {
left: 0; top: 90px; height: 30px; width: 90px;
}
#r {
left: 120px; top: 90px; height: 30px; width: 330px;
}
</style>
<div id="a">
<div id="t" class="overlay"></div>
<div id="b" class="overlay"></div>
<div id="l" class="overlay"></div>
<div id="r" class="overlay"></div>
<img src="http://clagnut.com/images/ithaka.jpg">
</div>
If you want to be sure that the images have a certain color for a background, you could just as well stick a background to all IMG-elements in your stylesheet:
div#a img { background: #FFF; }
Anyhow, the filter-property in CSS should not be relied upon, as it is not part of the official specifications for CSS 2.1.
I might have misunderstood the question, though. Could you rephrase it or provide pictures of expected results?
To follow on what Rex M said, you'll need to change things so that the non-transparent elements aren't children of the transparent elements.
You can use absolute or relative positioning to line up your "border" with the picture, although this can often have inconsistencies between browsers.
The most painless way off the top of my head is to use javascript to get the top and left pixel locations of the image and set the top/left css properties of the border to match (and set the size of the border to that of the image).
UPDATE:
The asker showed an example of what he is trying to recreate. In the example linked, the shaded areas (the "not selected" area) of the picture is created by 4 divs.
The top and bottom divs are the full width of the image, and are set to have a height that is the difference between the top/bottom of the selection box and the top/bottom of the image respectively.
The side divs have height and width modified so that they fill in the "side areas" of the image.
The sizes are updated via a mousemove event.