diff options
| author | Mark Otto <[email protected]> | 2016-12-05 23:31:14 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2016-12-05 23:31:14 -0800 |
| commit | ede925d79bf92d5983a4508c6ed6fda9310e1e8b (patch) | |
| tree | 2106dc9b4f97d109f91c06a31234802c8d1890b6 | |
| parent | 306f75216d2b66bfe8e6e4b587939491e637b8da (diff) | |
| parent | e0edea0d1a69d51990cb8d8de41183e94331b3a2 (diff) | |
| download | bootstrap-ede925d79bf92d5983a4508c6ed6fda9310e1e8b.tar.xz bootstrap-ede925d79bf92d5983a4508c6ed6fda9310e1e8b.zip | |
Merge pull request #21298 from twbs/carousel
Refactor carousel
| -rw-r--r-- | docs/components/carousel.md | 124 | ||||
| -rw-r--r-- | docs/examples/carousel/carousel.css | 18 | ||||
| -rw-r--r-- | docs/examples/carousel/index.html | 20 | ||||
| -rw-r--r-- | docs/migration.md | 9 | ||||
| -rw-r--r-- | js/src/carousel.js | 42 | ||||
| -rw-r--r-- | scss/_carousel.scss | 262 | ||||
| -rw-r--r-- | scss/_variables.scss | 17 |
7 files changed, 238 insertions, 254 deletions
diff --git a/docs/components/carousel.md b/docs/components/carousel.md index 3942309f0..8dd819fba 100644 --- a/docs/components/carousel.md +++ b/docs/components/carousel.md @@ -5,7 +5,11 @@ description: A slideshow component for cycling through elements—images or slid group: components --- -A slideshow component for cycling through elements—images or slides of text—like a carousel. In browsers where the [Page Visibility API](https://www.w3.org/TR/page-visibility/) is supported, the carousel will avoid sliding when the webpage is not visible to the user (such as when the browser tab is inactive, the browser window is minimized, etc.). **Nested carousels are not supported.** +The carousel is a slideshow for cycling through a series of content, built with CSS 3D transforms and a bit of JavaScript. It works with a series of images, text, or custom markup. It also includes support for previous/next controls and indicators. + +In browsers where the [Page Visibility API](https://www.w3.org/TR/page-visibility/) is supported, the carousel will avoid sliding when the webpage is not visible to the user (such as when the browser tab is inactive, the browser window is minimized, etc.). + +Please be aware that nested carousels are not supported, and carousels are generally not compliant with accessibility standards. ## Contents @@ -14,32 +18,86 @@ A slideshow component for cycling through elements—images or slides of text— ## Example -When building carousels, be sure your slides are the same size as one another. The carousel doesn't automatically crop images to the same dimensions for you across slides. +Carousels don't automatically normalize slide dimensions. As such, you may need to use additional utilities or custom styles to appropriately size content. While carousels support previous/next controls and indicators, they're not explicitly required. Add and customize as you see fit. + +Be sure to set a unique id on the `.carousel` for optional controls, especially if you're using multiple carousels on a single page. + +### Slides only + +Here's a carousel with slides only. Note the presence of the `.d-block` and `.img-fluid` on carousel images to prevent browser default image alignment. + +{% example html %} +<div id="carouselExampleSlidesOnly" class="carousel slide" data-ride="carousel"> + <div class="carousel-inner" role="listbox"> + <div class="carousel-item active"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=777&fg=555&text=First slide" alt="First slide"> + </div> + <div class="carousel-item"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=666&fg=444&text=Second slide" alt="Second slide"> + </div> + <div class="carousel-item"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=555&fg=333&text=Third slide" alt="Third slide"> + </div> + </div> +</div> +{% endexample %} + +### With controls + +Adding in the previous and next controls: + +{% example html %} +<div id="carouselExampleControls" class="carousel slide" data-ride="carousel"> + <div class="carousel-inner" role="listbox"> + <div class="carousel-item active"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=777&fg=555&text=First slide" alt="First slide"> + </div> + <div class="carousel-item"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=666&fg=444&text=Second slide" alt="Second slide"> + </div> + <div class="carousel-item"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=555&fg=333&text=Third slide" alt="Third slide"> + </div> + </div> + <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev"> + <span class="carousel-control-prev-icon" aria-hidden="true"></span> + <span class="sr-only">Previous</span> + </a> + <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next"> + <span class="carousel-control-next-icon" aria-hidden="true"></span> + <span class="sr-only">Next</span> + </a> +</div> +{% endexample %} + +### With indicators + +You can also add the indicators to the carousel, alongside the controls, too. {% example html %} -<div id="carousel-example-generic" class="carousel slide" data-ride="carousel"> +<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel"> <ol class="carousel-indicators"> - <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li> - <li data-target="#carousel-example-generic" data-slide-to="1"></li> - <li data-target="#carousel-example-generic" data-slide-to="2"></li> + <li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li> + <li data-target="#carouselExampleIndicators" data-slide-to="1"></li> + <li data-target="#carouselExampleIndicators" data-slide-to="2"></li> </ol> <div class="carousel-inner" role="listbox"> <div class="carousel-item active"> - <img data-src="holder.js/900x500/auto/#777:#555/text:First slide" alt="First slide"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=777&fg=555&text=First slide" alt="First slide"> </div> <div class="carousel-item"> - <img data-src="holder.js/900x500/auto/#666:#444/text:Second slide" alt="Second slide"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=666&fg=444&text=Second slide" alt="Second slide"> </div> <div class="carousel-item"> - <img data-src="holder.js/900x500/auto/#555:#333/text:Third slide" alt="Third slide"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=555&fg=333&text=Third slide" alt="Third slide"> </div> </div> - <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev"> - <span class="icon-prev" aria-hidden="true"></span> + <a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev"> + <span class="carousel-control-prev-icon" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> - <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next"> - <span class="icon-next" aria-hidden="true"></span> + <a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next"> + <span class="carousel-control-next-icon" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div> @@ -57,45 +115,45 @@ Bootstrap exclusively uses CSS3 for its animations, but Internet Explorer 9 does The `.active` class needs to be added to one of the slides. Otherwise, the carousel will not be visible. {% endcallout %} -### Optional captions +### With captions -Add captions to your slides easily with the `.carousel-caption` element within any `.carousel-item`. Place just about any optional HTML within there and it will be automatically aligned and formatted. +Add captions to your slides easily with the `.carousel-caption` element within any `.carousel-item`. They can be easily hidden on smaller viewports, as shown below, with optional [display utilities]({{ site.baseurl }}/utilities/display-property/). We hide them initially with `.d-none` and bring them back on medium-sized devices with `.d-md-block`. <div class="bd-example"> - <div id="carousel-example-captions" class="carousel slide" data-ride="carousel"> + <div id="carouselExampleCaptions" class="carousel slide" data-ride="carousel"> <ol class="carousel-indicators"> - <li data-target="#carousel-example-captions" data-slide-to="0" class="active"></li> - <li data-target="#carousel-example-captions" data-slide-to="1"></li> - <li data-target="#carousel-example-captions" data-slide-to="2"></li> + <li data-target="#carouselExampleCaptions" data-slide-to="0" class="active"></li> + <li data-target="#carouselExampleCaptions" data-slide-to="1"></li> + <li data-target="#carouselExampleCaptions" data-slide-to="2"></li> </ol> <div class="carousel-inner" role="listbox"> <div class="carousel-item active"> - <img data-src="holder.js/900x500/auto/#777:#777" alt="First slide image"> - <div class="carousel-caption"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=777&fg=555&text=First slide" alt="First slide"> + <div class="carousel-caption d-none d-md-block"> <h3>First slide label</h3> <p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p> </div> </div> <div class="carousel-item"> - <img data-src="holder.js/900x500/auto/#666:#666" alt="Second slide image"> - <div class="carousel-caption"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=666&fg=444&text=Second slide" alt="Second slide"> + <div class="carousel-caption d-none d-md-block"> <h3>Second slide label</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> </div> </div> <div class="carousel-item"> - <img data-src="holder.js/900x500/auto/#555:#555" alt="Third slide image"> - <div class="carousel-caption"> + <img class="d-block img-fluid" data-src="holder.js/800x400?auto=yes&bg=555&fg=333&text=Third slide" alt="Third slide"> + <div class="carousel-caption d-none d-md-block"> <h3>Third slide label</h3> <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur.</p> </div> </div> </div> - <a class="left carousel-control" href="#carousel-example-captions" role="button" data-slide="prev"> + <a class="carousel-control carousel-control-left" href="#carouselExampleCaptions" role="button" data-slide="prev"> <span class="icon-prev" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> - <a class="right carousel-control" href="#carousel-example-captions" role="button" data-slide="next"> + <a class="carousel-control carousel-control-right" href="#carouselExampleCaptions" role="button" data-slide="next"> <span class="icon-next" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> @@ -105,25 +163,15 @@ Add captions to your slides easily with the `.carousel-caption` element within a {% highlight html %} <div class="carousel-item"> <img src="..." alt="..."> - <div class="carousel-caption"> + <div class="carousel-caption d-none d-md-block"> <h3>...</h3> <p>...</p> </div> </div> {% endhighlight %} -{% callout danger %} -#### Accessibility issue - -The carousel component is generally not compliant with accessibility standards. If you need to be compliant, please consider other options for presenting your content. -{% endcallout %} - ## Usage -### Multiple carousels - -Carousels require the use of an `id` on the outermost container (the `.carousel`) for carousel controls to function properly. When adding multiple carousels, or when changing a carousel's `id`, be sure to update the relevant controls. - ### Via data attributes Use data attributes to easily control the position of the carousel. `data-slide` accepts the keywords `prev` or `next`, which alters the slide position relative to its current position. Alternatively, use `data-slide-to` to pass a raw slide index to the carousel `data-slide-to="2"`, which shifts the slide position to a particular index beginning with `0`. diff --git a/docs/examples/carousel/carousel.css b/docs/examples/carousel/carousel.css index a1ec54fa5..58fdde1cb 100644 --- a/docs/examples/carousel/carousel.css +++ b/docs/examples/carousel/carousel.css @@ -19,6 +19,7 @@ body { /* Since positioning the image, we need to help out the caption */ .carousel-caption { z-index: 10; + bottom: 3rem; } /* Declare heights because of positioning of img element */ @@ -34,17 +35,12 @@ body { height: 32rem; } -.carousel-indicators { - top: 1.5rem; - right: 1.5rem; - bottom: auto; - left: auto; - width: 1rem; - margin-left: 0; -} - -.carousel-indicators > li { - margin-bottom: .25rem; +.carousel-indicators li { + width: .75rem; + height: .75rem; + margin-right: .25rem; + margin-left: .25rem; + border-radius: 50%; } diff --git a/docs/examples/carousel/index.html b/docs/examples/carousel/index.html index 990553b97..edab89919 100644 --- a/docs/examples/carousel/index.html +++ b/docs/examples/carousel/index.html @@ -37,11 +37,7 @@ </ul> </nav> - - <!-- Carousel - ================================================== --> <div id="myCarousel" class="carousel slide" data-ride="carousel"> - <!-- Indicators --> <ol class="carousel-indicators"> <li data-target="#myCarousel" data-slide-to="0" class="active"></li> <li data-target="#myCarousel" data-slide-to="1"></li> @@ -51,7 +47,7 @@ <div class="carousel-item active"> <img class="first-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="First slide"> <div class="container"> - <div class="carousel-caption text-left"> + <div class="carousel-caption d-none d-md-block text-left"> <h1>Example headline.</h1> <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> <p><a class="btn btn-lg btn-primary" href="#" role="button">Sign up today</a></p> @@ -61,7 +57,7 @@ <div class="carousel-item"> <img class="second-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Second slide"> <div class="container"> - <div class="carousel-caption"> + <div class="carousel-caption d-none d-md-block"> <h1>Another example headline.</h1> <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> <p><a class="btn btn-lg btn-primary" href="#" role="button">Learn more</a></p> @@ -71,7 +67,7 @@ <div class="carousel-item"> <img class="third-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Third slide"> <div class="container"> - <div class="carousel-caption text-right"> + <div class="carousel-caption d-none d-md-block text-right"> <h1>One more for good measure.</h1> <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p> <p><a class="btn btn-lg btn-primary" href="#" role="button">Browse gallery</a></p> @@ -79,15 +75,15 @@ </div> </div> </div> - <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev"> - <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> + <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> - <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next"> - <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> + <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><!-- /.carousel --> + </div> <!-- Marketing messaging and featurettes diff --git a/docs/migration.md b/docs/migration.md index 9b6e006c7..b6704a669 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -183,7 +183,14 @@ Dropped entirely for the new card component. ### Carousel -- Renamed `.item` to `.carousel-item`. +- Overhauled the entire component to simplify design and styling. We have fewer styles for you to override, new indicators, and new icons. +- All CSS has been un-nested and renamed, ensuring each class is prefixed with `.carousel-`. + - For carousel items, `.next`, `.prev`, `.left`, and `.right` are now `.carousel-item-next`, `.carousel-item-prev`, `.carousel-item-left`, and `.carousel-item-right`. + - `.item` is also now `.carousel-item`. + - For prev/next controls, `.carousel-control.right` and `.carousel-control.left` are now `.carousel-control-right` and `.carousel-control-left`, meaning they no longer require a specific base class. +- Removed all responsive styling, deferring to utilities (e.g., showing captions on certain viewports) and custom styles as needed. +- Removed image overrides for images in carousel items, deferring to utilities. +- Tweaked the Carousel example to include the new markup and styles. ### Utilities diff --git a/js/src/carousel.js b/js/src/carousel.js index 7fda8f615..304d0160f 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -45,7 +45,9 @@ const Carousel = (($) => { const Direction = { NEXT : 'next', - PREVIOUS : 'prev' + PREV : 'prev', + LEFT : 'left', + RIGHT : 'right' } const Event = { @@ -62,8 +64,10 @@ const Carousel = (($) => { CAROUSEL : 'carousel', ACTIVE : 'active', SLIDE : 'slide', - RIGHT : 'right', - LEFT : 'left', + RIGHT : 'carousel-item-right', + LEFT : 'carousel-item-left', + NEXT : 'carousel-item-next', + PREV : 'carousel-item-prev', ITEM : 'carousel-item' } @@ -71,7 +75,7 @@ const Carousel = (($) => { ACTIVE : '.active', ACTIVE_ITEM : '.active.carousel-item', ITEM : '.carousel-item', - NEXT_PREV : '.next, .prev', + NEXT_PREV : '.carousel-item-next, .carousel-item-prev', INDICATORS : '.carousel-indicators', DATA_SLIDE : '[data-slide], [data-slide-to]', DATA_RIDE : '[data-ride="carousel"]' @@ -276,10 +280,10 @@ const Carousel = (($) => { } - _triggerSlideEvent(relatedTarget, directionalClassname) { + _triggerSlideEvent(relatedTarget, eventDirectionName) { const slideEvent = $.Event(Event.SLIDE, { relatedTarget, - direction: directionalClassname + direction: eventDirectionName }) $(this._element).trigger(slideEvent) @@ -310,16 +314,26 @@ const Carousel = (($) => { const isCycling = Boolean(this._interval) - const directionalClassName = direction === Direction.NEXT ? - ClassName.LEFT : - ClassName.RIGHT + let directionalClassName + let orderClassName + let eventDirectionName + + if (direction === Direction.NEXT) { + directionalClassName = ClassName.LEFT + orderClassName = ClassName.NEXT + eventDirectionName = Direction.LEFT + } else { + directionalClassName = ClassName.RIGHT + orderClassName = ClassName.PREV + eventDirectionName = Direction.RIGHT + } if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) { this._isSliding = false return } - const slideEvent = this._triggerSlideEvent(nextElement, directionalClassName) + const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName) if (slideEvent.isDefaultPrevented()) { return } @@ -339,13 +353,13 @@ const Carousel = (($) => { const slidEvent = $.Event(Event.SLID, { relatedTarget: nextElement, - direction: directionalClassName + direction: eventDirectionName }) if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.SLIDE)) { - $(nextElement).addClass(direction) + $(nextElement).addClass(orderClassName) Util.reflow(nextElement) @@ -355,10 +369,10 @@ const Carousel = (($) => { $(activeElement) .one(Util.TRANSITION_END, () => { $(nextElement) - .removeClass(`${directionalClassName} ${direction}`) + .removeClass(`${directionalClassName} ${orderClassName}`) .addClass(ClassName.ACTIVE) - $(activeElement).removeClass(`${ClassName.ACTIVE} ${direction} ${directionalClassName}`) + $(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`) this._isSliding = false diff --git a/scss/_carousel.scss b/scss/_carousel.scss index 09f6ea73e..8a077f083 100644 --- a/scss/_carousel.scss +++ b/scss/_carousel.scss @@ -7,77 +7,47 @@ position: relative; width: 100%; overflow: hidden; +} - > .carousel-item { - position: relative; - display: none; - @include transition(left .6s ease-in-out); - - // Account for jankitude on images - > img, - > a > img { - @extend .img-fluid; - line-height: 1; - } +.carousel-item { + position: relative; + display: none; + width: 100%; - // CSS3 transforms when supported by the browser - @include if-supports-3d-transforms() { - @include transition(transform .6s ease-in-out); - backface-visibility: hidden; - perspective: 1000px; - - &.next, - &.active.right { - left: 0; - transform: translate3d(100%, 0, 0); - } - &.prev, - &.active.left { - left: 0; - transform: translate3d(-100%, 0, 0); - } - &.next.left, - &.prev.right, - &.active { - left: 0; - transform: translate3d(0, 0, 0); - } - } + @include if-supports-3d-transforms() { + @include transition(transform .6s ease-in-out); + backface-visibility: hidden; + perspective: 1000px; } +} - > .active, - > .next, - > .prev { - display: block; - } +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} - > .active { - left: 0; - } +.carousel-item-next, +.carousel-item-prev { + position: absolute; + top: 0; +} - > .next, - > .prev { - position: absolute; - top: 0; - width: 100%; +// CSS3 transforms when supported by the browser +@include if-supports-3d-transforms() { + .carousel-item-next.carousel-item-left, + .carousel-item-prev.carousel-item-right { + transform: translate3d(0, 0, 0); } - > .next { - left: 100%; - } - > .prev { - left: -100%; - } - > .next.left, - > .prev.right { - left: 0; + .carousel-item-next, + .active.carousel-item-right { + transform: translate3d(100%, 0, 0); } - > .active.left { - left: -100%; - } - > .active.right { - left: 100%; + .carousel-item-prev, + .active.carousel-item-left { + transform: translate3d(-100%, 0, 0); } } @@ -86,30 +56,18 @@ // Left/right controls for nav // -.carousel-control { +.carousel-control-prev, +.carousel-control-next { position: absolute; top: 0; bottom: 0; - left: 0; width: $carousel-control-width; - font-size: $carousel-control-font-size; color: $carousel-control-color; text-align: center; - text-shadow: $carousel-text-shadow; opacity: $carousel-control-opacity; - // We can't have this transition here because WebKit cancels the carousel + // We can't have a transition here because WebKit cancels the carousel // animation if you trip this while in the middle of another animation. - // Set gradients for backgrounds - &.left { - @include gradient-x($start-color: rgba(0,0,0,.5), $end-color: rgba(0,0,0,.0001)); - } - &.right { - right: 0; - left: auto; - @include gradient-x($start-color: rgba(0,0,0,.0001), $end-color: rgba(0,0,0,.5)); - } - // Hover/focus state @include hover-focus { color: $carousel-control-color; @@ -117,39 +75,38 @@ outline: 0; opacity: .9; } +} +.carousel-control-prev { + left: 0; +} +.carousel-control-next { + right: 0; +} - // Toggles - .icon-prev, - .icon-next { - position: absolute; - top: 50%; - z-index: 5; - display: inline-block; - width: $carousel-icon-width; - height: $carousel-icon-width; - margin-top: -($carousel-icon-width / 2); - font-family: serif; - line-height: 1; - } - .icon-prev { - left: 50%; - margin-left: -($carousel-icon-width / 2); - } - .icon-next { - right: 50%; - margin-right: -($carousel-icon-width / 2); - } - - .icon-prev { - &::before { - content: "\2039";// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) - } - } - .icon-next { - &::before { - content: "\203a";// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) - } - } +// Icons for within +.carousel-control-prev-icon, +.carousel-control-next-icon { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + width: $carousel-control-icon-width; + height: $carousel-control-icon-width; + margin-top: -($carousel-control-icon-width / 2); + font-family: serif; + line-height: 1; + background: transparent no-repeat center center; + background-size: 100% 100%; +} +.carousel-control-prev-icon { + left: 50%; + margin-left: -($carousel-control-icon-width / 2); + background-image: $carousel-control-prev-icon-bg; +} +.carousel-control-next-icon { + right: 50%; + margin-right: -($carousel-control-icon-width / 2); + background-image: $carousel-control-next-icon-bg; } @@ -160,36 +117,48 @@ .carousel-indicators { position: absolute; + right: 0; bottom: 10px; - left: 50%; + left: 0; z-index: 15; - width: $carousel-indicators-width; - padding-left: 0; - margin-left: -($carousel-indicators-width / 2); + padding-left: 0; // override <ul> default + // Use the .carousel-control's width as margin so we don't overlay those + margin-right: $carousel-control-width; + margin-left: $carousel-control-width; text-align: center; list-style: none; li { + position: relative; display: inline-block; - width: $carousel-indicator-size; - height: $carousel-indicator-size; - margin: 1px; + width: $carousel-indicator-width; + height: $carousel-indicator-height; text-indent: -999px; cursor: pointer; - // IE9 hack for event handling - // - // Internet Explorer 9 does not properly handle clicks on elements with a `background-color` of `transparent`, - // so we use `rgba(0,0,0,0)` instead since it's a non-buggy equivalent. - // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer - background-color: rgba(0,0,0,0); // IE9 - border: 1px solid $carousel-indicator-border-color; - border-radius: $carousel-indicator-size; + background-color: rgba($carousel-indicator-active-bg, .5); + + // Use pseudo classes to increase the hit area by 10px on top and bottom. + &::before { + position: absolute; + top: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; + } + &::after { + position: absolute; + bottom: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; + } } .active { - width: $carousel-indicator-active-size; - height: $carousel-indicator-active-size; - margin: 0; background-color: $carousel-indicator-active-bg; } } @@ -209,45 +178,4 @@ padding-bottom: 20px; color: $carousel-caption-color; text-align: center; - text-shadow: $carousel-text-shadow; - - .btn { - text-shadow: none; // No shadow for button elements in carousel-caption - } -} - - -// -// Responsive variations -// - -@include media-breakpoint-up(sm) { - // Scale up the controls a smidge - .carousel-control { - .icon-prev, - .icon-next { - width: $carousel-control-sm-up-size; - height: $carousel-control-sm-up-size; - margin-top: -($carousel-control-sm-up-size / 2); - font-size: $carousel-control-sm-up-size; - } - .icon-prev { - margin-left: -($carousel-control-sm-up-size / 2); - } - .icon-next { - margin-right: -($carousel-control-sm-up-size / 2); - } - } - - // Show and left align the captions - .carousel-caption { - right: ((100% - $carousel-caption-sm-up-width) / 2); - left: ((100% - $carousel-caption-sm-up-width) / 2); - padding-bottom: 30px; - } - - // Move up the indicators - .carousel-indicators { - bottom: 20px; - } } diff --git a/scss/_variables.scss b/scss/_variables.scss index d57e59575..50803fc3f 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -882,26 +882,21 @@ $media-alignment-padding-x: 10px !default; // 33. Carousel -$carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6) !default; - $carousel-control-color: #fff !default; $carousel-control-width: 15% !default; -$carousel-control-sm-up-size: 30px !default; $carousel-control-opacity: .5 !default; -$carousel-control-font-size: 20px !default; - -$carousel-indicators-width: 60% !default; -$carousel-indicator-size: 10px !default; -$carousel-indicator-active-size: 12px !default; +$carousel-indicator-width: 30px !default; +$carousel-indicator-height: 3px !default; $carousel-indicator-active-bg: #fff !default; -$carousel-indicator-border-color: #fff !default; $carousel-caption-width: 70% !default; -$carousel-caption-sm-up-width: 60% !default; $carousel-caption-color: #fff !default; -$carousel-icon-width: 20px !default; +$carousel-control-icon-width: 20px !default; + +$carousel-control-prev-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M4 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"), "#", "%23") !default; +$carousel-control-next-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M1.5 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"), "#", "%23") !default; // 34. Close |
