I am new to web design and this is merely a hobby. I am trying to set up a little webpage for myself here.
I would like to have images appear in the "same location".
I have a sort of menu bar, with a caption that appears on hover over the bar, that will then display the images.
I had some issues with the menu bar displaying in a different container. Would using JavaScript be a solution?
As a work around I made the images display with a hover just below the text. Which is suitable but not preferred.
The problem is I cannot seem to add more than one .image and .text variable in the CSS. They seem to just over ride. I tried duplicating the div containers and adding duplicate classes to match the ones i found online. ie.:
.text2
.image2
.hover_container2
I am weak in this software coding stuff and would appreciate some help.
<!DOCTYPE html>
<html>
<head>
<style>
.item1{
position:relative fixed;
}
img {
position:relative;
top:5%;
left:5%;
opacity: 0; /* Change this to .5 for 50% opacity */
-webkit-transition: .5s;
-moz-transition: .5s;
-ms-transition: .5s;
-o-transition: .5s;
transition: .5s;
}
img:hover {
opacity: 1;
}
body {
margin: 0;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #000;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover {
background-color: #111;
}
div.hover_container
{
width: 100px; /* set a fixed width */
height: 900px; /* set a fixed height */
margin:-45px;
}
div.hover_container .text
{
display:block; /* shown as a block-type element by default, visible */
width: 100px; /* same width as container */
height: 100%; /* same height as container */
}
div.hover_container .image
{
display: none; /* hidden by default */
width: 100px; /* same width as container */
height: 100%; /* same height as container */
}
div.hover_container .image img
{
max-width: 900px; /* width of the image */
max-height: 900px; /* height of the image */
padding-left: 20px;
margin:0;
}
div.hover_container:hover .text
{
display: none; /* hidden when hovering the container */
}
div.hover_container:hover .image
{
display: block; /* shown when hovering the container */
}
</style>
</head>
<body>
<ul>
<li>viking</li>
</ul>
<div class="hover_container">
<div class="text"></div>
<div class="text2"></div>
<div class="image">
<img src="valerie_purple3_tn.png" alt="" />
</div>
</div>
</div>
<div style="margin-left:10%;padding:1px 16px;height:1000px;">
</div>
</body>
</html>
Related
THE PROBLEM: I need to apply some mouse wheel smooth horizontal scrolling to this layout: https://jsfiddle.net/38qLnzkh/.
ALTERNATIVE: I've found this Script that does exactly what I want but it seems to work only vertically: Butter.js. If you can make it work Horizontally it would probably solve all my problems.
IMPORTANT:
1. The Script should be disabled based on screen width and in touch devices.
2. It should accommodate a menu on top of everything like you seen in the fiddle.
Thank you in advance.
EDIT:
In case it's not clear what I need, here are two examples with the effect I'm looking for:
https://nemesiscorporation.com/
https://www.tentwenty.me/about-us
MY LAYOUT:
HTML:
<main class="outer-wrapper">
<div class="wrapper">
<article class="section" id="a"><h2>01</h2></article>
<article class="section" id="b"><h2>02</h2></article>
<article class="section" id="c"><h2>03</h2></article>
<article class="section" id="d"><h2>04</h2></article>
<article class="section" id="e"><h2>05</h2></article>
<article class="section" id="f"><h2>06</h2></article>
</div>
</main>
CSS:
.outer-wrapper {
width: auto;
height: 100vw;
transform: rotate(-90deg) translateX(-100vh);
transform-origin: top left;
overflow-y: scroll;
overflow-x: hidden;
position: absolute;
scrollbar-width: none;
-ms-overflow-style: none;
}
::-webkit-scrollbar {
display: none;
}
.wrapper {
display: flex;
flex-direction: row;
width: auto;
transform: rotate(90deg) translateY(-100vh);
transform-origin: top left;
margin: 0;
padding: 0;
}
.section {
color: #000;
width: 100vw;
height: 100vh;
}
I've published an API on github that can easily solve this problem, below you'll find the code to do what you want.
Compared to yours I've just added the js code and the <script> in the HTML.
If you want to know more about it, here you can find the documentation.
EDIT
Since the requirements have changed a little bit and the API has been updated I've modified the example below so that it better fits the question.
Main changes to the answer:
Now the js is inside a init() method called onload
The css styles have been modified (transform:rotate brakes most of scrolling APIs)
The support for the navbar's smooth scroll has been added
The scrolling amount now depends on how much the user physically scrolls the mousewheel
/* UPDATED 2022 ANSWER */
function init() {
/*
* Variables preparation
*/
let yourWrapperElement = document.getElementsByClassName("outer-wrapper")[0];
let whateverEaseFunctionYouWant = remaningScrollDistance => { return remaningScrollDistance / 15 + 1 };
//Added support for navbar menu's smooth scrolling
uss.hrefSetup();
/*
* As you asked for, we only apply the custom scrolling for desktop devices
* by using the "wheel" event instead of the "scroll" or "touchmove" events.
*/
yourWrapperElement.addEventListener("wheel", event => {
/*
* We want to overwrite the default scrolling behaviour
* of your outer-wrapper component.
*/
event.preventDefault();
event.stopPropagation();
uss.scrollXBy(event.deltaY, yourWrapperElement, null, false);
}, {passive:false});
/*
* We apply a the custom ease function
* which will be used whenever our component is scrolled by the API
*/
uss.setXStepLengthCalculator(whateverEaseFunctionYouWant, yourWrapperElement);
}
body {
margin: 0;
padding: 0;
}
.outer-wrapper {
width: auto;
height: 100vh; /* Changed to vh */
width: 100vw; /* Added */
/*transform: rotate(-90deg) translateX(-100vh); ROTATING containers brakes 90% of scrolling APIs
transform-origin: top left;*/
overflow-y: scroll;
overflow-x: hidden;
position: absolute;
scrollbar-width: none;
-ms-overflow-style: none;
/*scroll-behavior: smooth; ISN'T NEEDED FOR MY API */
}
::-webkit-scrollbar {
display: none;
}
.wrapper {
display: flex;
flex-direction: row;
/*width: auto; NOT NEEDED IF WE USE FLEX-SHRINK 0
transform: rotate(90deg) translateY(-100vh); ROTATING containers brakes 90% of scrolling APIs
transform-origin: top left;*/
margin: 0; /* not really needed */
padding: 0; /* not really needed */
}
.section {
color: #000;
flex-shrink: 0; /* ADDED insted of the width/height of the wrapper */
width: 100vw;
height: 100vh;
}
#a { background-color: #ccc; }
#b { background-color: #fff; }
#c { background-color: #ccc; }
#d { background-color: #fff; }
#e { background-color: #ccc; }
#f { background-color: #fff; }
h2 {
text-align: center;
font-size: 200px;
margin: 0;
}
/* MENU _________________________ */
.logo {
float: left;
}
nav {
width: 100%;
}
/* HEADER */
header {
float: left;
width: 100%;
position: absolute;
z-index: 9999;
}
/* HEADER LARGE */
header.large {
height: 50px;
}
header.large .logo {
width: 225px;
height: 50px;
margin: 20px 0 0 20px;
background: url('../images/logo-fireqa-green-500px.png');
background-repeat: no-repeat;
background-size: contain;
transition: 0.7s all;
-moz-transition: 0.7s all;
-webkit-transition: 0.7s all;
-o-transition: 0.7s all;
}
/* UNORDERED LIST */
header.large ul {
list-style: none;
float: right;
margin-right: 25px;
}
header.small ul {
list-style: none;
float: right;
margin: 0;
}
header.large li {
display: inline;
float: left;
list-style-position: inside;
height: 50px;
-webkit-transition: all ease 0.3s;
-moz-transition: all ease 0.3s;
transition: all 0.3s ease-in-out;
}
header.large li a {
display: block;
padding: 20px;
color: #0E6245;
text-decoration: none;
font-family: 'Montserrat', 'arial', sans-serif;
font-weight: 600 !important;
letter-spacing: -1px;
font-size: 25px;
background-image: linear-gradient(#0E6245, #0E6245);
background-position: 50% 80%;
background-repeat: no-repeat;
background-size: 0% 4px;
-moz-transition: all 0.3s ease-in-out 0s;
-ms-transition: all 0.3s ease-in-out 0s;
-o-transition: all 0.3s ease-in-out 0s;
-webkit-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
header.large li a:hover, a:focus {
background-size: 60% 4px;
}
<script src = "https://cdn.jsdelivr.net/npm/universalsmoothscroll#latest/universalsmoothscroll-min.js"></script>
<body onload = init()>
<main class="outer-wrapper">
<div class="wrapper">
<article class="section" id="a"><h2>01</h2></article>
<article class="section" id="b"><h2>02</h2></article>
<article class="section" id="c"><h2>03</h2></article>
<article class="section" id="d"><h2>04</h2></article>
<article class="section" id="e"><h2>05</h2></article>
<article class="section" id="f"><h2>06</h2></article>
</div>
</main>
<!-- MENU _____________________ -->
<header class="large">
<div class="container">
<nav>
<a><div class="logo"></div></a>
<ul>
<li>01</li>
<li>02</li>
<li>03</li>
<li>04</li>
</ul>
</nav>
</div>
</header>
</body>
</html>
There is a nice package called smooth-scrollbar.
I've adjusted your example. It disables smooth scrolling for mobile devices, but otherwise it's just calling the package. And I've cleaned up some CSS.
/** #see https://stackoverflow.com/a/52855084/5312432 */
function isTouchDevice() {
return window.matchMedia("(pointer: coarse)").matches;
}
function initSmoothScrolling() {
const options = {
damping: 0.1,
alwaysShowTracks: true
};
const elements = document.querySelectorAll(".smooth-scrollbar");
for (const element of elements) {
Scrollbar.init(element, options);
}
}
if (!isTouchDevice()) {
initSmoothScrolling();
}
body {
margin: 0;
padding: 0;
}
.smooth-scrollbar {
overflow: auto;
}
.wrapper {
display: flex;
flex-direction: row;
}
.section {
width: 100vw;
height: 100vh;
flex-shrink: 0;
}
.section:nth-child(odd) {
background-color: #ccc;
}
.section:nth-child(even) {
background-color: #fff;
}
h2 {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
font-size: 200px;
margin: 0;
}
<main class="smooth-scrollbar">
<div class="wrapper">
<article class="section"><h2>01</h2></article>
<article class="section"><h2>02</h2></article>
<article class="section"><h2>03</h2></article>
<article class="section"><h2>04</h2></article>
<article class="section"><h2>05</h2></article>
<article class="section"><h2>06</h2></article>
</div>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/smooth-scrollbar/8.5.3/smooth-scrollbar.js"></script>
TL DR it should be display: flex; opacity: 1
I have a menu which works in the following way:
On mouseenter or click, the menu is shown (display: flex, opacity: 1)
On mouseleave or click (outside the menu area) the menu is hidden (display: none, opacity: 0)
The problem occures when I try to "open" the menu in the Dev. Tools on 320x480 resolution.
When I click on the menu area, only #envelope does the transformation. #links (should also transform but don't becouse of the following reasons) which should get display: flex actually gets display: none assigned to it.
Note: It's working in full screen. Something is bothering him with the 320x480 res.
If I can elaborate or provide any additional information, let me know.
Thank you
function hide (){
document.getElementById("links").style.display = "none";
};
function show (){
document.getElementById("links").style.display = "flex";
document.getElementById("links").style.opacity = "1";
};
var menu = document.getElementById("menu");
menu.addEventListener("mouseenter", show);
menu.addEventListener("mouseleave", hide);
menu.addEventListener("click", show);
document.addEventListener("click", function (){
if (this != menu){
document.getElementById("links").style.display="none";
}
});
#menu{
height: 10vh;
background-color: red;
text-align: center;
transition: all 1s ease-out;
padding-top: 5vh;
}
#menu:hover{
color: red;
}
#envelope{
height: 0;
display: block;
background-color: blue;
min-width: 100%;
z-index: 1;
position: absolute;
left: 0;
content: "";
opacity: 0;
transition: all 1.3s ease-out;
}
#links{
height: 0;
display: none;
background-color: pink;
justify-content: center;
z-index: 2;
min-width: 100%;
opacity: 0;
transition: all 1s ease-in;
}
#google{
margin-top: -1vh;
width: 150px;
}
#mysite{
padding-left: 5%;
margin-top: -1vh;
width: 150px;
}
#menu:hover #envelope{
height: 100px;
opacity: 1;
}
#menu:focus #envelope{
height: 100px;
opacity: 1;
}
#menu:hover #links{
opacity: 1;
height: 300px;
}
#menu:focus #links{
opacity: 1;
height: 300px;
}
<div id="menu">Click here to browse the internet.
<div id="envelope">
<div id="links" >
<div><img id="google" src="https://seomofo.com/wp-content/uploads/2010/05/google_logo_new.png" /></div>
<div style="width: 20%;"></div>
<div><img id="mysite" src="https://toppng.com/uploads/preview/wwf-logo-horizontal-world-wildlife-foundation-logo-shirt-11563219164hg5hfcveei.png"/></div>
</div>
</div>
</div>
Don't use transition: all because the browser then need to loop through all properties, and it might cause lag.
Don't use position: absolute unless you have to.
I removed #envelope and inserted the "Click here ..." text in a label (explanation why below).
I arranged classes so I didn't have to repeat code.
Pure CSS solution below.
I made a little CSS hack, where I used a label and a checkbox to simulate a click. So when clicking on the label#menu-toggler, the (hidden) checkbox is checked, which triggers #menu-toggler:checked ~ #links.invisible. I had to add another class to #links, otherwise the low specificity wouldn't trigger the change.
html, body { /* new */
margin: 0px;
padding: 0px;
}
#menu {
height: 15vh; /* changed */
background-color: red;
text-align: center;
margin: 0.5rem; /* new */
}
#menu > input#menu-toggler { /* new */
display: none;
}
#menu > .tagline { /* new */
display: block; /* to get padding to work */
padding: 5vh 0px;
transition: opacity 1s;
}
#menu:hover > .tagline { /* new */
opacity: 0;
}
#menu > .tagline, /* new */
#menu > #links /* new */
{
transition-timing-function: ease-out;
}
#menu > #links {
display: flex;
justify-content: space-around; /* changed */
position: relative; /* changed */
left: -0.5rem; /* changed */
top: -5vh; /* changed */
opacity: 0;
height: 0;
width: 100vw; /* changed */
z-index: 1;
overflow: hidden; /* new */
background-color: pink;
transition-property: height, opacity;
transition-duration: 1.3s;
}
#menu:hover #links,
#menu-toggler:checked ~ #links.invisible { /* new */
height: 150px !important; /* changed */
opacity: 1 !important;
}
#links #google,
#links #mysite
{
width: 150px;
}
<div id="menu">
<input id="menu-toggler" type="checkbox" />
<label for="menu-toggler" class="tagline">Click here to browse the internet.</label>
<div id="links" class="invisible">
<div><img id="google" src="https://seomofo.com/wp-content/uploads/2010/05/google_logo_new.png" /></div>
<div><img id="mysite" src="https://toppng.com/uploads/preview/wwf-logo-horizontal-world-wildlife-foundation-logo-shirt-11563219164hg5hfcveei.png"/></div>
</div>
</div>
I've been using a tutorial for making a hover box go over a set of images.
The article can be found here.
Got it working perfectly, except I want my images and the hover to be responsive to window size (just via width is fine), I've tried looking up how to do this. Seems like it might be a case of using % rather than a fixed value, but not experienced enough to know how to execute the markup. Even if I get the images to re-size the hover box doesn't re-size with them.
Is it possible to add something to the existing CSS to make this happen.
ul.img-list {
list-style-type: none;
margin: 0;
padding: 0;
text-align: center;
}
ul.img-list li {
display: inline-block;
height: 150px;
margin: 0 1em 1em 0;
position: relative;
width: 150px;
}
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;
opacity: 0;
-webkit-transition: opacity 500ms;
-moz-transition: opacity 500ms;
-o-transition: opacity 500ms;
transition: opacity 500ms;
}
span.text-content span {
display: table-cell;
text-align: center;
vertical-align: middle;
}
ul.img-list li:hover span.text-content {
opacity: 1;
}
<ul class="img-list">
<li>
<a href="#">
<img src="http://placehold.it/150x150">
<span class="text-content"><span>Text</span></span>
</a>
</li>
</ul>
you can use only width to keep image ratio.
you can use display:block for a and img, and use flex to center text.
not too sure about the responsive behavior you look for for, you can use a % width on li or a mix a % width + min-width and max-width.
example with % width set at 50% (and max/min width ) , it can be any other value and units.
ul.img-list {
list-style-type: none;
margin: 0;
padding: 0;
text-align: center;
}
ul.img-list li {
display: inline-block;
vertical-align:top;
margin: 0;
position: relative;
width:50%;
max-width:100vh;
min-width:60vh;
}
ul.img-list li a, ul.img-list li a img {
display:block;
width:100%;
}
span.text-content {
background: rgba(0,0,0,0.5);
color: white;
cursor: pointer;
display:flex;
left: 0;
right:0;
position: absolute;
top: 0;
bottom:0;
opacity: 0;
-webkit-transition: opacity 500ms;
-moz-transition: opacity 500ms;
-o-transition: opacity 500ms;
transition: opacity 500ms;
}
span.text-content span {
margin:auto;
}
ul.img-list li:hover span.text-content {
opacity: 1;
}
* {
margin:0;
padding:0;
}
<ul class="img-list">
<li>
<a href="#">
<img src="http://placehold.it/150x150">
<span class="text-content"><span>Text</span></span>
</a>
</li>
</ul>
You could also do it like this, using pseudo elements to display the overlay content on the image. This method is fully responsive.
.wrapper {
width: 100%;
overflow: auto;
padding: 1%;
box-sizing: border-box;
background: rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
/* Columns floated left */
.col-4 {
width: 33.3%;
float: left;
padding: 1%;
box-sizing: border-box;
height: auto;
overflow: hidden;
}
/* Container to make absolute positioning easier on psuedo element */
.image_container {
position: relative;
overflow: auto;
padding: 0;
margin: 0;
}
.image_container img {
width: 100%;
display: block;
}
/* Structure for ::before element */
#img_1::before,
#img_2::before,
#img_3::before {
background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0;
right: 0;
height: 100%;
width: 100%;
box-sizing: border-box;
display: block;
opacity: 0;
color: white;
padding: 10px;
transition: 0.5s ease;
}
/* Hover state for container to show ::before on mouseover */
.image_container:hover#img_1::before,
.image_container:hover#img_2::before,
.image_container:hover#img_3::before {
opacity: 1;
cursor: pointer;
}
/* Text for ::before elements */
#img_1::before {
content: 'Image Title 1';
}
#img_2::before {
content: 'Image Title 2';
}
#img_3::before {
content: 'Image Title 3';
}
<div class="wrapper">
<div class="col-4">
<div class="image_container" id="img_1">
<img src="https://images.unsplash.com/reserve/B6PfiQ8QoSzmsZYOCkSB__DSC0530-1.jpg?dpr=1&auto=format&fit=crop&w=1500&h=1004&q=80&cs=tinysrgb&crop=">
</div>
</div>
<div class="col-4">
<div class="image_container" id="img_2">
<img src="https://images.unsplash.com/photo-1418985991508-e47386d96a71?dpr=1&auto=format&fit=crop&w=1500&h=1000&q=80&cs=tinysrgb&crop=">
</div>
</div>
<div class="col-4">
<div class="image_container" id="img_3">
<img src="https://images.unsplash.com/photo-1476362555312-ab9e108a0b7e?dpr=1&auto=format&fit=crop&w=1500&h=1000&q=80&cs=tinysrgb&crop=">
</div>
</div>
</div>
You could also set the images as a background-image for the div which would give you more control over the text in the overlay, if you needed it.
Kindly check this fiddle and tell me how I can keep the second <div> at the same position even when the height of first <div> is increased. If the first <div> overlaps the second it's fine. I just don't want the second div to move at all.
https://jsfiddle.net/7v9dud8u/
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<!-- page content -->
<div id="main-div" style="background-color: #ae2477; width:300px; height: 100px;" onclick="expandHeight();">
Main
</div>
<br/>
<div id="sub-div" style="background-color: #FF0000; width:300px; height: 100px;" onclick="reduceHeight();">
Sub
</div>
<script>
function expandHeight(){
$("#main-div").animate({height:"200px"},400);
}
function reduceHeight(){
$("#main-div").animate({height:"100px"},400);
}
</script>
Thanks.
Using CSS, you can use position: absolute;
<style>
#main-div {
position: absolute;
}
</style>
Doing this will allow the two divs to move freely around the browser window without affecting one another.
If all you want is to keep the second div from moving, then some simple css will do. Just add this to the second div's style attribute:
position:absolute; top:130px;
Try similar answer:
http://fiddle.jshell.net/MvzFC/24/
CSS:
.userWrap {
position: relative;
display: inline-block;
width: 300px;
height: 50px;
overflow: visible;
z-index: 1;
}
.userWrap:hover {
z-index: 2;
}
.user {
position: absolute;
display: inline-block;
width: 300px;
height: 50px;
margin-bottom: 5px;
background: #fff;
transition: width 0.3s, height 0.3s;
}
.user:hover {
width: 350px;
height: 200px;
background: #eee;
transition: width 0.3s ease 0.5s, height 0.3s ease 0.5s;
}
.user img {
float: left;
}
.user .name, .skills {
margin-left: 5px;
}
.user .name {
font-size: 21px;
font-weight: bold;
}
I'm wondering if anyone can help me / If this is even possible.
I'm trying to half style (using halfstyle.js) the youtube font-awesome icon so that the icon is like the youtube logo (bottom half red, top half white)
I'd like to do this on hover, but I can't even seem to get this going for just as default.
JSFiddle
body {
background: rgba(0,0,0,.4);
}
.fa {
font-size: 10em;
color: white;
}
.fa-youtube {}
.halfStyle {
position:relative;
display:inline-block;
font-size:80px; /* or any font size will work */
color: transparent; /* hide the base character */
overflow:hidden;
white-space: pre; /* to preserve the spaces from collapsing */
}
.halfStyle:before { /* creates the top part */
display:block;
z-index:2;
position:absolute;
top:0;
height: 50%;
content: attr(data-content); /* dynamic content for the pseudo element */
overflow:hidden;
pointer-events: none; /* so the base char is selectable by mouse */
color: #f00; /* for demo purposes */
text-shadow: 2px -2px 0px #af0; /* for demo purposes */
}
.halfStyle:after { /* creates the bottom part */
display:block;
position:absolute;
z-index:1;
top:0;
height: 100%;
content: attr(data-content); /* dynamic content for the pseudo element */
overflow:hidden;
pointer-events: none; /* so the base char is selectable by mouse */
color: #000; /* for demo purposes */
text-shadow: 2px 2px 0px #0af; /* for demo purposes */
}
<i class="fa fa-youtube textToHalfStyle"></i>
You cannot do that for FontAwesome i.fa icons because, already HalfStyle is based on the ::after and ::before pseudo elements. Also, FontAwesome uses :after for this. You need to create another element and give :hover option for achieving this.
Snippet
$(function () {
$(".textToHalfStyle").each(function () {
$(this).parent().append('<div class="cloned"></div>');
$(".cloned").append($(this).clone());
});
});
body {
background: rgba(0,0,0,.4);
font-size: 160px;
}
.fa {
color: #fff;
}
.cloned {
opacity: 0;
position: absolute;
display: block;
z-index: 1;
left: 8px;
top: 76px;
height: 0.65em;
overflow: hidden;
}
.cloned .fa {
position: relative;
top: -68px;
color: #f00;
}
.fa:hover ~ .cloned,
.cloned:hover {
opacity: 1;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" />
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<i class="fa fa-youtube textToHalfStyle"></i>