Dapatkah pertanyaan media mengubah ukuran berdasarkan elemen div, bukan pada layar?

317

Saya ingin menggunakan kueri media untuk mengubah ukuran elemen berdasarkan ukuran divelemen yang digunakan. Saya tidak bisa menggunakan ukuran layar karena divhanya digunakan seperti widget di dalam halaman web, dan ukurannya dapat bervariasi.

Memperbarui

Sepertinya ada pekerjaan yang sedang dilakukan sekarang: https://github.com/ResponsiveImagesCG/cq-demos

Yazz.com
sumber
2
Saya pikir pertanyaan ini terlalu singkat untuk mendapatkan jawaban yang bagus. Mungkin Anda bisa memberikan contoh tentang apa yang Anda coba lakukan? Mungkin menggunakan jsfiddle.net untuk menguji ide Anda dan membiarkan orang lain membantu Anda? Secara umum seharusnya tidak ada alasan untuk apa yang Anda minta, Anda harus dapat mencapai hasil yang diinginkan dengan CSS tanpa permintaan media. Anda dapat menggunakan dimensi persentase dan ems untuk font untuk skala elemen bersarang. Tapi mungkin saya hanya perlu melihat contoh kode html Anda dan css untuk lebih mengerti?
BenSwayne
1
Bagaimana ukuran widget Anda bervariasi? Apakah lebar halaman Anda tetap (misalnya 960px) dengan viewports di atas 1024px atau keduanya lancar? Itu tidak jelas dan akan berguna untuk diketahui
FelipeAls
3
Sebenarnya, proyek saya saat ini memiliki situasi yang sama. Daftar item ditampilkan dalam tata letak 2-col untuk perangkat lebar atau tata letak 1-col untuk perangkat sempit, tetapi satu item akan berada dalam tata letak 1-col tidak peduli apa pun. Baik daftar dan versi tunggal memiliki 2 elemen yang cukup lebar dan pendek. Pada perangkat yang lebih luas, 2 elemen terlihat terbaik berdampingan. Idealnya, perangkat sempit: selalu vertikal, perangkat lebar: selalu paralel, di suatu tempat antara (tergantung 1 atau 2-col): vertikal atau paralel. Mengambang adalah solusi sederhana, tetapi lebarnya perlu bervariasi tergantung pada tata letaknya.
cimmanon
1
KURANG akan dikompilasi ke CSS, jadi jika CSS tidak mendukungnya, KURANG tidak dapat membantu Anda juga.
jvannistelrooy
3
Tautan tidak lagi aktif?
mix3d

Jawaban:

228

Tidak, kueri media tidak dirancang untuk berfungsi berdasarkan elemen di halaman. Mereka dirancang untuk bekerja berdasarkan perangkat atau jenis media (karenanya mengapa mereka disebut pertanyaan media ). width,, heightdan fitur media berbasis dimensi lainnya semuanya mengacu pada dimensi viewport atau layar perangkat dalam media berbasis layar. Mereka tidak dapat digunakan untuk merujuk ke elemen tertentu pada halaman.

Jika Anda perlu menerapkan gaya tergantung pada ukuran divelemen tertentu pada halaman Anda, Anda harus menggunakan JavaScript untuk mengamati perubahan dalam ukuran divelemen itu alih-alih permintaan media.

BoltClock
sumber
Saya mendengar tentang beberapa cara saya mungkin dapat menggunakan fungsi dengan pertanyaan media untuk mendapatkan ukuran dari elemen yang mengandung. Apakah ada cara saya bisa menggabungkan ini dengan permintaan media untuk mengubah ukuran elemen?
Yazz.com
1
Anda harus menggunakan JS untuk secara berkala mendapatkan lebar elemen Anda dan bereaksi sesuai (secara berkala = setiap detik atau lebih atau itu akan memperlambat beberapa browser; sesuai = dengan mengubah kelas mendesain widget Anda jika Anda menginginkan metode tercepat).
FelipeAls
6
Untuk mencapai ini secara asli, kita perlu @elementpertanyaan. W3C memiliki beberapa dokumentasi yang baik tentang sajak / alasan untuk @mediapertanyaan: w3.org/TR/css3-mediaqueries/#width (tautan ini membawa Anda ke bagian yang membahas lebar --- lebar jenis media, bukan elemen yang terkandung di dalamnya)
Dawson
Apakah ada peluang membuatnya berfungsi dalam email? Saya mencoba menerapkan penataan ponsel ke email saat div wadah terlalu kecil (yaitu ketika ruang email versi desktop Gmail terlalu kecil untuk masuk ke dalam desain 2 kolom, karena ukuran jendela misalnya).
Im
Ngomong-ngomong, @element queries akan menjadikan css bahasa lengkap Turing
Nick
117

Saya baru saja membuat shav javascript untuk mencapai tujuan ini. Lihatlah jika Anda mau, ini adalah konsep bukti, tapi berhati-hatilah: ini versi awal dan masih perlu beberapa pekerjaan.

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

Marc J. Schmidt
sumber
5
Terima kasih, saya terkesan
Yazz.com
5
Ini luar biasa. Dikombinasikan dengan bootstrap responsif, saya melakukan beberapa hal luar biasa yang tidak dapat dicapai hanya dengan @media. Sudah selesai dilakukan dengan baik.
Aku
3
Anda menyelamatkan hidup kita
Broda Noel
Wow, sangat menyenangkan, membuat segalanya lebih mudah
kaiser
Keren. Punya pertanyaan. Нow plugin mendeteksi ini - elemen apa yang memerlukan min-widthpembaruan atribut; apakah saya perlu menulis daftar kelas css secara manual, elemen yang ditandai, diaktifkan untuk min-widthpembaruan?
Alexander Goncharov
38

Kueri Media di dalam iframe dapat berfungsi sebagai kueri elemen. Saya sudah berhasil mengimplementasikan ini. Idenya datang dari posting terbaru tentang Iklan Responsif oleh Zurb. Tanpa Javascript!

haddnin
sumber
Saya pikir ini adalah solusi terbaik, karena, kueri media berfungsi dalam iframe.
emfi
25

Ini saat ini tidak dimungkinkan dengan CSS saja seperti yang ditulis oleh @BoltClock dalam jawaban yang diterima, tetapi Anda dapat mengatasinya dengan menggunakan JavaScript.

Saya membuat permintaan kontainer (alias permintaan elemen) prolyfill untuk menyelesaikan masalah semacam ini. Kerjanya sedikit berbeda dari skrip lain, jadi Anda tidak perlu mengedit kode HTML elemen Anda. Yang harus Anda lakukan adalah memasukkan skrip dan menggunakannya dalam CSS Anda seperti:

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

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

ausi
sumber
2
Penuh dengan JS. Tujuannya adalah untuk memiliki fungsi dalam CSS saja.
Hijau
13
Prolyfill (dan polyfill ) biasanya ditulis dalam JS untuk mengaktifkan fitur yang belum didukung oleh browser. Tujuan dari prolyfill adalah menjadi usang setelah fitur ini didukung dalam CSS.
ausi
3
@ius tidak disebutkan "CSS saja" dalam pertanyaan. Bagaimana Anda sampai pada kesimpulan itu?
ausi
1
@ius kecuali Anda tidak mungkin melakukannya dalam CSS sehingga menawarkan solusi di luar css sangat masuk akal. Jauh lebih baik daripada "tidak Anda tidak bisa" tidak berpikir;)
Wesley Smith
1
@ DelightedD0D setelah komentar saya, dia mengubah jawabannya dan saya memilih +1 untuk perubahan itu. Jawaban saat ini tidak masalah bagi saya karena mengatakan bahwa ini tidak mungkin hanya dengan CSS.
ius
17

Saya mengalami masalah yang sama beberapa tahun yang lalu dan mendanai pengembangan plugin untuk membantu saya dalam pekerjaan saya. Saya telah merilis plugin sebagai sumber terbuka sehingga orang lain dapat memperoleh manfaat darinya juga, dan Anda dapat mengambilnya di Github: https://github.com/eqcss/eqcss

Ada beberapa cara kita dapat menerapkan gaya responsif yang berbeda berdasarkan apa yang dapat kita ketahui tentang suatu elemen pada halaman. Berikut adalah beberapa pertanyaan elemen yang memungkinkan Anda menulis di CSS dengan plugin EQCSS:

@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 */
  }
}

Jadi kondisi apa yang didukung untuk gaya responsif dengan EQCSS?

Pertanyaan Berat

  • min-lebar px
  • min-lebar %
  • lebar maks px
  • lebar maks %

Kueri Tinggi

  • tinggi min px
  • tinggi min %
  • max-height in px
  • max-height in %

Hitung Kueri

  • min-karakter
  • maks-karakter
  • min-line
  • maks-baris
  • min-anak-anak
  • maks anak-anak

Selektor Khusus

Di dalam kueri elemen EQCSS Anda juga dapat menggunakan tiga penyeleksi khusus yang memungkinkan Anda untuk menerapkan gaya Anda secara lebih spesifik:

  • $this (elemen yang cocok dengan kueri)
  • $parent (elemen induk dari elemen yang cocok dengan kueri)
  • $root(elemen dasar dokumen, <html>)

Query elemen memungkinkan Anda untuk menyusun tata letak Anda dari modul desain yang responsif secara individual, masing-masing dengan sedikit 'kesadaran diri' tentang bagaimana mereka ditampilkan pada halaman.

Dengan EQCSS Anda dapat mendesain satu widget agar terlihat bagus dari lebar 150px hingga lebar 1000px, maka Anda dapat dengan percaya diri memasukkan widget itu ke bilah sisi mana pun di halaman mana pun menggunakan templat apa saja (di situs mana pun) dan

innovati
sumber
1
Proyek yang bagus! Saya melihat apa yang Anda buat
Yazz.com
@innovati Saya menemukan posting ini sambil mencari cara untuk melakukan query pada elemen. Sepertinya saya tidak bisa membuatnya bekerja. Maukah Anda melihat tiket saya? github.com/eqcss/eqcss/issues/96
Andrew Newby
10

Dari perspektif tata letak, dimungkinkan menggunakan teknik modern.

Itu dibuat (saya percaya) oleh Heydon Pickering. Dia merinci prosesnya di sini: http://www.heydonworks.com/article/the-flexbox-holy-albatross

Chris Coyier mengambilnya dan bekerja melalui demo di sini: https://css-tricks.com/putting-the-flexbox-albatross-to-real-use/

Untuk menyatakan kembali masalah ini, di bawah ini kita melihat 3 dari komponen yang sama, masing-masing terdiri dari tiga div oranye berlabel a, bdan c.

Blok dua yang kedua ditampilkan secara vertikal, karena terbatas pada ruang horizontal, sedangkan komponen atas 3 blok diletakkan secara horizontal.

Ini menggunakan flex-basisproperti CSS dan Variabel CSS untuk membuat efek ini.

Contoh terakhir

.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 );
  }
}

Demo

Artikel Heydon adalah 1000 kata yang menjelaskannya secara terperinci, dan saya sangat merekomendasikan untuk membacanya.

Djave
sumber
Hal itu dari artikel Heydon ... Terlihat dan bekerja seperti sulap! Terima kasih atas tanggapan Anda, luar biasa.
ptyskju
2
Ini adalah jawaban yang dicari semua orang pada pertanyaan ini
TehShrike
7

Pertanyaannya sangat kabur. Seperti yang dikatakan BoltClock, pertanyaan media hanya mengetahui dimensi perangkat. Namun, Anda dapat menggunakan kueri media dalam kombinasi dengan penyeleksi descender untuk melakukan penyesuaian.

.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;
    }
}

Satu-satunya solusi lain membutuhkan JS.

cimmanon
sumber
47
Pertanyaannya tidak kabur sama sekali. Sebenarnya, ini adalah pertanyaan yang sangat bagus. Sayangnya, tidak ada jawaban yang bagus untuk itu.
stepanian
2
Pemeliharaan yang mengerikan menggunakan pendekatan ini.
Totty.js
4

Satu-satunya cara saya bisa berpikir bahwa Anda dapat mencapai apa yang Anda inginkan murni dengan css, adalah dengan menggunakan wadah cairan untuk widget Anda. Jika lebar wadah Anda adalah persentase dari layar maka Anda dapat menggunakan kueri media untuk gaya tergantung pada lebar wadah Anda, karena sekarang Anda akan tahu untuk setiap dimensi layar berapa dimensi wadah Anda. Sebagai contoh, katakanlah Anda memutuskan untuk membuat wadah Anda 50% dari lebar layar. Kemudian untuk lebar layar 1200px Anda tahu bahwa wadah Anda adalah 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 */
}
Roumelis George
sumber
Tidak, itu terlihat jelek di layar. Ukuran layar berubah lebih cepat, tetapi elemen muncul di layar nanti dan lebih kecil.
Hijau
3

Saya juga memikirkan pertanyaan media, tetapi kemudian saya menemukan ini:

Cukup buat pembungkus <div>dengan nilai persentase untuk padding-bottom, seperti ini:

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

Ini akan menghasilkan <div>dengan tinggi sama dengan 75% dari lebar wadahnya (rasio aspek 4: 3).

Teknik ini juga dapat digabungkan dengan pertanyaan media dan sedikit pengetahuan khusus tentang tata letak halaman untuk kontrol yang lebih halus.

Cukup untuk kebutuhan saya. Yang mungkin cukup untuk kebutuhan Anda juga.

Hendy Irawan
sumber
2

Anda dapat menggunakan API ResizeObserver . Ini masih dalam masa awal sehingga belum didukung oleh semua browser (tetapi ada beberapa polyfill yang dapat membantu Anda dengan itu).

Pada dasarnya API ini memungkinkan Anda untuk melampirkan pendengar acara ke ukuran elemen DOM.

Demo 1 - Demo 2

José Salgado
sumber
Ada polyfill untuk spesifikasi rancangan. github.com/juggle/resize-observer
Trevor Karjanis
Artikel Heydon memberikan contoh implementasi ini. Cari "ResizeObserver" di halaman: heydonworks.com/article/the-flexbox-holy-albatross
Gabe Rogan
0

Untuk saya, saya melakukannya dengan mengatur lebar maksimum div, maka untuk widget kecil tidak akan terpengaruh dan widget besar diubah ukurannya karena gaya max-width.

  // assuming your widget class is "widget"
  .widget {
    max-width: 100%;
    height: auto;
  }
Jacky Choo
sumber
Pertanyaan menyebutkan bahwa ukuran widget mungkin bervariasi, pengaturan lebar maks tidak akan mengubah ukuran widget ketika wadahnya lebar. .widgethanya sampel sebagai kelas untuk widget div.
Jacky Choo