ฉันพยายามใช้ตัวแปร CSS ในการสืบค้นสื่อ แต่ไม่ได้ผล
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
ฉันพยายามใช้ตัวแปร CSS ในการสืบค้นสื่อ แต่ไม่ได้ผล
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
คำตอบ:
จากสเป็ค ,
var()
ฟังก์ชั่นสามารถนำมาใช้ในสถานที่ของส่วนหนึ่งของค่าใด ๆ ในทรัพย์สินใด ๆ เกี่ยวกับองค์ประกอบvar()
ฟังก์ชั่นไม่สามารถนำมาใช้เป็นชื่อคุณสมบัติเตอร์หรือสิ่งอื่นนอกเหนือจากค่าทรัพย์สิน (การทำเช่นนี้มักจะสร้างไวยากรณ์ที่ไม่ถูกต้องหรือมิฉะนั้นค่าที่ความหมายไม่มีส่วนเกี่ยวข้องกับตัวแปร)
ไม่คุณไม่สามารถใช้ในแบบสอบถามสื่อได้
และนั่นก็สมเหตุสมผล เนื่องจากคุณสามารถตั้งค่า--mobile-breakpoint
เช่นเป็น:root
นั่นคือ<html>
องค์ประกอบและจากนั้นจะสืบทอดไปยังองค์ประกอบอื่น ๆ แต่แบบสอบถามสื่อไม่ใช่องค์ประกอบไม่ได้รับการสืบทอดมา<html>
จึงไม่สามารถทำงานได้
นี่ไม่ใช่สิ่งที่ตัวแปร CSS พยายามทำให้สำเร็จ คุณสามารถใช้ตัวประมวลผลล่วงหน้า CSS แทนได้
ตามที่Oriol ได้ตอบไว้ปัจจุบันตัวแปร CSS ระดับ 1 var()
ไม่สามารถใช้ในการสืบค้นสื่อได้ อย่างไรก็ตามมีความคืบหน้าล่าสุดที่จะแก้ไขปัญหานี้ ในอีกไม่กี่ปีหลังจากCSS Environment Variables Module Level 1 ได้รับการปรับมาตรฐานและนำไปใช้แล้วเราจะสามารถใช้env()
ตัวแปรในการสืบค้นสื่อในเบราว์เซอร์สมัยใหม่ทั้งหมดได้
หากคุณอ่านข้อกำหนดและมีข้อกังวลหรือหากคุณต้องการแสดงความสนับสนุนสำหรับกรณีการใช้งานแบบสอบถามสื่อคุณยังสามารถทำได้ในGitHub w3c / csswg-drafts # 1693หรือในปัญหา CSS GitHub ที่ขึ้นต้นด้วย“ [ CSS-env-1]”
คำตอบเดิม2017/11/09 : เมื่อเร็ว ๆ นี้คณะทำงาน CSS ตัดสินใจว่าตัวแปร CSS ระดับ 2 จะให้การสนับสนุนผู้ใช้กำหนดตัวแปรสภาพแวดล้อมการใช้env()
และพวกเขาจะพยายามที่จะทำให้พวกเขาถูกต้องในคำสั่งสื่อ กลุ่มแก้ไขปัญหานี้หลังจากที่ Apple เสนอคุณสมบัติตัวแทนผู้ใช้มาตรฐานเป็นครั้งแรกก่อนการประกาศอย่างเป็นทางการของ iPhone X ในเดือนกันยายน 2017 (ดูWebKit:“ การออกแบบเว็บไซต์สำหรับ iPhone X” โดย Timothy Horton ) จากนั้นตัวแทนของเบราว์เซอร์อื่น ๆ ก็เห็นด้วยว่าโดยทั่วไปแล้วพวกเขาจะมีประโยชน์ในอุปกรณ์ต่างๆเช่นจอโทรทัศน์และการพิมพ์หมึกที่มีขอบตก ( env()
เคยเรียกconstant()
แต่ตอนนี้เลิกใช้แล้ว คุณอาจยังคงเห็นบทความที่อ้างถึงชื่อเก่าเช่นบทความนี้โดย Peter-Paul Koch ) หลังจากผ่านไปหลายสัปดาห์Cameron McCormack จาก Mozilla ก็ตระหนักว่าตัวแปรสภาพแวดล้อมเหล่านี้สามารถใช้งานได้ในการสืบค้นของสื่อและTab Atkins, Jr. จากนั้น Google ได้ตระหนักว่าตัวแปรสภาพแวดล้อมที่ผู้ใช้กำหนดเองจะมีประโยชน์อย่างยิ่งในฐานะตัวแปรรูทส่วนกลางที่ไม่สามารถเขียนทับได้ซึ่งใช้ในการสืบค้นสื่อ ตอนนี้Dean“ Dino” Jackson จาก Apple จะเข้าร่วม Atkinsในการแก้ไขระดับ 2
คุณสามารถสมัครรับการปรับปรุงในเรื่องนี้ในw3c/csswg-drafts
GitHub รุ่น # (สำหรับรายละเอียดทางประวัติศาสตร์ที่เกี่ยวข้องโดยเฉพาะให้ขยายบันทึกการประชุมที่ฝังอยู่ในมติของ CSSWG Meeting Botและค้นหา "MQ" ซึ่งย่อมาจาก "media queries")
ฉันวางแผนที่จะอัปเดตคำถามนี้ในอนาคตเมื่อมีการพัฒนาเพิ่มเติม อนาคตเป็นเรื่องที่น่าตื่นเต้น
อัปเดต2018-02-08 :
Safari Technology Preview 49ได้เพิ่มการรองรับสำหรับการแยกวิเคราะห์calc()
ในการสืบค้นสื่อซึ่งอาจเป็นการนำไปสู่การสนับสนุนenv()
เช่นกัน
ปรับปรุง2018/04/27 : ทีมโครเมี่ยมที่ Google env()
ได้ตัดสินใจที่จะเริ่มต้นการทำงานใน ในการตอบสนองแอตกินส์ได้เริ่มต้นในการระบุenv()
ในการแยกร่างมาตรฐานทางการที่: CSS ตัวแปรสภาพแวดล้อมโมดูลระดับ 1 (ดูความคิดเห็น GitHub ของเขาใน w3c / csswg-drafts # 1693และความคิดเห็นของเขาใน w3c / csswg-drafts # 1817 ) แบบร่างเรียกตัวแปรในการสืบค้นสื่อว่าเป็นกรณีการใช้งานที่ชัดเจน:
เนื่องจากตัวแปรสภาพแวดล้อมไม่ได้ขึ้นอยู่กับค่าของสิ่งที่ดึงมาจากองค์ประกอบใดองค์ประกอบหนึ่งจึงสามารถใช้ในสถานที่ที่ไม่มีองค์ประกอบที่ชัดเจนให้ดึงออกมาเช่นใน
@media
กฎซึ่งvar()
ฟังก์ชันจะไม่ถูกต้อง
หากคุณอ่านข้อกำหนดและมีข้อกังวลหรือหากคุณต้องการแสดงความสนับสนุนสำหรับกรณีการใช้งานแบบสอบถามสื่อคุณยังสามารถทำได้ในGitHub w3c / csswg-drafts # 1693หรือในปัญหา CSS GitHub ที่ขึ้นต้นด้วย“ [ CSS-env-1]”
อัปเดต2019-07-06 : ทำงานต่อไปตามข้อกำหนด GitHub issue # 2627และGitHub issue # 3578ใช้สำหรับตัวแปรสภาพแวดล้อมที่กำหนดเองในการสืบค้นสื่อ
สิ่งที่คุณทำได้คือ @media ค้นหาคำสั่ง: root!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
ใช้งานได้ทั้งหมดใน Chrome, Firefox และ Edge อย่างน้อยเวอร์ชันการผลิตล่าสุด ณ โพสต์นี้
var
ดังนั้นจึงสามารถใช้ในการคำนวณที่อื่นในส่วนcss
นี้ได้ก็ยังต้องใส่ "ค่าวิเศษ" (ที่นี่คือ 479px) ในสองตำแหน่ง: คิวรีสื่อและการประกาศ var
เห็นได้ชัดว่ามันเป็นไปไม่ได้ที่จะใช้ตัวแปร CSS ดั้งเดิมเช่นนั้น มันเป็นข้อ จำกัดอย่างหนึ่ง
วิธีที่ชาญฉลาดในการใช้คือการเปลี่ยนตัวแปรของคุณในแบบสอบถามสื่อเพื่อให้ส่งผลต่อสไตล์ของคุณทั้งหมด ผมขอแนะนำให้บทความนี้
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
postcss-media-variables
วิธีหนึ่งที่จะบรรลุสิ่งที่คุณต้องการใช้แพคเกจ NPM
หากคุณพอใจกับการใช้แพ็คเกจ npm คุณสามารถดู documentatoin ได้ที่นี่
ตัวอย่าง
/* input */
:root {
--min-width: 1000px;
--smallscreen: 480px;
}
@media (min-width: var(--min-width)) {}
@media (max-width: calc(var(--min-width) - 1px)) {}
@custom-media --small-device (max-width: var(--smallscreen));
@media (--small-device) {}
เนื่องจากคุณสามารถอ่านคำตอบอื่น ๆ ได้ แต่ก็ยังไม่สามารถทำได้
มีคนพูดถึงตัวแปรสภาพแวดล้อมที่กำหนดเอง (คล้ายกับตัวแปร css ที่กำหนดเองenv()
แทนที่จะเป็นvar()
) และหลักการก็ฟังดูดีแม้ว่าจะยังมี 2 ประเด็นหลัก:
คุณสามารถใช้ JavaScript เพื่อเปลี่ยนค่าของคิวรีสื่อและตั้งเป็นค่าของตัวแปร css
// get value of css variable
getComputedStyle(document.documentElement).getPropertyValue('--mobile-breakpoint'); // '642px'
// search for media rule
var mediaRule = document.styleSheets[i].cssRules[j];
// update media rule
mediaRule.media.mediaText = '..'
ฉันเขียนสคริปต์เล็ก ๆ ซึ่งคุณสามารถรวมไว้ในเพจของคุณได้ แทนที่กฎสื่อทุกกฎด้วยค่าของ1px
ตัวแปร css --replace-media-1px
กฎที่มีค่า2px
ด้วย--replace-media-2px
และอื่น ๆ งานนี้สำหรับคำสั่งสื่อwith
, min-width
, max-width
, height
, min-height
และแม้ว่าพวกเขาจะเชื่อมต่อโดยใช้max-height
and
JavaScript:
function* visitCssRule(cssRule) {
// visit imported stylesheet
if (cssRule.type == cssRule.IMPORT_RULE)
yield* visitStyleSheet(cssRule.styleSheet);
// yield media rule
if (cssRule.type == cssRule.MEDIA_RULE)
yield cssRule;
}
function* visitStyleSheet(styleSheet) {
try {
// visit every rule in the stylesheet
var cssRules = styleSheet.cssRules;
for (var i = 0, cssRule; cssRule = cssRules[i]; i++)
yield* visitCssRule(cssRule);
} catch (ignored) {}
}
function* findAllMediaRules() {
// visit all stylesheets
var styleSheets = document.styleSheets;
for (var i = 0, styleSheet; styleSheet = styleSheets[i]; i++)
yield* visitStyleSheet(styleSheet);
}
// collect all media rules
const mediaRules = Array.from(findAllMediaRules());
// read replacement values
var style = getComputedStyle(document.documentElement);
var replacements = [];
for (var k = 1, value; value = style.getPropertyValue('--replace-media-' + k + 'px'); k++)
replacements.push(value);
// update media rules
for (var i = 0, mediaRule; mediaRule = mediaRules[i]; i++) {
for (var k = 0; k < replacements.length; k++) {
var regex = RegExp('\\((width|min-width|max-width|height|min-height|max-height): ' + (k+1) + 'px\\)', 'g');
var replacement = '($1: ' + replacements[k] + ')';
mediaRule.media.mediaText = mediaRule.media.mediaText.replace(regex, replacement);
}
}
CSS:
:root {
--mobile-breakpoint: 642px;
--replace-media-1px: var(--mobile-breakpoint);
--replace-media-2px: ...;
}
@media (max-width: 1px) { /* replaced by 642px */
...
}
@media (max-width: 2px) {
...
}