programing

미디어 쿼리가 화면 대신 div 요소를 기준으로 크기를 조정할 수 있습니까?

javamemo 2023. 7. 29. 08:05
반응형

미디어 쿼리가 화면 대신 div 요소를 기준으로 크기를 조정할 수 있습니까?

미디어 쿼리를 사용하여 크기를 기준으로 요소의 크기를 조정하고 싶습니다.div그들이 있는 요소.를 화면크사수없습다니로 할 수 .div웹 페이지 내에서 위젯처럼 사용되며 크기가 다를 수 있습니다.

예, CSS 컨테이너 쿼리를 찾고 있습니다.CSS 격납 모듈은 이 기능을 자세히 설명하는 사양입니다.여기에서 브라우저 지원을 확인할 수 있습니다.

제안서, 개념 증명, 토론 및 더 광범위한 웹 개발자 커뮤니티의 기타 기여를 포함하여 10년간의 작업에 대해 더 자세히 읽을 수 있습니다!이러한 기능의 작동 및 사용 방법에 대한 자세한 내용은 미리암 수잔의 광범위한 설명자참조하십시오.


미디어 쿼리는 페이지의 요소를 기반으로 작동하지 않습니다.장치 또는 미디어 유형을 기반으로 작동하도록 설계되었으므로 미디어 쿼리라고 합니다. , 및 기타 차원 기반 미디어 기능은 모두 화면 기반 미디어에서 뷰포트 또는 장치 화면의 치수를 나타냅니다.페이지의 특정 요소를 참조하는 데 사용할 수 없습니다.

div페이지의 요소, 당신은 자바스크립트를 사용하여 그 크기의 변화를 관찰해야 할 것입니다.div미디어 쿼리 대신 요소를 사용할 수 있습니다.

또는 Flexbox와 같은 이 답변의 원본 게시 이후 도입된 보다 현대적인 레이아웃 기법과 사용자 지정 속성과 같은 표준을 사용하면 결국 미디어나 요소 쿼리가 필요하지 않을 수 있습니다.Jave는 예를 들어 설명합니다.

저는 이 목표를 달성하기 위해 자바스크립트 심을 만들었습니다.원하는 경우 PoC(Proof of Concept)이지만 초기 버전이며 아직 작업이 필요하므로 주의하십시오.

https://github.com/marcj/css-element-queries

컨테이너 쿼리 데모

먼저 그리드를 설정합니다.

<div class="grid">

  <div class="post">
    <div class="post--content">
      <h2>Lorem, ipsum.</h2>
      <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Unde, sequi!</p>
      <button>Lorem.</button>
    </div>
  </div>

  <div class="post">
    <div class="post--content">
      <h2>Pariatur, doloremque.</h2>
      <p>Suscipit, ex porro delectus officia saepe facere nisi odio architecto.</p>
      <button>Animi!</button>
    </div>
  </div>

  ... more posts
</div>

CSS를 사용하여 동일한 요소의 특정 크기를 지정합니다.

.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.post {
  container-type: inline-size;
  min-width: 0; /* important so the grid can collapse */
}
.post:nth-child(1) {
  grid-column: span 7;
}
.post:nth-child(2) {
  grid-column: span 5;
}
.post:nth-child(3) {
  grid-column: span 8;
}
...

갓챠 #1

꼭 신청하세요.

.post {
  container-type: inline-size;
}

무엇이 당신의 컨테이너가 될 것인가에.

갓챠 #2

변경할 수 ..post이 예에서 컨테이너 쿼리를 사용하는 div. 컨테이너의 크기가 변경될 때 컨테이너 내부의 내용을 변경할 수 있습니다.

이제, 여러분은 장난칠 준비가 되어 있어야 합니다.

@container (min-width: 250px) {
  .post--content {
    background: hotpink;
  }
}
@container (min-width: 350px) {
  .post--content {
    background: blue;
  }
}

전체 데모:

* {
  box-sizing: border-box;
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.post {
  container-type: inline-size;
  min-width: 0;
}
.post:nth-child(1) {
  grid-column: span 7;
}
.post:nth-child(2) {
  grid-column: span 5;
}
.post:nth-child(3) {
  grid-column: span 8;
}
.post:nth-child(4) {
  grid-column: span 4;
}
.post:nth-child(5) {
  grid-column: span 3;
}
.post:nth-child(6) {
  grid-column: span 9;
}
.post:nth-child(7) {
  grid-column: span 10;
}

.post--content {
  overflow: hidden;
  padding: 20px;
  height: 100%;
}

@container (min-width: 250px) {
  .post--content {
    background: hotpink;
  }
}
@container (min-width: 350px) {
  .post--content {
    background: blue;
  }
}
@container (min-width: 450px) {
  .post--content {
    background: red;
    text-align: right;
  }
  
  .post--content button{
    background: green;
    color: #fff;
    font-weight: bold;
    border: none;
  }
}
@container (min-width: 550px) {
  .post--content {
    background: orange;
    text-align: right;
    font-family: sans-serif;
  }
  .post--content p{
    font-size: 1.4em;
  }
}
@container (min-width: 650px) {
  .post--content {
    background: lime;
    text-align: right;
  }
  
  .post--content button{
    border-radius: 10px;
    padding: 20px;
  }
}
<div class="grid">

  <div class="post">
    <div class="post--content">
      <h2>Lorem, ipsum.</h2>
      <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Unde, sequi!</p>
      <button>Lorem.</button>
    </div>
  </div>

  <div class="post">
    <div class="post--content">
      <h2>Pariatur, doloremque.</h2>
      <p>Suscipit, ex porro delectus officia saepe facere nisi odio architecto.</p>
      <button>Animi!</button>
    </div>
  </div>

  <div class="post">
    <div class="post--content">
      <h2>Voluptates, est.</h2>
      <p>Est doloremque, culpa illo praesentium laboriosam omnis dolores ducimus veniam!</p>
      <button>Distinctio.</button>
    </div>
  </div>

  <div class="post">
    <div class="post--content">
      <h2>Ea, temporibus.</h2>
      <p>Quibusdam doloremque ipsa, laudantium ad in doloribus hic? Commodi, libero?</p>
      <button>Culpa?</button>
    </div>
  </div>

  <div class="post">
    <div class="post--content">
      <h2>Optio, nesciunt.</h2>
      <p>A laborum facilis ex autem tenetur magnam officia aliquam aut!</p>
      <button>Illum.</button>
    </div>
  </div>
  
  <div class="post">
    <div class="post--content">
      <h2>Optio, nesciunt.</h2>
      <p>A laborum facilis ex autem tenetur magnam officia aliquam aut!</p>
      <button>Illum.</button>
    </div>
  </div>
  
  <div class="post">
    <div class="post--content">
      <h2>Optio, nesciunt.</h2>
      <p>A laborum facilis ex autem tenetur magnam officia aliquam aut!</p>
      <button>Illum.</button>
    </div>
  </div>
  
  <div class="post">
    <div class="post--content">
      <h2>Optio, nesciunt.</h2>
      <p>A laborum facilis ex autem tenetur magnam officia aliquam aut!</p>
      <button>Illum.</button>
    </div>
  </div>
  
  <div class="post">
    <div class="post--content">
      <h2>Optio, nesciunt.</h2>
      <p>A laborum facilis ex autem tenetur magnam officia aliquam aut!</p>
      <button>Illum.</button>
    </div>
  </div>
</div>

참조:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries

그리고 아직 속도를 지원하지 않는 브라우저를 지원하기 위한 폴리필이 있습니다.

https://github.com/GoogleChromeLabs/container-query-polyfill

여기에 이에 대한 간단한 개요 비디오가 있습니다.

https://www.youtube.com/watch?v=gCNMyYr7F6w

이제 크롬으로 배송되었습니다(2022년 9월 5일).

https://caniuse.com/css-container-queries

원답

레이아웃의 관점에서, 그것은 현대적인 기술을 사용하여 가능합니다.

그것은 헤이든 피커링에 의해 지어졌습니다.그는 여기에서 프로세스를 자세히 설명합니다. http://www.heydonworks.com/article/the-flexbox-holy-albatross

Chris Coyier가 그것을 집어 들고 여기서 데모를 통해 작업합니다. https://css-tricks.com/putting-the-flexbox-albatross-to-real-use/

이 문제를 다시 설명하자면, 아래에는 각각 레이블이 지정된 3개의 오렌지 디브로 구성된 동일한 구성 요소의 3개가 표시됩니다.a,b그리고.c.

두 번째 두 블록은 수평 공간에 제한되어 있기 때문에 수직으로 표시되고, 위쪽 구성 요소 세 블록은 수평으로 배치됩니다.

은 합다사니용을 합니다.flex-basis이 효과를 생성할 CSS 속성 및 CSS 변수.

Final example

.panel{
  display: flex;
  flex-wrap: wrap;
  border: 1px solid #f00;
  $breakpoint: 600px;
  --multiplier: calc( #{$breakpoint} - 100%);
  .element{
    min-width: 33%;
    max-width: 100%;
    flex-grow: 1;
    flex-basis: calc( var(--multiplier) * 999 );
  }
}

데모

헤이돈의 글은 1000단어로 자세히 설명하고 있는데, 꼭 읽어보길 권합니다.

iframe 내부의 미디어 쿼리는 요소 쿼리로 작동할 수 있습니다.성공적으로 구현했습니다.이 아이디어는 최근 Zurb의 Response Ads에 대한 게시물에서 나왔습니다.Javascript가 없습니다!

@BoltClock이 수락된 답변에 기록한 것처럼 CSS만으로는 현재 이것이 불가능하지만 JavaScript를 사용하여 해결할 수 있습니다.

저는 이러한 문제를 해결하기 위해 컨테이너 쿼리(일명 요소 쿼리) 폴리필을 만들었습니다.다른 스크립트와 조금 다르게 작동하므로 요소의 HTML 코드를 편집할 필요가 없습니다.스크립트를 포함하여 CSS에 다음과 같이 사용하기만 하면 됩니다.

.element:container(width > 99px) {
    /* If its container is at least 100px wide */
}

https://github.com/ausi/cq-prolyfill

저는 몇 년 전에 같은 문제에 부딪혔고 제 작업을 돕기 위해 플러그인 개발에 자금을 지원했습니다.다른 사람들도 혜택을 볼 수 있도록 플러그인을 오픈 소스로 출시했으며, Github: https://github.com/eqcss/eqcss 에서 다운로드할 수 있습니다.

페이지의 요소에 대해 알 수 있는 내용에 따라 다양한 반응 스타일을 적용할 수 있는 몇 가지 방법이 있습니다.다음은 EQCSS 플러그인을 통해 CSS로 작성할 수 있는 몇 가지 요소 쿼리입니다.

@element 'div' and (condition) {
  $this {
    /* Do something to the 'div' that meets the condition */
  }
  .other {
    /* Also apply this CSS to .other when 'div' meets this condition */
  }
}

그렇다면 EQCSS의 대응적인 스타일에는 어떤 조건이 지원됩니까?

가중치 쿼리

  • 는 의최폭으로 표시됩니다.px
  • 는 의최폭으로 표시됩니다.%
  • 는 의최폭입니다.px
  • 는 의최폭입니다.%

높이 쿼리

  • 의최소높의 최소 px
  • 의최소높의 최소 %
  • 는 의최고높입니다.px
  • 는 의최고높입니다.%

카운트 쿼리

  • 최소한도의 사람들
  • 최대 한도액
  • 가는 선
  • 최대선
  • 어린 아이들
  • 최대 자녀

특수 선택기

EQCSS 요소 쿼리 내에서 스타일을 보다 구체적으로 적용할 수 있는 세 가지 특수 선택기를 사용할 수도 있습니다.

  • $this리와쿼치일는소
  • $parent으)로 표시됩니다.
  • $root, (문서의루요소트,),<html>)

요소 쿼리를 사용하면 개별적으로 반응하는 설계 모듈로 레이아웃을 구성할 수 있으며, 각 모듈은 페이지에 표시되는 방식에 대한 약간의 '자체 인식'을 가집니다.

EQCSS를 사용하면 150px 너비에서 최대 1000px 너비까지 보기 좋게 하나의 위젯을 설계할 수 있습니다. 그러면 템플릿을 사용하여 모든 페이지의 사이드바에 위젯을 안전하게 배치할 수 있습니다.

그 질문은 매우 모호합니다.BoltClock이 말했듯이 미디어 쿼리는 장치의 치수만 알고 있습니다.그러나 미디어 쿼리를 디센더 선택기와 함께 사용하여 조정을 수행할 수 있습니다.

.wide_container { width: 50em }

.narrow_container { width: 20em }

.my_element { border: 1px solid }

@media (max-width: 30em) {
    .wide_container .my_element {
        color: blue;
    }

    .narrow_container .my_element {
        color: red;
    }
}

@media (max-width: 50em) {
    .wide_container .my_element {
        color: orange;
    }

    .narrow_container .my_element {
        color: green;
    }
}

유일한 해결책은 JS입니다.

제가 생각할 수 있는 유일한 방법은 당신이 순수하게 CSS로 원하는 것을 달성할 수 있는 것입니다. 당신의 위젯에 유동적인 용기를 사용하는 것입니다.컨테이너 너비가 화면의 백분율인 경우 미디어 쿼리를 사용하여 컨테이너 너비에 따라 스타일을 지정할 수 있습니다. 이제 각 화면의 치수에 대해 컨테이너의 치수가 무엇인지 알게 됩니다.예를 들어, 컨테이너를 화면 너비의 50%로 만들기로 결정했다고 가정해 보겠습니다.그러면 1200px의 화면 너비에 대해 당신은 당신의 컨테이너가 600px라는 것을 압니다.

.myContainer {
  width: 50%;
}

/* you know know that your container is 600px 
 * so you style accordingly
*/
@media (max-width: 1200px) { 
  /* your css for 600px container */
}

ResizeObserver API를 사용할 수 있습니다.아직 초기 단계이기 때문에 아직 모든 브라우저에서 지원되지는 않습니다(그러나 이에 도움이 될 수 있는 폴리필이 여러 개 있습니다).

이 API를 사용하면 DOM 요소의 크기를 조정할 때 이벤트 수신기를 연결할 수 있습니다.

데모 1 - 데모 2

미디어 질의도 생각하고 있었지만, 다음과 같은 것을 발견했습니다.

그냥 포장지 만들기<div>의 백분율 값으로padding-bottom다음과 같이:

div {
  width: 100%;
  padding-bottom: 75%;
  background:gold; /** <-- For the demo **/
}
<div></div>

결과는 다음과 같습니다.<div>높이가 컨테이너 폭의 75%에 해당합니다(4:3 가로 세로 비율).

이 기술은 미디어 쿼리 및 페이지 레이아웃에 대한 약간의 특별한 지식과 결합하여 훨씬 더 세분화된 제어를 할 수 있습니다.

제가 필요로 하는 것은 충분합니다.당신이 필요로 하는 것도 충분할 겁니다.

@Djave는 이런 종류의 질문에 대해 언급했지만 이해하기 어려웠습니다.저는 결국 다음과 같은 해결책을 찾았습니다. HTML이 있다고 가정해 보십시오.

div {
    width: 50%;
    container-type: inline-size;
}
span {
    color: red;
}
@container (inline-size > 150px) {
    span {
        color: green;
    }        
}
<div>
    <span>Text</span>
</div>

<div>
    <span>Text</span>
</div>

만약 우리가 내부에 div 컨테이너와 스팬을 가지고 있고, 당신이 div가 더 크거나 작을 때 스팬을 변경하고 싶다면, 당신은 div(컨테이너)에 다음의 css 속성을 부여합니다.container-type: inline-size;그런 다음 미디어 쿼리를 추가합니다.전체 CSS는 다음과 같습니다.

div {
    width: 50%;
    container-type: inline-size;
}
span {
    color: red;
}
@container (inline-size > 150px) {
    span {
        color: green;
    }        
}

저는 div의 최대 너비를 설정하여 수행했기 때문에 작은 위젯의 경우 영향을 받지 않으며 최대 너비 스타일로 인해 큰 위젯의 크기가 조정됩니다.

  // assuming your widget class is "widget"
  .widget {
    max-width: 100%;
    height: auto;
  }

언급URL : https://stackoverflow.com/questions/12251750/can-media-queries-resize-based-on-a-div-element-instead-of-the-screen

반응형