Vấn đề về kiểu dáng của các phần tử biểu mẫu. Gửi biểu mẫu sau khi chọn tệp có thiết kế đầu vào

Khá nhiều bản sao của các nhà phát triển front-end đã bị hỏng do vấn đề tạo kiểu cho trường nhập liệu. Mấu chốt của vấn đề là đặc tả HTML không quy tắc nghiêm ngặt, thiết lập cách trình duyệt hiển thị phần tử này. Hơn nữa, không có thuộc tính nào cho đầu vào cho phép bạn thay đổi nó vẻ bề ngoài, bằng cách sử dụng Kiểu CSS bạn chỉ có thể thay đổi hình thức của đường viền và phông chữ của nó và sử dụng JavaScript, vì lý do bảo mật, bạn không thể mô phỏng nhấp chuột vào thành phần này, điều này sẽ gây ra cửa sổ hệ thốngđể chọn tệp *. Nhưng phải làm gì khi khách hàng muốn có một trang web responsive với hình thức cách điệu đẹp mắt mà không thể thiếu trường nhập liệu này?

* - tại thời điểm viết bài này, tôi vẫn chưa biết rằng trong tất cả các trình duyệt hiện đại, việc mô phỏng một cú nhấp chuột vào đầu vào sẽ hiển thị một cửa sổ chọn tệp hệ thống. Cảm ơn bạn rất nhiều vì liên kết đến một ví dụ hoạt động từ !

Các cách giải quyết vấn đề tạo kiểu trường Vì vấn đề này đã tồn tại (và nó đã tồn tại từ rất lâu), nên một số cách để giải quyết nó đã được tìm ra. Tổng cộng có năm trong số đó: Phương pháp số 1 (phổ biến nhất) Thuyết phục khách hàng rằng bạn có thể chấp nhận đầu vào tiêu chuẩn. Phương pháp số 2 Viết/sử dụng trình tải tệp làm sẵn trên một ứng dụng Flash/Java. Ví dụ: được sử dụng trên habrastorage.org Phương pháp số 3 (sẽ được thảo luận trong bài viết) Sử dụng CSS để “che giấu” đầu vào tiêu chuẩn, làm cho nó hoàn toàn trong suốt và đặt nó thay cho trường giả cách điệu, sao cho một cú nhấp chuột ở cái sau gây ra một cú nhấp chuột vào cái tiêu chuẩn và kết quả là, đã mở cửa sổ chọn tệp hệ thống Phương pháp số 4 mới! (sẽ được đề cập trong bài viết) Đặt một đầu vào trong suốt bên trong phần tử nhãn, cùng với các phần tử nội tuyến được tạo kiểu tùy ý (tất nhiên ngoại trừ đầu vào, nút, vùng chọn và vùng văn bản). Nhấp vào nhãn sẽ tự động dẫn đến nhấp vào trường ẩn để chọn tệp. Cảm ơn bạn vì Phương pháp số 5 mới! (sẽ được thảo luận trong bài viết) Sử dụng mô phỏng nhấp chuột vào đầu vào ẩn bằng JavaScript. Có, tính năng này đã hoạt động trên tất cả các trình duyệt hiện đại. Cảm ơn một lần nữa cho!
CẬP NHẬT: Chú ý, phương pháp này không áp dụng được cho trình duyệt Internet Explorer! Mặc dù tệp được chọn ở đầu vào ẩn nhưng khi biểu mẫu được gửi, giá trị của tệp sau sẽ được "đặt lại". Cảm ơn vì !

Tất nhiên, tất cả bốn phương pháp cuối cùng đều có nhược điểm. Một nhược điểm đáng kể của giải pháp Flash/Java là hoạt động của nó yêu cầu các plugin thích hợp, có thể không có sẵn trong trình duyệt của người dùng. Nhược điểm lớn của giải pháp “che giấu” là để triển khai nó, bạn cần phải sử dụng hack (điều này sẽ được thảo luận bên dưới), và cũng bởi vì nó sẽ vô nghĩa nếu không sử dụng JavaScript (xét cho cùng, bạn cần phải phân biệt bằng cách nào đó giữa “file not” đã chọn” trạng thái) và “tệp đã chọn” cho trường giả được cách điệu, điều này không thể thực hiện được chỉ với CSS). Nói chung, một giải pháp bằng JavaScript sẽ rất tốt, nhưng trên thực tế, nó không được trình duyệt Internet Explorer hỗ trợ, như đã đề cập ở trên. Nhược điểm của giải pháp sử dụng nhãn là sử dụng cùng một JavaScript, tuy nhiên, nó tốt hơn nhiều so với phương pháp “che đậy” và theo tôi, nên sử dụng ngay bây giờ để giải quyết vấn đề cấp bách này.

Sơ đồ xe đạp Nhiệm vụ chính là tạo ra đầu vào “cao su”, trên màn hình thiêt bị di động sẽ đại diện nút đơn giảnđể chọn một tập tin (tên của tập tin đã chọn được hiển thị trên đó) và trên màn hình rộng sẽ trông giống như một trường văn bản + nút quen thuộc có thể trải dài trên toàn bộ chiều rộng của cửa sổ:

Sơ đồ xem phần tử trên thiết bị di động

Sơ đồ xem phần tử trên thiết bị máy tính để bàn

Bài viết này sẽ thảo luận về ba phương pháp mới nhất tạo kiểu cho trường chọn tập tin. Như vậy, xét sơ đồ trên, bố cục ban đầu của phương pháp “ngụy trang” số 3 sẽ có lượt xem tiếp theo(thứ tự của trẻ rất quan trọng!):

Chọn File chưa được chọn

Bố cục có thể có cho phương thức sử dụng phần tử nhãn:
Chọn File chưa được chọn

Bố cục có thể có cho một giải pháp trong JavaScript (giống như bố cục cho phương thức “ngụy trang”):
Chọn File chưa được chọn

“Kéo đi, heo con!” hoặc kiểu cho phương pháp "ngụy trang" Để tránh cho người đọc có ấn tượng sai lầm rằng mỗi giá trị thuộc tính CSS được sử dụng trong bài viết đều có tầm quan trọng lớn (cái gọi là "số ma thuật"), chúng tôi sẽ đồng ý đánh dấu những giá trị có thể thay đổi một cách an toàn để phù hợp với nhu cầu của bạn với một nhận xét

/* ví dụ */

Đã đồng ý? Tuyệt vời! Hãy bắt đầu tạo kiểu cho trường chọn tệp giả mạo của chúng tôi bằng “trình bao bọc” - div.file_upload :

File_upload( vị trí: tương đối; tràn: ẩn; cỡ chữ: 1em; /* ví dụ */ chiều cao: 2em; /* ví dụ */ chiều cao dòng: 2em /* giống với chiều cao */ )
- thuộc tính vị trí được đặt sao cho các phần tử con của nó có thể được định vị tuyệt đối so với div.file_upload và thuộc tính tràn được đặt để ẩn mọi thứ mà vì lý do nào đó không vừa với trình bao bọc của chúng tôi (và có một thứ như vậy, nhưng về sau). Trên màn hình rộng, trường và nút đẹp mắt của chúng ta phải được hiển thị trên một dòng - hãy đặt dòng sau thành chiều rộng cố định và float: bên phải, còn dòng trước là một phần đệm nhỏ:

File_upload > nút( float: right; width: 8em; /* ví dụ */ chiều cao: 100% ) .file_upload > div( đệm-trái: 1em /* ví dụ */ )
Vì chúng tôi muốn ẩn trường văn bản trên thiết bị di động, chỉ để lại nút chọn tệp, nên chúng tôi cần đặt truy vấn phương tiện:
@media chỉ có màn hình và (độ rộng tối đa: 500px)( /* example */ .file_upload > div( display: none ) .file_upload > nút( width: 100% ) )
Chà, bây giờ - phần thú vị của phương pháp này! Cần phải làm cho đầu vào tiêu chuẩn hoàn toàn trong suốt và mở rộng nó đến kích thước của “trình bao bọc” div.file_upload . Để triển khai điều sau, chúng tôi sẽ sử dụng một bản hack ở dạng định vị tuyệt đối và thuộc tính biến đổi CSS 3, chẳng hạn như chúng tôi sẽ tăng phần tử lên 20 lần (vâng, đây là cách phổ biến nhất “ con số kỳ diệu»):
.file_upload input(vị trí: tuyệt đối; trái: 0; trên cùng: 0; chiều rộng: 100%; chiều cao: 100%; biến đổi: tỷ lệ (20); khoảng cách giữa các chữ cái: 10em; /* Sửa lỗi IE 9 */ -ms-transform : tỉ lệ (20); /* sửa lỗi IE 9 */ độ mờ: 0; con trỏ: con trỏ )
Như bạn có thể thấy từ đoạn mã CSS ở trên, IE 9 yêu cầu một số điều chỉnh bổ sung. Điều này là do thực tế là khi trình duyệt này nhấp vào trường văn bản, nó không mở cửa sổ chọn tệp hệ thống mà vui lòng đề nghị "xóa" tên của tên đã chọn, được biểu tượng bằng con trỏ văn bản nhấp nháy . Do đó, nó còn được cung cấp thêm một khoảng cách lớn giữa các chữ cái, điều này làm tăng kích thước của nút phần tử lên div.file_upload . Tôi cũng lưu ý rằng chỉ số z trong trong trường hợp này không được chỉ định, bởi vì phần tử này là “con” cuối cùng trong phần đánh dấu được chọn ngay từ đầu.

Sử dụng ví dụ về máy tính để bàn Trình duyệt FireFox, bây giờ trường chọn tệp tùy chỉnh của chúng tôi cho kích cỡ khác nhau cửa sổ trông như thế này:

“Mọi thứ khéo léo đều đơn giản!” hoặc kiểu cho phương thức nhãn Các kiểu cơ bản được áp dụng cho trương Văn bản và một nút, đối với phương pháp này tương tự như các phương pháp đã được thảo luận ở trên:

File_upload( display: block; vị trí: tương đối; tràn: ẩn; cỡ chữ: 1em; /* ví dụ */ chiều cao: 2em; /* ví dụ */ chiều cao dòng: 2em /* giống với chiều cao */ ) .file_upload .button, .file_upload > mark( display: block; con trỏ: con trỏ /* ví dụ */ ) .file_upload .button( float: right; box-sizing: border-box; -moz-box-sizing: border-box; width : 8em; /* ví dụ */ chiều cao: 100%; căn chỉnh văn bản: trung tâm /* ví dụ */ ) .file_upload > mark( nền: trong suốt; /* ví dụ */ đệm-trái: 1em /* ví dụ */ )
Tuy nhiên, bây giờ không cần phải sử dụng hack để “kéo dài” đầu vào trong suốt:

Đầu vào File_upload (vị trí: tuyệt đối; trên cùng: 0; độ mờ: 0)

"Làm thế nào nó hoạt động?" hoặc kiểu cho giải pháp trong JavaScript Vì bố cục ban đầu cho phương thức này được chọn giống như trong bố cục "ngụy trang", nên kiểu cho nút và trường văn bản cho cả hai phương pháp cũng giống nhau (có lẽ ngoại trừ đối với con trỏ: thuộc tính con trỏ, trong trường hợp này, thuộc tính này sẽ được áp dụng cho nút và trường văn bản). Kiểu đầu vào có thể được lấy giống như kiểu được sử dụng trong phương thức sử dụng phần tử nhãn, nhưng tốt hơn là sử dụng thuộc tính khả năng hiển thị thay vì thuộc tính độ mờ:

Đầu vào File_upload (vị trí: tuyệt đối; trên cùng: 0; mức độ hiển thị: ẩn)

Cần nhiều phong cách hơn! Tất nhiên, ở dạng nguyên thủy như vậy, trường chọn tệp khó có thể phù hợp với bất kỳ ai, vì vậy chúng tôi sẽ thêm các kiểu bổ sung sẽ làm cho nút chọn tệp, chẳng hạn như màu tím, thêm bóng, v.v. Cũng đừng quên thêm kiểu của riêng chúng ta cho nút khi con trỏ di chuột qua nó, kiểu cho nút được nhấn và chúng ta cũng sẽ thêm kiểu cho toàn bộ phần tử khi tiêu điểm nằm trên đó (sẽ được áp dụng khi Trợ giúp về JavaScript):

/* Làm cho nó đẹp */ .file_upload( border: 1px solid #ccc; border-radius: 3px; box-shadow: 0 0 5px rgba(0,0,0,0.1); transition: box-shadow 0.1s tuyến tính ) .file_upload.focus( box-shadow: 0 0 5px rgba(0,30,255,0.4) ) .file_upload > nút( nền: #7300df; chuyển tiếp: nền 0,2s; đường viền: rgba rắn 1px (0,0,0,0,1 ); màu đường viền: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25); bán kính đường viền: 2px; rgba(255, 255, 255, 0.2) inet, 0 1px 2px rgba(0, 0, 0, 0.05); màu: #fff; bóng văn bản: #6200bd 0 -1px 0; tràn: dấu ba chấm ) .file_upload:hover > nút( nền: #6200bd; bóng văn bản: #5d00b3 0 -1px 0 ) .file_upload:active > nút( nền: #5d00b3; bóng hộp: 0 0 3px rgba(0, 0,0,0,3) chèn )

Bây giờ trường chọn tệp của chúng tôi trông như thế này:

Cần thêm nạng! Vì chúng ta đang tạo một trường chính thức để chọn tệp nên chúng ta cần đảm bảo rằng nó có thể được điền một cách thoải mái từ bàn phím (đối với phương pháp “che giấu”, tiêu điểm bây giờ trước tiên được đặt thành nút cách điệu, sau đó đến đầu vào bị ẩn, không được hiển thị trực quan dưới bất kỳ hình thức nào). Tất nhiên, đối với điều này, chúng tôi sử dụng JavaScript. Để tránh phải viết nhiều mã, tôi sẽ thoải mái sử dụng thư viện jQuery phổ biến. Sau đó, đối với phương pháp “ngụy trang”:

Var Wrapper = $(".file_upload"), inp = Wrapper.find("input"), btn = Wrapper.find("button"), lbl = Wrapper.find("div"); btn.focus(function())( inp.focus() )); // Nạng cho kiểu:focus: inp.focus(function())( Wrapper.addClass("focus"); )).blur(function())( Wrapper.removeClass("focus"); ));
Đối với phương thức sử dụng nhãn, bạn có thể loại bỏ phần mã chịu trách nhiệm buộc tập trung từ nút vào đầu vào (vì ở đó chúng tôi không có nút nào cả mà chỉ có một khoảng).

Đối với một phương thức mà bản chất của nó là mô phỏng một cú nhấp chuột vào input , bạn thực sự cần phải thêm chính cái mô phỏng này:

// Đúng, nó hoạt động! btn.add(lbl).click(function())( inp.click(); )); và cũng điều chỉnh mã để thiết lập lớp .focus, trước đó đã loại bỏ đoạn chịu trách nhiệm buộc tiêu điểm:
// Nạng cho kiểu:focus: btn.focus(function())( Wrapper.addClass("focus"); )).blur(function())( Wrapper.removeClass("focus"); ));

Trường đầu vào vẫn "chết" - khi chọn tệp, tên của tệp sau không được hiển thị ở bất kỳ đâu. Đã đến lúc phải sửa lỗi này:

Var file_api = (window.File && window.FileReader && window.FileList && window.Blob) ? đúng sai;
inp.change(function())( var file_name; if(file_api && inp[ 0 ].files[ 0 ]) file_name = inp[ 0 ].files[ 0 ].name; else file_name = inp.val().replace ("C:\\fakepath\\", ""); if(! file_name.length) return; if(lbl.is(":visible"))( lbl.text(file_name); btn.text("Select " ); )else btn.text(file_name);

Có vẻ như mọi thứ được yêu cầu đều đã được viết sẵn. Và đây là những bức tượng nhỏ! Nếu bạn chọn một tệp bằng trường “di động”, sau đó tăng kích thước cửa sổ và chuyển phần tử sang “máy tính để bàn”, thì “Tệp không được chọn” sẽ vẫn ở trong trường văn bản - bạn cần cập nhật phần tử mỗi khi thay đổi kích thước cửa sổ:
$(window).resize(function())( $(".file_upload input").triggerHandler("change"); ));

Và cuối cùng chúng ta đã nhận được gì? Trường chọn tệp cách điệu kết quả đã được thử nghiệm thành công cho cả ba phương pháp trong các trình duyệt sau:
  • FireFox 22.0 (Linux, Windows)
  • Opera 12.16 (Linux, Windows)
  • Internet Explorer 9
  • Crom 27.0 (Linux)
  • Apple Safari (iOS 6.3.1)
  • Trình duyệt Android (Android 2.3.6)
  • Android FireFox

Trong số những ưu điểm của tất cả các phương pháp được thảo luận trong bài viết, có thể xác định những ưu điểm chính sau:

  • Đèn flash không được sử dụng.
  • Phần tử có thể được tạo kiểu dễ dàng bằng CSS bằng các công nghệ thiết kế đáp ứng hiện đại.
  • Trường này cũng có thể được điền bằng bàn phím.

Trong số những nhược điểm chính:

  • Nhu cầu sử dụng JavaScript (áp dụng cho tất cả các phương thức).
  • Sử dụng CSS hack để "ngụy trang" mọi thứ.
  • Cần phải viết thêm các điểm hỗ trợ cho trường có thuộc tính multiple (áp dụng cho tất cả các phương thức).
  • Không phải trình duyệt chéo - tất cả các phương pháp đều thiếu hỗ trợ cho IE 8 và bạn cũng cần sử dụng các thuộc tính CSS của “trình duyệt” để hỗ trợ các “cũ” còn lại.
  • Giải pháp JavaScript không được mọi người hỗ trợ Phiên bản Internet Explorer, cũng như một số phiên bản cũ hơn của những phiên bản khác trình duyệt phổ biến(mặc dù hầu như không còn ai sử dụng chúng nữa).

Bạn nên chọn cách nào trong số ba cách hay để tạo đầu vào cách điệu cho sử dụng hàng ngày- bạn quyết định. Lựa chọn của tôi là phương pháp sử dụng nhãn (mặc dù nó có bố cục phi ngữ nghĩa).

Bạn có thể tìm thấy các ví dụ hoạt động của cả ba phương pháp trên CodePen.

Chúng tôi tiếp tục chủ đề về cuộc đối đầu vĩnh cửu giữa các nhà thiết kế và nhà thiết kế bố cục. Xung đột chính nảy sinh khi người thiết kế vẽ ra một bức tranh về trang web theo nhu cầu của khách hàng, và sau đó người thiết kế bố cục phải điều chỉnh theo nhiều cách khác nhau. phần tử HTML. Một trong những phần tử khó tạo kiểu nhất là trường chọn tệp, phần tử đầu vào có loại tệp. BẰNG ví dụ rõ ràng, đây là cách nó xuất hiện trong các trình duyệt khác nhau:

Trường loại đầu vào = "tệp" trong các trình duyệt khác nhau


Sự phức tạp bổ sung được tạo ra bởi thực tế là trường này tuân theo các quy tắc bảo mật khác nhau của trình duyệt, do đó, chẳng hạn, nó không thể được thay thế bằng một số div cách điệu, nó không thể được gói trong thẻ nhãn, nó không thể được gán trực tiếp một giá trị bằng cách sử dụng tập lệnh hoặc nó không thể mở cửa sổ chọn tệp bằng cách mô phỏng một cú nhấp chuột thông qua phần tử .click(). Và trong một số trình duyệt, bạn thậm chí không thể ẩn trường chọn tệp, vì sau khi gửi biểu mẫu, giá trị của nó sẽ không được truyền đến máy chủ. TRONG các mạng internet khác nhau Tôi đã thấy những nỗ lực tạo ra giải pháp đa trình duyệt, nhưng trên thực tế, tất cả chúng đều không phổ biến và bị giới hạn ở các trình duyệt cụ thể.

Khi tôi cần giải quyết vấn đề này, tôi quyết định sử dụng thủ thuật đã được chứng minh, trong đó phần tử mong muốn được đặt bên trong khối div với kích thước cố định và hình nền và bản thân phần tử đó được gán thuộc tính “trong suốt”. Không ẩn, nhưng hoàn toàn minh bạch. Tôi đã phải mày mò thêm một chút để trong ranh giới của div gốc sẽ có một vùng đầu vào phản hồi khi nhấp chuột và mở cửa sổ chọn tệp. Để thực hiện điều này, phông chữ và chiều cao của chính đầu vào đã được tối đa hóa. Mã HTML là đơn giản nhất: Mã CSS không hoàn toàn hợp lệ do sử dụng bộ lọc trình duyệt Internet Explorer, nhưng đây là cái giá phải trả cho khả năng tương thích giữa nhiều trình duyệt. Phương án cuối cùng, nếu bạn cần xác thực 100% trình xác thực, bạn có thể đặt động thuộc tính này bằng cách sử dụng JavaScript hoặc tải bàn riêng styles cho IE. Lúc này trên màn hình chúng ta chỉ thấy một nút cách điệu, khi nhấn vào sẽ mở ra một cửa sổ chọn file. Trường nhập để chọn tệp không được hiển thị nhưng hoạt động tốt. Một vấn đề nhỏ vẫn là một số trình duyệt bỏ qua kiểu con trỏ và vẫn hiển thị nó dưới dạng văn bản trên trường nhập. Tuy nhiên, đối với tôi, có vẻ như bạn có thể bỏ qua điều này, mặc dù biết về nó sẽ rất hữu ích.

Chúng tôi có thể kết thúc ở đây, nhưng trong một số trường hợp, chúng tôi có thể cần tên của tệp đã chọn chẳng hạn, để trước khi gửi biểu mẫu, chúng tôi có thể thực thi kiểm tra sơ bộ nếu một tập tin thuộc một loại nhất định được mong đợi. Hoặc, ví dụ, để người dùng có thể kiểm tra xem mình có tải đúng tệp hay không. Trong trường nhập thông thường, người dùng vẫn nhìn thấy nó, nhưng trong trường cách điệu của chúng tôi thì không. Để thực hiện việc này, chúng tôi sẽ thêm trình xử lý cho sự kiện onchange, mã HTML sẽ được bổ sung một chút: và tập lệnh sau sẽ được thêm vào:

  • < script type = "text/javascript" >
  • hàm file_selected() (
  • thử (
  • tập tin var = tài liệu. getElementById("tệp_tải lên"). tập tin[0];
  • nếu (tập tin) (
  • var file_size = 0 ;
  • if (kích thước tệp . > 1024 * 1024 ) (
  • file_size = (Toán . round (file . size * 100 /(1024 * 1024 ))/ 100 ). toString() + "MB";
  • khác(
  • file_size = (Toán . round (file . size *100/1024)/100). toString() + "KB";
  • tài liệu. getElementById("file_name"). bên trongHTML = "Tên: " + tệp . tên ;
  • tài liệu. getElementById("file_size"). bên trongHTML = "Kích thước: " + file_size ;
  • bắt(e) (
  • tập tin var = tài liệu. getElementById("tệp_tải lên"). giá trị ;
  • tập tin = tập tin. thay thế (/\\/ g , "/" ). tách ra("/" ). nhạc pop();
  • tài liệu. getElementById("file_name"). bên trongHTML = "Tên: " + tập tin ;
  • Một số trình duyệt cung cấp quyền truy cập mở rộng vào các thuộc tính tệp trong trường đầu vào; đối với các trình duyệt như vậy, bạn không chỉ có thể nhận được tên tệp mà còn cả kích thước của nó. Theo đó, thông tin mở rộng như vậy sẽ được hiển thị. Đối với các trình duyệt khác, chúng tôi sẽ chỉ hiển thị tên của tệp đã chọn, giá trị này luôn có sẵn thông qua thuộc tính value của trường đầu vào.

    Bạn có thể xem ví dụ tạo sẵn về biểu mẫu có trường chọn tệp cách điệu và cách xử lý nó

    Đến năm 1998, khi CSS Cấp 2 được phát hành, các thành phần biểu mẫu đã được tất cả các trình duyệt chính hỗ trợ. Đặc tả CSS 2 không giải quyết được vấn đề trình bày. Vì các phần tử này là một phần của giao diện người dùng nên các tác giả của đặc tả đã chọn loại bỏ chúng đại diện trực quan nhờ sự giúp đỡ của các nhà phát triển trình duyệt.

    Năm này qua năm khác, thông số kỹ thuật không đủ chi tiết đã buộc các nhà phát triển web phải thử nghiệm nỗ lực đưa cách trình bày các phần tử như input , select , fieldset , chú giải và vùng văn bản trong các trình duyệt khác nhau về một “mẫu số chung”. Trong bài viết này, chúng ta sẽ xem xét một số kỹ thuật CSS được các nhà phát triển web sử dụng để chuẩn hóa cách trình bày trực quan của các thành phần biểu mẫu.

    Thử nghiệm của Roger Johansson

    Đầu tiên vào năm 2004 và sau đó là vào năm 2007, Roger Johansson đã tạo ra một bộ thử nghiệm toàn diện để kiểm tra việc áp dụng các kiểu CSS để tạo thành các phần tử. Bạn có thể tìm thấy kết quả của những thử nghiệm này trong bài viết “Về các thành phần biểu mẫu tạo kiểu bằng CSS” của anh ấy, dẫn đến một kết luận đáng thất vọng, mà Johansson đã bày tỏ bằng những lời sau:

    Vậy thí nghiệm này cho thấy điều gì? Như tôi đã nói, nó cho thấy rằng sử dụng CSSđể tạo kiểu cho các phần tử của biểu mẫu nhằm mang lại cho chúng một diện mạo đồng nhất trong các trình duyệt khác nhau và trên nền tảng khác nhau không thể nào. Nó cũng cho thấy hầu hết các trình duyệt đều bỏ qua nhiều thuộc tính CSS được áp dụng cho các thành phần của biểu mẫu.

    Bất chấp tính xác thực không thể nghi ngờ của những kết luận này, các nhà phát triển web vẫn tiếp tục tích cực thử nghiệm việc áp dụng các kiểu CSS để tạo thành các phần tử nhằm tìm ra Chén Thánh cho bản trình bày trên nhiều trình duyệt của họ hoặc ít nhất là một sự thỏa hiệp hợp lý giữa các kiểu được trình duyệt áp dụng bởi mặc định và những cài đặt do nhà phát triển chỉ định.

    Mô hình mặc định

    Đặc tả CSS 2.1 chỉ định trong biểu định kiểu mặc định được đề xuất cho HTML4 tạo thành các phần tử như textarea , input và select là khối nội tuyến:

    vùng văn bản, đầu vào, chọn ( display : inline-block; )

    Đổi lại, các thành phần biểu mẫu và bộ trường là cấp khối:

    bộ trường, biểu mẫu (hiển thị: khối;)

    Mô tả về mô hình mặc định do đặc tả CSS đề xuất chỉ giới hạn ở điều này. Tất cả các khía cạnh trực quan khác của thành phần biểu mẫu đều phụ thuộc vào biểu định kiểu mặc định của trình duyệt. Tuy nhiên, các quy tắc được liệt kê có nghĩa như sau:

      Các phần tử khối nội tuyến có thể được tạo kiểu bằng mô hình nội tuyến. Nó cho phép bạn sử dụng các thuộc tính CSS như chiều cao dòng và căn chỉnh dọc để kiểm soát chiều cao của khối và căn chỉnh dọc của nó. Ngoài ra, để biểu thị mức thụt lề bên ngoài và bên trong của một khối, bạn có thể sử dụng thuộc tính lề và phần đệm. Các phần tử khối nội tuyến hỗ trợ chiều rộng và chiều cao vì chúng sử dụng mô hình định dạng khối.

      Các phần tử khối có thể được tạo kiểu bằng cách sử dụng các phần tử nổi tiếng mô hình khối. Tuy nhiên, có vấn đề nảy sinh với các phần tử fieldset và chú giải, vì chú giải hoàn toàn phụ thuộc vào kiểu mặc định của trình duyệt.

    Các nhà phát triển web giải quyết những vấn đề này như thế nào?

    Kích thước

    Các nhà phát triển web nhanh chóng nhận thấy rằng các trình duyệt hoạt động kỳ lạ khi sử dụng các phần tử khối nội tuyến khi cần chỉ định rõ ràng các kích thước. Việc chỉ định chiều cao thường dẫn đến kết quả bất ngờ:

    nhập, chọn (chiều rộng: 120px; chiều cao: 32px;)

    Các nhà phát triển đã cố gắng giải quyết vấn đề này bằng cách biến các phần tử này thành các phần tử khối:

    nhập, chọn (chiều rộng: 120px; chiều cao: 32px; hiển thị: khối;)

    Chỉ hoạt động với vùng văn bản. Giải pháp tiêu chuẩn Vấn đề này nằm ở việc sử dụng thuộc tính kích thước phông chữ và phần đệm thay vì chiều cao.

    Các thành phần của biểu mẫu không kế thừa kiểu chữ và kích thước phông chữ, vì vậy điều đầu tiên bạn cần làm là chỉ định chúng:

    nhập, chọn ( width : 120px ; font : 1em Arial, sans-serif; )

    Sau khi xác định kiểu chữ, bạn có thể đặt phần đệm để thêm phần đệm vào khối phần tử:

    đầu vào, chọn ( chiều rộng: 120px ; phông chữ : 1em Arial, sans-serif; phần đệm : 3px 6px ; )

    Các phần tử đầu vào và vùng văn bản có đường viền được xác định trong biểu định kiểu trình duyệt. Hãy bình thường hóa nó:

    đầu vào, đầu vào, vùng văn bản ( đường viền : 1px Solid #ccc ; )

    Trình duyệt thêm phần đệm bổ sung vào các phần tử đầu vào của nút loại và gửi. Một cách thực hành phổ biến để bình thường hóa chúng là:

    đầu vào, đầu vào (phần đệm: 2px;)

    Vấn đề với kỹ thuật này là các trình duyệt, trong số những thứ khác, áp dụng các thuộc tính dành riêng cho trình duyệt cho các thành phần này và không phải lúc nào phần đệm cũng có thể bình thường hóa chúng. Ví dụ: trong các trình duyệt sử dụng công cụ Webkit, bạn có thể tìm thấy thông tin sau:

    đầu vào , đầu vào , đầu vào , đầu vào ::-webkit-file-upload-button , nút ( -webkit-box-align : center; text-align : center; con trỏ : mặc định; color : Buttontext; phần đệm : 2px 6px 3px ; đường viền : 2px mặt nút đầu tiên; hình ảnh viền: ban đầu; màu nền: mặt nút; kích thước hộp: hộp viền; ngoại hình -webkit: nút ấn; khoảng trắng: trước;)

    phần đệm cũng được sử dụng cho các phần tử fieldset và legend, nhưng tạo ra các kết quả khác nhau:

    • Đặt giá trị thuộc tính đệmđối với một phần tử, tập hợp trường bằng 0 theo mặc định sẽ đặt lại mức thụt lề của phần tử chú giải trong một số trình duyệt (nhưng không phải IE).
    • Đặt thuộc tính đệm của phần tử chú giải thành 0 sẽ khiến nó bị thu gọn.

    Đối với select và đối với đầu vào có hộp kiểm và loại radio, bạn chỉ nên sử dụng:

    • họ phông chữ
    • cỡ chữ
    • chiều rộng (để chọn),
    • đệm.

    Việc áp dụng các thuộc tính khác cho các phần tử này thường dẫn đến kết quả không nhất quán trong các trình duyệt khác nhau.

    Căn chỉnh

    Các phần tử của biểu mẫu có thể được căn chỉnh theo chiều ngang và chiều dọc. Chúng có thể được đặt trên một dòng hoặc dưới dạng một nhóm các khối bên dưới nhau. Để căn chỉnh chúng trên cùng một dòng, bạn có thể sử dụng một trong hai cách tiếp cận:

  • Sử dụng phao
  • Sử dụng mô hình khối dòng cho một số phần tử.
  • sử dụng phần tử nổi tự động trở thành dựa trên khối. Điều này có nghĩa là các phần tử biểu mẫu này hiện phải tuân theo quy tắc chín phần tử nổi.

    Các phần tử của biểu mẫu có thể được căn chỉnh theo chiều dọc và chiều ngang.

    Khi sử dụng float, vấn đề chính là làm cho nó được căn chỉnh chính xác theo chiều dọc so với dòng hiện tại. Điều này thường được thực hiện bằng cách sử dụng lề hoặc phần đệm:

    nhập, chọn ( width : 120px ; float : left ; Margin-top : 0.4em ; )

    Cách tiếp cận này hoạt động khi bạn không cần đặt căn chỉnh các khối liên quan đến văn bản, chẳng hạn như nội dung của nhãn . Trong trường hợp điều này là cần thiết, bạn có thể sử dụng vị trí, phần đệm và lề tương đối trên các phần tử chỉ chứa văn bản:

    nhãn ( float : trái; phần đệm trên : 0,4em ; chiều rộng : 5em ; lề phải : 1em ; )

    Một vấn đề khác phát sinh với các nút. Trong trường hợp bạn có một nút lớn hơn các thành phần khác, bạn có thể đặt căn chỉnh theo chiều dọc của nó bằng cách sử dụng vị trí tương đối:

    đầu vào ( float : trái; chiều rộng : 90px ; vị trí : tương đối; top : 0,4em ; )

    Một kỹ thuật khác với vị trí tương đối có thể được sử dụng cho đầu vào bằng các loại hộp kiểm và radio. Định vị tương đối thậm chí có thể được sử dụng để chuẩn hóa phần đệm bên trái của phần tử chú giải bên trong phần tử fieldset. Sự khác biệt duy nhất là bạn cần sử dụng thuộc tính left thay vì thuộc tính top.

    Khi sử dụng mô hình nội tuyến và hộp nội tuyến, bạn có thể sử dụng thuộc tính Vertical-align để căn chỉnh các phần tử theo chiều dọc:

    nhãn , đầu vào ( căn chỉnh dọc : giữa; lề phải : 1em ; )

    Có thể thuận tiện khi sử dụng thuộc tính này cùng với line-height . Điều quan trọng cần lưu ý là bạn phải áp dụng thuộc tính này cho phần tử cha. Nếu bạn áp dụng thuộc tính này trực tiếp cho các phần tử của biểu mẫu, nó sẽ có tác dụng khi tính chiều cao của chúng:

    .form-row ( chiều cao dòng : 1.4 ; )

    Đặc điểm chiều cao rõ ràng phần tử cha Nó cũng có hiệu quả khi được sử dụng kết hợp với giá trị chiều cao dòng bằng nhau:

    .form-row (chiều cao dòng: 1,8; chiều cao: 1,8em;)

    Khi sử dụng mô hình dòng hoặc khối dòng, bạn cũng có thể sử dụng thuộc tính căn chỉnh văn bảnđể phần tử cha căn chỉnh các phần tử sang phải, trái hoặc giữa.

    Tính năng lạ của phần tử chọn file

    - Cái này một trường hợp đặc biệt. Vì lý do bảo mật, loại phần tử này phải luôn hiển thị và dễ nhận biết trong trình duyệt. Điều này có nghĩa là các trình duyệt cố tình bỏ qua một số kiểu (ví dụ: các kiểu liên quan đến khả năng hiển thị của một phần tử) và có xu hướng thực thi cách trình bày được mô tả bằng biểu định kiểu của riêng chúng.

    Điều đáng lưu ý là bố cục mặc định khác nhau giữa các trình duyệt: một số trình duyệt chỉ hiển thị một nút, trong khi những trình duyệt khác thêm trường văn bản để cho biết đường dẫn đến tệp đang được tải xuống.

    Tuy nhiên, các nhà phát triển web đã nhanh chóng tìm ra cách khắc phục những hạn chế này. Đầu tiên họ đặt trường đầu vào vào một thùng chứa:

    Sau đó, họ ẩn phần tử đầu vào bằng cách sử dụng thuộc tính opacity và áp dụng các kiểu cho vùng chứa:

    .upload ( chiều rộng : 157px ; chiều cao : 57px ; nền : url (upload.png) không lặp lại; tràn : ẩn; ) .upload đầu vào ( display : block !important ; width : 157px !important ; Height : 57px !important ; độ mờ : 0 ! quan trọng ; tràn : ẩn! quan trọng )

    Lưu ý!quan trọng . Đây là phương pháp ưa thích để ghi đè kiểu trình duyệt mặc định.

    Phần kết luận

    Không thể kiểm soát hoàn toàn việc trình bày các thành phần của biểu mẫu do thiếu sự chắc chắn trong đặc tả CSS và do các kiểu mặc định được trình duyệt áp dụng. Tuy nhiên, bằng cách sử dụng một số kỹ thuật phổ biến, bạn có thể giảm (nhưng không loại bỏ) sự khác biệt trong thiết kế các phần tử.

    Bài viết gốc: Vấn đề về các thành phần biểu mẫu CSS Bài viết được đọc bởi: , guestFM , Anton Khlynovskiy , Igor Adamenko

    3,9 trên 5

    Xin chào. Hôm nay tôi muốn nói với bạn về cách bạn có thể thay đổi giao diện của tệp đầu vào, cách tạo kiểu cho tệp đầu vào cho phù hợp với thiết kế của bạn, cách tạo kiểu cho tệp .

    Đủ từ khóa=). Tôi nghĩ rằng bạn sẽ có được điểm.

    Thực tế là việc thay đổi hình thức của đầu vào, theo quy luật, không gây khó khăn, nhưng loại đầu vào này khác với các loại đầu vào khác. Trước hết, điều này là do tính bảo mật và thứ hai là do mỗi trình duyệt hiển thị phần tử này một cách khác nhau và điều này gần như không thể bị ảnh hưởng.

    Bài viết này sẽ cho bạn biết cách đạt được giao diện của tệp đầu vào mà bạn cần.

    Trước tiên, hãy xem cách hiển thị đầu vào tệp mà không áp dụng bất kỳ kiểu nào trong các trình duyệt khác nhau.

    Kết quả là, ở mọi nơi ngoại trừ safari, chúng ta đều thấy phần đầu của địa chỉ, hầu như không có ý nghĩa ngữ nghĩa. Tôi nghi ngờ rằng có ai đó không biết về điều này, mà chỉ có những người ở Apple mới chú ý đến sự ngu ngốc này và có thể nhìn thấy ngay không chỉ tên của tệp đã chọn mà còn cả biểu tượng. Chúng tôi sẽ triển khai chức năng nhập tệp giống nhau cho tất cả các trình duyệt.

    Nhưng trước tiên, hãy làm quen với vấn đề.
    1. Sử dụng JS, chúng tôi không thể mô phỏng một cú nhấp chuột vào đầu vào như vậy. Đây là những gì thánh thư của đặc tả DOM nói về nó:

    nhấp chuột
    Mô phỏng một cú click chuột. Đối với các phần tử INPUT có thuộc tính loại có một trong các giá trị sau: “button”, “checkbox”, “radio”, “reset” hoặc “submit”.
    Không có thông số
    Không có giá trị trả lại
    Không có ngoại lệ

    Nghĩa là, bằng cách sử dụng phương pháp nhấp chuột, chúng ta có thể mô phỏng một nhấp chuột trên hầu hết các loại đầu vào, nhưng không phải trên đầu vào tệp. Điều này được thực hiện để bảo vệ máy tính của khách hàng: nếu không, chủ sở hữu trang web có thể dễ dàng nhận bất kỳ tệp nào từ máy tính của khách hàng. Mặt khác, khi nhấp vào, chỉ có cửa sổ chọn tệp được mở ra. Bằng cách này hay cách khác, trong trung tâm nhà phát triển Firefox, thực tế này được coi là một lỗi.

    Có một giải pháp, và chúng tôi không phát minh ra xe đạp, chúng tôi điều chỉnh nó. Mọi người tạo kiểu cho đầu vào đều tuân theo cùng một mẫu: một đầu vào có độ trong suốt bằng 0 được tạo và đặt lên trên nút hoặc hình ảnh đại diện cho nút chọn tệp.

    Khó khăn chính nằm ở vấn đề sau.

    2. Chúng tôi không thể tự do tác động đến kích thước của các nút “xem lại” để điều chỉnh đầu vào theo kích thước của hình ảnh chồng chéo. Trong Firefox, chúng tôi hoàn toàn không thể thay đổi giao diện của tệp đầu vào. sử dụng css(trừ chiều cao). Nghĩa là, nhiệm vụ là xác định kích thước tối ưu hình ảnh chồng chéo sao cho số lượng pixel tối thiểu không thể nhấp vào được và các vùng trống không phản hồi với các nhấp chuột.

    Hãy xem các khu vực có thể nhấp vào và kích thước của chúng trong các trình duyệt khác nhau.