Несогласованное изменение размера HTMLDivElement после сборки WebpackDevServer

#javascript #html #css

Вопрос:

У меня есть пользовательский веб-компонент, который я пытаюсь создать, который выглядит примерно так, Пример Изображения 1но после перезагрузки страницы Пример Изображения 2я замечаю тонкий белый div в самом низу каждого изображения.

Я замечаю, что получаю желаемый результат (изображение кулака) сразу после сборки Webpack, инициированной сохранением файла javascript этого компонента. Каждый раз, когда я перезагружаю страницу, на экране отображается второе изображение. Что вызывает такое поведение? Я приложу соответствующие части моего кода ниже. (Укладка больших желтых и белых компонентов выполнена для обеспечения конфиденциальности)

FeaturedProjectCard.js

 const template = document.createElement('template') template.innerHTML = `  lt;stylegt;  .bottomDivider {  position: absolute;  bottom: 0;  width: 75%;  height: 1px;  margin: 0;  background-color: white;  }  .container {  position: relative;  width: 1000px;  isolation: isolate;  }  .description {  border-radius: 10px;  padding: 25px;  color: white;  background-color: white;  }  .linksContainer {  display: flex;  }  .linksContainer gt; a {  width: 20px;  padding: 10px;  color: white;  transition: color 0.5s;  }  .linksContainer gt; a:first-child {  padding-left: 0;  }  .linksContainer gt; a:hover {  color: yellow;  }  .projDesc {  width: 50%;  display: flex;  flex-direction: column;  pointer-events: none;  }  .projDesc gt; * {  width: fit-content;  pointer-events: auto;  }  .projImage {  position: absolute;  top: 50%;  right: 0;  height: 300px;  transform: translateY(-50%);  background-color: yellow;  border-radius: 5px;  z-index: -1;  }  .projImage gt; img {  height: inherit;  border-radius: inherit;  filter: grayscale(100%);  -webkit-filter: grayscale(100%);  opacity: 0;  transition: opacity 0.5s, filter 0.5s, -webkit-filter 0.5s;  }  .projImage gt; img:hover {  opacity: 1;  filter: grayscale(0%);  -webkit-filter: grayscale(0%);  }  .projectHeading {  margin: 10px 0;  color: yellow;  font-size: 12pt;  }  .projectName {  display: inline;  margin: 15px 0;  font-size: 21pt;  color: white;  }  .softwareContainer {  margin: 25px 0 10px 0;  color: white;  }  .softwareContainer gt; span:not(:last-child) {  padding-right: 30px;  }  lt;/stylegt;  lt;div class="container"gt;  lt;div class="projDesc"gt;  lt;span class="projectHeading"gt;Recent Projectlt;/spangt;  lt;span class="projectName"gt;lt;/spangt;  lt;div class="description"gt;lt;/divgt;  lt;div class="softwareContainer"gt;lt;/divgt;  lt;div class="linksContainer"gt;lt;/divgt;  lt;/divgt;  lt;div class="projImage"gt;  lt;imggt;  lt;/divgt;  lt;p class="bottomDivider"gt;lt;/pgt;  lt;/divgt; `  class FeaturedProjectCard extends HTMLElement {   constructor() {  super()    //Enable shadow DOM  this.attachShadow({ mode: 'open' })  this.shadowRoot.appendChild(template.content.cloneNode(true))    //Insert project image  this.shadowRoot.querySelector('img').src = this.getAttribute('image')   //Insert project heading  this.shadowRoot.querySelector('.projectName').textContent = this.getAttribute('heading')    //Insert project description  this.shadowRoot.querySelector('.description').innerHTML = //Get description text    //Insert software array  const softwareItems = //Get items  if(softwareItems) {  const softwareContainer = this.shadowRoot.querySelector('.softwareContainer')  for(let i = 0; i lt; softwareItems.length; i  )  softwareContainer.innerHTML  = `lt;spangt;${softwareItems[i].textContent}lt;/spangt;`  }   //Insert link array  const links = //Get links  if(links) {  const linksContainer = this.shadowRoot.querySelector('.linksContainer')  for(let i = 0; i lt; links.length; i  ) {  linksContainer.innerHTML  = `lt;a target="_blank" href="${links[i].getAttribute('target')}"gt;${links[i].innerHTML}lt;/agt;`  }  }   //Handle reverse attribute  if(this.hasAttribute('reversed')) {  this.shadowRoot.querySelector('.bottomDivider').style.right = 0;  this.shadowRoot.lastElementChild.style.height = `${this.shadowRoot.lastElementChild.offsetHeight}px`  const projDesc = this.shadowRoot.querySelector('.projDesc')  const projImage = this.shadowRoot.querySelector('.projImage')  const softwareItems = Array.from(this.shadowRoot.querySelectorAll('.softwareContainer gt; span'))  projDesc.style.position = 'absolute'  projDesc.style.right = '0'  projDesc.style.left = 'auto'  projImage.style.left = '0'  projImage.style.right = 'auto'  projDesc.style.alignItems = 'flex-end'  softwareItems.splice(0, 1)[0].style.padding = '0'  const padding = getComputedStyle(softwareItems[0]).getPropertyValue('padding-right')  softwareItems.forEach(item =gt; {  item.style.paddingLeft = padding  item.style.paddingRight = '0'  })  }   //Clear markup  this.innerHTML = null  }  }  window.customElements.define('featured-project-card', FeaturedProjectCard)  

Я использую эти компоненты в HTML со следующим синтаксисом.

lt;featured-project-card class="" reversed image="/something.png" heading="Heading"gt;

Я думаю, что основной причиной такого поведения является включение необязательного атрибута «обратный». На другие компоненты, которые не используют этот атрибут, эта проблема не влияет, так div.projDesc как имеет position: static для этих экземпляров. Это позволяет div.container изменять размер. На этих изображениях показан единственный компонент, в котором используется этот атрибут. Я закончу этот пост одним окончательным изображением компонента без атрибута «обратный» для справки. По сути, я добиваюсь обратного эффекта, задавая div.projDesc свойства position , right , и left absolute , 0 , и auto соответственно. Следовательно, мне пришлось установить div.container высоту, равную той, какой она была до этих изменений. В противном случае элемент не будет иметь правильного размера, так как position: absolute используется на единственном дочернем элементе с position: static Я использовал сервер ResizeObserver, чтобы проверить, не изменял ли div.projDesc он размер сам по себе более одного раза, и это действительно было так. Чтобы завершить, «перевернутый» div.projDesc странно изменяет размер (вероятно, из-за того, как обрабатывается атрибут «обратный»), в отличие от не «перевернутых» элементов. Я знаю, что может быть более простой способ решить эту проблему, и я открыт для предложений, однако я хотел бы определить источник такого поведения в надежде лучше понять нюансы HTML, CSS и JS. Я более чем счастлив разъяснить себя любому, кто готов протянуть руку помощи. Заранее благодарю вас!

Не обращенный компонент Пример Изображения 3

Комментарии:

1. Удалите все абсолютные позиции в вашем компоненте, они вам здесь не нужны. Это приведет только к ошибкам (как вы описали) Также для «обратного» абсолютного позиционирования не требуется. Не используйте lt;pgt; для создания границ, используйте границу или :после из CSS. Используйте flexbox (или сетку), чтобы получить свой макет.

2. Спасибо за комментарии! В настоящее время я нахожусь в процессе преобразования в гибкий макет. Я думаю, что это значительно сократит мой код. Я совершенно забыл о псевдоэлементах, которые, думаю, я тоже включу. Еще раз спасибо, что протянули мне руку помощи.