I am currently working on an application where I have a notification panel with different cattegories. The categories are divided by images and dashed lines, but how can I set the height of that dashed line to auto so it changes its height automatically when an new notification is added.
Here is a FIDDLE which represents the problem.
Normally I have this as my html:
<div class="departure-wrapper">
<div class="ui-grid-a">
<div class="ui-block-a">
<span class="departure-img">
<img class="image" src="img/icons/car.png">
</span>
</div>
<div class="ui-block-b">
<h4>Vertrek</h4>
<div class="departure-notification-append"></div>
</div>
</div>
</div>
Where I append with js the new added notifications to the departure-notification-append class
if (category === 'vertrek'){
departureHtml = `
${departureHtml}
<div class='notification-item' style='${style}'>
<div class='ui-grid-a notification-grid'>
<div class='ui-block-a'>
<img class='notification-image' id='${id}' src='${imgPath}'>
</div>
<div class='ui-block-b'>
<span class='notification-text'>${shortmessage}</span>
</div>
</div>
</div>`;
$('.departure-notification-append').empty().prepend(departureHtml);
}
So my question is how can I set the dashed lines to height auto, when I do now the height of the dashed line is 1px or something. I'll hope someone can help me out on this.
use :afrer on parent div like below
.departure-wrapper:after {
content: '';
display: block;
position: absolute;
top: 88px;
left: 60px;
width: 0;
height: 100%;
border: 1px dashed white;
}
try this http://jsfiddle.net/7uygyvwo/
Related
I'm looking for an answer to my problem. I have one large image on the top and eight small images on the bottom of my page. I want to make it so when you hover the small image (it's also a link which goes to different place) the large image changes to this small image. So clearly explained, two images change/swap places. And when I unhover the large image changes back.
Here's the picture so you know what I'm talking about!
And I'm looking for CSS, React (if there is any useful components) or just JavaScript-solution (if else statement or something like that).
https://i.ibb.co/C5m5sH3/demonstration.png
Thank you for your time!
You can use jQuery for your case, capture the hover event and update main image source.
$(document).ready(function(){
$('.thumbnail').hover(function(e){
src = $(e.target).data('main');
$("#target_img").attr('src', src);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main_image" style="width: 200px; height: 100px">
<img id="target_img" src="#"/>
</div>
<ul>
<li>
<img class="thumbnail" src="https://th.bing.com/th/id/OIP.wx64GmJDu2nd32eO_tieDgHaEK?pid=Api&rs=1" data-main="https://th.bing.com/th/id/OIP.wx64GmJDu2nd32eO_tieDgHaEK?pid=Api&rs=1" width="50px" height="50px"/>
</li>
<li>
<img class="thumbnail" src="https://1.bp.blogspot.com/_138avbqsoJQ/S31zZz9qPZI/AAAAAAAABNQ/ARDHrOa5_pg/s400/Loch_Lomond.JPG" data-main="https://1.bp.blogspot.com/_138avbqsoJQ/S31zZz9qPZI/AAAAAAAABNQ/ARDHrOa5_pg/s400/Loch_Lomond.JPG" width="50px" height="50px"/>
</li>
</ul>
Use mouseover and mouseout event listeners to change the background image of your big div.
The below snippet explains it all -
function change(e){
document.getElementById("main").style.backgroundImage = `url(${e.target.src})`;
}
let imgs = document.getElementsByTagName("img");
for(let i = 0; i<imgs.length; i++){
imgs[i].addEventListener("mouseover", function(){
change(event);
});
imgs[i].addEventListener("mouseout", function(){
document.getElementById("main").style.backgroundImage = `url("https://cdn.pixabay.com/photo/2020/11/28/11/03/advent-5784271__340.jpg")`;
});
}
#main{
height: 150px;
width: 150px;
border: 3px dashed red;
background-image: url("https://cdn.pixabay.com/photo/2020/11/28/11/03/advent-5784271__340.jpg");
}
img{
height: 50px;
width: 50px;
}
<div id="main"></div>
<img src="https://cdn.pixabay.com/photo/2020/03/24/11/21/winter-4963715__340.jpg">
<img src="https://cdn.pixabay.com/photo/2019/12/10/19/15/new-years-eve-4686590__340.jpg">
<img src="https://cdn.pixabay.com/photo/2020/11/17/15/44/cup-5752775__340.jpg">
<img src="https://cdn.pixabay.com/photo/2019/05/18/13/34/branches-4211837__340.jpg">
Currently I don't know what is the structure of your html, but you can tweak this solution to fit your case.
I have created an example of the swap effect that you specified, and created a code pen of it using colors instead:
https://codepen.io/DaudWaqas/pen/xxEgxLm
<section class="main" id="main" style="background-color: #000"></section>
<div>
<Section style="background-color: orange" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: cyan" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: maroon" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: #444" onmouseover="grabAndSwap(event)"></section>
</div>
<div>
<Section style="background-color: #ff0000" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: #00ff00" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: #0000ff" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: magenta" onmouseover="grabAndSwap(event)"></section>
</div>
CSS:
.main {
height: 30vh;
width: 100%;
}
section {
height: 15vh;
width: 25%;
float: left;
}
div {
height: 15vh;
width: 100%;
}
JS:
const main = document.getElementById('main');
function grabAndSwap(event) {
var toSwapWith = event.target;
var mainColor = main.style.backgroundColor;
console.log(mainColor);
var otherColor = toSwapWith.style.backgroundColor;
console.log(otherColor);
main.style.backgroundColor = otherColor;
toSwapWith.style.backgroundColor = mainColor;
}
You can capture mouseover in Javascript and simply swap the background-image and swap back on mouseout.
const picEls= document.getElementsByClassName('small');
const largeEl = document.getElementsByClassName('large')[0];
for (let i=0; i<picEls.length; i++) {
picEls[i].addEventListener('mouseover', hovered);
picEls[i].addEventListener('mouseout', hovered);
}
function hovered(event) {
const bg = event.target.style.backgroundImage;
this.style.backgroundImage = largeEl.style.backgroundImage;
largeEl.style.backgroundImage = bg;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.pic {
border-style: solid;
border-radius: 50%;
background-size: cover;
}
.large {
width: 40vw;
height: 30vw;
margin: 0 auto 0 auto;
}
.small {
display: inline-block;
width: 20vw;
height: 15vw;
margin: 2vw;
}
<div class="container">
<div class="large pic" style="background-image: linear-gradient(red,yellow);"></div>
<div class="small pic" style="background-image: linear-gradient(red,green);"></div>
<div class="small pic" style="background-image: linear-gradient(green,blue);"></div>
<div class="small pic" style="background-image: linear-gradient(blue,red);"></div>
<div class="small pic" style="background-image: linear-gradient(cyan,yellow);"></div>
<div class="small pic" style="background-image: linear-gradient(yellow,magenta);"></div>
<div class="small pic" style="background-image: linear-gradient(magenta,cyan);"></div>
<div class="small pic" style="background-image: linear-gradient(cyan,red);"></div>
<div class="small pic" style="background-image: linear-gradient(yellow, green);"></div>
</div>
I want to create a web site that contains a network graph. I used vis.js for this. If you hover over an image of a person the image should flip and show some information on the background. I created a JavaScript file that creates a tree out of a json file dynamically. Here is a picture of the result:
As you can see the images are visible outside the box which should not be the case. They should not be displayed outside of the borders.
Here is my html-code:
<div id="fullpage">
<div class="section " id="section0">
...
</div>
<div class="section" id="section1">
...
</div>
<div class="section" id="section2">
<div class="intro">
...
</div>
<div id="media">
...
</div>
</div>
<div class="section active" id="section3">
<div class="slide" id="slide1">
<div id="network_container_1">
<div id="network"></div>
</div>
</div>
<div class="slide active" id="slide2">
<div id="network_container_2">
</div>
</div>
</div>
Here is the CSS:
#network{
width: 100%;
height: 100%;
left: 0;
top: 0;
}
#network_container_bewohner{
width: 100%;
height: 100%;
left: 0;
top: 0;
border:1px black solid;
}
#network_container_freunde{
width: 100%;
height: 100%;
left: 0;
top: 0;
}
.overlay {
position: absolute;
padding: 4px;
z-index: 0;
}
#slide1{
z-index:0;
}
#slide2{
z-index:1;
}
The images are located as #block1, #block2, #block3, etc. as class overlay inside of #network_container_1.
As you can see I tried to mess around with the z-index but it doesn't work.
Okay I found the solution. The problem was the absolute position.
See here: Position absolute and overflow hidden
I essentially have a horizontal div that populates content from omdb API. It dynamically generates a bunch of search results, and displays them all; however the overflow: hidden is active.
I have 2 questions:
I have two custom "buttons" that I made with an empty div and icon. I gave it a bit of a box-shadow to give it the illusion that it's hovering. Is it better practice to use a button element instead, or does it matter?
My main question is this: I want to be able to navigate back and forth between my search results using my arrow buttons. What would be the best way to implement this? The only thing I can think of is using the buttons to adjust the left or right margins of my search results. (ie. pressing the left button would adjust the margin-left of my results with a negative margin, and the right arrow would adjust it with a positive margin)
However, this feels crude and not very accurate. Meaning with a few extra clicks, the content could be pushed out of the view entirely (either by accident or on purpose).
Is there a way to set this up more efficiently?
Here is some code as an example:
const leftArrow = document.querySelector("#left-arrow");
const rightArrow = document.querySelector("#right-arrow");
const marginSelector = document.querySelector("#nav-margin");
var marginValue = -20;
leftArrow.addEventListener('click', () => {
marginSelector.style.marginLeft = marginValue + "px";
marginValue += -20;
});
.scrollbar-container {
width: 800px;
display: flex;
border: 1px #5e9af9 solid;
position: relative;
top: 100px;
overflow: hidden;
margin: auto;
align-items: center;
}
.result-container {
display: inline-block;
margin: 2px;
}
img {
display: inline-block;
vertical-align: middle;
position: relative;
}
.nav-button {
position: absolute;
width: 50px;
height: 50px;
background: rgba(230, 232, 237, .5);
text-align: center;
margin: auto 0;
}
.left-arrow {
left: 1%;
}
.right-arrow {
right: 1%;
}
.margin-start {}
<script src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<div class="scrollbar-container">
<div id="nav-margin" class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div id="left-arrow" class="nav-button left-arrow">
<i class="fas fa-angle-left fa-3x"></i>
</div>
<div id="left-arrow" class="nav-button right-arrow">
<i class="fas fa-angle-right fa-3x"></i>
</div>
</div>
I've written script to move back and forth the search results. You just need to check and adjust the marginLeft value for your marginSelector. I've added transition into the CSS of #nav-margin so that it looks smooth. marginValue is been initialized with 0. max-width of container has been set to 500px for convenience. When you change your max-width do not forget to change it in addEventListener for rightArrow. You can also make the value inside if condition to dynamic so that it actually takes the value from .scrollbar-container.
Let me know if you have any queries.
const leftArrow = document.querySelector("#left-arrow");
const rightArrow = document.querySelector("#right-arrow");
const marginSelector = document.querySelector("#nav-margin");
var marginRightValue = 0;
rightArrow.addEventListener('click', () => {
if(-(marginRightValue) <= (500+20))
marginRightValue += -100;
marginSelector.style.marginLeft = marginRightValue + "px";
});
leftArrow.addEventListener('click', () => {
if(marginRightValue < 0)
marginRightValue += 100;
marginSelector.style.marginLeft = marginRightValue + "px";
});
.scrollbar-container {
max-width: 500px;
display: flex;
border: 1px #5e9af9 solid;
position: relative;
top: 100px;
overflow: hidden;
margin: auto;
align-items: center;
}
#nav-margin{
transition: all 1s;
}
.result-container {
display: inline-block;
margin: 2px;
}
img {
display: inline-block;
vertical-align: middle;
position: relative;
}
.nav-button {
position: absolute;
width: 50px;
height: 50px;
background: rgba(230, 232, 237, .5);
text-align: center;
margin: auto 0;
cursor: pointer;
}
.left-arrow {
left: 1%;
}
.right-arrow {
right: 1%;
}
.margin-start {}
<script src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<div class="scrollbar-container">
<div id="nav-margin" class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div id="left-arrow" class="nav-button left-arrow">
<i class="fas fa-angle-left fa-3x"></i>
</div>
<div id="right-arrow" class="nav-button right-arrow">
<i class="fas fa-angle-right fa-3x"></i>
</div>
</div>
I'm not entirely sure if this would be the best response, but:
Point 1 - I don't think it matters here. A <button> is meant for a form, from a semantics point of view. For more context, read: https://css-tricks.com/use-button-element/
Point 2 - I can already scroll/swipe from left to right (in your code demo when I run the snippet), using my mouse/trackpad. So having extra buttons to do that job seems unnecessary. I would think rather to make a Javascript carousel (or slider) like effect when clicking the right button takes me to the next "slide", or the next chunk of your results. You could then disable buttons when there is no more content on the right (or left), or have them cycle back to the beginning. Effectively you want to think of a fixed width "slide" window (responsive for different viewports) and "slide" accordingly. Does that make sense for your problem?
I've stuck at the problem with this
.autoHeightParent {
width: 500px; /* just for example */
position: relative;
}
.absolutePosChild {
/* absolute is required to make pretty drag and drop transitions with interpolating left property */
position: absolute;
display:flex;
flex-direction: column;
border: 1px solid green;
}
.absolutePosChild div {
width: 100%;
}
<div class="autoHeightParent" style="height:170px;">
<div class="absolutePosChild" style="left: 0px; width: 100px;">
<div>
Child content
</div>
</div>
<div class="absolutePosChild" style="left: 100px; width: 150px;">
<div>
Child content with nesting
</div>
<!-- !! NESTING -->
<div class="autoHeightParent">
<div class="absolutePosChild" style="left: 0px; width: 50px;">
<div>
We don't know this height too
</div>
</div>
<div class="absolutePosChild" style="left: 50px; width: 100px;">
<div>
G.Child 2
</div>
</div>
</div>
</div>
</div>
<div style="border: 1px solid red">
I need to automatcally calculate height of the box above to make THIS box right after it. For now you can see hardcoded 170px height.
</div>
How do you guys solve problems like this?
I have tried to solve it with JavaScript but my solution looks wrong.
function setRootHeight() {
var root = document.getElementById("root");
var allChilds = root.getElementsByTagName("*");
var rootRect = root.getBoundingClientRect();
var maxChildHeight = 0;
_.each(allChilds, function(item) {
var nodeRect = item.getBoundingClientRect();
var nodeHeightRelativeToRoot = ( nodeRect.top + nodeRect.height ) - rootRect.top;
if ( nodeHeightRelativeToRoot > maxChildHeight) maxChildHeight = nodeHeightRelativeToRoot;
});
root.style.height = maxChildHeight + "px";
}
setInterval(setRootHeight, 300);
.autoHeightParent {
width: 500px; /* just for example */
position: relative;
}
.absolutePosChild {
/* absolute is required to make pretty drag and drop transitions with interpolating left property */
position: absolute;
display:flex;
flex-direction: column;
border: 1px solid green;
}
.absolutePosChild div {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.2.1/lodash.min.js"></script>
Test content Above
<div id="root" class="autoHeightParent">
<div class="absolutePosChild" style="left: 0px; width: 100px;">
<div>
Child content
</div>
</div>
<div class="absolutePosChild" style="left: 100px; width: 150px;">
<div>
Child content with nesting
</div>
<!-- !! NESTING -->
<div class="autoHeightParent">
<div class="absolutePosChild" style="left: 0px; width: 50px;">
<div>
We don't know this height too
</div>
</div>
<div class="absolutePosChild" style="left: 50px; width: 100px;">
<div>
G.Child 2
</div>
</div>
</div>
</div>
</div>
<div style="border: 1px solid red">
Visualization of that height was calculated
</div>
It uses setInteval to check if any of nested children changed it's height and then recalculate height of the parent box. Actually i need to find better solution because of performance and code beauty.
Snippets very simplified compared to real recalculations.
I am free to use flexbox or any tool that can solve this
I've solved this issue with relative positioning.
For my complex "absolute position" animations i made function that translates absolute to relative.
.autoHeightParent {
width: 500px; /* just for example */
position: relative;
display: flex;
}
.absolutePosChild {
/* relative position here must do absolutes' job here */
position: relative;
display:flex;
flex-direction: column;
border: 1px solid green;
}
.absolutePosChild div {
width: 100%;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="autoHeightParent">
<div class="absolutePosChild">
<div>
Child content
</div>
</div>
<div class="absolutePosChild">
<div>
Child content with nesting
</div>
<!-- !! NESTING -->
<div class="autoHeightParent">
<div class="absolutePosChild">
<div>
We don't know this height too
</div>
</div>
<div class="absolutePosChild">
<div>
G.Child 2
</div>
</div>
</div>
</div>
</div>
</body>
</html>
You see that parent box automatically resizes fine.
But now i can use translate3d to any child and parent box keeps it's size and position.
Note: I am unable to edit the HTML, so I have to find a workaround.
HTML:
<div id="container">
<div id="breadcrumbAds">...</div>
<div id="breadcrumbWrapper">...</div>
<div id="containerTopParsys">...</div>
<div id="leftColWrapper" class="column663Wrapper">...</div>
<div id="rightColWrapper" class="rightColumn663Wrapper">...</div>
<div style="clear:both;"></div>
<div id="containerBottomParsys">...</div>
<div style="clear:both;"></div>
<div id="bgpromo">...</div>
<div style="clear:both;">...</div>
<div style="clear:both;"></div>
</div>
The issue is that all of the divs inside #container, EXCEPT for #leftColWrapper and #rightColWrapper, need to be 100% width of #container, but #leftColWrapper and #rightColWrapper need to be stacked next to each other and centered (together) within the 100% #container, with a max-width of 1224px.
I tried utilizing the following jQuery to add a wrapper div around #left... and #right..., but it ended up grabbing the ads in those containers and placing them in the component where the JS for the page is stored.
(function($) {
$("#leftColWrapper, #rightColWrapper").wrapAll("<div class=\"colWrapper\" />");
})(jQuery);
I either need another solution to wrap those two divs together, so that I can set a max-width of 1224px and center them, or I need to know why this jQuery is picking up those ads and duplicating them within the JS component.
#container{
text-align: center;
font-size: 0;
}
#container > div{
outline: 1px solid #333;
display: inline-block;
min-height: 10px;
text-align: left;
width: 100%;
font-size: 14px;
}
#container #leftColWrapper, #container #rightColWrapper{
width: 50%;
max-width: 612px;
}
<div id="container">
<div id="breadcrumbAds">...</div>
<div id="breadcrumbWrapper">...</div>
<div id="containerTopParsys">...</div>
<div id="leftColWrapper" class="column663Wrapper">width: 50%;<br>
max-width: 612px;</div><div id="rightColWrapper" class="rightColumn663Wrapper">width: 50%;<br>
max-width: 612px;</div>
<div style="clear:both;"></div>
<div id="containerBottomParsys">...</div>
<div style="clear:both;"></div>
<div id="bgpromo">...</div>
<div style="clear:both;">...</div>
<div style="clear:both;"></div>
</div>