Good day.
Please consider next simple code:
<div className="box-and-clock">
{isBoxShown && (
<div className="box">
{value}
</div>
)}
<img
onMouseOver={() => setIsBoxShown(true)}
onMouseOut={() => setIsBoxShown(false)}
src={clockIcon}/>
</div>
So I've got following layout (I've cut some redundant data)
When user points at the clock icon he sees some data.
The problem is when there is more data in the black box the arrow (which is done by pseudoelements) doesn't point to clock icon anymore. Something like this
I need to make that blackbox to be on certain position from the clock icon without depending on its height.
I've tried display: table to the parent div and display: table-cell to the child, but with no luck. any advices?
My css
.box {
width: 200px;
min-height: 130px;
height: auto;
background: black;
border-radius: 2px;
position: absolute;
top: 320px;
right: 228px;
}
.box-and-clock {
display: flex;
flex-direction: column;
}
you can set parent element with css position: relative; to let children identity its position, so children element can use position: absolute; to place itself relative to its parent's position.
.box {
width: 200px;
min-height: 130px;
/* height: auto; */
background: black;
border-radius: 2px;
/* top: 320px; */
/* right: 228px; */
position: absolute;
top: 0px;
transform: translateY(-100%); /* offset element */
}
.box-and-clock {
display: flex;
flex-direction: column;
position: relative; /* you need this! */
}
ps, for more detailed concept of css position, you may keyword search: css position property
Related
TL;DR: How to keep the div children proportional to the div itself?
I have a div, containing various elements like text, images, icons etc. It keeps 16:9 aspect ratio and fills as much viewport it can, while resizing the browser window, the div (with background different from the body background) changes size well, though the contents are staying the same size which is bad because I'm trying to make a presentation website which needs to look the same at various resolutions. How do I make the child elements align and resize properly inside the div?
I tried using viewport units though it didn't turn out really well.
My Code:
I tried using % units to set font size and then use em to scale other things but it didn't work. I also tried using only % units to set all properties but it did not work either
body {
background: black;
user-select: none;
margin: 0;
height: 100vh;
}
.container2 {
overflow: auto;
box-sizing: border-box;
resize: both;
overflow: auto;
max-width: 100%;
height: 100%;
display: flex;
justify-content: center;
}
.presentation-place {
user-select: none;
background: white;
top: 50%;
transform: translate(0, -50%);
position: absolute;
align-items: center;
aspect-ratio: 16 / 9;
}
#media screen and (max-aspect-ratio: 16 / 9) {
.presentation-place {
width: 100vw;
}
}
#media screen and (min-aspect-ratio: 16 / 9) {
.presentation-place {
height: 100vh;
}
}
.slide {
font-size: 100%;
position: absolute;
top: 0;
bottom: 0;
margin: 0 auto;
width: 100%;
height: 100%;
overflow: hidden;
background: red;
background-position: center center;
}
.title1 {
margin-left: 1em;
font-size: 6em;
position: absolute;
margin-top: 2em;
}
<html>
<body>
<div class="container">
<div class="presentation-place">
<div class="slide s1">
<h1 class="title1">test</h1>
</div>
</div>
</div>
</body>
</html>
Make sure to avoid specific units like cm, px etc because those are fixed units no matter the scale of the site itself or the monitor, the use of Units like % since vh/vw didnt work. % scales relative to the size of the monitor or website, so this should help. Alternativly you could use aspect-ratio because it scales relative to the size of the parent element
Running the following code snippet will provide a framework for what I am visually hoping to accomplish, with some concessions made in the CSS that I'd like to remove:
body {
height: 100vh;
margin: 0;
}
.container>* {
height: 100%;
width: 100%;
flex: 0 0 50px;
}
.container {
width: 100%;
height: 100%;
background-color: black;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.header {
background-color: red;
}
.content {
background-color: blue;
flex: 1;
position: relative;
}
.footer {
margin-top: auto;
background-color: yellow;
}
.fixedRatio {
height: 56.25vw;
max-height: calc(100vh - 100px);
width: calc((100vh - 100px) * (1/0.5625));
;
max-width: 100vw;
background-color: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
<div class="container">
<div class="header"></div>
<div class="content">
<div class="fixedRatio"></div>
</div>
<div class="footer"></div>
</div>
Included are a header and footer of arbitrary height and a fixed aspect ratio box centered vertically and horizontally between them. I'd like it to letter- and pillar-box as the page is resized, and respond to increases/decreases in header height.
As it stands, the code accomplishes many of these goals but falls short in that it requires that the heights of the header and footer be included in the CSS for the fixed aspect ratio box. This limits my ability to freely manipulate the size of the header, or let it grow arbitrarily as a function of content (at least to the extent I am not using JavaScript).
I've managed to make this work successfully for the case of letter-boxing (top and bottom black bars) by leveraging the fact that the content is full-width. As a result, I can use 100vw / 56.25vw (in the case of 16:9) for the width/height and achieve the desired result. Unfortunately, when moving the content around to pillar-box, this obviously falls apart.
I've more or less resigned myself to needing JavaScript to - at the very least - toggle a class based on the dimensions of the inner content box to determine whether letter or pillar boxing is appropriate. However, it became very clear very quickly that setting width as a function of height is not trivial.
I was fortunate to come across this post, where a solution leveraging a 1x1 pixel is used to set width as a function of height.
I was able to successfully make this work for the pillar-boxing case in both Chrome and Safari, but not Firefox (IE11 and Edge not yet tested, but coverage is desired... pray for me). I'd like to get recent versions of Chrome/Safari/Firefox covered, as well as I11/Edge if possible.
The solution for Chrome/Safari is as follows:
body {
height: 100vh;
margin: 0;
}
.header,
.footer {
height: 100%;
width: 100%;
}
.container>* {
flex: 0 0 50px;
}
.container {
width: 100%;
height: 100%;
background-color: black;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.header {
background-color: red;
}
img {
display: block;
height: 100%;
background: orange;
}
.content {
background-color: blue;
flex: 1;
position: relative;
overflow: hidden;
height: 100%;
display: inline-block;
left: 50%;
transform: translateX(-50%);
}
.footer {
margin-top: auto;
background-color: yellow;
}
.fixedRatio {
background-color: purple;
position: absolute;
left: 0;
top: 0;
right: 0;
margin: auto;
bottom: 0;
}
<div class="container">
<div class="header"></div>
<div class="content">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" />
<div class="fixedRatio"></div>
</div>
<div class="footer"></div>
</div>
There are a few things to consider. I am comfortable with fixing the height of the footer. This constraint may prove valuable, but I've been unable to yield anything from it yet. I am also comfortable with radical alterations to the included markup, supposing it enables the desired behavior.
The end-purpose of this would be to maintain fixed aspect ratio content between this flexible header, static footer, and overlay content upon it.
I am well aware that I could run some JavaScript and set these heights manually with great success, but I am coming at this from a position largely based in intellectual curiosity. If you, too, are curious, perhaps you can lend a hand in exploring :)
Thank you!
I have pictures in a horizontal scroll and I want to be able to hover over each image, and when I do, I want the picture to be slightly "grayed out" with text over it.
I can't for the life of me figure out how to do it.
I made this fiddle to show what my scroll bar looks like.
https://jsfiddle.net/burgoyne/u1zdn80p/1/
#scroll {
height: 25%;
overflow-x: scroll;
white-space: nowrap;
width: 50%;
}
#scroll img {
height: 100%;
vertical-align: top; /* this prevents vertical whitespace */
}
Can someone point me in the right direction here? I have been trying different things with CSS to gray it out and add text, with no luck.
Thanks!
You have to specify what you want in a CSS img:hover rule, like this:
html, body {
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
#scroll {
height: 25%;
overflow-x: scroll;
white-space: nowrap;
width: 50%;
}
#scroll img {
height: 100%;
vertical-align: top; /* this prevents vertical whitespace */
}
#scroll img:hover {
opacity: .5;
}
<div id="scroll">
<a href="http://www.google.ca"><img src="http://www.fotoviva.co.uk/image/cache/data/prods/doug-blue-lake-500x500.jpg" /><!--
--><a href="http://www.google.ca"><img src="http://wannasmile.com/wp-content/uploads/2009/09/c76c_Gordon-McBryde-Field-Sunset-500x500.jpg" /><!--
--><a href="http://www.google.ca"><img src="http://creativefan.com/important/cf/2012/10/patio-garden-ideas/nice-patio-gardeen.jpg" /><!--
--><a href="http://www.google.ca"><img src="http://globotours.net/wp-content/uploads/2015/05/Desert-Safari-Dubai-500x500.jpg" />
</div>
About the gray color over the image, you can just add opacity to the image on hover ("opacity: 0.5") and, if you want, some transition between the event and the "grayness" with "transition: 0.5s" or so.
About the problem with the text overlay, I think you should visit this answer: Text on image mouseover?
You can place text inside with class named
<span class="text-content"><span>Some text here</span></span>
and then u can use css to place text on the image, something like ...
span.text-content
{
background: rgba(0,0,0,0.5);
color: white;
cursor: pointer;
display: table;
height: 150px;
left: 0;
position: absolute;
top: 0;
width: 150px;
}
span.text-content span
{
display: table-cell;
text-align: center;
vertical-align: middle;
}
I hope this helps.
I have 2x Divs and 1x Img with the following CSS
#StageDiv {
position: absolute;
left: 50%;
margin-left: -200px;
}
#LogoDiv {
position: absolute;
margin-top: 135px;
left: 50%;
margin-left: -500px;
}
#logoimg {
/* max-width: 75%; /* */
width: 1000px; /* */
}
inside of #logoimg, I would like to use max-width: 75%; and then have margin-left: of both #LogoDiv and #StageDiv be a function of #logoimg as it changes
http://jsfiddle.net/3KLUW/1/
Is this possible in pure CSS or will I have to do this in javascript in a on resize event? (not sure what the actual function call is currently but im sure my buddy google will know) I think in the long run, I will most likely have to use a javascript event to scale my kineticjs stage anyway but I am curious to know if there is some CSS wizardry to do the first part.
Thoughts?
Edit:
window.onresize=function(){
var img = document.getElementById('logoimg');
var width = img.offsetWidth;
var div = document.getElementById('LogoDiv');
div.style.marginLeft= "-" + width/2 + "px";
};
still would be interested in a CSS solution
If you can get away with a wrapper div for the whole logo:
<div id="logo">
<div id="StageDiv">...</div>
<div id="LogoDiv">
<img id="logoimg" src="..." />
</div>
</div>
Then you can set the width and max-width on it, and use margin: auto to center it on the page:
#logo {
width: 1000px;
max-width: 75%;
margin: auto;
position: relative;
}
And positioning the other elements become much easier:
#LogoDiv {
top: 135px;
position: absolute;
}
#StageDiv {
text-align: center;
}
#logoimg {
width: 100%;
}
The margin: auto and text-align: center together give us the automatic margin you wanted.
Updated fiddle: http://jsfiddle.net/3KLUW/2/
The canvas will need to be scaled though, as you said on the question.
Check this jsFiddle.
The orange bar is serving as a progress bar where the value under the circle is how high the progress bar should be.
Any idea why the overflow:hidden; is beeing disregarded and how do one solve this problem? Oblviously nothing should go outside the circle.
Also is there a better solution for this?
Modified your fiddle a little bit. Here is the link
Modifications:
Changed .outerContainer css to display:block from display:table and addedmargin-top:30px to p css
Check if this works for you.
position: absolute and overflow: hidden don't appear to be playing nicely with display: table/table-cell. Removing the table stuff you had in there to vertically center the text fixes the problem. In Firefox, at least.
I think it's the browser thing...
This is the CSS3 version...
.progressBar {
display: block;
width: 100%;
height: 0;
position: absolute;
bottom: 0;
left: 0;
background: #ec6730;
transition: height 1s;
}
.innerContainer:hover > .progressBar {
height: 300px;
}
http://jsfiddle.net/ZyhgT/2/
It no longer flashing 'cause browser handle the job (not js loop animation...). But still it shows the edge on animation finish!!! This could be the browser things... Could be a bug...
This is not related to jQuery or any javascript. In fact, if you delete all your javascript and manipulate the height of your .progressBar using css on li:hover, you will notice the bug anyway.
It appears to be a browser issue as reported on: https://code.google.com/p/chromium/issues/detail?id=157218
As a workaround try adding an imperceptible css transform to the mask element:
.outerContainer {
-webkit-transform: rotate(0.000001deg);
}
You just need to change your .outerContainer class and it works just fine!
.outerContainer {
position: relative;
display: block;
height: 96px;
width: 96px;
overflow: hidden;
background: #fff;
border: 2px solid #fff;
-webkit-border-radius: 50px;
border-radius: 50px;
}
Put the level class inside the outerContainer div and style the span inside the level class to be relatively positioned. In the JavaScript, to calculate the level, divide by 10 instead of 100 for the perfect circular hover effect.
Here is a fiddle.
HTML
<div class="outerContainer">
<div class="innerContainer">
<p>Circle 3</p>
<span class="progressBar"></span>
</div>
<div class="level"><span>75</span>
</div>
</div>
CSS
body {
background: blue;
}
#circles {
text-align: center;
margin: 100px 0;
}
li {
display: inline-block;
margin: 0 10px;
position: relative;
}
.outerContainer {
position: relative;
display: block;
height: 96px;
width: 96px;
overflow: hidden;
background: #fff;
border: 2px solid #fff;
-webkit-border-radius: 50px;
border-radius: 50px;
}
.innerContainer {
display: table-cell;
vertical-align: middle;
width: 100%;
margin: 0 auto;
text-align: center;
}
p {
color: #000;
width: 96px;
position: relative;
z-index: 2;
}
.progressBar {
display: block;
width: 100%;
height: 0;
position: absolute;
bottom: 0;
left: 0;
background: #ec6730;
}
.level span{
position:relative;
}
JS
$(function() {
$("#circles li").hover(function(){
var thisElement = $(this);
var level = $(this).find(".level").text();
var elementHeight = $(this).find(".outerContainer").height();
level = (level/10)*elementHeight;
$(thisElement).find(".progressBar").stop().animate({
height: level
}, 300);
}, function() {
var thisElement = $(this);
$(".progressBar").stop().animate({
height: 0
}, 300);
});
});
display: table doesn't work that good with CSS positioning;
you should avoid using that, and find some other way to vertically center your labels.
If your circles have a known height, like your code seems to indicate (height:96px ecc), then just use a fixed top position for an absolutely positioned <p> element:
http://jsfiddle.net/ZyhgT/5/
Note that you don't even need jQuery for this, it is all achievable with just CSS3 (unless you are targeting old browsers)