Smaller horizontal scrollbar than div width? + No figcaption? - css

I'm trying to do image "carousel" with horizontal scroll. Pure HTML + CSS without JS.
This is my HTML:
<div class="slideshow">
<figure class="slideshow__fig">
<img src="img/hilti-png.png" alt="" class="slideshow__fig-img">
<figcaption>Fig.1 - Trulli, Puglia, Italy.</figcaption>
</figure>
<figure class="slideshow__fig">
<img src="img/hilti-png.png" alt="" class="slideshow__fig-img">
<figcaption>Fig.1 - Trulli, Puglia, Italy.</figcaption>
</figure>
<figure class="slideshow__fig">
<img src="img/hilti-png.png" alt="p" class="slideshow__fig-img">
<figcaption>Fig.1 - Trulli, Puglia, Italy.</figcaption>
</figure>
</div>
This is my css:
.slideshow {
display: flex;
flex-wrap: nowrap;
overflow-y: hidden;
overflow-x: scroll;
//width: 80vw;
//margin: auto;
&::-webkit-scrollbar {
width: 350px;
height: 10px;
}
/* Track */
&::-webkit-scrollbar-track {
background: #f1f1f1;
}
/* Handle */
&::-webkit-scrollbar-thumb {
background: #888;
border-radius: 500px;
}
/* Handle on hover */
&::-webkit-scrollbar-thumb:hover {
background: #555;
}
&__fig {
flex: 0 0 auto;
height: 900px;
&-img{
height: 100%;
//width: 100%;
display: block;
}
}
}
1 - The problem is when I set the width of the .slideshow to 80vw, then naturally the scrollbar is shorter, but my images are cropped and not going full display width. When I try to adjust the width of the scrollbar with ::-webkit-scrollbar {width: 350px or 50vw or ...} exactly nothing happens.
I would like to have a scrollbar which is not full width of the div which I'm scrolling, but somehow can't figure it out.
2 - The other problem is I would like to have a figcaption at the bottom left side of the image. But somehow it doesn't show when the horizontal scroll is there. Any suggestions?
Here is the example how I would like to have it:
example image
edit: Now I finally managed to do it by adding:
&::-webkit-scrollbar-button:end:increment {
width: 50%;
display: block;
background: transparent;
}
But now the problem is that the scrollbar is not in middle, but on the left side. Margin:auto doesn't help. No idea how else to do it.
Also making img size 90% revealed the caption which is not that bad solution.
Now the only question is how to put the scroll bar in the centre.

Here is something close to the image you provided as an example. Sorry, but I really don't know how this can be achieved respecting the Pure HTML + CSS without JS criteria. I think it isn't possible at all.
So here, it uses jQuery and jQuery-ui draggable.
It uses a draggable div contained within its parent. Ondrag, it calculates the "scrolled" percentage to apply it to the scrollable width of the image slider.
For mobiles... I added the "touch punch" patch for jQuery-ui. More details about it here. I also placed the "initialisation code" in a function, so it can run on load AND on resize.
$(document).ready(function(){
function initDisplay(){
let slide_scrollWidth = $("#slide")[0].scrollWidth;
let customScrollbar_width = $("#sliderScroll_outer")[0].scrollWidth;
let percent = slide_scrollWidth/customScrollbar_width
$("#sliderScroll").css({"width":percent+"%", "left":0})
$("#slide")[0].scrollTo(0,0)
}
// On page load
initDisplay()
// Useful for mobile orientation change
window.onresize = initDisplay
$("#sliderScroll").draggable({
containment: "#sliderScroll_outer",
scroll: false,
drag: function(e){
let parentOffset = $(e.target).parent().offset().left
let offset = $(e.target).offset().left
let scrollableWidth = $(e.target).parent().width() - $(e.target).width()
let sliderPercent = (offset-parentOffset)/scrollableWidth
//console.log(sliderPercent)
let imageSliderWidth = $("#slide")[0].scrollWidth - $("#slide").width()
//console.log(imageSliderWidth)
$("#slide")[0].scrollTo(sliderPercent*imageSliderWidth,0)
}
});
});
#container{
margin: 1em;
}
#slide{
display: flex;
overflow: hidden;
}
#slide img{
margin: 0 0.5em;
}
#sliderScroll_outer{
width: 40vw;
background: lightgrey;
margin: 1em;
}
#sliderScroll{
width: 0vw;
height: 10px;
background: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.2/jquery.ui.touch-punch.min.js"></script>
<div id="container">
<div id="slide">
<img src="https://via.placeholder.com/800x600.png">
<img src="https://via.placeholder.com/400x600.png">
<img src="https://via.placeholder.com/1000x600.png">
</div>
<div id="sliderScroll_outer">
<div id="sliderScroll"></div>
</div>
</div>
Run in full page mode or CodePen

Related

Overflow-y: auto without changing the content padding when the scrollbar appears

I am trying to create a content container that doesn't change the content position when overflow causes a scrollbar to appear. I can do this easily when my containers are fixed widths but I am struggling to think of a way where I can use percentages to scale to the browser width. I am using an extra container with a negative right margin so the scroll bar appears in the padding of the parent container.
How can I make the content div stay the same width as the header div? I either need to be able to create a variable with the width of the header and use it for the width of content or have some sort of css that targets a container that has overflow-y enabled.
const chars = 'abcdefghijklmnopqrstuzwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
const contentContainer = document.getElementsByClassName('content')[0];
function addContent(num) {
for (let i = 0; i < num; i++) {
contentContainer.innerHTML += chars[Math.floor(chars.length * Math.random())] + ' ';
}
}
addContent(150);
document.getElementById('add').addEventListener('click', function() {
addContent(1500);
});
.container {
height: 100px;
border: 1px solid black;
padding: 20px;
}
.header {
background-color: #eee;
padding: 10px;
}
.scrollbar {
margin-right: -20px;
height: 100%;
overflow-y: auto;
}
.content {
padding-right: 20px;
}
<div class="container">
<div class="header"></div>
<div class="scrollbar">
<div class="content"></div>
</div>
</div>
<button id="add">Add scrollbar</button>

How do I remove the CSS:Float property when image occupies >50% of screen

I have a mostly responsive Wordpress website with some images aligned either left or right. I want to remove the float property of these aligned images when they occupy a percentage of the screen (about %50) as it's causing issues with how the text is displayed (one word next to an image, then followed by the rest of the paragraph).
When I remove the float property I get exactly the behaviour I want from the website, but I don't know how to set it so it only triggers under these conditions.
Below is the CSS for the affected images.
img {
display: inline-block;
max-width: 100%;
}
.align-right {
float: right;
}
You should use javascript to calculate the width of window and compare to width of image.
function myFunction() {
var img = document.getElementById("Image");
var div = document.getElementById("myDiv");
if (img.offsetWidth > window.innerWidth / 2) {
div.style.cssFloat = "none";
}
else {
div.style.cssFloat = "right";
}
}
img {
display: inline-block;
max-width: 100%;
width: 400px;
background-color: lightgrey;
height: 200px;
}
<body onresize="myFunction()" onload="myFunction()">
<div>
<img id="Image" src="" alt="Image" />
<div id="myDiv" style="background-color: lightgrey;">
Hello This is Div.
</div>
</div>
</body>
Show the result in full page for your better results.

Enlarge image when hovering over parent element

Like many others I wanted to show an enlarged image when hovering over a thumbnail. I used a hover selector to enlarge the image which worked fine.
Instead of having the image shrink when I moved off the image, I wanted the image to shrink when I moved off area that was occupied by the original thumbnail which was 100px X 100px.
I put a div around it, sized it and put the :hover on it rather then the image. I thought because the enlarged image was positioned absolute it wouldn't enlarge the div.
The image still enlarges but it does not shrink unless the cursor moves off the enlarged image.
div.hov:hover >.thumbnail {
position:fixed;
top:100px;
left:50px;
width:800px;
height:auto;
display:block;
z-index:999;
}
div.hov{
width:101px;
height:101px;
float:left;
overflow:visible;
margin: 10px;
}
<p>
<div class="hov"><img src="./gm1.png" class="thumbnail" height="100" width="100" /></div>
<div class="hov"><img src="./gm2.png" class="thumbnail" height="100" width="100" /></div>
</p>
Is there any way to achieve this? The hosted version is here.
one way to do this is to show a new modal div on top of the original image. that way your original div doesn't enlarge. however, you'll need to use some javascript or jQuery
heres a fiddle to demonstrate: http://jsfiddle.net/k3oq1899/1/
don't mind the code, I put it together very quickly for you, but you can clean it up a bit.
html
<div class='image'>
<img src='http://www.online-image-editor.com//styles/2014/images/example_image.png'/>
</div>
<div id='modal'></div>
css
.image {
display: inline-block;
width: 100px;
height: auto;
}
img {
width: 100%;
height: 100%;
display: inline-block;
}
#modal {
display: none;
position: absolute;
top: 0;
left: 0;
}
jquery
$(function() {
var currentMousePos = { x: -1, y: -1 };
$(document).mousemove(function (event) {
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
if($('#modal').css('display') != 'none') {
$('#modal').css({
top: currentMousePos.y,
left: currentMousePos.x + 12
});
}
});
$('.image').on('mouseover', function() {
var image = $(this).find('img');
var modal = $('#modal');
$(modal).html(image.clone());
$(modal).css({
top: currentMousePos.y,
left: currentMousePos.x + 12
});
$(modal).show();
});
$('.image').on('mouseleave', function() {
$(modal).hide();
});
});
Instead of enlarging the image, think of actually creating two images, one big and one small one. Once you hover over the small one, you can make the big image visible or invisible when moving out of it.
use absolute positions, display:block and display:none and check if the z-index is right.
But is this really necessary?
The hovering does not seem convenient to me....
You can put an invisible DIV with same dimensions over the thumbnail, put it on top with z-index and use it for the hover-event. But you need a few lines of javascript (with jQuery in my example).
HTML
<div class="box">
<div class="thumbnail">
<img src="http://vignette4.wikia.nocookie.net/mrmen/images/5/52/Small.gif/revision/latest?cb=20100731114437" alt="">
<div class="overlay"></div>
</div>
<div class="large-image">
<img src="http://vignette4.wikia.nocookie.net/mrmen/images/5/52/Small.gif/revision/latest?cb=20100731114437" alt="">
</div>
</div>
Javascript (jQuery)
$('.overlay').hover(
function () {
$(this).closest('.box').addClass('show-large-image');
},
function () {
$(this).closest('.box').removeClass('show-large-image');
});
CSS
.box {
padding: 200px;
}
.thumbnail {
position: relative;
display: inline-block;
border: 1px solid #888;
}
.overlay {
z-index: 1;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.large-image {
display: none;
position: absolute;
top: 0;
left: 0;
width: 500px;
}
.large-image img {
width: 100%;
}
.box.show-large-image .large-image {
display: block;
}
Example: http://jsfiddle.net/dx0d1ceh/

Pinterest image button getting in the way of my :hover css

I have some pseudo code like this:
<div class="container">
<div class="hiddenatfirst">
<img>
<img>
<img>
</div>
</div>
and css like so:
.hiddenatfirst{
display:none;
}
.container:hover .hiddenatfirst{
display:block;
}
.hiddenatfirst:hover{
display:block;
}
The problem is - I have a design website and a lot of visitors have the pinterst extension installed. When someone hovers over the pin-it button that gets added to the images inside the .hiddenatfirst div the div gets hidden again.
I don't want to remove the pin-it buttons from the images but I don't want them to get in the way of the :hover events.
Any ideas?
Apologies for the pseudo-code, the real code is pretty messy and in staging! Hopefully this explains what I need.
Thanks
PS - if you look at the .third-level-menu in the navigation here you'll see it in action (note you'll need the pinterest chrome extension installed)
http://smith-hoyt.myshopify.com/?preview_theme_id=12397927
PPS - this is a crappy GIF but I think shows what's happening too:
http://recordit.co/anNtu8W1Vo
PPPS - you can see the pin-it button that pinterest adds to each image in this image: https://twitter.com/tomcritchlow/status/573920066124836864/photo/1
Most probably the problem is that 'Pin it' button is absolutely positioned on top of the image, but it's not the container's child, so hover on it hides the image like on the following sample:
.container {
display: block;
width: 500px;
height: 315px;
background-color: gray;
}
.hiddenatfirst {
display: none;
}
#pinit {
position: absolute;
top: 32px;
left: 32px;
}
.container:hover .hiddenatfirst {
display: block;
}
.hiddenatfirst:hover {
display: block;
}
<div class="container">
<div class="hiddenatfirst">
<img src='https://dq1eylutsoz4u.cloudfront.net/2014/10/sf-cat.jpg' />
</div>
</div>
<img id='pinit' src='http://www.brandaiddesignco.com/insights/PinIt.png' />
What you can do is using JavaScript or jQuery find all the 'Pin it' buttons and move them to the appropriate containers with the positions recalculation, so the result HTML will be like the following:
.container {
display: block;
width: 500px;
height: 315px;
background-color: gray;
}
.hiddenatfirst {
display: none;
}
#pinit {
position: absolute;
top: 32px;
left: 32px;
}
.container:hover .hiddenatfirst {
display: block;
}
.hiddenatfirst:hover {
display: block;
}
<div class="container">
<div class="hiddenatfirst">
<img src='https://dq1eylutsoz4u.cloudfront.net/2014/10/sf-cat.jpg' />
<img id='pinit' src='http://www.brandaiddesignco.com/insights/PinIt.png' />
</div>
</div>
Rather than use the javascript solution above, since these images are small and in the navigation I found a way to remove the pin-it button, simply add to each image:
nopin="nopin"
As per the documentation here:
https://developers.pinterest.com/on_hover_pin_it_buttons/

CSS Fixed Position overlapping each other

Basically I'm making a navigation bar and due to Jquery doing a lot of resizing to make a website look 'pretty' I don't want to use a horizontal list and so each button is created like so:
<img src="homeicon.png"><span id="homex"><br /><img src="home.png" /></span>
(yes they're all image buttons for good reason)
but the only problem is they're fixed and set to "top 0" at the top of the page and as a result cannot sit next to each other but rather overlap, any idea on how I can I still keep the position to fixed and they top to 0 yet keep them next to each other?
HTML
<div id="top">
<img src="homeicon.png"><span id="homex"><br /><img src="home.png" /></span>
</div>
CSS
#top a.button { position: fixed; top: 0; padding: 12px; background: url('glacial_ice.jpg'); text-decoration: none; color: black; border-radius: 0px 0px 25px 25px; }
#top { position: relative; top:0; padding-left: 25px; }
Init function (runs on $(document).ready())
$('a.button').animate({
height: '+=5px',
}, 20, function() {
$('a.button').animate({
opacity: 0.6,
height: '-=5px',
}, 20);
});
Thanks
Put them all in a container, i.e. id="header", give the header position:fixed;top:0;etc...
Then, for each of the link/buttons give them:
position:relative;display:inline-block;float:left;
if you want them centered, then in the #header use text-align:center; and remove float:left from the links
So the container will be fixed, but the buttons inside will be relative and not overlap.
hope this helps!
very crude example
http://jsfiddle.net/6SCTZ/
<div id="header">
<div class="button">button1</div>
<div class="button">button2</div>
<div class="button">button3</div>
</div>
CSS:
#header { position:fixed;top:0;width:100%;height:30px;background:black; text-align:center }
.button {position:relative;display:inline-block;color:white;margin:0 5px 0 5px;}
Just put whatever elements need to be fixed within a container element (in this case, I'll use a div with an ID of "top_fixed").
Consider the following html:
<div id='top_fixed'>
<a href='http://google.com'>Google</a>
<a href='http://yahoo.com'>Yahoo</a>
</div>
<div id='tall'></div>
Now, the following CSS:
a { display: inline; }
#top_fixed { position: fixed; top: 0; left: 0; width: auto; }
#tall {height: 2000px; background: #000;}
​
DEMO: http://jsfiddle.net/mHKNc/1/

Resources