Is it possible to use pseudo-elements to make containing elements wrap around an absolutely-positioned element (like a clearfix)?
Asked Answered
P

2

1

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/

Premed answered 20/2, 2013 at 10:16 Comment(5)
Can you provide a jsfiddle? Makes it easier to achieve what you are looking for..Dallman
Been building one for the last few minutes actually lol. Will post ASAPPremed
Cool ;-) Will then update my (probably) random answer or create a new one..Dallman
okay, well jsFiddle doesn't want to run on a POS HP Mini (all I have with me)... So you can see the situation at cs7tutorials.com until I get the jsFiddle on here :)Premed
jsfiddle.net/derekmx271/Hu6YfPremed
A
2

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 use position: relative but this usually requires manual/code intervention to specify exact positions.

Available options

  1. 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.

  2. Use display: table or float: 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).

  3. 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.

  4. 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.

  5. Look into flexbox and see if it has the ability to stack elements.

  6. 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 (using background-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...

Ashly answered 20/2, 2013 at 11:58 Comment(2)
Awesome info. As far as actually creating the slider, I ended up using the visibility:hidden method... I guess I was more interested in the idea that these new things (to me), pseudo-elements, could re-vamp the usage of absolutely positioned elements. I got close, but no cigar. You cannot re-size pseudo-element images...Premed
Thanks for taking the time to layout the info above for everyone though @pebbl:) Good stuff...Premed
D
0

For a clearfix, try this CSS:

#slider img:after {
    clear: both;
}
#slider img:before, #slider img:after {
    content: " ";
    display: block;
    height: 0;
    overflow: hidden;
    visibility: hidden;
    width: 0;
}
Dallman answered 20/2, 2013 at 10:19 Comment(3)
Great clearfix for floated elements... Doesn't work for my situation however... Thanks for the input though :)Premed
Sounds a bit overcomplicated for a clearfix when .cf:after { clear: both; content: ''; display: table; } is more than enough.Metaphrast
IF you are looking for clearfix solutions, check this page out... css-tricks.com/snippets/css/clear-fix I use the longer (but legacy-friendly) version...Premed

© 2022 - 2024 — McMap. All rights reserved.