Positioning a button on top of a canvas - css

I'm trying to position a font-awesome button on top of a canvas. My current markup:
<li id="container">
<i class="fa fa-plus"></i>
<canvas></canvas>
</li>
The container and the canvas are visible by default. When the user mouse-overs the container, the button also appears. However, it pushes the canvas downward, causing it to spill out of the container:
The container has position: absolute and I don't have any control over that (it's part of a plugin I'm using). I do have full control over the styling of the canvas and the button.
What makes this tricky is that the user can resize the container, and the button has to remain on the top center of it at all times. Currently that works fine, but I can't get it to also appear on top of the canvas.

Hover to see i.
*,
*:before,
*:after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #F72F4E;
}
#container {
position: absolute;
width: 50vmin;
height: 50vmin;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,.2);
}
#container:hover i {
opacity: 1;
transition: opacity .2s ease-out;
}
#container i {
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 3;
text-align: center;
opacity: 0;
transition: opacity .2s ease-in;
}
#container canvas {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
border: 5px solid green;
}
<li id="container">
<i class="fa fa-plus">i</i>
<canvas></canvas>
</li>

Have you tried to utilize the z-index?
If you don't know what it is you can read up on it here: http://www.w3schools.com/cssref/pr_pos_z-index.asp
Essentially, you will have the button sit on top of all other elements.
Hope this gives some guidance.
Also! Just thought of this, try to mess around with the position property.
http://www.w3schools.com/cssref/pr_class_position.asp
The 'fixed' value will position your button relative to the DOM window, meaning other elements shouldn't have an effect on its position.

Resolved it by changing the font-awesome element to a div and setting its height to 0. It's z-index was already larger than that of the canvas.

Related

CSS - stack two elements on top of each other

I have a stackblitz here
This should be the simplest thing but I can't see why its not working.
I have react app with Typescript and a styled components, I'm sure none of that is the problem this is just css.
I'm trying to position two divs on top of each other.
The container has position: relative;
And then the div are absolutely positioned.
.FlexContainerColOne,
.FlexContainerColTwo{
position: absolute;
top: 0;
left: 0;
}
But both div disappear, what am I missing
From what I am seeing here is that they are not disappearing, you just can't see them because they don't have a width assigned or content. See the following, I added width, and opacity to show the two divs merging over each other.
stackblitz snippet
Result:
flexcontainer {
position: relative;
}
.FlexContainerColOne,
.FlexContainerColTwo {
position: absolute;
top: 0;
left: 0;
}
.FlexContainerColOne {
background: red;
height: 500px;
width: 500px;
opacity: 0.5;
}
.FlexContainerColTwo {
background: green;
height: 500px;
width: 500px;
opacity: 0.3;
}
<flexcontainer>
<div class="FlexContainerColOne"></div>
<div class="FlexContainerColTwo"></div>
</flexcontainer>

Aligning div overlay on percentage width element

I'm building a "staff" page with a liquid, four-column layout. I've placed a div element, absolutely positioned on top of the photo of each staff member to act as a button/link. My problem is that when I align this overlay div to bottom:0 and right:0 I will get the occasional 1 pixel gap between the image and the overlay as I resize the window. It seems this is a function of some sort of round-off error.
I've searched this site and others for help on this, but I haven't found this issue explicitly discussed anywhere. Any insights are greatly appreciated.
The page in question can be seen here:
communicationdesign.com/cwt-beta/about.html
Resize the window to see the occasional error/gap...
Here is the relevant markup:
<div class="staff-block">
<div class="staff-photo">
<img src="img/gruber.jpg" class="portrait" />
<a href="gruber.html">
<div class="plus-link">
<div class="plus-sign">+</div>
</div>
</a>
</div>
<div class="caption">
Drew Gruber<br /><span class="job-title">Executive Director</span>
</div>
</div>
And here is the CSS:
.staff-block {
position: relative;
width: 22.3%;
float: left;
background-color: #ffc;
margin-right: 3.5%;
}
.staff-photo{
position: relative;
}
.staff-photo img, .board-photo img, .bio-photo img {
width: 100%;
}
.portrait {
opacity: 1;
display: block;
width: 100%;
height: auto;
transition: .5s ease;
backface-visibility: hidden;
}
.plus-link {
transition: .5s ease;
opacity: 1;
position: absolute;
bottom: 0;
right: 0;
}
.plus-sign {
background-color: rgba(255,204,78,0.8);
color: white;
font-size: 40px;
line-height: 30px;
padding: 4px 8px 6px;
}
This is an occupational hazard when using percentages. You could use a hack like this:
.staff-photo{
overflow: hidden;
}
.plus-link {
background-color: rgba(255,204,78,0.8); // color on the plus sign parent
position: absolute;
bottom: -5px; // position it over the edge
right: -5px;
padding: 0 5px 5px 0; // and correct the extra space
}
.plus-sign {
background-color: transparent; // or remove bg color
}

Transparency towards parent, but not towards another elements

Is there any way to make semi-transparent overlapping elements, from which only higher z-index will be visible? I would like the images to be transparent to the background, but not to the other pictures. Here is fiddle.
body {
background: white;
}
section {
height: 400px;
position: relative;
perspective: 500px;
}
img {
height: 300px;
left: 50%;
margin: -100px;
position: absolute;
top: 40%;
transform: rotateY(-30deg);
width: 200px;
}
img:nth-child(1) {
left: 30%;
opacity: 0.8;
z-index: 3;
}
img:nth-child(2) {
left: 45%;
opacity: 0.4;
z-index: 2;
}
img:nth-child(3) {
left: 60%;
opacity: 0.2;
z-index: 1;
}
<section>
<img src="https://media4.s-nbcnews.com/j/newscms/2016_36/1685951/ss-160826-twip-05_8cf6d4cb83758449fd400c7c3d71aa1f.nbcnews-ux-2880-1000.jpg">
<img src="http://toprozdily.cz/wp-content/uploads/2015/04/slon-africky.jpg">
<img src="http://img.huffingtonpost.com/asset/,scalefit_950_800_noupscale/55fc14631c00004800082775.jpeg">
</section>
So what you're going to need to do is put the images each in their own div container and set the div background-color to white. That way you see the white background through the semi-opaque images and not the image underneath.
I edited your fiddle to give you the functionality you're looking for. Hope it helps!
There isn't a way to make an element be transparent to one element but opaque to another.
However, you might be able to simulate the transparency by tinting the images instead, either by positioning a partially-transparent div of that color over each image, or with CSS filters:
https://www.w3schools.com/cssref/css3_pr_filter.asp

Jagged "border" showing due to background colour on wrapper element with border-radius: 50%;

As I was in the process of trying to make an animated figure (transitions on hover), I found out that the background of my <figure> is showing near the edges when I apply border-radius: 50% to it, even though my image should be taking up all available space.
For a quick demo that illustrates the problem, please look at http://codepen.io/anon/pen/KwMMKz
HTML
<figure>
<img src="http://placehold.it/400x400" alt>
<figcaption>Demo</figcaption>
</figure>
CSS
figure {
background-color: red;
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
position: relative; /* For caption */
}
img {
border-radius: 50%; /* Forced on image for smooth transition */
width: 100%;
transition: opacity 1s ease-out;
}
figcaption {
position: absolute;
top: 100%;
left: 0;
width: 100%;
color: hotpink;
text-align: center;
transition: top 1s ease-out;
}
figure:hover img {
opacity: 0;
}
figure:hover figcaption {
top: 50%;
}
Please note: I know that placing the background-color on figure:hover is a work-around, but I am more interested in the reason why this "jagged border"-like look is appearing.
My guess is that it has to do with AA rendering (or something related) of the browser and that it treats theĀ <figure> element differently than a media element such as <img>, but I can't find any proof of this online. Is this a bug, is it a "feature", or is it something I can actually fix?
Lastly, I also know that I could have used transform: translateY(); here for the animation, but that's not part of my question so please don't provide it as an answer.
UPDATE 17/12 14:03
It appears that this issue is not exclusive to border-radius: 50%. The issue can occur when any wrapping element uses border-radius in combination with overflow: hidden, when the wrapper contains content that is equal or bigger than the wrapper's dimensions.
UPDATE 17/12 14:14
Neither the usage of overflow: hidden on the wrapper element, nor the usage of border-radius on the contained image (or any other child element) seem to be the cause of this as they can be interchanged and the pixelated edge will still appear.
This seems to indicate that this issue is solely caused by 2 DOM elements being in exactly the same place, when any sort of border-radius is applied to the wrapper element and the visible area of the child is limited to that of the parent's.
I've been having same issue and ended up using pseudo element instead of background, kinda like that:
figure::before {
content: '';
display: block;
background-color: red;
width: 400px;
height: 400px;
transform: scale(0.997);
border-radius: 50%;
}
This allowed me to create 'pseudo background' which I later shrinked a little bit with transform: scale(0.997); so it will be just the same size but a bit below visible edge. Of course in your case you would also need to position image absolutely so it is not pushed below by this ::before.
It appears that it is indeed a "feature" of how the browser handles border-radius to give a smooth edge to the rounded corners of a container. The image background is anti-aliased in the same way (but as it is transparent has no effect) as can be seen by setting the img background color.
When the border is anti-aliased it "bleeds" into the background to soften the edges and so you are seeing that around the image as a "jaggy" ring in much the same way you would see a corona around the moon during a full solar eclipse.
the issue is always there, whether the anti-aliased object is covered or not, if you were to draw a circle then anti-alias it, you would see the circle is marginally narrower than the anti-aliased version. Most anti-aliasing algorithms aggregate the surrounding pixels of the object rather than those contained within it.
To overcome it, you'd either need to make your image large enough to cover the space taken up by the anti-aliased edge or reduce the container such that the anti-aliased area is smaller than the image.
You could add a new tag with an opacity of 0 then have that fade in with the image fading out.
figure {
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
position: relative; /* For caption */
}
background {
background-color: red;
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
opacity: 0;
position: fixed;
z-index: 5;
transition: opacity 1s ease-out;
}
img {
border-radius: 50%; /* Forced on image for smooth transition */
width: 100%;
transition: opacity 1s ease-out;
position: relative;
z-index: 100;
}
figcaption {
position: absolute;
top: 100%;
left: 0;
width: 100%;
color: hotpink;
text-align: center;
transition: top 1s ease-out;
z-index: 10000;
}
figure:hover img {
opacity: 0;
}
figure:hover background {
opacity: 1;
}
figure:hover figcaption {
top: 50%;
}
<figure>
<background></background>
<img src="http://placehold.it/400x400" alt>
<figcaption>Demo</figcaption>
</figure>
Notice I added the background tag and removed background-color from figure
http://codepen.io/marczking/pen/KwMgaR
So after playing around (used background-image and pseudo-elements, changes nothing...) you notice that this light border is only visible if you apply round corners. So I am assuming here it has to do how the Browser renders the CSS, nothing wrong with the CSS-rules ^^)
<figure>
<figcaption>Demo</figcaption>
</figure>
figure {
background-color: red;
width: 400px;
height: 400px;
border-radius: 100px;
position: relative; /* For caption */
}
figure::before {
content: "";
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: url("http://placehold.it/400x400") no-repeat;
border-radius: 100px; /* Forced on image for smooth transition */
transition: opacity 1s ease-out;
}
figcaption {
position: absolute;
top: 100%;
left: 0;
width: 100%;
color: hotpink;
text-align: center;
transition: top 1s ease-out;
}
figure:hover::before {
opacity: 0;
}
figure:hover figcaption {
top: 50%;
}

div height and width 100% follows page screen size not the element size inside

I have
<div id=overlay>
<div></div>
</div>
the height and width of the outer div is set to 100%.
What happens here is, the 100% refers to the size of the element inside (inside div).
I have a dynamically changing element on inside div, and I wanted to be my outer div got the size of the page screen.
NOTE that these div (outer and inside) are a popup element. So I wanted to cover all other elements behind the popup that's why I need the 100% of the page behind.
this is my css for the outer div
#overlay {
visibility: hidden;
position: absolute;
left: 0px;
top: 0px;
width:100%;
height:100%;
min-height: 100%;
min-width: 100%;
height: auto !important;
width: auto !important;
text-align:center;
z-index: 1000;
background-image:url(template/popup-bg.png);
}
my js
function overlay(e)
{
el = document.getElementById("overlay");
el.style.visibility = (el.style.visibility == "visible") ? "hidden" : "visible";
}
Simply change the HTML to this
<div id='overlay' class='hideOverlay'>
<div></div>
</div>
Now on clicking simply change the class.
Change your js to this
function overlay(e)
{
$('#overlay').attr('class', 'showOverlay');
}
Check the following style
.showOverlay
{
background-color: red;
height: 100%;
left: 0;
top: 0;
opacity: 0.2;
position: fixed;
width: 100%;
z-index: 1001;
}
.hideOverlay
{
display:none;
}
Background-color is given just to check the div's visibility. Change it as per your choice.
It is nice to have some opacity for overlays to have a better look and feel effect.
Try to set:
position: absolute;
Something like this...
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;

Resources