html - CSS:使父级内部的子级响应

标签 html css 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. 宽度是在您的 JS 中硬编码的,因此如果宽度以 px 为单位,则它无法响应。
  2. 通过将 position:absolute 应用于您的 carousel-item,它迫使 children 跳出框框。

我做了什么:

  1. 从您的 JS 中删除静态宽度和其他与宽度相关的功能
  2. carousel-item 中移除了 position:absolute

如果这就是您所期望的,请告诉我。

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>

关于html - CSS:使父级内部的子级响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49600533/

相关文章:

html - 父 div 的高度百分比未转换为子 div 的百分比

javascript - 未填写所需输入时将标签标记为红色

javascript - 我们可以在单个元素中使用多个 ng-style 对象吗?

java - 无法在tomcat的生产模式下使用资源

javascript - 如何覆盖具有类样式定义的元素的样式

html - JPG 欢迎图像不显示在 Rails 应用程序中

html - 媒体查询在它应该执行之后执行

javascript - 如何使用 Vuejs 在 html 中显示 mysql blob 图像?

html - 如何使用 JS 将 html 中的 div 内容放入和下载到 pdf 文件中?

css - 如何让 flexbox、transitions 和 IE10 协同工作?