diff --git a/src/components/carousel/carousel-item.vue b/src/components/carousel/carousel-item.vue
index b995e94..ea964c6 100644
--- a/src/components/carousel/carousel-item.vue
+++ b/src/components/carousel/carousel-item.vue
@@ -1,10 +1,26 @@
 <template>
-    <div :class="prefixCls"><slot></slot></div>
+    <div :class="prefixCls" v-bind:style="styles">{{width}}<slot></slot></div>
 </template>
 <script>
     const prefixCls = 'ivu-carousel-item';
 
     export default {
-        name: 'CarouselItem'
+        componentName: 'carousel-item',
+
+        data () {
+            return {
+                prefixCls: prefixCls,
+                width: 0,
+                left: 0
+            };
+        },
+        computed: {
+            styles () {
+                return {
+                    width: `${this.width}px`,
+                    left: `${this.left}px`
+                }
+            }
+        },
     };
 </script>
diff --git a/src/components/carousel/carousel.vue b/src/components/carousel/carousel.vue
index 680cd56..e048061 100644
--- a/src/components/carousel/carousel.vue
+++ b/src/components/carousel/carousel.vue
@@ -1,10 +1,18 @@
 <template>
     <div :class="classes">
-        <slot></slot>
+        <!-- button -->
+        <div :class="[prefixCls + '-list']">
+            <div :class="[prefixCls + '-track']" :style="trackStyles" v-el:slides>
+                <!-- opacity: 1; width: 4480px; transform: translate3d(-1120px, 0px, 0px); -->
+                <slot></slot>
+            </div>
+        </div>
+        <!-- button -->
     </div>
 </template>
 <script>
     import Icon from '../icon/icon.vue';
+    import { oneOf, getStyle, deepCopy, getScrollBarSize } from '../../utils/assist';
 
     const prefixCls = 'ivu-carousel';
 
@@ -40,6 +48,15 @@
                 default: false
             }
         },
+        data () {
+            return {
+                prefixCls: prefixCls,
+                listWidth: 0,
+                trackWidth: 0,
+                slides: [],
+                slideInstances: []
+            }
+        },
         // events: before-change(from, to), after-change(current, from)
         computed: {
             classes () {
@@ -49,7 +66,99 @@
                         [`${prefixCls}-vertical`]: this.vertical
                     }
                 ];
+            },
+            trackStyles () {
+                return {
+                    width: `${this.trackWidth}px`
+                };
+            }
+        },
+        methods: {
+            // find option component
+            findChild (cb) {
+                const find = function (child) {
+                    const name = child.$options.componentName;
+
+                    if (name) {
+                        cb(child);
+                    } else if (child.$children.length) {
+                        child.$children.forEach((innerChild) => {
+                            find(innerChild, cb);
+                        });
+                    }
+                };
+
+                if (this.slideInstances.length) {
+                    this.slideInstances.forEach((child) => {
+                        find(child);
+                    });
+                } else {
+                    this.$children.forEach((child) => {
+                        find(child);
+                    });
+                }
+            },
+            updateSlides (init, slot = false) {
+                let slides = [];
+                let index = 1;
+
+                this.findChild((child) => {
+                    slides.push({
+                        $el: child.$el
+                    });
+                    child.index = index++;
+
+                    if (init) {
+                        this.slideInstances.push(child);
+                    }
+                });
+
+                this.slides = slides;
+
+                // this.updateSlideWidth();
+            },
+            updatePos () {
+                this.findChild((child) => {
+                    child.width = this.listWidth;
+                });
+
+                this.trackWidth = (this.slides.length || 0) * this.listWidth;
+            },
+            // use when slot changed
+            slotChange () {
+                this.slides = [];
+                this.slideInstances = [];
+            },
+            handleResize () {
+                this.$nextTick(() => {
+                    this.listWidth = parseInt(getStyle(this.$el, 'width'));
+                    this.updatePos();
+                });
             }
+        },
+        compiled () {
+            this.updateSlides(true);
+
+            // watch slot changed
+            if (MutationObserver) {
+                this.observer = new MutationObserver(() => {
+                    this.slotChange();
+                    this.updateSlides(true, true);
+                });
+
+                this.observer.observe(this.$els.slides, {
+                    childList: true,
+                    characterData: true,
+                    subtree: true
+                });
+            }
+        },
+        ready () {
+            this.handleResize();
+            window.addEventListener('resize', this.handleResize, false);
+        },
+        beforeDestroy () {
+            window.removeEventListener('resize', this.handleResize, false);
         }
     };
 </script>
diff --git a/src/styles/components/carousel.less b/src/styles/components/carousel.less
index b440717..87557dc 100644
--- a/src/styles/components/carousel.less
+++ b/src/styles/components/carousel.less
@@ -8,4 +8,30 @@
     user-select: none;
     touch-action: pan-y;
     -webkit-tap-highlight-color: transparent;
+
+    &-track, &-list {
+        transform: translate3d(0, 0, 0);
+    }
+
+    &-list {
+        position: relative;
+        display: block;
+        overflow: hidden;
+
+        margin: 0;
+        padding: 0;
+    }
+
+    &-track {
+        position: relative;
+        top: 0;
+        left: 0;
+        display: block;
+    }
+
+    &-item {
+        float: left;
+        height: 100%;
+        min-height: 1px;
+    }
 }
diff --git a/test/routers/carousel.vue b/test/routers/carousel.vue
index 4dff775..ff9bab6 100644
--- a/test/routers/carousel.vue
+++ b/test/routers/carousel.vue
@@ -1,5 +1,5 @@
 <template>
-    <Carousel>
+    <Carousel style="width: 400px">
         <Carousel-item>test1</Carousel-item>
         <Carousel-item>test2</Carousel-item>
         <Carousel-item>test3</Carousel-item>
--
libgit2 0.21.4