CSS:让父母内部的孩子做出回应

时间:2018-04-01 17:07:31

标签: html css css3 flexbox

所以我没有使用像bootstrap这样的CSS框架来获得开箱即用的响应能力,这就是我在制作响应式布局时遇到的问题。

Please see jsbin

我基本上根据浏览器窗口大小自动调整彩色框的大小,例如根据窗口大小自动缩小或增长。其父级内的彩色框应始终位于水平行,但应能够调整其宽度和高度like this example

我尝试使用flex-wrap: nowrap;,但它没有做到这一点:(

请注意,彩色框使用position:absolute,父级位置为relative。我还通过JavaScript将left css属性添加到这些框中,以便为了滑动动画而改变它们的位置。

function Carousel(options) {
  options = options || {};

  // options vars
  let speed = options.speed || 1; // animation speed in seconds
  let width = options.width || 200;
  let height = options.height || 100;
  let space = options.space || 30;

  // other vars
  let container = document.querySelector('.carousel-container .carousel');
  let slides = container.querySelectorAll('.carousel-item');
  let curSlide = null;
  let prevSlide = null;
  let nextSlide = null;

  if (areSlidesPresent()) {
    setup();
  }

  // functions //

  function setup() {
    // we assume first slide to be current one as per UI requirements
    //slides[0].classList.add("current");
    curSlide = slides[0];

    // we assume second slide to be next as per UI requirements
    nextSlide = slides[1];

    // we assume last slide to be prev as per UI requirements
    prevSlide = slides[slides.length - 1];

    // position elements horizontally        
    positionSlides();
  }

  function areSlidesPresent() {
    return slides.length > 0;
  }

  this.getCurrentSlide = function() {
    return curSlide;
  }

  this.getNextSlide = function() {
    return nextSlide;
  }

  this.getPreviousSlide = function() {
    return prevSlide;
  }

  this.setNextSlide = function() {

    if (areSlidesPresent()) {
      let allSlides = [];

      // build new order of slides
      allSlides.push(nextSlide);

      // middle ones
      for (let i = 2; i < slides.length; i++) {
        allSlides.push(slides[i]);
      }

      allSlides.push(curSlide);

      // now add to DOM after cleaning previous slide order
      for (let i = 0; i < allSlides.length; i++) {
        container.appendChild(allSlides[i]);
      }

      slides = allSlides;

      setup();
    }
  }

  this.setPreviousSlide = function() {
    if (areSlidesPresent()) {
      let allSlides = [];

      // build new order of slides
      allSlides.push(prevSlide);
      allSlides.push(curSlide);

      // middle ones
      for (let i = 1; i < slides.length - 1; i++) {
        allSlides.push(slides[i]);
      }

      // now add to DOM after cleaning previous slide order
      for (let i = 0; i < allSlides.length; i++) {
        container.appendChild(allSlides[i]);
      }

      slides = allSlides;

      setup();
    }
  }

  function positionSlides() {

    curSlide.style.marginLeft = '0px';

    for (let i = 0; i < slides.length; i++) {

      slides[i].querySelector('.carousel-content').style.width = (width) + 'px';
      slides[i].querySelector('.carousel-content').style.height = (height) + 'px';

      let elementWidth = getStyle(nextSlide, 'width');

      if (i === 0) {
        slides[i].style.zIndex = -10;
        //slides[i].style.opacity = '1';

        slides[i].querySelector('.carousel-content').style.width = (width + 50) + 'px';
        slides[i].querySelector('.carousel-content').style.height = (height + 50) + 'px';
      } else {
        slides[i].style.zIndex = 0;
        //slides[i].style.opacity = '0.7';
      }

      if (i > 0) {
        slides[i].style.marginLeft = (space * 2) + 'px';
        elementWidth = parseInt(elementWidth, 10) + space;
      }

      slides[i].style.transition = speed + 's';
      slides[i].style.left = (elementWidth * i) + 'px';
    }
  }

  function getStyle(el, prop) {
    return window.getComputedStyle(el, null).getPropertyValue(prop)
      .replace('px', '')
      .replace('em', '');
  }
}

// utility
function log(text) {
  console.log(text);
}

var options = {
  speed: 1, // animation speed
  width: 250, // slide width
  height: 150, // slide height
  space: 25 // space in px between slides
};

var carousel = new Carousel(options);

function selectCurrent() {
  log(carousel.getCurrentSlide());
}

function selectNext() {
  carousel.setNextSlide();
}

function selectPrev() {
  carousel.setPreviousSlide();
}
.carousel-container {
  width: auto;
  height: auto;
  margin: 25px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.carousel {
  height: 100%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.carousel .carousel-item {
  position: absolute;
  transition: transform .5s ease-in-out;
  color: #fff;
  margin-left: 10px;
  -webkit-box-reflect: below 10px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(70%, transparent), to(rgba(255, 255, 255, 0.2)));
}

.carousel .carousel-item:first-child .carousel-content {
  opacity: 1;
}

.carousel .carousel-item .carousel-title {
  font-size: 24px;
  text-align: center;
}

.carousel .carousel-item .carousel-content {
  font-size: 18px;
  font-weight: bold;
  border: 1px solid #ccc;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
}


/* temp css below */

body {
  background: #2C374A;
  padding-top: 150px;
}

.navigation {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 150px;
}

.button {
  color: #444;
  padding: 10px;
  width: 60px;
  cursor: pointer;
  background: #CCC;
  text-align: center;
  font-weight: bold;
  border-radius: 5px;
  border-top: 1px solid #FFF;
  box-shadow: 0 5px 0 #999;
  transition: box-shadow 0.1s, top 0.1s;
  margin: 10px;
}

.button:hover,
.button:hover {
  color: #000;
}

.button:active,
.button:active {
  top: 104px;
  box-shadow: 0 1px 0 #999;
}
<div class="carousel-container">
  <div class="carousel">

    <div class="carousel-item">
      <div class="carousel-title">Make a Call</div>
      <div class="carousel-content" style="background:#0E6DE8;border:10px solid #78B1FA">Slide One</div>
    </div>

    <div class="carousel-item">
      <div class="carousel-title">Send a Message</div>
      <div class="carousel-content" style="background:#D90080;border:10px solid #E357A9">Slide Two</div>
    </div>

    <div class="carousel-item">
      <div class="carousel-title">Send a Picture</div>
      <div class="carousel-content" style="background:#FEC601;border:10px solid #FFDD64">Slide Three</div>
    </div>

    <div class="carousel-item">
      <div class="carousel-title">Send a Video</div>
      <div class="carousel-content" style="background:#3DB365;border:10px solid #90E0AB">Slide Four</div>
    </div>

  </div>
</div>


<div class="navigation">
  <div class="button" onclick="selectNext()">Next</div>
  <div class="button" onclick="selectCurrent()">Select</div>
  <div class="button" onclick="selectPrev()">Prev</div>
</div>

1 个答案:

答案 0 :(得分:4)

问题在于:

  1. 宽度在您的JS中是硬编码的,因此如果宽度在px中,则无法响应。
  2. position:absolute应用于carousel-item,迫使孩子们开箱即用。
  3. 我做了什么:

    1. 摆脱了JS
    2. 中与宽度相关的静态宽度和其他功能
    3. position:absolute
    4. 中删除了carousel-item

      请告诉我这是否是您所期待的。

      function Carousel(options) {
        options = options || {};
      
        // options vars
        let speed = options.speed || 1; // animation speed in seconds
        // let width = options.width || 100;
        let height = options.height || 100;
        let space = options.space || 30;
      
        // other vars
        let container = document.querySelector('.carousel-container .carousel');
        let slides = container.querySelectorAll('.carousel-item');
        let curSlide = null;
        let prevSlide = null;
        let nextSlide = null;
      
        if (areSlidesPresent()) {
          setup();
        }
      
        // functions //
      
        function setup() {
          // we assume first slide to be current one as per UI requirements
          //slides[0].classList.add("current");
          curSlide = slides[0];
      
          // we assume second slide to be next as per UI requirements
          nextSlide = slides[1];
      
          // we assume last slide to be prev as per UI requirements
          prevSlide = slides[slides.length - 1];
      
          // position elements horizontally        
          positionSlides();
        }
      
        function areSlidesPresent() {
          return slides.length > 0;
        }
      
        this.getCurrentSlide = function() {
          return curSlide;
        }
      
        this.getNextSlide = function() {
          return nextSlide;
        }
      
        this.getPreviousSlide = function() {
          return prevSlide;
        }
      
        this.setNextSlide = function() {
      
          if (areSlidesPresent()) {
            let allSlides = [];
      
            // build new order of slides
            allSlides.push(nextSlide);
      
            // middle ones
            for (let i = 2; i < slides.length; i++) {
              allSlides.push(slides[i]);
            }
      
            allSlides.push(curSlide);
      
            // now add to DOM after cleaning previous slide order
            for (let i = 0; i < allSlides.length; i++) {
              container.appendChild(allSlides[i]);
            }
      
            slides = allSlides;
      
            setup();
          }
        }
      
        this.setPreviousSlide = function() {
          if (areSlidesPresent()) {
            let allSlides = [];
      
            // build new order of slides
            allSlides.push(prevSlide);
            allSlides.push(curSlide);
      
            // middle ones
            for (let i = 1; i < slides.length - 1; i++) {
              allSlides.push(slides[i]);
            }
      
            // now add to DOM after cleaning previous slide order
            for (let i = 0; i < allSlides.length; i++) {
              container.appendChild(allSlides[i]);
            }
      
            slides = allSlides;
      
            setup();
          }
        }
      
        function positionSlides() {
      
          curSlide.style.marginLeft = '0px';
      
          for (let i = 0; i < slides.length; i++) {
      
            // slides[i].querySelector('.carousel-content').style.width = (width) + 'px';
            slides[i].querySelector('.carousel-content').style.height = (height) + 'px';
      
            let elementWidth = getStyle(nextSlide, 'width');
      
            if (i === 0) {
              slides[i].style.zIndex = -10;
              //slides[i].style.opacity = '1';
      
              // slides[i].querySelector('.carousel-content').style.width = (width + 50) + 'px';
              slides[i].querySelector('.carousel-content').style.height = (height + 50) + 'px';
            } else {
              slides[i].style.zIndex = 0;
              //slides[i].style.opacity = '0.7';
            }
      
            if (i > 0) {
              slides[i].style.marginLeft = (space * 2) + 'px';
              // elementWidth = parseInt(elementWidth, 10) + space;
            }
      
            slides[i].style.transition = speed + 's';
            // slides[i].style.left = (elementWidth * i) + 'px';
          }
        }
      
        function getStyle(el, prop) {
          return window.getComputedStyle(el, null).getPropertyValue(prop)
            .replace('px', '')
            .replace('em', '');
        }
      }
      
      // utility
      function log(text) {
        console.log(text);
      }
      
      var options = {
        speed: 1, // animation speed
        width: 250, // slide width
        height: 150, // slide height
        space: 25 // space in px between slides
      };
      
      var carousel = new Carousel(options);
      
      function selectCurrent() {
        log(carousel.getCurrentSlide());
      }
      
      function selectNext() {
        carousel.setNextSlide();
      }
      
      function selectPrev() {
        carousel.setPreviousSlide();
      }
      .carousel-container {
        height: auto;
        margin: 25px;
        display: flex;
      }
      
      .carousel {
        flex: 1;
        height: 100%;
        width: 100vh;
        /*   overflow:hidden; */
        display: flex;
        align-items: center;
        justify-content: center;
      }
      
      .carousel .carousel-item {
        transition: transform .5s ease-in-out;
        color: #fff;
        flex: 1;
        margin-left: 10px;
        -webkit-box-reflect: below 10px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(70%, transparent), to(rgba(255, 255, 255, 0.2)));
      }
      
      .carousel .carousel-item:first-child .carousel-content {
        opacity: 1;
      }
      
      .carousel .carousel-item .carousel-title {
        font-size: 24px;
        text-align: center;
      }
      
      .carousel .carousel-item .carousel-content {
        font-size: 18px;
        font-weight: bold;
        border: 1px solid #ccc;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 10px;
      }
      
      
      /* temp css below */
      
      body {
        background: #2C374A;
      }
      
      .navigation {
        display: flex;
        align-items: center;
        justify-content: center;
      }
      
      .button {
        color: #444;
        padding: 10px;
        width: 60px;
        cursor: pointer;
        background: #CCC;
        text-align: center;
        font-weight: bold;
        border-radius: 5px;
        border-top: 1px solid #FFF;
        box-shadow: 0 5px 0 #999;
        transition: box-shadow 0.1s, top 0.1s;
        margin: 10px;
      }
      
      .button:hover,
      .button:hover {
        color: #000;
      }
      
      .button:active,
      .button:active {
        box-shadow: 0 1px 0 #999;
      }
      <div class="navigation">
        <div class="button" onclick="selectNext()">Next</div>
        <div class="button" onclick="selectCurrent()">Select</div>
        <div class="button" onclick="selectPrev()">Prev</div>
      </div>
      
      <div class="carousel-container">
        <div class="carousel">
      
          <div class="carousel-item">
            <div class="carousel-title">Make a Call</div>
            <div class="carousel-content" style="background:#0E6DE8;border:10px solid #78B1FA">Slide One</div>
          </div>
      
          <div class="carousel-item">
            <div class="carousel-title">Send a Message</div>
            <div class="carousel-content" style="background:#D90080;border:10px solid #E357A9">Slide Two</div>
          </div>
      
          <div class="carousel-item">
            <div class="carousel-title">Send a Picture</div>
            <div class="carousel-content" style="background:#FEC601;border:10px solid #FFDD64">Slide Three</div>
          </div>
      
          <div class="carousel-item">
            <div class="carousel-title">Send a Video</div>
            <div class="carousel-content" style="background:#3DB365;border:10px solid #90E0AB">Slide Four</div>
          </div>
      
        </div>
      </div>