I am making a lightweight responsive jQuery slider for my site, and am using the very common markup:
HTML:
<div id="slider">
<ul>
<li><img class="active" src="slide1.jpg" alt=""></li>
<li><img src="slide2.jpg" alt=""></li>
<li><img src="slide3.jpg" alt=""></li>
</ul>
</div>
CSS:
#slider {
width:80%;
max-width:800px;
margin:0 auto;
}
#slider ul {
margin:0px;
padding:0px;
list-style:none;
width:100%;
}
#slider ul li {
width:100%;
position:relative;
}
#slider img {
width:100%;
position:absolute;
top:0px;
box-shadow:0px 20px 40px rgba(0,0,0,.66);
}
#slider img.active {
z-index:1;
}
The problem I am having is that my absolute positioned slides are doing what they are supposed to and removing them self from the structure of the page. (This is not what I want them to do, but it was the easy way to stack them).
I have been reading about CSS Pseudo-Elements today and all the cool stuff people are doing with them. And it made me think... Could they be used to "clearfix" these absolute-positioned elements? My thought was that there might be a way to do something like the following:
#slider img:before {
content:"";
display:block;
position:static;
}
It will obviously take more than those styles to make this happen (because it isn't rendering things how I want it to... I know by this point you may be thinking "Why not just specify the height of the container and be done with it?". Well, the slides are meant to be responsive in that when they shrink, so does the height of the container.
I really want to do as much of this as possible without resorting to jQuery to set the container's height relative to the image height... It's tempting, but I think there's ways around that...
I can't find anything online (yet) on how to do this (or if it is possible). Can some CSS gurus step up and help me out here? I would love to hear alternative ways to stack my slides, or (mainly) if it is possible to use the pseudo-elements to retain the container height around my absolutely-positioned images...
Update: jsFiddle here: http://jsfiddle.net/derekmx271/Hu6Yf/
Update: Getting close to a solution with this (just need to lock down the same dimensions as the slides) :) http://jsfiddle.net/derekmx271/T7A7M/
There are many different ways to achieve a slider/carousel system (in terms or Markup, JavaScript and CSS), if you are finding one way isn't quite working, it is normally a good idea to rethink approach. As far as I'm aware what you are asking with
:before
and:after
wont work, because as soon as an element is absolutely positioned it stops listening to any other element's influence (save—in some situations—it's positional parent).It's for the above reason that I've been hoping for a new display mode e.g.
display: stack
or something.. but alas, nothing yet :)The requirement
If I'm understanding correctly, what you want is for your "container" to assume the size of the largest image in your UL, but you want these items to be stacked on top of each other. As far as my CSS knowledge goes, one of these things has to change, as you can't do both — unless you want to experiment with the possibilities that flexbox might give?
The problem
The only way I know of (outside of flexbox) to stack elements is to use
position: absolute
and as soon as you use absolute positioning on an element, that element is no longer taken into account when calculating it's parent's dimensions. You can useposition: relative
but this usually requires manual/code intervention to specify exact positions.Available options
Keep you elements positioned using positive and negative relative positioning (or margins) — this makes your JavaScript development harder, but would mean the elements keep their space in the document.
Use
display: table
orfloat: left
(with enough container width) to bring all your elements into a horizontal line — this will keep your height but will mean you limit what your transitions can be (unless you use JavaScript to duplicate this row of elements into separate layers).Your JS could leave the original images hidden (using
visibility: hidden
as this means the element still takes up space) and then only work with cloned absolutely positioned images. By fiddling with your hidden image's css layout you could still preserve the maximum height generated by these 'ghosted' elements.At the end of the day, as most carousel systems require JavaScript to work, you might as well just define the container's dimensions in JS (as you mention) and have done with it. Keeping your elements absolutely positioned will make your coding job easier.
Look into flexbox and see if it has the ability to stack elements.
It may be possible to stack elements using CSS transforms, however my experience of this has meant visually you might get what you want, but transformed elements quite often leave 'ghosted' space taken up elsewhere in the document.
update
With regard to adding images via
content
using:before
and:after
you won't be able to control the dimensions. You could probably set the image via a background instead, which would allow you to scale them (usingbackground-size
), but I'm not sure how this would make your life easier when building a carousel as you would have to hardcode these image URLs into the CSS rather than using the markup...For a clearfix, try this CSS: