Frame-Border for image in Bootstrap-Carousel

Hi
I just want to have a 2px border around the image in this Carousel, like a Frame-Border for a picture. The image should slide behind that Frame-Border.
Maybe it sounds simple, but i didn’t find a way for making it really work.
Thanks for helping.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <meta name="description" content="" />
    <meta name="author" content="M.C." />
    <title>Carousel Test</title>
    <!-- Bootstrap core CSS -->
    <link rel="stylesheet" href="bootstrap 4.2.1.css">
<style>
	/* GLOBAL STYLES*/
/*-------------------------------------------------- */
body {
     padding-top: 3rem;
     padding-bottom: 3rem;
     color: #5a5a5a;
}
 .portfolio-item {
     padding: 0;
     margin-bottom: 0;
     max-width: 950px 
}
 .title {
     width:100%;
     height: 6rem;
     padding-left: 0px;
     padding-right: 0px;
     margin-left: -15px;
     margin-right: -15px;
     border-bottom: 2px solid grey 
}
.loading {
	z-index: -1;
	opacity: 0;
	animation: fadeIn .25s linear .5s 1 forwards;
	-webkit-animation: fadeIn .25s linear .5s 1 forwards;
	-moz-animation: fadeIn .25s linear .5s 1 forwards;
	-o-animation: fadeIn .25s linear .5s 1 forwards;
	-ms-animation: fadeIn .25s linear .5s 1 forwards
}

@keyframes fadeIn {
	0% {
		opacity: 0
	}
	100% {
		opacity: 1;
		z-index: 1
	}
}

@-moz-keyframes fadeIn {
	0% {
		opacity: 0
	}
	100% {
		opacity: 1;
		z-index: 1
	}
}

@-webkit-keyframes fadeIn {
	0% {
		opacity: 0
	}
	100% {
		opacity: 1;
		z-index: 1
	}
}

@-o-keyframes fadeIn {
	0% {
		opacity: 0
	}
	100% {
		opacity: 1;
		z-index: 1
	}
}

@-ms-keyframes fadeIn {
	0% {
		opacity: 0
	}
	100% {
		opacity: 1;
		z-index: 1
	}
}

 @media (min-width:576px) and (max-width:767.98px) {
 .title {
	 width:100%;
	 height: 8rem;
	 padding-left: 0px;
	 padding-right: 0px;
	 margin-left: -15px;
	 margin-right: -15px;
	 border-bottom: 2px solid grey 
}
}
 @media (min-width: 768px) {
 .title {
	 width:100%;
	 height: 10rem;
	 padding-left: 0px;
	 padding-right: 0px;
	 margin-left: -15px;
	 margin-right: -15px;
	 border-bottom: 2px solid grey 
}
}
/* CAROUSEL STYLES*/
/*-------------------------------------------------- */
 .carousel {
     margin-bottom: 0;
}
 .carousel-caption {
     bottom: 0;
     left: 0;
     z-index: 1;
     background-color: transparent;
     text-align: center;
     padding-left: 15px;
     padding-right: 15px;
    /*border: 2px solid red;
    */
     margin-left: -15px;
     margin-right: -15px;
     color: black;
     margin-top: 15px;
     padding-top: 15px;
     padding-bottom: 15px;
     border-top: 2px solid grey;
     position: relative 
}
 .carousel-caption h5 {
     font-size: 14px;
     font-weight: bold;
}
 .carousel-caption p {
     font-size: 14px;
}
 .carousel-inner img {
     width: 100%;
     height: 100% 
}
 .carousel-item img {
     border-top: 2px solid grey;
     border-bottom: 2px solid grey;
}
 .carousel-control-next, .carousel-control-prev {
     position: absolute;
     top: 0;
     bottom: 0;
     z-index: 1;
    /*display: -ms-flexbox;
     display: flex;
     -ms-flex-align: center;
     align-items: center;
     -ms-flex-pack: center;
     justify-content: center;
    */
     width: 15%;
     color: #fff;
     text-align: center;
     opacity: 1;
     transition: opacity .15s ease;
    /*background-color: rgba(0,255,255,0.5)*/
}
 .carousel-control-next-icon {
     display: inline-block;
     width: 40px;
     height: 40px;
     opacity: 1;
     right: 0;
     background: no-repeat 50%/100% 100%;
     position: absolute;
}
 .carousel-control-prev-icon {
     display: inline-block;
     width: 40px;
     height: 40px;
     opacity: 1;
     left: 0;
     background: no-repeat 50%/100% 100%;
     position: absolute;
}
 .carousel-control-prev-icon {
     background-image: url("F-left.png") !important;
}
 .carousel-control-next-icon {
     background-image: url("F-right.png") !important;
}
 @media (min-width:576px) and (max-width:767.98px) {
 .carousel-caption h5 {
	 font-size: 16px;
	 font-weight: bold;
}
 .carousel-caption p {
	 font-size: 16px;
}
}
 @media (min-width:768px) {
 .carousel-caption h5 {
	 font-size: 18px;
	 font-weight: bold;
}
 .carousel-caption p {
	 font-size: 18px;
}
}

/*===================================================*/
 </style>
  </head>
  <body class="bg-dark loading">
    <main role="main">
      <div class="container bg-light" style="border:2px solid grey">
        <div class="row">
          <div class="col">
            <div class="container title mx-auto mb-5 text-center pt-5">
              <h1>Carousel Test</h1>
            </div>
            <div class="container mb-5">
              <div class="row">
                <div class="col-sm-12 mx-auto portfolio-item">
                <!--myCarousel -->
                <!--=======================================================================================-->
                  <div id="myCarousel" class="carousel slide" data-interval="false">
                    <ol class="carousel-indicators" style="display: none">
                      <li data-target="#myCarousel" data-slide-to="0" class="active"></li>
                      <li data-target="#myCarousel" data-slide-to="1"></li>
                      <li data-target="#myCarousel" data-slide-to="2"></li>
                      <li data-target="#myCarousel" data-slide-to="3"></li>
                    </ol>
                    <div class="carousel-inner">
                      <div class="carousel-item active">
                        <img src="CWA.jpg" class="d-block w-100" alt="pic1" />
                        <div class="container" style="background-color: ">
                          <div class="carousel-caption">
                            <h5>PIC SLIDE #1</h5>
                            <p>Donec id elit non mi porta gravida at eget metus.</p>
                          </div>
                          <!--caption -->
                        </div>
                        <!--container -->
                      </div>
                      <!--item -->
                      <div class="carousel-item">
                        <img src="CW1.jpg" class="d-block w-100" alt="pic2" />
                        <div class="container" style="background-color: ">
                          <div class="carousel-caption">
                            <h5>PIC SLIDE #2</h5>
                            <p>Donec id elit non mi porta gravida at eget metus.</p>
                          </div>
                          <!--caption -->
                        </div>
                        <!--container -->
                      </div>
                      <!--item -->
                      <div class="carousel-item">
                        <img src="CW3.jpg" class="d-block w-100" alt="pic3" />
                        <div class="container" style="background-color: ">
                          <div class="carousel-caption">
                            <h5>PIC SLIDE #3</h5>
                            <p>Donec id elit non mi porta gravida at eget metus.</p>
                          </div>
                          <!--caption -->
                        </div>
                        <!--container -->
                      </div>
                      <!--item -->
                      <div class="carousel-item">
                        <img src="CW6.jpg" class="d-block w-100" alt="pic4" />
                        <div class="container" style="background-color: ">
                          <div class="carousel-caption">
                            <h5>PIC SLIDE #4</h5>
                            <p>Donec id elit non mi porta gravida at eget metus.</p>
                          </div>
                          <!--caption -->
                        </div>
                        <!--container -->
                      </div>
                      <!--item -->
                      <div class="control-left">
                        <a class="carousel-control-prev" href="#myCarousel" role="button" data-slide="prev">
                        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                        <span class="sr-only">Previous</span>
                        </a>
                      </div>
                      <div class="control-right">
                        <a class="carousel-control-next" href="#myCarousel" role="button" data-slide="next">
                        <span class="carousel-control-next-icon" aria-hidden="true"></span>
                        <span class="sr-only">Next</span>
                        </a>
                      </div>
                    </div>
                    <!--inner -->
                  </div>
                  <!--myCarousel -->
                  <!--=======================================================================================-->
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </main>
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script>window.jQuery || document.write('<script src="../assets/js/vendor/jquery.slim.min.js"><\/script>')</script>
    <script src="../assets/dist/js/bootstrap.bundle.min.js"></script>
    
	<script type="text/javascript">
      $(document).ready(function () {
          $("#myCarousel").carousel({
              swipe: 30,
      pause: true,
              interval: false
          });
      });
    </script>
    
	<script type="text/javascript">
      var $iconleft = $("#myCarousel.carousel.slide div.carousel-inner div.control-left a.carousel-control-prev span.carousel-control-prev-icon");
         //iconleft.css({"border":"2px solid yellow"});
      var $iconright = $("#myCarousel.carousel.slide div.carousel-inner div.control-right a.carousel-control-next span.carousel-control-next-icon");
             
       $(document).ready(function () { 
      var imgbox = $("#myCarousel div.carousel-item img").height();
      var iconpos = imgbox/2-20;
      $iconleft.css({"top": ""+iconpos+"px"});
      $iconright.css({"top": ""+iconpos+"px"});
      
       console.dir(imgbox);		
       console.dir(iconpos);
      });
      
      $(window).resize(function () {	  
      var imgbox = $("#myCarousel div.carousel-item img").height();
      var iconpos = imgbox/2-20;
      $iconleft.css({"top": ""+iconpos+"px"});
      $iconright.css({"top": ""+iconpos+"px"});
      
       console.dir(imgbox);		
       console.dir(iconpos);
      });    
    </script>    
</html>

What do you mean by "Frame-Border?

Should the border adapt to the image-size(s) and stay fix in front of the image(s)?

1 Like

I’m not sure if I understand what you want exactly?

You can add a border to the carousel container quite easily but that also goes around the caption.

.carousel{border:2px solid red}

But it sounds like you are after something more complex.

You could add a border to the image but of course that will slide with the image. If you can clarify a bit more then I may be able to offer something better :slight_smile:

1 Like

Re-reading the question it looks like you want a frame border around the image (but not on the image so it doesn’t slide away) and not around the caption either?

If so then yes it will be quite hard to implement as there is no element in your code that just wraps an image and doesn’t slide away.

The slider also looks to be variable in height and I’m guessing will just change with caption size and image size which would make overlaying a border somewhat awkward and probably based on magic numbers.

If all of your images are the same size and aspect ratio then we could shim a pseudo element over the top based on the image’s aspect ratio.

There may be some other tricks such as putting a border on the carousel and then trying to rub out the bottom parts using the caption which might also work.

.

Exactly. I’m after a way to have a border like one layer up related to the image and the image should stay behind. The border should not slide away with the image and should be only for the image. For the caption it’s already ok as it is.
Thanks for your interest.

P.S. images are all same size and ratio.

Then I think @PaulOB has already mentioned a viable solution: a pseudo element overlay on the container.

I was just working up a demo but your site seems to be down at the moment. I’ll look back later this afternoon unless Erik wants to jump in first :slight_smile:

Have to leave the keyboard for some time, sorry. :grin:

1 Like

Paul, do you mean a solution with ::before and ::after elements?

Yes either of those will do as long as they are not in use already. You’d need to base it on the carousel container and then absolutely position it at top and left. To make its height match the image aspect ratio you would need a percentage padding top that matches the aspect ratio of the image. then just add your border and you should be good to go.

You will probably need pointer-events:none on the psuedo element if the image is clickable.

Something like this (untested);

.carousel:before{
content:"";
position:absolute;
left:0;
right:0;
top:0;
padding-top:66.5%;
border:2px solid red;
z-index:5;
pointer-events:none;
}
.carousel-control-next, .carousel-control-prev{z-index:6;}

[edit]
Just tested it :slight_smile:

2 Likes

:astonished: :partying_face: wow, perfect!
as last solution too (captions outside) >link.
This time on this carousel i tried also to reposition the arrows with js, but it seems that this part is a little buggy. Resizing the browser sometimes works, sometimes not. Must have to do with the on window resize event.

You could do the same for the arrows without js using the aspect ratio trick. This all assumes you keep images the same size.

You’d place the control:left and control-right absolutely in the same way as the pseudo element. Then the next button can also be absolutely placed at top: 50% minus its own height. That will keep it centred on the image.

No need for JS :slight_smile:

Roughly like this :slight_smile:

.control-left,
.control-right{
position:absolute;
left:0;
top:0;
right:0;
padding-top:66.5%;
height:0;
}
.carousel-control-next, .carousel-control-prev{z-index:6;}
.carousel-control-next{right:0;left:auto;}
.carousel-control-next span{right:0;top:50%!important;margin-top:-20px;}
.carousel-control-prev span{left:0;top:50%!important;margin-top:-20px;}
2 Likes

Exactly my thought, though the aspect ratio is 66.6% exactly rounded, so…

…please enlighten me; is the 66.5% ratio to be safe of px rounding errors?

I just did it by eye in the devtools window as I’m too lazy to work it out exactly. I used the .6 as it doesn’t leave a gap when changing the window size :slight_smile:

2 Likes

66.5% was perfect with the 2px bottom and top border. I changed it to 66.2% now, because there is no more need for the bottom and top border.
Will try later your suggestion about the arrows.
Thanks a lot!

1 Like

:dizzy: :100: :ok_hand: :muscle: :champagne: :clinking_glasses:
Arrows are P-E-R-F-E-C-T too!

1 Like