Related
I am experimenting with single-page design, and have built a page out of a number of different pages, by essentially creating a column of <div> elements each at 100% of the window height, and positioned absolutely one under another.
Each page, therefore, requires it's elements to be set absolutely, since there is (as far as I can tell) no normal document flow to follow. However, when it comes to text, I am finding it difficult to design. I'd like to try and keep the current design, rather than start over.
On a particular page, I have a text container. In that container, there are two titles. The first title heads two small paragraphs, the second heads one:
HTML
<div id="introTextContainer">
<div id="introTextHeader" class="blurbheader">First title</div>
<div id="introText" class="blurb">
Generic text about the roots of the company
</div>
<div id="introTextParg2" class="blurb">
further information about the roots
</div>
<div id="introStatement1" class="blurb StrongStatement">
Second title
</div>
<div id="introTextParg3" class="blurb">
Eye-catching mission statement
</div>
</div>
CSS
.blurb {
font-family: Lato;
font-size: 16px;
padding-right:10px;
font-size: 1.4vh
}
.blurbheader {
font-family: Lato;
font-size: 2vh;
padding-right:10px;
}
.StrongStatement {
font-family: Lato;
font-size: 20px;
}
#introTextContainer {
height: 20%;
width: 45%;
background: rgba(255,255,255,0.8);
position: absolute;
left: 200px;
top: 10%;
border-radius: 5px;
}
#introTextHeader {
position: absolute;
width: 280px;
left: 30px;
top: 5px;
height: 10%;
}
#introText {
position:absolute;
left: 10px;
font-family: Lato;
}
#introTextParg2 {
position:absolute;
left: 10px;
}
#introStatement1 {
position:absolute;
left: 30px;
}
#introTextParg3 {
position:absolute;
left: 10px;
}
At a standard resolution of 1080p, all of this looks perfectly acceptable. However, when the resolution is changed, the design is not responsive to the same. As you can see with the CSS, I have been experimenting with viewport-height for the text, however the spacing and height of the <div> elements is a different matter.
How can I create a positioning/size context within the scope of the text containers, in order that I can set the height and padding of the text paragraphs therein, within the scope of those containers? The current approach uses javascript, but I don't like the idea of attempting to use javascript to target every screen size possible as this would result in a lot of spaghetti code. Ideally, I would like to use javascript only to set the heights of the "page" <div> elements and the containing boxes.
edit: CSS, JS, HTML of page design
The first page is given a width and height of 100%. The subsequent pages are altered with JQuery. The value data-section-name is used in the seamless scrolling plugin. The canvas is used only to house the background image:
HTML
<section id="pageOne" class="panel pageone" data-section-name="sectionpageOne"> <!-- About -->
<canvas id="pageOneCanvas"></canvas>
<div id="introTextContainer">
<div id="introTextHeader" class="blurbheader">First title</div>
<div id="introText" class="blurb">
Generic text about the roots of the company
</div>
<div id="introTextParg2" class="blurb">
further information about the roots
</div>
<div id="introStatement1" class="blurb StrongStatement">
Second title
</div>
<div id="introTextParg3" class="blurb">
Eye-catching mission statement
</div>
</div>
</div>
</section>
CSS
#pageOne {
position: absolute;
/*top: 0;*/
left: 0;
width: 100%;
}
#pageOneCanvas {
height: 100%;
width: 100%;
z-index: 1;
background-image: url("/Resources/images/aboutcanvas.jpg");
background-size: cover;
opacity: 0.6
}
JS
// Canvas height and positioning
var posheight = $(window).height();
$("#home").height(posheight);
$("#pageOne").height(posheight);
$("#pageTwo").height(posheight);
$("#pageThree").height(posheight);
$("#pageFour").height(posheight);
$("#pageFive").height(posheight);
$("#pageOne").css("top", posheight);
$("#pageTwo").css("top", (posheight * 2));
$("#pageThree").css("top", (posheight * 3));
$("#pageFour").css("top", (posheight * 4));
$("#pageFive").css("top", (posheight * 5));
Additionally, the current solution for fixing the text container dimensions is also in JS. You can start to see why I want to achieve this in CSS, as it's becoming messy here:
var introTextTitleHeight = $("#introTextHeader").height();
$("#introText").css("top", (introTextTitleHeight + 10));
$("#introTextParg2").css("top", ($("#introText").position().top + $("#introText").height() + 10));
$("#introStatement1").css("top", ($("#introTextParg2").position().top + $("#introTextParg2").height() + 10));
$("#introTextParg3").css("top", ($("#introStatement1").position().top + $("#introStatement1").height() + 10));
Would removing position: absolute; on the child divs not do what you want?
And use margin-left instead of left.
So the rules would look like this:
#introTextHeader {
margin-left: 30px;
margin-top: 5px;
height: 10%;
}
#introText {
margin-left: 10px;
font-family: Lato;
}
#introTextParg2 {
margin-left: 10px;
}
#introStatement1 {
margin-left: 30px;
}
#introTextParg3 {
margin-left: 10px;
}
So i've come to live by these 3 CSS rules that almost always vertically center any block level element:
.vertically-center {
position: relative;
top: 50%;
transform: translateY( -50% );
}
It works often. But in the case of this particular layout I'm building it is pushing the elements too high ( partially off the screen ) and I don't know why.
This is how the webpage looks before adding my vertically-center class to my portrait-container div:
And this code snippet is how it appears after adding the vertically-center class to the portrait-container div:
.clearfix:after {
content: "";
display: block;
clear: both;
}
.vertically-center {
position: relative;
top: 50%;
transform: translateY( -50% );
}
body {
overflow: hidden;
}
main {
padding-top: 50px;
background: #fafafa;
text-align: left;
}
.portrait-container {
float: left;
}
img {
width: 150px;
border-radius: 50%;
}
.about-container {
width: 70%;
float: right;
}
<main class="clearfix">
<div class="portrait-container vertically-center">
<img src="http://i.imgur.com/Eb5sRZr.jpg" alt="Portrait of John Lesko">
</div>
<div class="about-container">
<h3>About</h3>
<p>
Hi, I'm John Lesko! This is my art portfolio where I share all
of my favorite work. When I'm not creating things, I enjoy excercising,
playing video games, drinking good Kool Aid, and more.
<br><br> If you'd like to follow me on Twitter, my username is
#jletsgo.
</p>
</div>
</main>
I just want the image container to be vertically-centered regardless of the height of it's parent. Help? Inspecting elements gave me no insights.
Edit: Just to show how this has always worked for me in the past. Here is a jsfiddle: https://jsfiddle.net/9kyjt8ze/4/. Why does it work for me there and not here?
Related question: What does top: 50%; actually do on relatively positioned elements?
Your CSS was not bad but I didn't get along with it. So here is another approach on how you could solve it, maybe it helps also. It will always center the image vertically and does not matter how much text the box on the right will have. The colored borders are just there to help show the visual effect of the box sizes.
* {
box-sizing: border-box;
}
.portrait-container {
position: relative;
margin: 20px 0;
}
.portrait-container:after {
content: '';
display: block;
clear: both;
}
.portrait-container img {
position: absolute;
top: calc(50% - 80px); /* 50% from top minus half img height*/
width: 150px;
height: 160px;
border-radius: 50%;
float: left;
}
.portrait-container {
border: solid 2px orange;
}
.portrait-container .about-container {
border: solid 2px green;
padding: 0 50px;
margin-left: 150px; /* this elements should be at least 150px away from left side */
width: calc(100% - 150px); /* the max width this element should have to be placed */
/* next to the image is the total width(100%) - the image width */
}
<main>
<div class="portrait-container">
<img src="http://i.imgur.com/Eb5sRZr.jpg" alt="Portrait of John Lesko">
<div class="about-container">
<h3>About</h3>
<p>
Hi, I'm John Lesko! This is my art portfolio where I share all
of my favorite work. When I'm not creating things, I enjoy excercising,
playing video games, drinking good fruit punch, and more.
<br><br> If you'd like to follow me on Twitter, my username is
#jletsgo.
</p>
</div>
</div>
</main>
<main>
<div class="portrait-container">
<img src="http://i.imgur.com/Eb5sRZr.jpg" alt="Portrait of John Lesko">
<div class="about-container">
<h3>About</h3>
<p>
Hi, I'm John Lesko! This is my art portfolio where I share all
of my favorite work. When I'm not creating things, I enjoy excercising,
playing video games, drinking good fruit punch, and more.
<br><br> If you'd like to follow me on Twitter, my username is
#jletsgo.
</p>
<p>
Hi, I'm John Lesko! This is my art portfolio where I share all
of my favorite work. When I'm not creating things, I enjoy excercising,
playing video games, drinking good fruit punch, and more.
<br><br> If you'd like to follow me on Twitter, my username is
#jletsgo.
</p>
</div>
</div>
</main>
UPDATE
Edit: Just to show how this has always worked for me in the past. Here is a jsfiddle: https://jsfiddle.net/9kyjt8ze/4/. Why does it work for me there and not here?
The black circle is the only element there in the Fiddle, there's no obstructions. In the code you are having trouble with, you have many elements either in the way or wrapped around other elements trapping them. Your ruleset will work if you start stripping away the layers. Or you can just add a property and change another property as per Snippet 1.
One important note a relative element is actually occupying the original spot, so if given a left:40px it appears to be moved 40px to the left, but in reality it still occupies the space 40px to the right of where it appears to be. So relative elements are not really in a flow different from static elements. Therefore they are affected by and affect static layout, it's just not noticeable normally because they stack with z-index.
Snippet 2 is an interactive demo, I figured maybe that'll help explain things better.
The 3 CSS ruleset is a common way to vertically align elements, but it was originally position: absolute instead of position:relative and it had to be in another positioned element if I remember correctly.
REFERENCE
Specific Ruleset
W3Schools
MDN
SOLUTION
.vertically-center {
/* Changed to absolute from relative */
position: absolute;
top: 50%;
transform: translateY( -50% );
}
main {
/* Added position: relative */
position: relative;
padding-top: 50px;
background: #fafafa;
text-align: left;
}
SNIPPET 1
.vertically-center {
position: relative;
top: 50%;
transform: translateY( -50%);
}
body {}
main {
padding-top: 50px;
overflow: scroll;
background: #fafafa;
text-align: left;
}
img {
width: 150px;
border-radius: 50%;
float: left;
}
.about {
width: calc(100% - 150px);
float: right;
}
<main class="clearfix">
<img src="http://i.imgur.com/Eb5sRZr.jpg" alt="Portrait of John Lesko" class="vertically-center">
<article class="vertically-center about">
<h3>About</h3>
<p>
Hi, I'm John Lesko! This is my art portfolio where I share all of my favorite work. When I'm not creating things, I enjoy excercising, playing video games, drinking good Kool Aid, and more.</p>
<p>If you'd like to follow me on Twitter, my username is
#jletsgo.
</p>
</article>
</main>
SNIPPET 2
$('#b1').click(function() {
$('body').toggleClass('R S');
});
$('#b2').click(function() {
$('#N1,#N2,#N3').toggleClass('N M');
});
$('input[id$="2"]').on('input', function() {
var grp = "." + $(this).attr('class');
var num = parseInt($(this).val(), 10);
grp !== '.S' ? $('section' + grp).css('left', num + '%') : $('section.S').css('margin-left', num + '%');
});
$('input[id$="3"]').on('input', function() {
var grp = "." + $(this).attr('class');
var num = parseInt($(this).val(), 10);
grp !== '.S' ? $('section' + grp).css('top', num + '%') : $('section.S').css('margin-top', num + '%');
});
html,
body {
height: 100%;
width: 100%;
}
body {
overflow: scroll;
font: 400 12px/1.2 Consolas;
}
section {
width: 50px;
height: 150px;
border: 2px dashed grey;
text-align: center;
color: white;
}
.R {
position: relative;
background: rgba(0, 0, 255, .3)
}
.A {
position: absolute;
background: rgba(255, 0, 0, .3)
}
.F {
position: fixed;
background: rgba(0, 255, 0, .3)
}
.S {
position: static;
background: rgba(122, 122, 0, .3)
}
.N {
position: absolute;
background: yellow;
color: blue;
}
.M {
position: relative;
background: black;
color: yellow;
}
#R1 {
left: 20%;
top: 3%;
z-index: 1;
}
#A1 {
left: 42%;
top: 44%;
z-index: 2;
}
#F1 {
right: 20%;
top: 44%;
z-index: 3;
}
#S1 {
margin-left: 0;
margin-top: -28%;
}
#N1 {
bottom: 0;
right: 0;
width: 25px;
height: 80px;
z-index: 4;
}
input {
width: 6ex;
position: static !important;
}
button {
font: inherit;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body class='S'>
<fieldset>
<button id='b1'>Body Relative/Static</button>
<button id='b2'>Nested Absolute/Relative</button>
<br><br> RLeft
<input id='R2' class='R' type='number' value='20'> RTop
<input id='R3' class='R' type='number' value='3'> ALeft
<input id='A2' class='A' type='number' value='44'> ATop
<input id='A3' class='A' type='number' value='44'><br> FLeft
<input id='F2' class='F' type='number' value='64'> FTop
<input id='F3' class='F' type='number' value='44'> SLeft
<input id='S2' class='S' type='number' value='0'> STop
<input id='S3' class='S' type='number' value='-28'><br> NLeft
<input id='N2' class='N' type='number' value='45'> NTop
<input id='N3' class='N' type='number' value='45'>
</fieldset>
<section id='R1' class='R'>RELATIVE
<section id='N1' class='N'>N<br>E<br>S<br>T<br>E<br>D</section>
</section>
<section id='A1' class='A'><br><br><br>ABSOLUTE</section>
<section id='F1' class='F'><br><br>FIXED</section>
<section id='S1' class='S'><br><br><br><br><br>STATIC</section>
</body>
You can achieve this by using flexboxwith a lot less code. The below code will do the trick.
.clearfix {
display: flex;
align-items: center;
}
img {
width: 150px;
border-radius: 50%;
}
.about-container {
width: 70%;
padding-left: 30px;
}
Check it out in codepen http://codepen.io/anon/pen/OWYxrb
I'm working on this banner ad that I posted here yesterday and I got my images fading properly, but I had everything positioned in an absolute manner, and I need to have it so that when my ad expands, it pushes whatever content below it down. Right now, when I press expand, it covers the image below it, rather than push it down even though the picture's positioning is relative.
Here's a link to my project on codepen.
And here's my CSS:
#banner{
position: relative;
min-height: 100px;
}
.hide {
transition: opacity .5s ease-in-out;
opacity: 0;
position:absolute;
}
.show {
transition: opacity .5s ease-in-out;
opacity: 1;
position: absolute;
z-index: 1;
}
#toggle, #toggle2{
cursor: pointer;
}
#toggle{
margin-left:-123px;
}
#toggle2{
position: relative;
}
#twitterIcon{
position: relative;
}
.videoDiv > video {
display:inline-block;
border: 1px solid;
font-size:0;
margin: 0;
padding:0;
}
.videoDiv{
font-size:0;
margin-left:413px;
padding-top:152px;
}
I've read that absolute positioning makes it this way, but I need the collapsed and expanded version to be absolute so that they're on top of one another. Is there anyway I can make it so that the Coach ad pushes the image of Ron Swanson down rather than covering it?
Here is a complete solution: http://codepen.io/anon/pen/mewMEO
The solution is to make the smaller banner absolute with a negative z-index so it is in fact behind the normally positioned large banner.
Also, I took the liberty of improving your JS code by making it more generic and adding support for multiple banners on the page.
HTML
<div class="banner collapsed">
<img class="preview-size" src="http://i.imgur.com/y6foj3Z.jpg"/>
<img class="full-size" src="http://i.imgur.com/CeUfSAX.jpg"/>
<div class="btn-expand">
<img id="toggle" src="http://i.imgur.com/axmdldH.png" />
</div>
<div class="btn-collapse">
<img src="http://i.imgur.com/5wZwdGz.png" />
<a href="https://twitter.com/intent/tweet?text=I%20LOVE%20the%20new%20%40coach%20swagger!">
<img id="twitterIcon" src="http://i.imgur.com/WxSsDpb.png" />
</a>
</div>
</div>
<div class="push">
<img src="http://i.imgur.com/sFNERNs.jpg" />
</div>
CSS
.banner {
position: relative;
width: 970px;
}
.banner img {
/* Get rid of that margin on the bottom of the images */
display: block;
}
.banner .btn-collapse img {
display: inline;
}
.banner .btn-expand {
position: absolute;
bottom: 0;
right: 0;
}
.banner .preview-size {
z-index: -1;
position: absolute;
}
.banner .btn-expand {
display: none;
}
.banner.collapsed .preview-size {
z-index: 0;
position: relative;
}
.banner.collapsed .preview-size,
.banner.collapsed .btn-expand {
display: block;
}
.banner.collapsed .full-size,
.banner.collapsed .btn-collapse {
display: none;
}
JS
(function() {
var bannerEls = document.getElementsByClassName('banner');
// Support multiple banners
for (var index = 0; index < bannerEls.length; index++) {
var currBannerEl = bannerEls[index];
var expandEl = currBannerEl.getElementsByClassName('btn-expand')[0];
var collapseEl = currBannerEl.getElementsByClassName('btn-collapse')[0];
registerBannerToggle(expandEl, currBannerEl);
registerBannerToggle(collapseEl, currBannerEl);
}
function registerBannerToggle(clickableEl, bannerEl) {
clickableEl.addEventListener('click', function(e) {
toggleCollapseState(bannerEl);
});
}
function toggleCollapseState(bannerEl) {
if (bannerEl.className.indexOf('collapsed') !== -1) {
bannerEl.className =
bannerEl.className.replace(/collapsed/g, '');
}
else {
bannerEl.className += ' collapsed';
}
}
})();
The reason you are not able to do this was intentional to deter advertisers from messing with the actual website content. To pull it off, you would have to keep the position relative for the add or manipulate the ".push" div using javascript.
I dont know much plain javascript so I changed it for jQuery if you don't mind
All I've done was get images height and set animate on them with click on #toggle/#toggle2
CODEPEN
This question already has answers here:
Creating a hole in a <div> element
(10 answers)
Closed 7 years ago.
So say I have the following HTML structure:
<canvas></canvas>
<div class="overLay">
<button>Click me!</button>
</div>
The canvas is absolutely positioned with a negative z index, so the overlay is positioned over it (I have that much working). The issue is that I want the overlay div to have a white background, but the button to have a transparent background and show through to the canvas/body background color.
background-color:rgba(0,0,0,0);
doesn't work because it just shows the white background behind it. Any ideas on how to accomplish this effect?
The question this may have been marked as a potential duplicate of fails to account for the fact that buttons can have properties such as border-radius and offers no suitable solutions.
There's no way to create a hole inside an HTML element. A Transparent background can only be applied to an element that does not descend from a parent that has a non-transparent background.
What you could do, thought it's a little bit more complicate, is to create divs around your button, at it's same level, as siblings. Give those divs a white background, and then your transparent button should work.
I've created a sample using a table layout, where the button remains in the middle row, in the center cell. See that the button reveals the canvas background color:
canvas {
width: 200px;
height: 200px;
background: purple;
position: absolute;
z-index: -1;
}
.overLay {
width: 200px;
height: 200px;
display: table;
}
.overLay button {
background-color: Transparent;
white-space: nowrap;
}
.overLay > div {
display: table-row;
}
.overLay > .middle {
height: 1px;
}
.overLay > div > div {
display: table-cell;
text-align: center;
}
.overLay > .middle > div:nth-child(2) {
width: 1px;
}
/* Now, set the background on the divs around the button */
.top, .left, .right, .bottom {
background: white;
}
<canvas></canvas>
<div class="overLay">
<div class="top">
<div></div>
<div></div>
<div></div>
</div>
<div class="middle">
<div class="left"></div>
<div>
<button>Click me!</button>
</div>
<div class="right"></div>
</div>
<div class="bottom">
<div></div>
<div></div>
<div></div>
</div>
</div>
Since in my original answer, you pointed the intention of using a border radius. So there's another approach to make this possible.
Based on this asnwer
Make the overlay with a gradient radius background, that creates the gradient color center in the position where you want the button to be, at the button's size. Make the outer color as white, and the inner color as Transparent;.
Then, set your button's position. (I did this by centering it in a table layout):
canvas {
width: 200px;
height: 200px;
background: purple;
position: absolute;
z-index: -1;
}
.overLay {
width: 200px;
height: 200px;
display: table;
background-color: white;
background: -webkit-radial-gradient(50% 50%, circle, transparent 25px, white 0px);
background: radial-gradient(50% 50%, circle, transparent 25px, white 0px);
}
.overLay > div {
display: table-cell;
text-align: center;
vertical-align: middle;
}
button {
background-color: transparent;
border-radius: 50%;
width: 50px;
height: 50px;
position: relative;
}
<canvas></canvas>
<div class="overLay">
<div>
<button>Click me!</button>
</div>
</div>
Mmm..., have you thought about using an SVG element with a mask. That should do the trick. Take a look at the snippet.
body {
padding: 0;
margin: 0;
}
.your-canvas {
position: absolute;
top: 0;
left: 0;
z-index: -1;
}
button {
width: 150px;
height: 100px;
background-color: transparent;
color: white;
cursor: pointer;
}
<div class="your-canvas">
<img width="512" alt="Weingarten Kuppel 8" src="//upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Weingarten_Kuppel_8.jpg/512px-Weingarten_Kuppel_8.jpg"/>
</div>
<svg height="324" width="512">
<defs>
<mask id="mask">
<rect width="512" height="324" fill="white"/>
<rect x="181" y="112" width="150" height="100" fill="black"/>
</mask>
</defs>
<rect width="512" height="324" style="fill:rgba(255,0,0,.6);" mask="url(#mask)"/>
<foreignObject class="node" x="181" y="112" width="150" height="100">
<body xmlns="http://www.w3.org/1999/xhtml">
<button>Click Me</button>
</body>
</foreignObject>
</svg>
As far as i know it is even possible to use masking in pure css, but haven't had the time to look it up. Here is some information on using masks with svg Clipping and masking.
Have fun.
You could...
Reduce a canvas element to button size (== a button-canvas!),
Use CSS to position the button-canvas as desired over the div,
Add a click event listener on the canvas,
Draw whatever design you need on the button-canvas.
This way you have complete flexibility using the amazing drawing tools available with the canvas element.
Here's example code and a (fanciful) Demo.
While this demo is just for fun, you can easily restyle this example & turn it into a reusable widget:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var width=80;
var height=40;
var borderwidth=4;
var x=0;
var y=0;
x+=borderwidth;
y+=borderwidth/2;
var w=width-borderwidth-borderwidth;
var h=height-borderwidth;
var depth=5;
//
var stopCount=8;
var angle=0;
var angleDelta=360;
//
var labelColor='black';
canvas.width=width;
canvas.height=height;
requestAnimationFrame(animate);
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseUp(e);});
function makeGradient(){
var g=ctx.createLinearGradient(0,0,cw,0);
for(var i=0;i<stopCount;i++){
var stop=i/stopCount;
var hslDegrees=(angle+angleDelta*stop)%360;
var hsl="hsl(" + hslDegrees + ",100%, 50%)"
g.addColorStop(stop,hsl);
}
return(g);
}
function animate(){
ctx.clearRect(0,0,cw,ch);
gradientBorder();
ctx.font='12px verdana';
ctx.fillStyle=labelColor;
ctx.fillText('Click Me',x+10,y+25);
angle++;
requestAnimationFrame(animate);
}
//
function gradientBorder(){
var lw=ctx.lineWidth
var ss=ctx.strokeStyle;
ctx.lineWidth=borderwidth;
ctx.strokeStyle=makeGradient();
//
ctx.beginPath();
ctx.moveTo(x+w-depth,y);
ctx.lineTo(x+depth,y);
ctx.bezierCurveTo( x-depth/2,y+h*1/6, x+depth*2,y+h*2/6, x,y+h/2);
ctx.bezierCurveTo( x+depth*2,y+h*4/6, x-depth/2,y+h*5/6, x+depth,y+h);
ctx.lineTo(x+w-depth,y+h);
ctx.bezierCurveTo( x+w+depth/2,y+h*5/6, x+w-depth*2,y+h*4/6, x+w,y+h/2);
ctx.bezierCurveTo( x+w-depth*2,y+h*2/6, x+w+depth/2,y+h*1/6, x+w-depth,y);
ctx.closePath();
ctx.stroke();
//
var b2=borderwidth/2;
ctx.beginPath();
ctx.moveTo(x+w-depth-1,y+b2);
ctx.lineTo(x+depth+2,y+b2);
ctx.bezierCurveTo( x-depth/2+b2+2,y+h*1/6+1, x+depth*2+b2,y+h*2/6, x+b2+1,y+h/2);
ctx.bezierCurveTo( x+depth*2+b2,y+h*4/6+1, x-depth/2+b2+1,y+h*5/6, x+depth+b2-2,y+h-b2);
ctx.strokeStyle='#666';
ctx.lineWidth=0.50;
ctx.moveTo(x+depth+b2-2,y+h-b2);
ctx.lineTo(x+w-depth-2,y+h-b2);
ctx.bezierCurveTo( x+w+depth/2-b2-2,y+h*5/6, x+w-depth*2-b2+1,y+h*4/6, x+w-b2-2,y+h/2);
ctx.bezierCurveTo( x+w-depth*2-b2+1,y+h*2/6, x+w+depth/2-b2-2,y+h*1/6, x+w-depth-b2+3,y+b2);
ctx.strokeStyle='#666';
ctx.lineWidth=0.50;
ctx.stroke();
//
ctx.strokeStyle=ss;
ctx.lineWidth=lw;
ctx.fillStyle='gainsboro';
ctx.fill();
}
function handleMouseDown(e){ labelColor='red'; }
function handleMouseUp(e){ labelColor='black'; }
body{ background-color:white; }
.demo{
width:200px;
height:100px;
border:1px solid red;
position:relative;
}
#canvas{
position:absolute;
left:10px;
top:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class='demo'>
<canvas id="canvas"></canvas>
</div>
I'm trying to create the following:
Using two images: one as mask (the diagonal lines) and the other the image and text themselves (the mask and image+text are the same size):
..and I just can't get it done!
I've tried all combinations with divs and z-indeces, opacity and background-image.. (should mention I'm noob to html).
Here's one shot I got at it (with only the mask and an image):
div {
position: absolute;
top: 775px;
left: 0px;
height: 188px;
width: 272px;
background-image: url('grey-out.png');
}
img {
z-index: 1000;
}
<div></div>
<img src="41_large.png" />
Which just gives the diagonal lines themselves..
Can someone please help me out?
How do I make that "disabled" look combining the (semi-transparent) mask and the div?
Thanks!
This approach works:
<div id="pspThing" class="disabled">
<img class="disabled" src="http://i.stack.imgur.com/lCTVr.png" />
</div>
#pspThing {
background: transparent url(http://i.stack.imgur.com/WpgNy.jpg) 0 0 no-repeat;
height: 93px;
width: 273px;
border: 1px solid #000;
margin: 0 auto;
overflow: hidden;
}
#pspThing img {
display: none;
opacity: 0.5;
}
#pspThing img.disabled {
display: block;
}
JS Fiddle demo
Bearing in mind that there's no transparency in your striped png (so far as the imgur hosted image is concerned, anyway, so I'm using opacity instead). Also the JS Fiddle demo's a little more complicated than necessary, so's I could show the disabled/enabled states.
Pleass consider this simple snippet. Very universal solution. Acts and feels very much like the 'disable' attribute of input elements. See the snippet
function disable(elementId, enabling) {
el = document.getElementById(elementId);
if (enabling) {
el.classList.remove("masked");
} else
{
el.classList.add("masked");
}
}
.masked {
position: relative;
pointer-events: none;
display: inline-block;
//visibility:hidden; /* Uncomment this for complete disabling */
}
.masked::before {
position: absolute;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
visibility: visible;
opacity: 0.5;
background-color: black;
//background: url('http://i.imgur.com/lCTVr.png'); /* Uncomment this to use the image */
content: "";
}
<button onclick="alert('Now, click \'OK\' then \'Tab\' key to focus next button.\nThen click \'Enter\' to activate it.');">Test</button>
<div id="div1" style="display:inline-block" class="masked">
<button onclick="alert('Sample button was clicked.')">Maskakable</button>
<button onclick="alert('Sample button was clicked.')">Maskakable</button><br/>
<br/>
<button onclick="alert('Sample button was clicked.')">Maskakable</button>
<button onclick="alert('Sample button was clicked.')">Maskakable</button><br/>
<img src="http://i.stack.imgur.com/WpgNy.jpg">
</div>
<button>Dummy</button>
<br/>
<button id="enableBtn" onclick="disable('div1',true);disable('enableBtn',false);disable('disableBtn',true);">Enable</button>
<button id="disableBtn" onclick="disable('div1',false);disable('enableBtn',true);disable('disableBtn',false);" class="masked">Disable</button>
I built an example here.
I doubt that the position:absolute approach is the best way to handle this since you need to know the size of the image.
For doing it by z-index your both images should be in the container with img tag.