From c058fa0fb22dc40ef0225b21a97578cddd0aaffa Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 14:51:05 +0100 Subject: unslug ru: move --- .../index.html" | 51 - .../web/api/audiocontext/createpanner/index.html | 211 -- .../ru/web/api/audiocontext/currenttime/index.html | 97 - .../api/audiocontext/decodeaudiodata/index.html | 220 -- .../api/baseaudiocontext/createpanner/index.html | 211 ++ .../api/baseaudiocontext/currenttime/index.html | 97 + .../baseaudiocontext/decodeaudiodata/index.html | 220 ++ .../tutorial/applying_styles_and_colors/index.html | 726 +++++ .../tutorial/basic_animations/index.html | 308 +++ .../api/canvas_api/tutorial/compositing/index.html | 108 + .../canvas_api/tutorial/drawing_shapes/index.html | 582 ++++ .../canvas_api/tutorial/drawing_text/index.html | 166 ++ .../canvas_api/tutorial/using_images/index.html | 333 +++ .../index.html" | 333 --- .../index.html" | 108 - .../index.html" | 308 --- .../index.html" | 726 ----- .../index.html" | 166 -- .../index.html" | 582 ---- files/ru/web/api/crypto/getrandomvalues/index.html | 73 + .../managing_screen_orientation/index.html | 183 ++ .../index.html" | 183 -- files/ru/web/api/document/activeelement/index.html | 165 -- files/ru/web/api/document/async/index.html | 35 - files/ru/web/api/document/createelement/index.html | 82 + files/ru/web/api/document/getselection/index.html | 9 - files/ru/web/api/document/images/index.html | 29 + .../api/document/readystatechange_event/index.html | 90 + .../api/document_object_model/events/index.html | 80 + .../api/document_object_model/examples/index.html | 382 +++ files/ru/web/api/document_object_model/index.html | 387 +++ .../document_object_model/introduction/index.html | 230 ++ .../index.html | 50 + .../documentorshadowroot/activeelement/index.html | 165 ++ .../documentorshadowroot/getselection/index.html | 9 + files/ru/web/api/element/accesskey/index.html | 74 - files/ru/web/api/element/blur_event/index.html | 153 ++ files/ru/web/api/element/error_event/index.html | 95 + files/ru/web/api/element/focusin_event/index.html | 123 + files/ru/web/api/element/focusout_event/index.html | 126 + .../web/api/elementcssinlinestyle/style/index.html | 78 + .../ru/web/api/eventtarget/attachevent/index.html | 9 - .../ru/web/api/eventtarget/detachevent/index.html | 92 - .../introduction/index.html | 291 ++ .../index.html" | 291 -- files/ru/web/api/fullscreen_api/index.html | 198 ++ .../api/geolocation/using_geolocation/index.html | 91 - .../using_the_geolocation_api/index.html | 170 -- files/ru/web/api/geolocation_api/index.html | 91 + .../using_the_geolocation_api/index.html | 170 ++ .../drag_operations/index.html | 314 +++ files/ru/web/api/html_drag_and_drop_api/index.html | 72 + .../ru/web/api/htmlaudioelement/audio()/index.html | 85 - files/ru/web/api/htmlaudioelement/audio/index.html | 85 + files/ru/web/api/htmlelement/accesskey/index.html | 74 + files/ru/web/api/htmlelement/dataset/index.html | 114 - files/ru/web/api/htmlelement/innertext/index.html | 46 + files/ru/web/api/htmlelement/nonce/index.html | 44 - files/ru/web/api/htmlelement/style/index.html | 78 - files/ru/web/api/htmlelement/tabindex/index.html | 134 - .../api/htmlelement/transitionend_event/index.html | 165 ++ .../api/htmlmediaelement/seeking_event/index.html | 80 + .../api/htmlorforeignelement/dataset/index.html | 114 + .../web/api/htmlorforeignelement/nonce/index.html | 44 + .../api/htmlorforeignelement/tabindex/index.html | 134 + .../echocancellation/index.html | 77 + .../index.html" | 77 - files/ru/web/api/navigator/connection/index.html | 100 + files/ru/web/api/navigatorgeolocation/index.html | 103 - .../api/networkinformation/connection/index.html | 100 - files/ru/web/api/node.replacechild/index.html | 64 - files/ru/web/api/node/baseuriobject/index.html | 26 - files/ru/web/api/node/innertext/index.html | 46 - files/ru/web/api/node/nodeprincipal/index.html | 29 - files/ru/web/api/node/replacechild/index.html | 64 + .../nextelementsibling/index.html | 173 ++ .../index.html | 173 -- files/ru/web/api/notation/index.html | 52 + files/ru/web/api/page_visibility_api/index.html | 195 ++ .../web/api/push_api/using_the_push_api/index.html | 420 --- .../api/randomsource/getrandomvalues/index.html | 73 - files/ru/web/api/randomsource/index.html | 111 - files/ru/web/api/slotable/index.html | 45 - files/ru/web/api/storage/localstorage/index.html | 146 - .../api/svgaelement/svgalement.target/index.html | 107 - .../checking_authenticity_with_password/index.html | 33 - .../web_workers_api/using_web_workers/index.html | 871 ++++++ .../creating_3d_objects_using_webgl/index.html | 131 + .../index.html" | 131 - .../ru/web/api/webrtc_api/connectivity/index.html | 70 + files/ru/web/api/webrtc_api/protocols/index.html | 38 + .../ru/web/api/webrtc_api/webrtc_basics/index.html | 351 --- .../index.html" | 38 - .../index.html" | 70 - files/ru/web/api/websockets_api/index.html | 58 + .../index.html | 195 ++ .../api/window/domcontentloaded_event/index.html | 146 + files/ru/web/api/window/load_event/index.html | 88 + .../api/window/requestanimationframe/index.html | 92 + .../api/window/unhandledrejection_event/index.html | 49 + .../base64_encoding_and_decoding/index.html | 138 - files/ru/web/api/windowbase64/btoa/index.html | 141 - files/ru/web/api/windowbase64/index.html | 121 - .../api/windoworworkerglobalscope/btoa/index.html | 141 + .../settimeout/index.html | 260 ++ files/ru/web/api/windowtimers/index.html | 120 - .../ru/web/api/windowtimers/settimeout/index.html | 260 -- files/ru/web/api/xmldocument/async/index.html | 35 + .../api/xmlhttprequest/loadstart_event/index.html | 89 + .../index.html" | 195 -- .../index.html" | 52 - files/ru/web/css/@viewport/user-zoom/index.html | 106 - files/ru/web/css/_colon_any/index.html | 190 -- files/ru/web/css/actual_value/index.html | 40 + files/ru/web/css/box_model/index.html | 66 - files/ru/web/css/comments/index.html | 50 + files/ru/web/css/common_css_questions/index.html | 182 -- .../ispolzovanie_css_animatciy/index.html | 388 --- .../css_animations/using_css_animations/index.html | 388 +++ .../border-radius_generator/index.html | 1599 +++++++++++ .../index.html" | 1599 ----------- .../box-shadow_generator/index.html | 2884 ++++++++++++++++++++ .../web/css/css_background_and_borders/index.html | 155 -- .../index.html" | 53 - .../web/css/css_backgrounds_and_borders/index.html | 155 ++ .../using_multiple_backgrounds/index.html | 53 + .../index.html | 120 + .../index.html" | 120 - .../css_box_model/box-shadow_generator/index.html | 2884 -------------------- .../introduction_to_the_css_box_model/index.html | 66 + files/ru/web/css/css_color/index.html | 117 + files/ru/web/css/css_colors/index.html | 117 - .../using_multi-column_layouts/index.html | 124 + .../aligning_items_in_a_flex_container/index.html | 213 ++ .../index.html | 194 ++ .../using_css_flexible_boxes/index.html | 379 --- .../index.html" | 213 -- .../index.html" | 194 -- .../index.html | 123 + .../intro_to_formatting_contexts/index.html | 85 + .../index.html" | 123 - .../index.html" | 85 - .../index.html | 498 ---- .../index.html | 498 ++++ .../css_grid_layout/grid_template_areas/index.html | 529 ++++ .../line-based_placement_with_css_grid/index.html | 652 +++++ .../index.html" | 529 ---- .../index.html" | 652 ----- .../adding_z-index/index.html | 157 ++ .../understanding_z_index/index.html | 51 + .../stacking_without_z-index/index.html | 140 + files/ru/web/css/css_selectors/index.html | 122 + .../index.html | 62 + files/ru/web/css/css_user_interface/index.html | 119 - .../index.html" | 122 - .../index.html" | 62 - files/ru/web/css/filter-function/url/index.html | 35 - files/ru/web/css/grid-gap/index.html | 194 -- files/ru/web/css/layout_mode/index.html | 28 + files/ru/web/css/length/index.html | 153 ++ .../media_queries/testing_media_queries/index.html | 83 + .../index.html" | 83 - files/ru/web/css/pseudo-classes/index.html | 146 + files/ru/web/css/replaced_element/index.html | 49 + files/ru/web/css/specified_value/index.html | 43 + files/ru/web/css/syntax/index.html | 76 + files/ru/web/css/url/index.html | 94 - .../ru/web/css/visual_formatting_model/index.html | 209 ++ .../index.html" | 40 - .../index.html" | 49 - .../index.html" | 146 - .../index.html" | 153 -- .../index.html" | 76 - .../index.html" | 28 - .../index.html" | 50 - .../index.html" | 43 - files/ru/web/events/abort/index.html | 70 - files/ru/web/events/blur/index.html | 153 -- files/ru/web/events/domcontentloaded/index.html | 146 - files/ru/web/events/error/index.html | 95 - files/ru/web/events/focusin/index.html | 123 - files/ru/web/events/focusout/index.html | 126 - files/ru/web/events/load/index.html | 88 - files/ru/web/events/loadstart/index.html | 89 - files/ru/web/events/readystatechange/index.html | 90 - files/ru/web/events/transitionend/index.html | 165 -- files/ru/web/events/unhandledrejection/index.html | 49 - files/ru/web/guide/ajax/getting_started/index.html | 258 ++ .../index.html" | 258 -- .../index.html" | 6 - files/ru/web/guide/api/dom/index.html | 38 - files/ru/web/guide/api/dom/storage/index.html | 368 --- files/ru/web/guide/api/webrtc/index.html | 35 - .../cascading_and_inheritance/index.html | 152 -- .../web/guide/css/getting_started/color/index.html | 345 --- .../css/getting_started/how_css_works/index.html | 122 - files/ru/web/guide/css/getting_started/index.html | 60 - .../css/getting_started/readable_css/index.html | 166 -- .../guide/css/getting_started/selectors/index.html | 434 --- .../getting_started/svg_\320\270_css/index.html" | 213 -- .../css/getting_started/text_styles/index.html | 152 -- .../css/getting_started/what_is_css/index.html | 120 - .../css/getting_started/why_use_css/index.html | 110 - .../index.html" | 525 ---- files/ru/web/guide/css/index.html | 12 - .../adding_z-index/index.html | 157 -- .../web/guide/css/understanding_z_index/index.html | 51 - .../stacking_without_z-index/index.html | 140 - .../css/using_multi-column_layouts/index.html | 124 - .../guide/css/visual_formatting_model/index.html | 209 -- .../creating_and_triggering_events/index.html | 92 + .../index.html" | 92 - files/ru/web/guide/graphics/index.html | 41 + .../html/drag_and_drop/drag_operations/index.html | 314 --- files/ru/web/guide/html/drag_and_drop/index.html | 72 - .../html/html5/constraint_validation/index.html | 343 +++ files/ru/web/guide/html/html5/index.html | 171 ++ .../html/html5/introduction_to_html5/index.html | 26 + .../index.html | 375 --- .../index.html | 204 -- .../guide/html/using_data_attributes/index.html | 129 - .../using_html_sections_and_outlines/index.html | 375 +++ .../index.html" | 149 - files/ru/web/guide/performance/index.html | 20 + .../index.html" | 41 - .../index.html" | 20 - .../ru/web/html/attributes/crossorigin/index.html | 130 + .../web/html/cors_settings_attributes/index.html | 130 - files/ru/web/html/element/button/index.html | 363 +++ files/ru/web/html/element/element/index.html | 112 - files/ru/web/html/element/link/index.html | 336 +++ .../html/element/video/seeking_event/index.html | 80 - .../index.html" | 363 --- .../index.html" | 336 --- .../web/html/global_attributes/dropzone/index.html | 43 - files/ru/web/html/inline_elements/index.html | 51 + files/ru/web/html/link_types/index.html | 502 ++++ .../index.html | 33 - files/ru/web/html/reference/index.html | 32 + .../html/using_the_application_cache/index.html | 327 +++ .../index.html" | 327 --- .../index.html" | 517 ---- .../index.html" | 32 - .../index.html" | 51 - .../index.html" | 502 ---- files/ru/web/http/authentication/index.html | 123 + .../identifying_resources_on_the_web/index.html | 188 ++ .../identifying_resources_on_the_web_ru/index.html | 188 -- files/ru/web/http/caching/index.html | 165 ++ files/ru/web/http/cookies/index.html | 173 ++ .../ru/web/http/headers/accept-charset/index.html | 83 + .../ru/web/http/headers/accept-language/index.html | 94 + files/ru/web/http/headers/accept-patch/index.html | 83 + files/ru/web/http/headers/accept-ranges/index.html | 77 + files/ru/web/http/headers/accept/index.html | 89 + .../access-control-allow-headers/index.html | 93 + .../access-control-allow-methods/index.html | 85 + .../headers/access-control-allow-origin/index.html | 94 + .../http/headers/access-control-max-age/index.html | 69 + files/ru/web/http/headers/authorization/index.html | 91 + files/ru/web/http/headers/cache-control/index.html | 173 ++ files/ru/web/http/headers/connection/index.html | 53 + .../http/headers/content-disposition/index.html | 137 + .../web/http/headers/content-encoding/index.html | 107 + .../web/http/headers/content-language/index.html | 103 + .../ru/web/http/headers/content-length/index.html | 67 + files/ru/web/http/headers/content-type/index.html | 111 + files/ru/web/http/headers/date/index.html | 86 + files/ru/web/http/headers/dnt/index.html | 83 + files/ru/web/http/headers/etag/index.html | 98 + files/ru/web/http/headers/expect/index.html | 87 + files/ru/web/http/headers/expires/index.html | 80 + files/ru/web/http/headers/host/index.html | 72 + files/ru/web/http/headers/if-match/index.html | 86 + .../web/http/headers/if-modified-since/index.html | 94 + .../http/headers/if-unmodified-since/index.html | 103 + files/ru/web/http/headers/index.html | 573 ++++ files/ru/web/http/headers/last-modified/index.html | 94 + files/ru/web/http/headers/origin/index.html | 77 + files/ru/web/http/headers/pragma/index.html | 78 + files/ru/web/http/headers/range/index.html | 88 + files/ru/web/http/headers/referer/index.html | 94 + files/ru/web/http/headers/retry-after/index.html | 86 + files/ru/web/http/headers/set-cookie/index.html | 193 ++ .../headers/strict-transport-security/index.html | 112 + files/ru/web/http/headers/vary/index.html | 81 + .../http/headers/x-content-type-options/index.html | 83 + .../ru/web/http/headers/x-forwarded-for/index.html | 72 + .../web/http/headers/x-xss-protection/index.html | 87 + .../web/http/server-side_access_control/index.html | 213 -- .../index.html" | 123 - .../accept-charset/index.html" | 83 - .../accept-language/index.html" | 94 - .../accept-patch/index.html" | 83 - .../accept-ranges/index.html" | 77 - .../accept/index.html" | 89 - .../access-control-allow-headers/index.html" | 93 - .../access-control-allow-methods/index.html" | 85 - .../access-control-allow-origin/index.html" | 94 - .../access-control-max-age/index.html" | 69 - .../authorization/index.html" | 91 - .../cache-control/index.html" | 173 -- .../connection/index.html" | 53 - .../content-disposition/index.html" | 137 - .../content-encoding/index.html" | 107 - .../content-language/index.html" | 103 - .../content-length/index.html" | 67 - .../content-type/index.html" | 111 - .../date/index.html" | 86 - .../dnt/index.html" | 83 - .../etag/index.html" | 98 - .../expect/index.html" | 87 - .../expires/index.html" | 80 - .../host/index.html" | 72 - .../if-match/index.html" | 86 - .../if-modified-since/index.html" | 94 - .../if-unmodified-since/index.html" | 103 - .../index.html" | 573 ---- .../last-modified/index.html" | 94 - .../origin/index.html" | 77 - .../pragma/index.html" | 78 - .../range/index.html" | 88 - .../referer/index.html" | 94 - .../retry-after/index.html" | 86 - .../set-cookie/index.html" | 193 -- .../strict-transport-security/index.html" | 112 - .../vary/index.html" | 81 - .../x-content-type-options/index.html" | 83 - .../x-forwarded-for/index.html" | 72 - .../x-xss-protection/index.html" | 87 - .../\320\272\321\203\320\272\320\270/index.html" | 173 -- .../index.html" | 165 -- .../ru/web/javascript/about_javascript/index.html | 60 + files/ru/web/javascript/guide/about/index.html | 159 -- .../web/javascript/guide/introduction/index.html | 159 ++ .../guide/ispolzovanie_promisov/index.html | 321 --- .../guide/javascript_overview/index.html | 142 - .../guide/loops_and_iteration/index.html | 362 +++ .../guide/predefined_core_objects/index.html | 923 ------- .../web/javascript/guide/using_promises/index.html | 321 +++ .../index.html" | 159 -- .../index.html" | 68 - .../index.html" | 362 --- .../index.html | 356 --- .../index.html" | 44 - files/ru/web/javascript/reference/about/index.html | 50 + .../reference/classes/class_fields/index.html | 350 --- .../classes/private_class_fields/index.html | 205 ++ .../classes/public_class_fields/index.html | 350 +++ .../index.html" | 205 -- .../reference/errors/var_hides_argument/index.html | 60 + .../index.html" | 60 - .../functions/method_definitions/index.html | 191 ++ .../index.html" | 191 -- .../global_objects/array/prototype/index.html | 171 -- .../asyncfunction/prototype/index.html | 55 - .../global_objects/boolean/prototype/index.html | 113 - .../global_objects/date/prototype/index.html | 229 -- .../global_objects/error/prototype/index.html | 155 -- .../global_objects/evalerror/prototype/index.html | 122 - .../global_objects/function/prototype/index.html | 152 -- .../generatorfunction/prototype/index.html | 59 - .../internalerror/prototype/index.html | 100 - .../intl/collator/prototype/index.html | 109 - .../intl/datetimeformat/prototype/index.html | 109 - .../intl/numberformat/prototype/index.html | 109 - .../global_objects/map/prototype/index.html | 126 - .../index.html" | 136 - .../global_objects/number/prototype/index.html | 124 - .../global_objects/object/prototype/index.html | 205 -- .../global_objects/promise/prototype/index.html | 67 - .../proxy/handler/deleteproperty/index.html | 131 - .../global_objects/proxy/handler/index.html | 135 - .../global_objects/proxy/handler/set/index.html | 179 -- .../proxy/proxy/deleteproperty/index.html | 131 + .../global_objects/proxy/proxy/set/index.html | 179 ++ .../global_objects/rangeerror/prototype/index.html | 123 - .../referenceerror/prototype/index.html | 123 - .../global_objects/regexp/prototype/index.html | 141 - .../global_objects/set/prototype/index.html | 81 - .../global_objects/string/prototype/index.html | 230 -- .../global_objects/string/trimend/index.html | 93 + .../global_objects/string/trimleft/index.html | 93 - .../global_objects/string/trimright/index.html | 93 - .../global_objects/string/trimstart/index.html | 93 + .../global_objects/symbol/prototype/index.html | 107 - .../syntaxerror/prototype/index.html | 123 - .../global_objects/typedarray/prototype/index.html | 129 - .../global_objects/typeerror/prototype/index.html | 123 - .../global_objects/urierror/prototype/index.html | 123 - .../global_objects/weakmap/prototype/index.html | 75 - .../global_objects/weakset/prototype/index.html | 142 - .../operators/arithmetic_operators/index.html | 291 -- .../reference/operators/assignment/index.html | 66 + .../operators/assignment_operators/index.html | 431 --- .../operators/bitwise_operators/index.html | 626 ----- .../reference/operators/comma_operator/index.html | 103 + .../operators/conditional_operator/index.html | 169 ++ .../reference/operators/grouping/index.html | 91 + .../operators/pipeline_operator/index.html | 77 + .../index.html" | 91 - .../index.html" | 77 - .../index.html" | 300 -- .../index.html" | 103 - .../index.html" | 286 -- .../index.html" | 66 - .../index.html" | 169 -- .../reference/statements/block/index.html | 177 ++ .../reference/statements/default/index.html | 117 - .../\320\261\320\273\320\276\320\272/index.html" | 177 -- .../reference/template_literals/index.html | 243 ++ .../reference/template_strings/index.html | 243 -- .../reference/\320\276\320\261/index.html" | 50 - files/ru/web/javascript/shells/index.html | 44 + .../web/javascript/\320\276_javascript/index.html" | 60 - files/ru/web/manifest/serviceworker/index.html | 91 - files/ru/web/mathml/attribute/index.html | 484 ++++ .../deriving_the_quadratic_formula/index.html | 18 + files/ru/web/mathml/examples/index.html | 26 + .../examples/mathml_pythagorean_theorem/index.html | 29 + .../index.html" | 484 ---- .../deriving_the_quadratic_formula/index.html" | 18 - .../index.html" | 26 - .../mathml_pythagorean_theorem/index.html" | 29 - .../ru/web/media/formats/webrtc_codecs/index.html | 483 ++++ .../index.html" | 483 ---- .../index.html | 174 ++ files/ru/web/performance/fundamentals/index.html | 224 ++ .../index.html" | 224 -- .../index.html" | 174 -- .../index.html" | 64 - files/ru/web/security/csp/index.html | 43 - .../information_security_basics/index.html | 30 - files/ru/web/svg/attribute/onload/index.html | 5 - files/ru/web/svg/element/a/index.html | 151 + files/ru/web/svg/element/animate/index.html | 81 + files/ru/web/svg/element/animatemotion/index.html | 112 + files/ru/web/svg/element/circle/index.html | 109 + files/ru/web/svg/element/defs/index.html | 101 + files/ru/web/svg/element/ellipse/index.html | 129 + files/ru/web/svg/element/feblend/index.html | 115 + files/ru/web/svg/element/foreignobject/index.html | 119 + files/ru/web/svg/element/g/index.html | 98 + files/ru/web/svg/element/image/index.html | 94 + files/ru/web/svg/element/index.html | 253 ++ files/ru/web/svg/element/line/index.html | 104 + files/ru/web/svg/element/lineargradient/index.html | 105 + files/ru/web/svg/element/path/index.html | 98 + files/ru/web/svg/element/pattern/index.html | 125 + files/ru/web/svg/element/polygon/index.html | 95 + files/ru/web/svg/element/radialgradient/index.html | 108 + files/ru/web/svg/element/rect/index.html | 115 + files/ru/web/svg/element/svg/index.html | 119 + files/ru/web/svg/element/text/index.html | 211 ++ files/ru/web/svg/element/use/index.html | 126 + files/ru/web/svg/tutorial/basic_shapes/index.html | 144 + .../svg/tutorial/basic_transformations/index.html | 98 + files/ru/web/svg/tutorial/introduction/index.html | 44 + files/ru/web/svg/tutorial/positions/index.html | 48 + files/ru/web/svg/tutorial/svg_and_css/index.html | 213 ++ .../index.html" | 98 - .../index.html" | 44 - .../index.html" | 144 - .../index.html" | 48 - .../a/index.html" | 151 - .../animate/index.html" | 81 - .../animatemotion/index.html" | 112 - .../circle/index.html" | 109 - .../defs/index.html" | 101 - .../ellipse/index.html" | 129 - .../feblend/index.html" | 115 - .../foreignobject/index.html" | 119 - .../g/index.html" | 98 - .../image/index.html" | 94 - .../index.html" | 253 -- .../line/index.html" | 104 - .../lineargradient/index.html" | 105 - .../path/index.html" | 98 - .../pattern/index.html" | 125 - .../polygon/index.html" | 95 - .../radialgradient/index.html" | 108 - .../rect/index.html" | 115 - .../svg/index.html" | 119 - .../text/index.html" | 211 -- .../use/index.html" | 126 - .../using_custom_elements/index.html | 243 ++ .../index.html" | 243 -- files/ru/web/webapi/index.html | 131 - files/ru/web/xpath/functions/floor/index.html | 21 + files/ru/web/xpath/functions/index.html | 6 + files/ru/web/xpath/funkcje/floor/index.html | 21 - files/ru/web/xpath/funkcje/index.html | 6 - 492 files changed, 34976 insertions(+), 46957 deletions(-) delete mode 100644 "files/ru/web/accessibility/\320\262\320\265\320\261-\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\260/index.html" delete mode 100644 files/ru/web/api/audiocontext/createpanner/index.html delete mode 100644 files/ru/web/api/audiocontext/currenttime/index.html delete mode 100644 files/ru/web/api/audiocontext/decodeaudiodata/index.html create mode 100644 files/ru/web/api/baseaudiocontext/createpanner/index.html create mode 100644 files/ru/web/api/baseaudiocontext/currenttime/index.html create mode 100644 files/ru/web/api/baseaudiocontext/decodeaudiodata/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/basic_animations/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/compositing/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/drawing_text/index.html create mode 100644 files/ru/web/api/canvas_api/tutorial/using_images/index.html delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\320\271/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\320\272\320\276\320\274\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\320\276\321\201\320\275\320\276\320\262\321\213_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\320\277\321\200\320\270\320\274\320\265\320\275\320\265\320\275\320\270\320\265_\321\201\321\202\320\270\320\273\320\265\320\271_\320\270_\321\206\320\262\320\265\321\202\320\276\320\262/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\202\320\265\320\272\321\201\321\202\320\260/index.html" delete mode 100644 "files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\204\320\270\320\263\321\203\321\200/index.html" create mode 100644 files/ru/web/api/crypto/getrandomvalues/index.html create mode 100644 files/ru/web/api/css_object_model/managing_screen_orientation/index.html delete mode 100644 "files/ru/web/api/css_object_model/\320\276\321\200\320\270\320\265\320\275\321\202\320\260\321\206\320\270\321\217_\321\215\320\272\321\200\320\260\320\275\320\260/index.html" delete mode 100644 files/ru/web/api/document/activeelement/index.html delete mode 100644 files/ru/web/api/document/async/index.html create mode 100644 files/ru/web/api/document/createelement/index.html delete mode 100644 files/ru/web/api/document/getselection/index.html create mode 100644 files/ru/web/api/document/images/index.html create mode 100644 files/ru/web/api/document/readystatechange_event/index.html create mode 100644 files/ru/web/api/document_object_model/events/index.html create mode 100644 files/ru/web/api/document_object_model/examples/index.html create mode 100644 files/ru/web/api/document_object_model/index.html create mode 100644 files/ru/web/api/document_object_model/introduction/index.html create mode 100644 files/ru/web/api/document_object_model/locating_dom_elements_using_selectors/index.html create mode 100644 files/ru/web/api/documentorshadowroot/activeelement/index.html create mode 100644 files/ru/web/api/documentorshadowroot/getselection/index.html delete mode 100644 files/ru/web/api/element/accesskey/index.html create mode 100644 files/ru/web/api/element/blur_event/index.html create mode 100644 files/ru/web/api/element/error_event/index.html create mode 100644 files/ru/web/api/element/focusin_event/index.html create mode 100644 files/ru/web/api/element/focusout_event/index.html create mode 100644 files/ru/web/api/elementcssinlinestyle/style/index.html delete mode 100644 files/ru/web/api/eventtarget/attachevent/index.html delete mode 100644 files/ru/web/api/eventtarget/detachevent/index.html create mode 100644 files/ru/web/api/file_and_directory_entries_api/introduction/index.html delete mode 100644 "files/ru/web/api/file_and_directory_entries_api/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" create mode 100644 files/ru/web/api/fullscreen_api/index.html delete mode 100644 files/ru/web/api/geolocation/using_geolocation/index.html delete mode 100644 files/ru/web/api/geolocation/using_geolocation/using_the_geolocation_api/index.html create mode 100644 files/ru/web/api/geolocation_api/index.html create mode 100644 files/ru/web/api/geolocation_api/using_the_geolocation_api/index.html create mode 100644 files/ru/web/api/html_drag_and_drop_api/drag_operations/index.html create mode 100644 files/ru/web/api/html_drag_and_drop_api/index.html delete mode 100644 files/ru/web/api/htmlaudioelement/audio()/index.html create mode 100644 files/ru/web/api/htmlaudioelement/audio/index.html create mode 100644 files/ru/web/api/htmlelement/accesskey/index.html delete mode 100644 files/ru/web/api/htmlelement/dataset/index.html create mode 100644 files/ru/web/api/htmlelement/innertext/index.html delete mode 100644 files/ru/web/api/htmlelement/nonce/index.html delete mode 100644 files/ru/web/api/htmlelement/style/index.html delete mode 100644 files/ru/web/api/htmlelement/tabindex/index.html create mode 100644 files/ru/web/api/htmlelement/transitionend_event/index.html create mode 100644 files/ru/web/api/htmlmediaelement/seeking_event/index.html create mode 100644 files/ru/web/api/htmlorforeignelement/dataset/index.html create mode 100644 files/ru/web/api/htmlorforeignelement/nonce/index.html create mode 100644 files/ru/web/api/htmlorforeignelement/tabindex/index.html create mode 100644 files/ru/web/api/mediatrackconstraints/echocancellation/index.html delete mode 100644 "files/ru/web/api/mediatrackconstraints/\321\215\321\205\320\276\320\277\320\276\320\264\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" create mode 100644 files/ru/web/api/navigator/connection/index.html delete mode 100644 files/ru/web/api/navigatorgeolocation/index.html delete mode 100644 files/ru/web/api/networkinformation/connection/index.html delete mode 100644 files/ru/web/api/node.replacechild/index.html delete mode 100644 files/ru/web/api/node/baseuriobject/index.html delete mode 100644 files/ru/web/api/node/innertext/index.html delete mode 100644 files/ru/web/api/node/nodeprincipal/index.html create mode 100644 files/ru/web/api/node/replacechild/index.html create mode 100644 files/ru/web/api/nondocumenttypechildnode/nextelementsibling/index.html delete mode 100644 files/ru/web/api/nondocumenttypechildnode/nondocumenttypechildnode.nextelementsibling/index.html create mode 100644 files/ru/web/api/notation/index.html create mode 100644 files/ru/web/api/page_visibility_api/index.html delete mode 100644 files/ru/web/api/push_api/using_the_push_api/index.html delete mode 100644 files/ru/web/api/randomsource/getrandomvalues/index.html delete mode 100644 files/ru/web/api/randomsource/index.html delete mode 100644 files/ru/web/api/slotable/index.html delete mode 100644 files/ru/web/api/storage/localstorage/index.html delete mode 100644 files/ru/web/api/svgaelement/svgalement.target/index.html delete mode 100644 files/ru/web/api/web_crypto_api/checking_authenticity_with_password/index.html create mode 100644 files/ru/web/api/web_workers_api/using_web_workers/index.html create mode 100644 files/ru/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html delete mode 100644 "files/ru/web/api/webgl_api/tutorial/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_3d_\320\276\320\261\321\212\320\265\320\272\321\202\320\276\320\262_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_webgl/index.html" create mode 100644 files/ru/web/api/webrtc_api/connectivity/index.html create mode 100644 files/ru/web/api/webrtc_api/protocols/index.html delete mode 100644 files/ru/web/api/webrtc_api/webrtc_basics/index.html delete mode 100644 "files/ru/web/api/webrtc_api/\320\277\321\200\320\276\321\202\320\276\320\272\320\276\320\273\321\213/index.html" delete mode 100644 "files/ru/web/api/webrtc_api/\321\201\320\262\321\217\320\267\321\214/index.html" create mode 100644 files/ru/web/api/websockets_api/index.html create mode 100644 files/ru/web/api/websockets_api/writing_websocket_client_applications/index.html create mode 100644 files/ru/web/api/window/domcontentloaded_event/index.html create mode 100644 files/ru/web/api/window/load_event/index.html create mode 100644 files/ru/web/api/window/requestanimationframe/index.html create mode 100644 files/ru/web/api/window/unhandledrejection_event/index.html delete mode 100644 files/ru/web/api/windowbase64/base64_encoding_and_decoding/index.html delete mode 100644 files/ru/web/api/windowbase64/btoa/index.html delete mode 100644 files/ru/web/api/windowbase64/index.html create mode 100644 files/ru/web/api/windoworworkerglobalscope/btoa/index.html create mode 100644 files/ru/web/api/windoworworkerglobalscope/settimeout/index.html delete mode 100644 files/ru/web/api/windowtimers/index.html delete mode 100644 files/ru/web/api/windowtimers/settimeout/index.html create mode 100644 files/ru/web/api/xmldocument/async/index.html create mode 100644 files/ru/web/api/xmlhttprequest/loadstart_event/index.html delete mode 100644 "files/ru/web/api/\320\262\320\270\320\264\320\270\320\274\320\276\321\201\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213_api/index.html" delete mode 100644 "files/ru/web/api/\320\275\320\276\321\202\320\260\321\206\320\270\321\217/index.html" delete mode 100644 files/ru/web/css/@viewport/user-zoom/index.html delete mode 100644 files/ru/web/css/_colon_any/index.html create mode 100644 files/ru/web/css/actual_value/index.html delete mode 100644 files/ru/web/css/box_model/index.html create mode 100644 files/ru/web/css/comments/index.html delete mode 100644 files/ru/web/css/common_css_questions/index.html delete mode 100644 files/ru/web/css/css_animations/ispolzovanie_css_animatciy/index.html create mode 100644 files/ru/web/css/css_animations/using_css_animations/index.html create mode 100644 files/ru/web/css/css_background_and_borders/border-radius_generator/index.html delete mode 100644 "files/ru/web/css/css_background_and_borders/border-radius_\320\263\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200/index.html" create mode 100644 files/ru/web/css/css_background_and_borders/box-shadow_generator/index.html delete mode 100644 files/ru/web/css/css_background_and_borders/index.html delete mode 100644 "files/ru/web/css/css_background_and_borders/\320\274\320\275\320\276\320\266\320\265\321\201\321\202\320\262\320\265\320\275\320\275\321\213\320\265_\321\204\320\276\320\275\321\213/index.html" create mode 100644 files/ru/web/css/css_backgrounds_and_borders/index.html create mode 100644 files/ru/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html create mode 100644 files/ru/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html delete mode 100644 "files/ru/web/css/css_basic_user_interface/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_url_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\271_\320\264\320\273\321\217_\321\201\320\262\320\276\320\271\321\201\321\202\320\262\320\260_cursor/index.html" delete mode 100644 files/ru/web/css/css_box_model/box-shadow_generator/index.html create mode 100644 files/ru/web/css/css_box_model/introduction_to_the_css_box_model/index.html create mode 100644 files/ru/web/css/css_color/index.html delete mode 100644 files/ru/web/css/css_colors/index.html create mode 100644 files/ru/web/css/css_columns/using_multi-column_layouts/index.html create mode 100644 files/ru/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.html create mode 100644 files/ru/web/css/css_flexible_box_layout/controlling_ratios_of_flex_items_along_the_main_ax/index.html delete mode 100644 files/ru/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html delete mode 100644 "files/ru/web/css/css_flexible_box_layout/\320\262\321\213\321\200\320\260\320\262\320\275\320\270\320\262\320\260\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262_flex_\320\272\320\276\320\275\321\202\320\265\320\271\320\275\320\265\321\200\320\265/index.html" delete mode 100644 "files/ru/web/css/css_flexible_box_layout/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\201\320\276\320\276\321\202\320\275\320\276\321\210\320\265\320\275\320\270\321\217_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262\320\264\320\276\320\273\321\214_\320\263\320\273\320\260\320\262\320\275\320\276\320\271_\320\276\321\201\320\270/index.html" create mode 100644 files/ru/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html create mode 100644 files/ru/web/css/css_flow_layout/intro_to_formatting_contexts/index.html delete mode 100644 "files/ru/web/css/css_flow_layout/\320\261\320\273\320\276\321\207\320\275\320\276\320\265_\320\270_\321\201\321\202\321\200\320\276\321\207\320\275\320\276\320\265_\321\200\320\260\320\267\320\274\320\265\321\211\320\265\320\275\320\270\320\265_\320\262_\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\320\276\320\274_\320\277\320\276\321\202\320\276\320\272\320\265/index.html" delete mode 100644 "files/ru/web/css/css_flow_layout/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_\320\272\320\276\320\275\321\202\320\265\320\272\321\201\321\202\321\213_\321\204\320\276\321\200\320\274\320\260\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" delete mode 100644 files/ru/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html create mode 100644 files/ru/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html create mode 100644 files/ru/web/css/css_grid_layout/grid_template_areas/index.html create mode 100644 files/ru/web/css/css_grid_layout/line-based_placement_with_css_grid/index.html delete mode 100644 "files/ru/web/css/css_grid_layout/\320\263\321\200\320\270\320\264-\320\276\320\261\320\273\320\260\321\201\321\202\320\270/index.html" delete mode 100644 "files/ru/web/css/css_grid_layout/\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276_\320\263\321\200\320\270\320\264-\320\273\320\270\320\275\320\270\321\217\320\274_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_css_grid/index.html" create mode 100644 files/ru/web/css/css_positioning/understanding_z_index/adding_z-index/index.html create mode 100644 files/ru/web/css/css_positioning/understanding_z_index/index.html create mode 100644 files/ru/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html create mode 100644 files/ru/web/css/css_selectors/index.html create mode 100644 files/ru/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html delete mode 100644 files/ru/web/css/css_user_interface/index.html delete mode 100644 "files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" delete mode 100644 "files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/using_the__colon_target_pseudo-class_in_selectors/index.html" delete mode 100644 files/ru/web/css/filter-function/url/index.html delete mode 100644 files/ru/web/css/grid-gap/index.html create mode 100644 files/ru/web/css/layout_mode/index.html create mode 100644 files/ru/web/css/length/index.html create mode 100644 files/ru/web/css/media_queries/testing_media_queries/index.html delete mode 100644 "files/ru/web/css/media_queries/\321\202\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\274\320\265\320\264\320\270\320\260_\320\267\320\260\320\277\321\200\320\276\321\201\321\213/index.html" create mode 100644 files/ru/web/css/pseudo-classes/index.html create mode 100644 files/ru/web/css/replaced_element/index.html create mode 100644 files/ru/web/css/specified_value/index.html create mode 100644 files/ru/web/css/syntax/index.html delete mode 100644 files/ru/web/css/url/index.html create mode 100644 files/ru/web/css/visual_formatting_model/index.html delete mode 100644 "files/ru/web/css/\320\264\320\265\320\271\321\201\321\202\320\262\320\270\321\202\320\265\320\273\321\214\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/web/css/\320\267\320\260\320\274\320\265\321\211\320\260\320\265\320\274\321\213\320\271_\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" delete mode 100644 "files/ru/web/css/\320\277\321\201\320\265\320\262\320\264\320\276-\320\272\320\273\320\260\321\201\321\201\321\213/index.html" delete mode 100644 "files/ru/web/css/\321\200\320\260\320\267\320\274\320\265\321\200/index.html" delete mode 100644 "files/ru/web/css/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\201/index.html" delete mode 100644 "files/ru/web/css/\321\201\320\277\320\276\321\201\320\276\320\261_\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\321\217/index.html" delete mode 100644 "files/ru/web/css/\321\202\320\270\321\205\320\270\320\271/index.html" delete mode 100644 "files/ru/web/css/\321\203\320\272\320\260\320\267\320\260\320\275\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" delete mode 100644 files/ru/web/events/abort/index.html delete mode 100644 files/ru/web/events/blur/index.html delete mode 100644 files/ru/web/events/domcontentloaded/index.html delete mode 100644 files/ru/web/events/error/index.html delete mode 100644 files/ru/web/events/focusin/index.html delete mode 100644 files/ru/web/events/focusout/index.html delete mode 100644 files/ru/web/events/load/index.html delete mode 100644 files/ru/web/events/loadstart/index.html delete mode 100644 files/ru/web/events/readystatechange/index.html delete mode 100644 files/ru/web/events/transitionend/index.html delete mode 100644 files/ru/web/events/unhandledrejection/index.html create mode 100644 files/ru/web/guide/ajax/getting_started/index.html delete mode 100644 "files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214/index.html" delete mode 100644 "files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" delete mode 100644 files/ru/web/guide/api/dom/index.html delete mode 100644 files/ru/web/guide/api/dom/storage/index.html delete mode 100644 files/ru/web/guide/api/webrtc/index.html delete mode 100644 files/ru/web/guide/css/getting_started/cascading_and_inheritance/index.html delete mode 100644 files/ru/web/guide/css/getting_started/color/index.html delete mode 100644 files/ru/web/guide/css/getting_started/how_css_works/index.html delete mode 100644 files/ru/web/guide/css/getting_started/index.html delete mode 100644 files/ru/web/guide/css/getting_started/readable_css/index.html delete mode 100644 files/ru/web/guide/css/getting_started/selectors/index.html delete mode 100644 "files/ru/web/guide/css/getting_started/svg_\320\270_css/index.html" delete mode 100644 files/ru/web/guide/css/getting_started/text_styles/index.html delete mode 100644 files/ru/web/guide/css/getting_started/what_is_css/index.html delete mode 100644 files/ru/web/guide/css/getting_started/why_use_css/index.html delete mode 100644 "files/ru/web/guide/css/getting_started/\321\202\320\260\320\261\320\273\320\270\321\206\321\213/index.html" delete mode 100644 files/ru/web/guide/css/index.html delete mode 100644 files/ru/web/guide/css/understanding_z_index/adding_z-index/index.html delete mode 100644 files/ru/web/guide/css/understanding_z_index/index.html delete mode 100644 files/ru/web/guide/css/understanding_z_index/stacking_without_z-index/index.html delete mode 100644 files/ru/web/guide/css/using_multi-column_layouts/index.html delete mode 100644 files/ru/web/guide/css/visual_formatting_model/index.html create mode 100644 files/ru/web/guide/events/creating_and_triggering_events/index.html delete mode 100644 "files/ru/web/guide/events/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\320\262\321\213\320\267\320\276\320\262_\321\201\320\276\320\261\321\213\321\202\320\270\320\271/index.html" create mode 100644 files/ru/web/guide/graphics/index.html delete mode 100644 files/ru/web/guide/html/drag_and_drop/drag_operations/index.html delete mode 100644 files/ru/web/guide/html/drag_and_drop/index.html create mode 100644 files/ru/web/guide/html/html5/constraint_validation/index.html create mode 100644 files/ru/web/guide/html/html5/index.html create mode 100644 files/ru/web/guide/html/html5/introduction_to_html5/index.html delete mode 100644 files/ru/web/guide/html/sections_and_outlines_of_an_html5_document/index.html delete mode 100644 files/ru/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html delete mode 100644 files/ru/web/guide/html/using_data_attributes/index.html create mode 100644 files/ru/web/guide/html/using_html_sections_and_outlines/index.html delete mode 100644 "files/ru/web/guide/html/\321\204\320\276\321\200\320\274\321\213_\320\262_html/index.html" create mode 100644 files/ru/web/guide/performance/index.html delete mode 100644 "files/ru/web/guide/\320\263\321\200\320\260\321\204\320\270\320\272\320\260/index.html" delete mode 100644 "files/ru/web/guide/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" create mode 100644 files/ru/web/html/attributes/crossorigin/index.html delete mode 100644 files/ru/web/html/cors_settings_attributes/index.html create mode 100644 files/ru/web/html/element/button/index.html delete mode 100644 files/ru/web/html/element/element/index.html create mode 100644 files/ru/web/html/element/link/index.html delete mode 100644 files/ru/web/html/element/video/seeking_event/index.html delete mode 100644 "files/ru/web/html/element/\320\272\320\275\320\276\320\277\320\272\320\260/index.html" delete mode 100644 "files/ru/web/html/element/\321\201\321\201\321\213\320\273\320\272\320\260/index.html" delete mode 100644 files/ru/web/html/global_attributes/dropzone/index.html create mode 100644 files/ru/web/html/inline_elements/index.html create mode 100644 files/ru/web/html/link_types/index.html delete mode 100644 files/ru/web/html/optimizing_your_pages_for_speculative_parsing/index.html create mode 100644 files/ru/web/html/reference/index.html create mode 100644 files/ru/web/html/using_the_application_cache/index.html delete mode 100644 "files/ru/web/html/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\272\321\215\321\210\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217_\320\277\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\320\271/index.html" delete mode 100644 "files/ru/web/html/\320\277\320\276\320\264\320\264\320\265\321\200\320\266\320\270\320\262\320\260\320\265\320\274\321\213\320\265_\320\274\320\265\320\264\320\270\320\260_\321\204\320\276\321\200\320\274\320\260\321\202\321\213/index.html" delete mode 100644 "files/ru/web/html/\321\201\321\201\321\213\320\273\320\272\320\270/index.html" delete mode 100644 "files/ru/web/html/\321\201\321\202\321\200\320\276\321\207\320\275\321\213\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\321\213/index.html" delete mode 100644 "files/ru/web/html/\321\202\320\270\320\277\321\213_\321\201\321\201\321\213\320\273\320\276\320\272/index.html" create mode 100644 files/ru/web/http/authentication/index.html create mode 100644 files/ru/web/http/basics_of_http/identifying_resources_on_the_web/index.html delete mode 100644 files/ru/web/http/basics_of_http/identifying_resources_on_the_web_ru/index.html create mode 100644 files/ru/web/http/caching/index.html create mode 100644 files/ru/web/http/cookies/index.html create mode 100644 files/ru/web/http/headers/accept-charset/index.html create mode 100644 files/ru/web/http/headers/accept-language/index.html create mode 100644 files/ru/web/http/headers/accept-patch/index.html create mode 100644 files/ru/web/http/headers/accept-ranges/index.html create mode 100644 files/ru/web/http/headers/accept/index.html create mode 100644 files/ru/web/http/headers/access-control-allow-headers/index.html create mode 100644 files/ru/web/http/headers/access-control-allow-methods/index.html create mode 100644 files/ru/web/http/headers/access-control-allow-origin/index.html create mode 100644 files/ru/web/http/headers/access-control-max-age/index.html create mode 100644 files/ru/web/http/headers/authorization/index.html create mode 100644 files/ru/web/http/headers/cache-control/index.html create mode 100644 files/ru/web/http/headers/connection/index.html create mode 100644 files/ru/web/http/headers/content-disposition/index.html create mode 100644 files/ru/web/http/headers/content-encoding/index.html create mode 100644 files/ru/web/http/headers/content-language/index.html create mode 100644 files/ru/web/http/headers/content-length/index.html create mode 100644 files/ru/web/http/headers/content-type/index.html create mode 100644 files/ru/web/http/headers/date/index.html create mode 100644 files/ru/web/http/headers/dnt/index.html create mode 100644 files/ru/web/http/headers/etag/index.html create mode 100644 files/ru/web/http/headers/expect/index.html create mode 100644 files/ru/web/http/headers/expires/index.html create mode 100644 files/ru/web/http/headers/host/index.html create mode 100644 files/ru/web/http/headers/if-match/index.html create mode 100644 files/ru/web/http/headers/if-modified-since/index.html create mode 100644 files/ru/web/http/headers/if-unmodified-since/index.html create mode 100644 files/ru/web/http/headers/index.html create mode 100644 files/ru/web/http/headers/last-modified/index.html create mode 100644 files/ru/web/http/headers/origin/index.html create mode 100644 files/ru/web/http/headers/pragma/index.html create mode 100644 files/ru/web/http/headers/range/index.html create mode 100644 files/ru/web/http/headers/referer/index.html create mode 100644 files/ru/web/http/headers/retry-after/index.html create mode 100644 files/ru/web/http/headers/set-cookie/index.html create mode 100644 files/ru/web/http/headers/strict-transport-security/index.html create mode 100644 files/ru/web/http/headers/vary/index.html create mode 100644 files/ru/web/http/headers/x-content-type-options/index.html create mode 100644 files/ru/web/http/headers/x-forwarded-for/index.html create mode 100644 files/ru/web/http/headers/x-xss-protection/index.html delete mode 100644 files/ru/web/http/server-side_access_control/index.html delete mode 100644 "files/ru/web/http/\320\260\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept-charset/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept-language/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept-patch/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept-ranges/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/accept/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/access-control-allow-headers/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/access-control-allow-methods/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/access-control-allow-origin/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/access-control-max-age/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/authorization/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/cache-control/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/connection/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-disposition/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-encoding/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-language/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-length/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/content-type/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/date/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/dnt/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/etag/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/expect/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/expires/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/host/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/if-match/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/if-modified-since/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/if-unmodified-since/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/last-modified/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/origin/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/pragma/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/range/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/referer/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/retry-after/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/set-cookie/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/strict-transport-security/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/vary/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/x-content-type-options/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/x-forwarded-for/index.html" delete mode 100644 "files/ru/web/http/\320\267\320\260\320\263\320\276\320\273\320\276\320\262\320\272\320\270/x-xss-protection/index.html" delete mode 100644 "files/ru/web/http/\320\272\321\203\320\272\320\270/index.html" delete mode 100644 "files/ru/web/http/\320\272\321\215\321\210\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/index.html" create mode 100644 files/ru/web/javascript/about_javascript/index.html delete mode 100644 files/ru/web/javascript/guide/about/index.html create mode 100644 files/ru/web/javascript/guide/introduction/index.html delete mode 100644 files/ru/web/javascript/guide/ispolzovanie_promisov/index.html delete mode 100644 files/ru/web/javascript/guide/javascript_overview/index.html create mode 100644 files/ru/web/javascript/guide/loops_and_iteration/index.html delete mode 100644 files/ru/web/javascript/guide/predefined_core_objects/index.html create mode 100644 files/ru/web/javascript/guide/using_promises/index.html delete mode 100644 "files/ru/web/javascript/guide/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_javascript/index.html" delete mode 100644 "files/ru/web/javascript/guide/\320\276\320\261_\321\215\321\202\320\276\320\274_\321\200\321\203\320\272\320\276\320\262\320\276\320\264\321\201\321\202\320\262\320\265/index.html" delete mode 100644 "files/ru/web/javascript/guide/\321\206\320\270\320\272\320\273\321\213_\320\270_\320\270\321\202\320\265\321\200\320\260\321\206\320\270\320\270/index.html" delete mode 100644 files/ru/web/javascript/introduction_to_object-oriented_javascript/index.html delete mode 100644 "files/ru/web/javascript/javascript_\321\210\320\265\320\273\320\273\321\213/index.html" create mode 100644 files/ru/web/javascript/reference/about/index.html delete mode 100644 files/ru/web/javascript/reference/classes/class_fields/index.html create mode 100644 files/ru/web/javascript/reference/classes/private_class_fields/index.html create mode 100644 files/ru/web/javascript/reference/classes/public_class_fields/index.html delete mode 100644 "files/ru/web/javascript/reference/classes/\320\277\321\200\320\270\320\262\320\260\321\202\320\275\321\213\320\265_\320\277\320\276\320\273\321\217_\320\272\320\273\320\260\321\201\321\201\320\260/index.html" create mode 100644 files/ru/web/javascript/reference/errors/var_hides_argument/index.html delete mode 100644 "files/ru/web/javascript/reference/errors/\320\277\320\265\321\200\320\265\320\274\320\265\320\275\320\275\321\213\320\265_\321\201\320\272\321\200\321\213\320\262\320\260\321\216\321\202_\320\260\321\200\320\263\321\203\320\274\320\265\320\275\321\202/index.html" create mode 100644 files/ru/web/javascript/reference/functions/method_definitions/index.html delete mode 100644 "files/ru/web/javascript/reference/functions/\320\276\320\277\321\200\320\265\320\264\320\265\320\273\320\270\320\275\320\270\320\265_\320\274\320\265\321\202\320\276\320\264\320\276\320\262/index.html" delete mode 100644 files/ru/web/javascript/reference/global_objects/array/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/asyncfunction/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/boolean/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/date/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/error/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/evalerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/function/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/generatorfunction/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/internalerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/intl/collator/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/map/prototype/index.html delete mode 100644 "files/ru/web/javascript/reference/global_objects/math/\320\274\320\265\321\202\320\276\320\264_math.max()_/index.html" delete mode 100644 files/ru/web/javascript/reference/global_objects/number/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/object/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/promise/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/proxy/handler/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/proxy/handler/set/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/proxy/set/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/rangeerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/referenceerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/regexp/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/set/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/string/prototype/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/string/trimend/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/string/trimleft/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/string/trimright/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/string/trimstart/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/symbol/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/syntaxerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/typedarray/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/typeerror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/urierror/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/weakmap/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/global_objects/weakset/prototype/index.html delete mode 100644 files/ru/web/javascript/reference/operators/arithmetic_operators/index.html create mode 100644 files/ru/web/javascript/reference/operators/assignment/index.html delete mode 100644 files/ru/web/javascript/reference/operators/assignment_operators/index.html delete mode 100644 files/ru/web/javascript/reference/operators/bitwise_operators/index.html create mode 100644 files/ru/web/javascript/reference/operators/comma_operator/index.html create mode 100644 files/ru/web/javascript/reference/operators/conditional_operator/index.html create mode 100644 files/ru/web/javascript/reference/operators/grouping/index.html create mode 100644 files/ru/web/javascript/reference/operators/pipeline_operator/index.html delete mode 100644 "files/ru/web/javascript/reference/operators/\320\263\321\200\321\203\320\277\320\277\320\270\321\200\320\276\320\262\320\272\320\260/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\272\320\276\320\275\320\262\320\265\320\271\320\265\321\200\320\275\321\213\320\271_\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\273\320\276\320\263\320\270\321\207\320\265\321\201\320\272\320\270\320\265_\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200\321\213/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200_\320\267\320\260\320\277\321\217\321\202\320\260\321\217/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200\321\213_\321\201\321\200\320\260\320\262\320\275\320\265\320\275\320\270\321\217/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\320\277\321\200\320\270\321\201\320\262\320\260\320\270\320\262\320\260\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/web/javascript/reference/operators/\321\203\321\201\320\273\320\276\320\262\320\275\321\213\320\271_\320\276\320\277\320\265\321\200\320\260\321\202\320\276\321\200/index.html" create mode 100644 files/ru/web/javascript/reference/statements/block/index.html delete mode 100644 files/ru/web/javascript/reference/statements/default/index.html delete mode 100644 "files/ru/web/javascript/reference/statements/\320\261\320\273\320\276\320\272/index.html" create mode 100644 files/ru/web/javascript/reference/template_literals/index.html delete mode 100644 files/ru/web/javascript/reference/template_strings/index.html delete mode 100644 "files/ru/web/javascript/reference/\320\276\320\261/index.html" create mode 100644 files/ru/web/javascript/shells/index.html delete mode 100644 "files/ru/web/javascript/\320\276_javascript/index.html" delete mode 100644 files/ru/web/manifest/serviceworker/index.html create mode 100644 files/ru/web/mathml/attribute/index.html create mode 100644 files/ru/web/mathml/examples/deriving_the_quadratic_formula/index.html create mode 100644 files/ru/web/mathml/examples/index.html create mode 100644 files/ru/web/mathml/examples/mathml_pythagorean_theorem/index.html delete mode 100644 "files/ru/web/mathml/\320\260\321\202\321\200\320\270\320\261\321\203\321\202/index.html" delete mode 100644 "files/ru/web/mathml/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/deriving_the_quadratic_formula/index.html" delete mode 100644 "files/ru/web/mathml/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/index.html" delete mode 100644 "files/ru/web/mathml/\320\277\321\200\320\270\320\274\320\265\321\200\321\213/mathml_pythagorean_theorem/index.html" create mode 100644 files/ru/web/media/formats/webrtc_codecs/index.html delete mode 100644 "files/ru/web/media/formats/webrtc_\320\272\320\276\320\264\320\265\320\272\320\270/index.html" create mode 100644 files/ru/web/performance/animation_performance_and_frame_rate/index.html create mode 100644 files/ru/web/performance/fundamentals/index.html delete mode 100644 "files/ru/web/performance/\320\276\321\201\320\275\320\276\320\262\321\213/index.html" delete mode 100644 "files/ru/web/performance/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" delete mode 100644 "files/ru/web/progressive_web_apps/\320\267\320\260\320\274\320\265\321\202\320\275\321\213\320\271/index.html" delete mode 100644 files/ru/web/security/csp/index.html delete mode 100644 files/ru/web/security/information_security_basics/index.html delete mode 100644 files/ru/web/svg/attribute/onload/index.html create mode 100644 files/ru/web/svg/element/a/index.html create mode 100644 files/ru/web/svg/element/animate/index.html create mode 100644 files/ru/web/svg/element/animatemotion/index.html create mode 100644 files/ru/web/svg/element/circle/index.html create mode 100644 files/ru/web/svg/element/defs/index.html create mode 100644 files/ru/web/svg/element/ellipse/index.html create mode 100644 files/ru/web/svg/element/feblend/index.html create mode 100644 files/ru/web/svg/element/foreignobject/index.html create mode 100644 files/ru/web/svg/element/g/index.html create mode 100644 files/ru/web/svg/element/image/index.html create mode 100644 files/ru/web/svg/element/index.html create mode 100644 files/ru/web/svg/element/line/index.html create mode 100644 files/ru/web/svg/element/lineargradient/index.html create mode 100644 files/ru/web/svg/element/path/index.html create mode 100644 files/ru/web/svg/element/pattern/index.html create mode 100644 files/ru/web/svg/element/polygon/index.html create mode 100644 files/ru/web/svg/element/radialgradient/index.html create mode 100644 files/ru/web/svg/element/rect/index.html create mode 100644 files/ru/web/svg/element/svg/index.html create mode 100644 files/ru/web/svg/element/text/index.html create mode 100644 files/ru/web/svg/element/use/index.html create mode 100644 files/ru/web/svg/tutorial/basic_shapes/index.html create mode 100644 files/ru/web/svg/tutorial/basic_transformations/index.html create mode 100644 files/ru/web/svg/tutorial/introduction/index.html create mode 100644 files/ru/web/svg/tutorial/positions/index.html create mode 100644 files/ru/web/svg/tutorial/svg_and_css/index.html delete mode 100644 "files/ru/web/svg/tutorial/\320\261\320\260\320\267\320\276\320\262\321\213\320\265_\320\277\321\200\320\265\320\276\320\261\321\200\320\260\320\267\320\276\320\262\320\260\320\275\320\270\321\217/index.html" delete mode 100644 "files/ru/web/svg/tutorial/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" delete mode 100644 "files/ru/web/svg/tutorial/\320\276\321\201\320\275\320\276\320\262\320\275\321\213\320\265_\321\204\320\270\320\263\321\203\321\200\321\213/index.html" delete mode 100644 "files/ru/web/svg/tutorial/\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/a/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/animate/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/animatemotion/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/circle/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/defs/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/ellipse/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/feblend/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/foreignobject/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/g/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/image/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/line/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/lineargradient/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/path/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/pattern/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/polygon/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/radialgradient/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/rect/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/svg/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/text/index.html" delete mode 100644 "files/ru/web/svg/\321\215\320\273\320\265\320\274\320\265\320\275\321\202/use/index.html" create mode 100644 files/ru/web/web_components/using_custom_elements/index.html delete mode 100644 "files/ru/web/web_components/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\214\321\201\320\272\320\270\321\205_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262/index.html" delete mode 100644 files/ru/web/webapi/index.html create mode 100644 files/ru/web/xpath/functions/floor/index.html create mode 100644 files/ru/web/xpath/functions/index.html delete mode 100644 files/ru/web/xpath/funkcje/floor/index.html delete mode 100644 files/ru/web/xpath/funkcje/index.html (limited to 'files/ru/web') diff --git "a/files/ru/web/accessibility/\320\262\320\265\320\261-\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\260/index.html" "b/files/ru/web/accessibility/\320\262\320\265\320\261-\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\260/index.html" deleted file mode 100644 index ce48a75de2..0000000000 --- "a/files/ru/web/accessibility/\320\262\320\265\320\261-\321\200\320\260\320\267\321\200\320\260\320\261\320\276\321\202\320\272\320\260/index.html" +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Веб-разработка -slug: Web/Accessibility/Веб-разработка -tags: - - ARIA - - Web Development - - XUL - - доступность -translation_of: Web/Accessibility -translation_of_original: Web/Accessibility/Web_Development ---- -

Здесь ссылки на более подробную информацию для разработчиков о доступности (accessibility) в Веб и в XUL.

- - - - - - - - -
-

Доступность в Вебе

- -
-
ARIA для разработчиков
-
ARIA позволяет делать доступным динамический HTML-контент. Examples are live content regions and JavaScript widgets.
-
Keyboard-navigable JavaScript widgets
-
До недавнего времени у веб-разработчиков, желавших сделать свои виджеты на основе <div>, <span> и стилей доступными с клавиатуры, не было the proper techniques. Управляемость с клавиатуры — одно из минимальных требований accessibility, о которых должен знать каждый разработчик.
-
- -

Доступность XUL

- -
-
 
-
Building accessible custom components in XUL
-
How to use DHTML Accessibility techniques to add accessibility to your custom XUL components.
-
Accessible XUL authoring guidelines
-
When authored according to these guidelines, XUL is capable of generating accessible user interfaces. Coders, reviewers, designers and QA engineers should be familiar with these guidelines.
-
-
-

Внешние ресурсы

- -
-
Dive into Accessibility
-
Эта книга отвечает на два вопроса. Первый — «Зачем мне делать мой сайт более доступным?» Второй — «Как мне сделать мой сайт более доступным?»
-
Accessible Web Page Authoring
-
A handy web accessibility checklist, from IBM.
-
-
- -

 

diff --git a/files/ru/web/api/audiocontext/createpanner/index.html b/files/ru/web/api/audiocontext/createpanner/index.html deleted file mode 100644 index 0a4d5db32b..0000000000 --- a/files/ru/web/api/audiocontext/createpanner/index.html +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: AudioContext.createPanner() -slug: Web/API/AudioContext/createPanner -translation_of: Web/API/BaseAudioContext/createPanner ---- -

{{ APIRef("Web Audio API") }}

- -
-

Метод createPanner() интерфейса {{ domxref("AudioContext") }} применяется для создания нового {{domxref("PannerNode")}}, который используется для размещения аудиопотока в виртуальном 3D пространстве.

-
- -

The panner node is spatialized in relation to the AudioContext's {{domxref("AudioListener") }} (defined by the {{domxref("AudioContext.listener") }} attribute), which represents the position and orientation of the person listening to the audio.

- -

Синтаксис

- -
var audioCtx = new AudioContext();
-var panner = audioCtx.createPanner();
- -

Возврат

- -

A {{domxref("PannerNode")}}.

- -

Пример

- -
-
Ниже можно увидеть пример использования {{domxref("AudioListener")}}, {{domxref("PannerNode")}} и метода createPanner() для управления пространством объемного звука. Обычно определяется положение в трехмерном пространстве, изначально занимаемое слушателем (listener) и источником звука (panner), а затем, при использовании приложения, обновляется позиция одного из них или обоих. Например, вы можете перемещать персонажа внутри игрового мира, и желательно чтобы передача звука изменялась реалистично, по мере приближения или отдаления персонажа относительно источника звука, вроде стереопроигрывателя. В этом примере можно видеть, что все это управляется функциями moveRight(), moveLeft(), и т.п., которые устанавливают новые значения для положения паннера через функцию PositionPanner().
- -
 
- -
-
-
Чтобы увидеть полную реализацию ознакомьтесь с нашим примером panner-node (просмотрите весь список примеров) — эта демонстрация перенесет вас в 2.5D "Room of metal" (2,5-мерную "металлическую комнату"), где можно проиграть трек на бумбоксе и затем походить вокруг него и посмотреть как изменяется звук!
- -
 
-
-
-
- -

Note how we have used some feature detection to either give the browser the newer property values (like {{domxref("AudioListener.forwardX")}}) for setting position, etc. if it supports those, or older methods (like {{domxref("AudioListener.setOrientation()")}}) if it still supports those but not the new properties.

- -
// set up listener and panner position information
-// установка сведений о слушателе (listener) и положении panner'а
-var WIDTH = window.innerWidth;
-var HEIGHT = window.innerHeight;
-
-var xPos = Math.floor(WIDTH/2);
-var yPos = Math.floor(HEIGHT/2);
-var zPos = 295;
-
-// define other variables (определяем другие переменные)
-
-var AudioContext = window.AudioContext || window.webkitAudioContext;
-var audioCtx = new AudioContext();
-
-var panner = audioCtx.createPanner();
-panner.panningModel = 'HRTF';
-panner.distanceModel = 'inverse';
-panner.refDistance = 1;
-panner.maxDistance = 10000;
-panner.rolloffFactor = 1;
-panner.coneInnerAngle = 360;
-panner.coneOuterAngle = 0;
-panner.coneOuterGain = 0;
-
-if(panner.orientationX) {
-  panner.orientationX.value = 1;
-  panner.orientationY.value = 0;
-  panner.orientationZ.value = 0;
-} else {
-  panner.setOrientation(1,0,0);
-}
-
-var listener = audioCtx.listener;
-
-if(listener.forwardX) {
-  listener.forwardX.value = 0;
-  listener.forwardY.value = 0;
-  listener.forwardZ.value = -1;
-  listener.upX.value = 0;
-  listener.upY.value = 1;
-  listener.upZ.value = 0;
-} else {
-  listener.setOrientation(0,0,-1,0,1,0);
-}
-
-var source;
-
-var play = document.querySelector('.play');
-var stop = document.querySelector('.stop');
-
-var boomBox = document.querySelector('.boom-box');
-
-var listenerData = document.querySelector('.listener-data');
-var pannerData = document.querySelector('.panner-data');
-
-leftBound = (-xPos) + 50;
-rightBound = xPos - 50;
-
-xIterator = WIDTH/150;
-
-// listener will always be in the same place for this demo
-// в этом демо слушатель всегда находится на одном и том же месте
-
-if(listener.positionX) {
-  listener.positionX.value = xPos;
-  listener.positionY.value = yPos;
-  listener.positionZ.value = 300;
-} else {
-  listener.setPosition(xPos,yPos,300);
-}
-
-listenerData.innerHTML = 'Listener data: X ' + xPos + ' Y ' + yPos + ' Z ' + 300;
-
-// panner will move as the boombox graphic moves around on the screen
-// паннер будет перемещаться по экрану за перемещением бумбокса
-function positionPanner() {
-  if(panner.positionX) {
-    panner.positionX.value = xPos;
-    panner.positionY.value = yPos;
-    panner.positionZ.value = zPos;
-  } else {
-    panner.setPosition(xPos,yPos,zPos);
-  }
-  pannerData.innerHTML = 'Panner data: X ' + xPos + ' Y ' + yPos + ' Z ' + zPos;
-}
- -
-

In terms of working out what position values to apply to the listener and panner, to make the sound appropriate to what the visuals are doing on screen, there is quite a bit of fiddly math involved, but you will soon get used to it with a bit of experimentation.

-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createPanner-PannerNode', 'createPanner()')}}{{Spec2('Web Audio API')}} 
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatVersionUnknown}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
- 22 (unprefixed)
6.0{{property_prefix("webkit")}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}33.0
-
- -

See also

- - diff --git a/files/ru/web/api/audiocontext/currenttime/index.html b/files/ru/web/api/audiocontext/currenttime/index.html deleted file mode 100644 index 51370701f4..0000000000 --- a/files/ru/web/api/audiocontext/currenttime/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: AudioContext.currentTime -slug: Web/API/AudioContext/currentTime -translation_of: Web/API/BaseAudioContext/currentTime ---- -

{{ APIRef("AudioContext") }}

-
-

Поле currentTime принадлежит {{ domxref("AudioContext") }} и возвращает время с момента создания AudioContext. Может использоваться при планировании воспроизведения или визуализации.  Поле currentTime является не перезаписываемым и не может быть остановлено или сброшено.

-
-

Синтаксис

-
var audioCtx = new AudioContext();
-console.log(audioCtx.currentTime);
-

Тип данных

-

A double.

-

Примеры

-
-

Примечание: для большего понимания реализации Web Audio, посмотрите наши Web Audio Demos на MDN Github repo, like panner-node. Попробуйте ввести audioCtx.currentTime в консоли вашего браузера.

-
-
var AudioContext = window.AudioContext || window.webkitAudioContext;
-var audioCtx = new AudioContext();
-// Older webkit/blink browsers require a prefix
-
-...
-
-console.log(audioCtx.currentTime);
-
-

Specifications

- - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-currentTime', 'currentTime')}}{{Spec2('Web Audio API')}} 
-

Browser compatibility

-
- {{CompatibilityTable}}
-
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
- 22 (unprefixed)
6.0{{property_prefix("webkit")}}
-
-
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}33.0
-
-

See also

- diff --git a/files/ru/web/api/audiocontext/decodeaudiodata/index.html b/files/ru/web/api/audiocontext/decodeaudiodata/index.html deleted file mode 100644 index faae982eae..0000000000 --- a/files/ru/web/api/audiocontext/decodeaudiodata/index.html +++ /dev/null @@ -1,220 +0,0 @@ ---- -title: AudioContext.decodeAudioData() -slug: Web/API/AudioContext/decodeAudioData -tags: - - API -translation_of: Web/API/BaseAudioContext/decodeAudioData ---- -

{{ APIRef("Web Audio API") }}

- -
-

The decodeAudioData() method of the {{ domxref("AudioContext") }} Interface is used to asynchronously decode audio file data contained in an {{domxref("ArrayBuffer")}}. In this case the ArrayBuffer is usually loaded from an {{domxref("XMLHttpRequest")}}'s response attribute after setting the responseType to arraybuffer. The decoded AudioBuffer is resampled to the AudioContext's sampling rate, then passed to a callback or promise.

-
- -

This is the preferred method of creating an audio source for Web Audio API from an audio track.

- -

Syntax

- -

Older callback syntax:

- -
audioCtx.decodeAudioData(audioData, function(decodedData) {
-  // use the dec​oded data here
-});
- -

Newer promise-based syntax:

- -
audioCtx.decodeAudioData(audioData).then(function(decodedData) {
-  // use the decoded data here
-});
- -

Example

- -

In this section we will first cover the older callback-based system and then the newer promise-based syntax.

- -

Older callback syntax

- -

In this example, the getData() function uses XHR to load an audio track, setting the responseType of the request to arraybuffer so that it returns an array buffer as its response that we then store in the audioData variable . We then pass this buffer into a decodeAudioData() function; the success callback takes the successfully decoded PCM data, puts it into an {{ domxref("AudioBufferSourceNode") }} created using {{ domxref("AudioContext.createBufferSource()") }}, connects the source to the {{domxref("AudioContext.destination") }} and sets it to loop.

- -

The buttons in the example simply run getData() to load the track and start it playing, and stop it playing, respectively. When the stop() method is called on the source, the source is cleared out.

- -
-

Note: You can run the example live (or view the source.)

-
- -
// define variables
-
-var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
-var source;
-
-var pre = document.querySelector('pre');
-var myScript = document.querySelector('script');
-var play = document.querySelector('.play');
-var stop = document.querySelector('.stop');
-
-// use XHR to load an audio track, and
-// decodeAudioData to decode it and stick it in a buffer.
-// Then we put the buffer into the source
-
-function getData() {
-  source = audioCtx.createBufferSource();
-  var request = new XMLHttpRequest();
-
-  request.open('GET', 'viper.ogg', true);
-
-  request.responseType = 'arraybuffer';
-
-
-  request.onload = function() {
-    var audioData = request.response;
-
-    audioCtx.decodeAudioData(audioData, function(buffer) {
-        source.buffer = buffer;
-
-        source.connect(audioCtx.destination);
-        source.loop = true;
-      },
-
-      function(e){"Error with decoding audio data" + e.err});
-
-  }
-
-  request.send();
-}
-
-// wire up buttons to stop and play audio
-
-play.onclick = function() {
-  getData();
-  source.start(0);
-  play.setAttribute('disabled', 'disabled');
-}
-
-stop.onclick = function() {
-  source.stop(0);
-  play.removeAttribute('disabled');
-}
-
-
-// dump script to pre element
-
-pre.innerHTML = myScript.innerHTML;
- -

New promise-based syntax

- -
ctx.decodeAudioData(compressedBuffer).then(function(decodedData) {
- // use the decoded data here
-});
- -

Parameters

- -
-
ArrayBuffer
-
An ArrayBuffer containing the audio data to be decoded, usually grabbed from an {{domxref("XMLHttpRequest")}}'s response attribute after setting the responseType to arraybuffer.
-
DecodeSuccessCallback
-
A callback function to be invoked when the decoding successfully finishes. The single argument to this callback is an AudioBuffer representing the decoded PCM audio data. Usually you'll want to put the decoded data into an {{domxref("AudioBufferSourceNode")}}, from which it can be played and manipulated how you want.
-
DecodeErrorCallback
-
An optional error callback, to be invoked if an error occurs when the audio data is being decoded.
-
- -

Returns

- -

An {{domxref("AudioBuffer") }} representing the decoded PCM audio data.

- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-decodeAudioData-Promise-AudioBuffer--ArrayBuffer-audioData-DecodeSuccessCallback-successCallback-DecodeErrorCallback-errorCallback', 'decodeAudioData()')}}{{Spec2('Web Audio API')}} 
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
- 22 (unprefixed)
6.0{{property_prefix("webkit")}}
Promise-based syntax{{CompatChrome(49.0)}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(33.0)}}
Promise-based syntax{{CompatUnknown}}{{CompatChrome(49.0)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(49.0)}}
-
- -

See also

- - diff --git a/files/ru/web/api/baseaudiocontext/createpanner/index.html b/files/ru/web/api/baseaudiocontext/createpanner/index.html new file mode 100644 index 0000000000..0a4d5db32b --- /dev/null +++ b/files/ru/web/api/baseaudiocontext/createpanner/index.html @@ -0,0 +1,211 @@ +--- +title: AudioContext.createPanner() +slug: Web/API/AudioContext/createPanner +translation_of: Web/API/BaseAudioContext/createPanner +--- +

{{ APIRef("Web Audio API") }}

+ +
+

Метод createPanner() интерфейса {{ domxref("AudioContext") }} применяется для создания нового {{domxref("PannerNode")}}, который используется для размещения аудиопотока в виртуальном 3D пространстве.

+
+ +

The panner node is spatialized in relation to the AudioContext's {{domxref("AudioListener") }} (defined by the {{domxref("AudioContext.listener") }} attribute), which represents the position and orientation of the person listening to the audio.

+ +

Синтаксис

+ +
var audioCtx = new AudioContext();
+var panner = audioCtx.createPanner();
+ +

Возврат

+ +

A {{domxref("PannerNode")}}.

+ +

Пример

+ +
+
Ниже можно увидеть пример использования {{domxref("AudioListener")}}, {{domxref("PannerNode")}} и метода createPanner() для управления пространством объемного звука. Обычно определяется положение в трехмерном пространстве, изначально занимаемое слушателем (listener) и источником звука (panner), а затем, при использовании приложения, обновляется позиция одного из них или обоих. Например, вы можете перемещать персонажа внутри игрового мира, и желательно чтобы передача звука изменялась реалистично, по мере приближения или отдаления персонажа относительно источника звука, вроде стереопроигрывателя. В этом примере можно видеть, что все это управляется функциями moveRight(), moveLeft(), и т.п., которые устанавливают новые значения для положения паннера через функцию PositionPanner().
+ +
 
+ +
+
+
Чтобы увидеть полную реализацию ознакомьтесь с нашим примером panner-node (просмотрите весь список примеров) — эта демонстрация перенесет вас в 2.5D "Room of metal" (2,5-мерную "металлическую комнату"), где можно проиграть трек на бумбоксе и затем походить вокруг него и посмотреть как изменяется звук!
+ +
 
+
+
+
+ +

Note how we have used some feature detection to either give the browser the newer property values (like {{domxref("AudioListener.forwardX")}}) for setting position, etc. if it supports those, or older methods (like {{domxref("AudioListener.setOrientation()")}}) if it still supports those but not the new properties.

+ +
// set up listener and panner position information
+// установка сведений о слушателе (listener) и положении panner'а
+var WIDTH = window.innerWidth;
+var HEIGHT = window.innerHeight;
+
+var xPos = Math.floor(WIDTH/2);
+var yPos = Math.floor(HEIGHT/2);
+var zPos = 295;
+
+// define other variables (определяем другие переменные)
+
+var AudioContext = window.AudioContext || window.webkitAudioContext;
+var audioCtx = new AudioContext();
+
+var panner = audioCtx.createPanner();
+panner.panningModel = 'HRTF';
+panner.distanceModel = 'inverse';
+panner.refDistance = 1;
+panner.maxDistance = 10000;
+panner.rolloffFactor = 1;
+panner.coneInnerAngle = 360;
+panner.coneOuterAngle = 0;
+panner.coneOuterGain = 0;
+
+if(panner.orientationX) {
+  panner.orientationX.value = 1;
+  panner.orientationY.value = 0;
+  panner.orientationZ.value = 0;
+} else {
+  panner.setOrientation(1,0,0);
+}
+
+var listener = audioCtx.listener;
+
+if(listener.forwardX) {
+  listener.forwardX.value = 0;
+  listener.forwardY.value = 0;
+  listener.forwardZ.value = -1;
+  listener.upX.value = 0;
+  listener.upY.value = 1;
+  listener.upZ.value = 0;
+} else {
+  listener.setOrientation(0,0,-1,0,1,0);
+}
+
+var source;
+
+var play = document.querySelector('.play');
+var stop = document.querySelector('.stop');
+
+var boomBox = document.querySelector('.boom-box');
+
+var listenerData = document.querySelector('.listener-data');
+var pannerData = document.querySelector('.panner-data');
+
+leftBound = (-xPos) + 50;
+rightBound = xPos - 50;
+
+xIterator = WIDTH/150;
+
+// listener will always be in the same place for this demo
+// в этом демо слушатель всегда находится на одном и том же месте
+
+if(listener.positionX) {
+  listener.positionX.value = xPos;
+  listener.positionY.value = yPos;
+  listener.positionZ.value = 300;
+} else {
+  listener.setPosition(xPos,yPos,300);
+}
+
+listenerData.innerHTML = 'Listener data: X ' + xPos + ' Y ' + yPos + ' Z ' + 300;
+
+// panner will move as the boombox graphic moves around on the screen
+// паннер будет перемещаться по экрану за перемещением бумбокса
+function positionPanner() {
+  if(panner.positionX) {
+    panner.positionX.value = xPos;
+    panner.positionY.value = yPos;
+    panner.positionZ.value = zPos;
+  } else {
+    panner.setPosition(xPos,yPos,zPos);
+  }
+  pannerData.innerHTML = 'Panner data: X ' + xPos + ' Y ' + yPos + ' Z ' + zPos;
+}
+ +
+

In terms of working out what position values to apply to the listener and panner, to make the sound appropriate to what the visuals are doing on screen, there is quite a bit of fiddly math involved, but you will soon get used to it with a bit of experimentation.

+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createPanner-PannerNode', 'createPanner()')}}{{Spec2('Web Audio API')}} 
+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatVersionUnknown}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
+ 22 (unprefixed)
6.0{{property_prefix("webkit")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}33.0
+
+ +

See also

+ + diff --git a/files/ru/web/api/baseaudiocontext/currenttime/index.html b/files/ru/web/api/baseaudiocontext/currenttime/index.html new file mode 100644 index 0000000000..51370701f4 --- /dev/null +++ b/files/ru/web/api/baseaudiocontext/currenttime/index.html @@ -0,0 +1,97 @@ +--- +title: AudioContext.currentTime +slug: Web/API/AudioContext/currentTime +translation_of: Web/API/BaseAudioContext/currentTime +--- +

{{ APIRef("AudioContext") }}

+
+

Поле currentTime принадлежит {{ domxref("AudioContext") }} и возвращает время с момента создания AudioContext. Может использоваться при планировании воспроизведения или визуализации.  Поле currentTime является не перезаписываемым и не может быть остановлено или сброшено.

+
+

Синтаксис

+
var audioCtx = new AudioContext();
+console.log(audioCtx.currentTime);
+

Тип данных

+

A double.

+

Примеры

+
+

Примечание: для большего понимания реализации Web Audio, посмотрите наши Web Audio Demos на MDN Github repo, like panner-node. Попробуйте ввести audioCtx.currentTime в консоли вашего браузера.

+
+
var AudioContext = window.AudioContext || window.webkitAudioContext;
+var audioCtx = new AudioContext();
+// Older webkit/blink browsers require a prefix
+
+...
+
+console.log(audioCtx.currentTime);
+
+

Specifications

+ + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-currentTime', 'currentTime')}}{{Spec2('Web Audio API')}} 
+

Browser compatibility

+
+ {{CompatibilityTable}}
+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
+ 22 (unprefixed)
6.0{{property_prefix("webkit")}}
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}33.0
+
+

See also

+ diff --git a/files/ru/web/api/baseaudiocontext/decodeaudiodata/index.html b/files/ru/web/api/baseaudiocontext/decodeaudiodata/index.html new file mode 100644 index 0000000000..faae982eae --- /dev/null +++ b/files/ru/web/api/baseaudiocontext/decodeaudiodata/index.html @@ -0,0 +1,220 @@ +--- +title: AudioContext.decodeAudioData() +slug: Web/API/AudioContext/decodeAudioData +tags: + - API +translation_of: Web/API/BaseAudioContext/decodeAudioData +--- +

{{ APIRef("Web Audio API") }}

+ +
+

The decodeAudioData() method of the {{ domxref("AudioContext") }} Interface is used to asynchronously decode audio file data contained in an {{domxref("ArrayBuffer")}}. In this case the ArrayBuffer is usually loaded from an {{domxref("XMLHttpRequest")}}'s response attribute after setting the responseType to arraybuffer. The decoded AudioBuffer is resampled to the AudioContext's sampling rate, then passed to a callback or promise.

+
+ +

This is the preferred method of creating an audio source for Web Audio API from an audio track.

+ +

Syntax

+ +

Older callback syntax:

+ +
audioCtx.decodeAudioData(audioData, function(decodedData) {
+  // use the dec​oded data here
+});
+ +

Newer promise-based syntax:

+ +
audioCtx.decodeAudioData(audioData).then(function(decodedData) {
+  // use the decoded data here
+});
+ +

Example

+ +

In this section we will first cover the older callback-based system and then the newer promise-based syntax.

+ +

Older callback syntax

+ +

In this example, the getData() function uses XHR to load an audio track, setting the responseType of the request to arraybuffer so that it returns an array buffer as its response that we then store in the audioData variable . We then pass this buffer into a decodeAudioData() function; the success callback takes the successfully decoded PCM data, puts it into an {{ domxref("AudioBufferSourceNode") }} created using {{ domxref("AudioContext.createBufferSource()") }}, connects the source to the {{domxref("AudioContext.destination") }} and sets it to loop.

+ +

The buttons in the example simply run getData() to load the track and start it playing, and stop it playing, respectively. When the stop() method is called on the source, the source is cleared out.

+ +
+

Note: You can run the example live (or view the source.)

+
+ +
// define variables
+
+var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+var source;
+
+var pre = document.querySelector('pre');
+var myScript = document.querySelector('script');
+var play = document.querySelector('.play');
+var stop = document.querySelector('.stop');
+
+// use XHR to load an audio track, and
+// decodeAudioData to decode it and stick it in a buffer.
+// Then we put the buffer into the source
+
+function getData() {
+  source = audioCtx.createBufferSource();
+  var request = new XMLHttpRequest();
+
+  request.open('GET', 'viper.ogg', true);
+
+  request.responseType = 'arraybuffer';
+
+
+  request.onload = function() {
+    var audioData = request.response;
+
+    audioCtx.decodeAudioData(audioData, function(buffer) {
+        source.buffer = buffer;
+
+        source.connect(audioCtx.destination);
+        source.loop = true;
+      },
+
+      function(e){"Error with decoding audio data" + e.err});
+
+  }
+
+  request.send();
+}
+
+// wire up buttons to stop and play audio
+
+play.onclick = function() {
+  getData();
+  source.start(0);
+  play.setAttribute('disabled', 'disabled');
+}
+
+stop.onclick = function() {
+  source.stop(0);
+  play.removeAttribute('disabled');
+}
+
+
+// dump script to pre element
+
+pre.innerHTML = myScript.innerHTML;
+ +

New promise-based syntax

+ +
ctx.decodeAudioData(compressedBuffer).then(function(decodedData) {
+ // use the decoded data here
+});
+ +

Parameters

+ +
+
ArrayBuffer
+
An ArrayBuffer containing the audio data to be decoded, usually grabbed from an {{domxref("XMLHttpRequest")}}'s response attribute after setting the responseType to arraybuffer.
+
DecodeSuccessCallback
+
A callback function to be invoked when the decoding successfully finishes. The single argument to this callback is an AudioBuffer representing the decoded PCM audio data. Usually you'll want to put the decoded data into an {{domxref("AudioBufferSourceNode")}}, from which it can be played and manipulated how you want.
+
DecodeErrorCallback
+
An optional error callback, to be invoked if an error occurs when the audio data is being decoded.
+
+ +

Returns

+ +

An {{domxref("AudioBuffer") }} representing the decoded PCM audio data.

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-decodeAudioData-Promise-AudioBuffer--ArrayBuffer-audioData-DecodeSuccessCallback-successCallback-DecodeErrorCallback-errorCallback', 'decodeAudioData()')}}{{Spec2('Web Audio API')}} 
+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
+ 22 (unprefixed)
6.0{{property_prefix("webkit")}}
Promise-based syntax{{CompatChrome(49.0)}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}26.01.2{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(33.0)}}
Promise-based syntax{{CompatUnknown}}{{CompatChrome(49.0)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(49.0)}}
+
+ +

See also

+ + diff --git a/files/ru/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html b/files/ru/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html new file mode 100644 index 0000000000..2c9eeaae78 --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html @@ -0,0 +1,726 @@ +--- +title: Применение стилей и цветов +slug: Web/API/Canvas_API/Tutorial/Применение_стилей_и_цветов +translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}
+ +
+

В главе о рисовании фигур, мы использовали для линий и заполнения только стили по умолчанию. Здесь мы будем исследовать опции canvas, которые мы имеем в нашем распоряжении, чтобы сделать наши рисунки немного более привлекательными. Вы узнаете, как добавлять различные цвета, стили линий, градиенты, узоры и тени вашим рисункам.

+
+ +

Цвета

+ +

До сих пор мы видели только методы рисования контекста. Если мы хотим применить цвета к фигуре, то есть два важных свойства, которые мы можем использовать: fillStyle и strokeStyle.

+ +
+
{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}
+
Устанавливает стиль для фона фигур.
+
{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}
+
Устанавливает стиль контура фигуры. 
+
+ +

color может быть цветом, (строка, представленная в CSS {{cssxref("<color>")}}), градиентом или паттерном. Градиенты и паттерны мы рассмотрим позже. По умолчанию цвет фона и контура  — черный (значение CSS цвета  #000000).

+ +
+

На заметку: Когда вы устанавливаете  значения strokeStyle и/или fillStyle, то новое значение становится стандартным для всех фигур, которые будут нарисованы с этого момента. Когда вам нужен другой цвет, вы должны перезаписать значение в fillStyle или в strokeStyle для каждой фигуры.

+
+ +

Чтобы строка color считалась валидной, она должна соответствовать CSS {{cssxref("<color>")}}. Далее приведены примеры того, как можно по-разному задать один и тот же цвет. 

+ +
// these all set the fillStyle to 'orange'
+
+ctx.fillStyle = "orange";
+ctx.fillStyle = "#FFA500";
+ctx.fillStyle = "rgb(255,165,0)";
+ctx.fillStyle = "rgba(255,165,0,1)";
+
+ +

Пример fillStyle

+ +

В этом примере мы опять воспользуемся двойным циклом, чтобы нарисовать сетку из прямоугольников, каждый из которых имеет свой цвет. Окончательное изображение должно иметь вид, как показано на скриншоте. Здесь не происходит ничего сверхъестественного. Мы используем две переменные i и j для генерации уникального RGB цвета для каждого квадрата и изменяем только красные и зеленые значения. Синий канал представляет собой фиксированное значение. Путем изменения каналов вы можете генерировать всю палитру. Увеличив количество шагов вы можете достигнуть такого вида палитры, какая используется в Photoshop.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  for (var i=0;i<6;i++){
+    for (var j=0;j<6;j++){
+      ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' +
+                       Math.floor(255-42.5*j) + ',0)';
+      ctx.fillRect(j*25,i*25,25,25);
+    }
+  }
+}
+ + + +

Результат выглядит так:

+ +

{{EmbedLiveSample("Пример_fillStyle", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}

+ +

Пример strokeStyle

+ +

Этот пример похож на предыдущий, но мы используем свойство strokeStyle чтобы изменить цвета очертаний фигур. Так же мы используем метод arc() для рисования окружностей вместо квадратов.

+ +
  function draw() {
+    var ctx = document.getElementById('canvas').getContext('2d');
+    for (var i=0;i<6;i++){
+      for (var j=0;j<6;j++){
+        ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' +
+                         Math.floor(255-42.5*j) + ')';
+        ctx.beginPath();
+        ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
+        ctx.stroke();
+      }
+    }
+  }
+
+ + + +

Результат выглядит так:

+ +

{{EmbedLiveSample("Пример_strokeStyle", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}

+ +

Прозрачность

+ +

В дополнении к рисованию непрозрачных фигур, мы также можем рисовать прозрачные (полупрозрачные) фигуры.  Это делается через установку свойства globalAlpha или задачи полупрозрачного цвета фона или контура.

+ +
+
{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}
+
Для применения, указывается значения прозрачности для всех будущих фигур, что будут нарисованы на canvas. Значение полупрозрачности могут быть между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность). Значение 1.0 (полная непрозрачность) установлено по умолчанию.
+
+ +

Свойство globalAlpha может быть использовано, если вы хотите рисовать формы с одинаковой прозрачностью, но в иной ситуации, обычно устанавливают прозрачность индивидуально к каждой форме, когда указывают их цвет.

+ +

Так как свойства strokeStyle и fillStyle принимают цветовые значения rgba через CSS, мы можем использовать следующее обозначение  для назначения прозрачных цветов.

+ +
// Assigning transparent colors to stroke and fill style
+
+ctx.strokeStyle = "rgba(255,0,0,0.5)";
+ctx.fillStyle = "rgba(255,0,0,0.5)";
+
+ +

Функция rgba() похожа на функцию rgb(), но имеет один дополнительный параметр. Последний параметр устанавливает значение прозрачности для конкретного цвета. Действующий диапозон значений находится между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность).

+ +

Пример globalAlpha

+ +

В данном примере мы нарисуем фон и четыре квадрата с различными цветами.  Сверху изображения будет выведен набор полупрозрачных кругов. Установим свойство globalAlpha значением 0.2, которое будет использовано для всех последующих форм. Каждый шаг цикла рисует круг с большим радиусом. По окончанию получим радиальный градиент. Накладывая еще больше кругов друг на друга, мы фактически сможем уменьшить прозрачность ранее нарисованных кругов. Увеличив счетчик итераций, при этом рисуя еще круги, мы сможем добиться исчезновение центра изображения.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  // фон изображения
+  ctx.fillStyle = '#FD0';
+  ctx.fillRect(0,0,75,75);
+  ctx.fillStyle = '#6C0';
+  ctx.fillRect(75,0,75,75);
+  ctx.fillStyle = '#09F';
+  ctx.fillRect(0,75,75,75);
+  ctx.fillStyle = '#F30';
+  ctx.fillRect(75,75,75,75);
+  ctx.fillStyle = '#FFF';
+
+  // устанавливаем значение прозрачности
+  ctx.globalAlpha = 0.2;
+
+  // Рисуем полупрозрачные круги
+  for (i=0;i<7;i++){
+    ctx.beginPath();
+    ctx.arc(75,75,10+10*i,0,Math.PI*2,true);
+    ctx.fill();
+  }
+}
+ + + +

{{EmbedLiveSample("Пример_globalAlpha", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}

+ +

Пример использования rgba()

+ +

В этом втором примере мы делаем что-то похожее на предыдущее, но вместо рисования кругов друг над другом, я рисовал маленькие прямоугольники с увеличением непрозрачности. Использование rgba() добавляет контроля и гибкости, поскольку мы можем индивидуально настраивать стиль заливки и штриха.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // Нарисовать фон
+  ctx.fillStyle = 'rgb(255,221,0)';
+  ctx.fillRect(0,0,150,37.5);
+  ctx.fillStyle = 'rgb(102,204,0)';
+  ctx.fillRect(0,37.5,150,37.5);
+  ctx.fillStyle = 'rgb(0,153,255)';
+  ctx.fillRect(0,75,150,37.5);
+  ctx.fillStyle = 'rgb(255,51,0)';
+  ctx.fillRect(0,112.5,150,37.5);
+
+  // Нарисовать полупрозрачные прямоугольники
+  for (var i=0;i<10;i++){
+    ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
+    for (var j=0;j<4;j++){
+      ctx.fillRect(5+i*14,5+j*37.5,14,27.5);
+    }
+  }
+}
+ + + +

{{EmbedLiveSample("Пример_использования_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}

+ +

Стили линий

+ +

Есть несколько свойств, которые позволяют нам стилизовать линии.

+ +
+
{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}
+
Устанавливает ширину линий, рисуемых в будущем.
+
{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}
+
Устанавливает внешний вид концов линий.
+
{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}
+
Устанавливает внешний вид «углов», где встречаются линии.
+
{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}
+
Устанавливает ограничение на митру, когда две линии соединяются под острым углом, чтобы вы могли контролировать её толщину.
+
{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}
+
Возвращает текущий массив тире штриховки, содержащий четное число неотрицательных чисел.
+
{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}
+
Устанавливает текущий пунктир линии.
+
{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}
+
Указывает, где следует начинать тире массива в строке.
+
+ +

Вы лучше поймете, что они делают, глядя на приведенные ниже примеры.

+ +

Пример lineWidth

+ +

Это свойство задает толщину текущей строки. Значения должны быть положительными. По умолчанию для этого значения установлено 1.0 единицы.

+ +

Ширина линии - это толщина хода, центрированного по данному пути. Другими словами, область, которая нарисована, простирается до половины ширины линии по обе стороны пути. Поскольку координаты холста не напрямую ссылаются на пиксели, особое внимание следует уделять получению четких горизонтальных и вертикальных линий.

+ +

В приведенном ниже примере 10 прямых линий рисуются с увеличением ширины линий. Линия в крайнем левом углу - 1.0 единицы. Тем не менее, толщина левой и всех других линий нечетной ширины не выглядят четкими из-за позиционирования пути.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  for (var i = 0; i < 10; i++){
+    ctx.lineWidth = 1+i;
+    ctx.beginPath();
+    ctx.moveTo(5+i*14,5);
+    ctx.lineTo(5+i*14,140);
+    ctx.stroke();
+  }
+}
+
+ + + +

{{EmbedLiveSample("Пример_lineWidth", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}

+ +

Получение четких строк требует понимания путей сглаживания. На рисунках ниже представлена сетка координат холста. Квадраты между сетками являются фактическими экранными пикселями. В первом изображении сетки ниже прямоугольник от (2, 1) до (5, 5) заполняется. Вся область между ними (светло-красный) падает на границы пикселей, поэтому полученный заполненный прямоугольник будет иметь четкие края.

+ +

+ +

Если вы рассмотрите путь от (3, 1) до (3, 5) с толщиной строки 1.0, вы получите ситуацию во втором изображении. Фактическая заполняемая область, (синяя), распространяется только наполовину в пикселях по обе стороны пути. Приблизительно это означает, что частично затенённые пиксели приводят к заполнению всей области (светло-голубой и синей) цветом, только наполовину темным, чем фактический цвет штриха. Это то, что происходит с линией шириной 1.0 в предыдущем примере кода.

+ +

Чтобы исправить это, вы должны быть более точными при создании пути. Зная, что линия шириной 1.0 занимает половину единицы по обе стороны пути, создание пути от (3.5, 1) до (3.5, 5) приведёт к ситуации в третьем изображении - ширина линии 1.0 закончится верно, точно заполняя вертикальную линию с одним пикселем.

+ +
+

Примечание: Имейте в виду, что в нашем примере с вертикальной линией позиция Y по-прежнему ссылается на целочисленную позицию сетки - иначе мы увидели бы пиксели с половинным охватом в конечных точках (также обратите внимание, что это поведение зависит от текущего стиля lineCap,  значение по умолчанию - butt; вы можете вычислить согласованные штрихи с полупиксельными координатами для линий с нечетной шириной, установив стиль lineCap в square, чтобы внешняя граница вокруг конечной точки линии автоматически расширялась, охватывая весь пиксель в точку).

+ +

Также обратите внимание, что затронуты только начальные и конечные  точки пути: если путь закрыт с помощью closePath(), - нет начальной и конечной точки; вместо этого все конечные точки в пути подключены к их прикрепленному предыдущему и следующему сегментам и при текущей настройке стиля lineJoin в значении по умолчанию - miter, с эффектом автоматического расширения внешних границ подключенных сегментов до их точки пересечения - обработанный ход будет точно покрывать полные пиксели с центром в каждой конечной точке, если эти связанные сегменты горизонтальны и/или вертикальны). См. следующие два раздела, демонстрирующие эти дополнительные стили.

+
+ +

Для линий с четной шириной каждая половина заканчивается как целое количество пикселей, поэтому вам нужен путь, который находится между пикселями (то есть (3,1) - (3,5)), вместо середины пикселей.

+ +

Хотя это и необычно, когда изначально работаешь с масштабируемой 2D-графикой, обращая внимание на сетку пикселей и положение путей, но вы убедитесь, что ваши рисунки будут выглядеть правильно, независимо от масштабирования или любых других преобразований. Вертикальная линия ширины 1,0, построенная таким образом, станет четкой 2-пиксельной линией при увеличении на 2 и появится в правильном положении.

+ +

Пример lineCap

+ +

Свойство lineCap определяет, как выводятся конечные точки каждой строки. Для этого свойства есть три возможных значения: butt, round и square. По умолчанию для этого свойства установлено значение butt.

+ +

+ +
+
butt
+
Концы линий соответствуют крайним точкам.
+
round
+
Концы линий округлены.
+
square
+
Концы линий описаны квадратом с равной шириной и половиной высоты толщины линии.
+
+ +

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

+ +

Строка слева использует butt опцию по умолчанию. Вы заметите, что она полностью очищена от направляющих. Второй вариант -  round опция. Это добавляет полукруг к концу, который имеет радиус, равный половине ширины линии. Строка справа использует square опцию. Это добавляет поле с равной шириной и половиной высоты толщины линии.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var lineCap = ['butt','round','square'];
+
+  // Draw guides
+  ctx.strokeStyle = '#09f';
+  ctx.beginPath();
+  ctx.moveTo(10,10);
+  ctx.lineTo(140,10);
+  ctx.moveTo(10,140);
+  ctx.lineTo(140,140);
+  ctx.stroke();
+
+  // Draw lines
+  ctx.strokeStyle = 'black';
+  for (var i=0;i<lineCap.length;i++){
+    ctx.lineWidth = 15;
+    ctx.lineCap = lineCap[i];
+    ctx.beginPath();
+    ctx.moveTo(25+i*50,10);
+    ctx.lineTo(25+i*50,140);
+    ctx.stroke();
+  }
+}
+
+ + + +

{{EmbedLiveSample("Пример_lineCap", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}

+ +

Пример lineJoin

+ +

Свойство lineJoin определяет, как соединяются два сегмента (линий, дуг или кривых) с ненулевой длиной в форме (вырожденные сегменты с нулевой длиной, заданные конечные точки и контрольные точки находятся точно в том же положении - пропущены).

+ +

Для этого свойства есть три возможных значения: round, bevel и miter. По умолчанию для этого свойства установлено значение miter. Обратите внимание, что настройка lineJoin не действует, если два связанных сегмента имеют одно и то же направление, потому что в этом случае не будет добавлена ​​область соединения.

+ +

+ +
+
round
+
Радиус заполняемой части для скругленных углов равен половине ширины линии. центр этого радиуса совпадает с концами подключенных сегментов.
+
bevel
+
Заполняет дополнительную треугольную область между общей конечной точкой подключенных сегментов и отдельными внешними прямоугольными углами каждого сегмента. 
+
miter
+
Подключенные сегменты соединяются путем расширения их внешних краев для соединения в одной точке с эффектом заполнения дополнительной области в форме пастилки. Эта настройка выполняется с помощью свойства miterLimit, которое объясняется ниже.
+
+ +

В приведенном ниже примере показаны три разных пути, демонстрирующие каждый из этих трех свойств lineJoin; результат - выше. 

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var lineJoin = ['round','bevel','miter'];
+  ctx.lineWidth = 10;
+  for (var i=0;i<lineJoin.length;i++){
+    ctx.lineJoin = lineJoin[i];
+    ctx.beginPath();
+    ctx.moveTo(-5,5+i*40);
+    ctx.lineTo(35,45+i*40);
+    ctx.lineTo(75,5+i*40);
+    ctx.lineTo(115,45+i*40);
+    ctx.lineTo(155,5+i*40);
+    ctx.stroke();
+  }
+}
+
+ + + +

{{EmbedLiveSample("Пример_lineJoin", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}

+ +

Демонстрация свойства miterLimit

+ +

Как вы видели в предыдущем примере, при объединении двух строк с опцией miter внешние края двух соединительных линий расширены до точки, где они встречаются. Для линий, которые находятся под большими углами друг с другом, эта точка находится недалеко от внутренней точки соединения. Однако, поскольку углы между каждой линией уменьшаются, расстояние (длина меча) между этими точками увеличивается экспоненциально.

+ +

Свойство miterLimit определяет, как далеко можно установить внешнюю точку соединения из внутренней точки подключения. Если две линии превышают это значение, вместо этого получается привязка конуса. Обратите внимание, что максимальная длина митра является произведением ширины линии, измеренной в текущей системе координат, значением этого свойства miterLimit (значение по умолчанию 10,0 в HTML {{HTMLElement("canvas")}}), поэтому miterLimit может устанавливаться независимо от текущей шкалы дисплея или любых аффинных преобразований путей: она влияет только на эффективно визуализированную форму ребер линии.

+ +

Точнее, предел митры является максимально допустимым отношением длины расширения (в холсте HTML он измеряется между внешним углом соединенных краев линии и общей конечной точкой соединительных сегментов, указанными на пути), до половины ширины линии. Его можно равнозначно определить как максимально допустимое отношение расстояния между внутренней и внешней точками перехода краев к общей ширине линии. Затем он равен косекансу с половиной минимального внутреннего угла соединительных сегментов, ниже которого не будет создано ни одного соединения митра, а только скос соединяется:

+ + + +

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

+ +

Если вы укажете в этой демонстрации значение miterLimit ниже 4.2, ни один из видимых углов не присоединится к расширению митры, но только с небольшим скосом рядом с синими линиями; с отметкой miterLimit выше 10, большинство углов в этой демонстрации должны соединяться с митрой, удаленной от синих линий, высота которой уменьшается между углами слева направо, потому что они соединяются с растущими углами; с промежуточными значениями углы с левой стороны будут соединяться только с скосом рядом с синими линиями, а углы с правой стороны с удлинителем митры (также с уменьшающейся высотой).

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // Clear canvas
+  ctx.clearRect(0,0,150,150);
+
+  // Draw guides
+  ctx.strokeStyle = '#09f';
+  ctx.lineWidth   = 2;
+  ctx.strokeRect(-5,50,160,50);
+
+  // Set line styles
+  ctx.strokeStyle = '#000';
+  ctx.lineWidth = 10;
+
+  // check input
+  if (document.getElementById('miterLimit').value.match(/\d+(\.\d+)?/)) {
+    ctx.miterLimit = parseFloat(document.getElementById('miterLimit').value);
+  } else {
+    alert('Value must be a positive number');
+  }
+
+  // Draw lines
+  ctx.beginPath();
+  ctx.moveTo(0,100);
+  for (i=0;i<24;i++){
+    var dy = i%2==0 ? 25 : -25 ;
+    ctx.lineTo(Math.pow(i,1.5)*2,75+dy);
+  }
+  ctx.stroke();
+  return false;
+}
+
+ + + +

{{EmbedLiveSample("Демонстрация_свойства_miterLimit", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}

+ +

Использование штрихов

+ +

Метод setLineDash и свойство lineDashOffset задают шаблон штрихов для линий. Метод setLineDash принимает список чисел, который определяет расстояния для попеременного рисования линии и разрыва, а свойство lineDashOffset устанавливает смещение, с которого начинается шаблон.

+ +

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

+ + + +
var ctx = document.getElementById('canvas').getContext('2d');
+var offset = 0;
+
+function draw() {
+  ctx.clearRect(0,0, canvas.width, canvas.height);
+  ctx.setLineDash([4, 2]);
+  ctx.lineDashOffset = -offset;
+  ctx.strokeRect(10,10, 100, 100);
+}
+
+function march() {
+  offset++;
+  if (offset > 16) {
+    offset = 0;
+  }
+  draw();
+  setTimeout(march, 20);
+}
+
+march();
+ +

{{EmbedLiveSample("Используемый штрих", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}

+ +

Градиенты

+ +

Just like any normal drawing program, we can fill and stroke shapes using linear and radial gradients. We create a {{domxref("CanvasGradient")}} object by using one of the following methods. We can then assign this object to the fillStyle or strokeStyle properties.

+ +
+
{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}
+
Creates a linear gradient object with a starting point of (x1, y1) and an end point of (x2, y2).
+
{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}
+
Creates a radial gradient. The parameters represent two circles, one with its center at (x1, y1) and a radius of r1, and the other with its center at (x2, y2) with a radius of r2.
+
+ +

For example:

+ +
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
+var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
+
+ +

Once we've created a CanvasGradient object we can assign colors to it by using the addColorStop() method.

+ +
+
{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}
+
Creates a new color stop on the gradient object. The position is a number between 0.0 and 1.0 and defines the relative position of the color in the gradient, and the color argument must be a string representing a CSS {{cssxref("<color>")}}, indicating the color the gradient should reach at that offset into the transition.
+
+ +

You can add as many color stops to a gradient as you need. Below is a very simple linear gradient from white to black.

+ +
var lineargradient = ctx.createLinearGradient(0,0,150,150);
+lineargradient.addColorStop(0, 'white');
+lineargradient.addColorStop(1, 'black');
+
+ +

Пример createLinearGradient

+ +

In this example, we'll create two different gradients. As you can see here, both the strokeStyle and fillStyle properties can accept a canvasGradient object as valid input.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // Create gradients
+  var lingrad = ctx.createLinearGradient(0,0,0,150);
+  lingrad.addColorStop(0, '#00ABEB');
+  lingrad.addColorStop(0.5, '#fff');
+  lingrad.addColorStop(0.5, '#26C000');
+  lingrad.addColorStop(1, '#fff');
+
+  var lingrad2 = ctx.createLinearGradient(0,50,0,95);
+  lingrad2.addColorStop(0.5, '#000');
+  lingrad2.addColorStop(1, 'rgba(0,0,0,0)');
+
+  // assign gradients to fill and stroke styles
+  ctx.fillStyle = lingrad;
+  ctx.strokeStyle = lingrad2;
+
+  // draw shapes
+  ctx.fillRect(10,10,130,130);
+  ctx.strokeRect(50,50,50,50);
+
+}
+
+ + + +

The first is a background gradient. As you can see, we assigned two colors at the same position. You do this to make very sharp color transitions—in this case from white to green. Normally, it doesn't matter in what order you define the color stops, but in this special case, it does significantly. If you keep the assignments in the order you want them to appear, this won't be a problem.

+ +

In the second gradient, we didn't assign the starting color (at position 0.0) since it wasn't strictly necessary, because it will automatically assume the color of the next color stop. Therefore, assigning the black color at position 0.5 automatically makes the gradient, from the start to this stop, black.

+ +

{{EmbedLiveSample("Пример_createLinearGradient", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}

+ +

Пример createRadialGradient

+ +

In this example, we'll define four different radial gradients. Because we have control over the start and closing points of the gradient, we can achieve more complex effects than we would normally have in the "classic" radial gradients we see in, for instance, Photoshop (that is, a gradient with a single center point where the gradient expands outward in a circular shape).

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // Create gradients
+  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
+  radgrad.addColorStop(0, '#A7D30C');
+  radgrad.addColorStop(0.9, '#019F62');
+  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
+
+  var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
+  radgrad2.addColorStop(0, '#FF5F98');
+  radgrad2.addColorStop(0.75, '#FF0188');
+  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
+
+  var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
+  radgrad3.addColorStop(0, '#00C9FF');
+  radgrad3.addColorStop(0.8, '#00B5E2');
+  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');
+
+  var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
+  radgrad4.addColorStop(0, '#F4F201');
+  radgrad4.addColorStop(0.8, '#E4C700');
+  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
+
+  // draw shapes
+  ctx.fillStyle = radgrad4;
+  ctx.fillRect(0,0,150,150);
+  ctx.fillStyle = radgrad3;
+  ctx.fillRect(0,0,150,150);
+  ctx.fillStyle = radgrad2;
+  ctx.fillRect(0,0,150,150);
+  ctx.fillStyle = radgrad;
+  ctx.fillRect(0,0,150,150);
+}
+
+ + + +

In this case, we've offset the starting point slightly from the end point to achieve a spherical 3D effect. It's best to try to avoid letting the inside and outside circles overlap because this results in strange effects which are hard to predict.

+ +

The last color stop in each of the four gradients uses a fully transparent color. If you want to have a nice transition from this to the previous color stop, both colors should be equal. This isn't very obvious from the code because it uses two different CSS color methods as a demonstration, but in the first gradient #019F62 = rgba(1,159,98,1).

+ +

{{EmbedLiveSample("Пример_createRadialGradient", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}

+ +

Шаблоны

+ +

В одном из предыдущих примеров мы использовали несколько циклов, чтобы создать шаблон из повторяющихся изображений. Однако, есть более простой способ сделать подобное - метод createPattern().

+ +
+
{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}
+
Создает и возвращает новый canvas объект - шаблон (pattern). image - {{domxref("CanvasImageSource")}} (то есть {{domxref ("HTMLImageElement")}}, другой холст, элемент {{HTMLElement ("video")}} или подобный  объект. type - строка, указывающая, как использовать image.
+
+ +

Тип указывает, как использовать image для создания шаблона и должен быть одним из следующих значений:

+ +
+
repeat
+
Повторяет изображение в вертикальном и горизонтальном направлениях.
+
repeat-x
+
Повторяет изображение по горизонтали, но не по вертикали.
+
repeat-y
+
Повторяет изображение по вертикали, но не по горизонтали.
+
no-repeat
+
Не повторяет изображение. Используется только один раз.
+
+ +

Мы используем этот метод, чтобы создать {{domxref("CanvasPattern")}} объект, который очень похож на методы градиента, рассмотренные ранее. Как только мы создали шаблон, мы можем назначить ему свойства fillStyle или strokeStyle. Например:

+ +
var img = new Image();
+img.src = 'someimage.png';
+var ptrn = ctx.createPattern(img,'repeat');
+
+ +
+

Примечание: По аналогии с методом drawImage(), вы должны убедиться, что изображение, которое вы используете, загружено до вызова этого метода. Иначе шаблон может быть отрисован некорректно.

+
+ +

Пример createPattern

+ +

In this last example, we'll create a pattern to assign to the fillStyle property. The only thing worth noting is the use of the image's onload handler. This is to make sure the image is loaded before it is assigned to the pattern.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // create new image object to use as pattern
+  var img = new Image();
+  img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
+  img.onload = function(){
+
+    // create pattern
+    var ptrn = ctx.createPattern(img,'repeat');
+    ctx.fillStyle = ptrn;
+    ctx.fillRect(0,0,150,150);
+
+  }
+}
+
+ + + +

{{EmbedLiveSample("Пример_createPattern", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}

+ +

Тени

+ +

Using shadows involves just four properties:

+ +
+
{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}
+
Indicates the horizontal distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
+
{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}
+
Indicates the vertical distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
+
{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}
+
Indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.
+
{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}
+
A standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.
+
+ +

The properties shadowOffsetX and shadowOffsetY indicate how far the shadow should extend from the object in the X and Y directions; these values aren't affected by the current transformation matrix. Use negative values to cause the shadow to extend up or to the left, and positive values to cause the shadow to extend down or to the right. These are both 0 by default.

+ +

The shadowBlur property indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.

+ +

The shadowColor property is a standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.

+ +
+

Note: Shadows are only drawn for source-over compositing operations.

+
+ +

Пример текста с тенью

+ +

This example draws a text string with a shadowing effect.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  ctx.shadowOffsetX = 2;
+  ctx.shadowOffsetY = 2;
+  ctx.shadowBlur = 2;
+  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
+
+  ctx.font = "20px Times New Roman";
+  ctx.fillStyle = "Black";
+  ctx.fillText("Sample String", 5, 30);
+}
+
+ + + +

{{EmbedLiveSample("Пример_текста_с_тенью", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}

+ +

We will look at the font property and fillText method in the next chapter about drawing text.

+ +

Canvas fill rules

+ +

When using fill (or {{domxref("CanvasRenderingContext2D.clip", "clip")}} and {{domxref("CanvasRenderingContext2D.isPointInPath", "isPointinPath")}}) you can optionally provide a fill rule algorithm by which to determine if a point is inside or outside a path and thus if it gets filled or not. This is useful when a path intersetcs itself or is nested.
+
+ Two values are possible:

+ + + +

In this example we are using the evenodd rule.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.beginPath();
+  ctx.arc(50, 50, 30, 0, Math.PI*2, true);
+  ctx.arc(50, 50, 15, 0, Math.PI*2, true);
+  ctx.fill("evenodd");
+}
+ + + +

{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}

diff --git a/files/ru/web/api/canvas_api/tutorial/basic_animations/index.html b/files/ru/web/api/canvas_api/tutorial/basic_animations/index.html new file mode 100644 index 0000000000..a47b8b734e --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/basic_animations/index.html @@ -0,0 +1,308 @@ +--- +title: Простые анимации +slug: Web/API/Canvas_API/Tutorial/Основы_анимации +tags: + - HTML + - HTML5 + - Графика + - Обучение + - Средний уровень + - Холст +translation_of: Web/API/Canvas_API/Tutorial/Basic_animations +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}
+ +
+

Поскольку для управления элементами {{HTMLElement ("canvas")}} используется JavaScript, не составляет труда сделать (интерактивные) анимации. В этой главе мы рассмотрим, как делаются некоторые базовые анимации.

+
+ +

Вероятно, самым большим ограничением является то, что когда фигура нарисована, её уже нельзя двигать. Чтобы изобразить движение нам нужно перерисовать фигуру и всё, что было нарисовано до неё. Перерисовка сложных кадров занимает много времени, и производительность сильно зависит от скорости компьютера, на котором она выполняется.

+ +

Основные шаги анимации

+ +

Ниже перечислены необходимые шаги для того, чтобы нарисовать кадр:

+ +
    +
  1. Очистить canvas
    + Если фигура, которую вы собираетесь нарисовать, не занимает всю площадь canvas (как фон, например), то всё что было нарисовано ранее необходимо стереть. Проще всего это сделать при помощи метода {{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}.
  2. +
  3. Сохранить изначальное состояние canvas
    + Если вы изменяете любые настройки (такие как стили, трансформации и т.п.), которые затрагивают состояние canvas и вы хотите убедиться, что оригинальное состояние используется каждый раз, когда был отрисован кадр, то вам следует сохранить это оригинальное состояние.
  4. +
  5. Нарисовать анимированные фигуры
    + Шаг на котором вы собственно отрисовываете кадр.
  6. +
  7. Восстановить состояние canvas
    + Если вы сохраняли состояние, восстановите его, прежде чем отрисовывать новый кадр.
  8. +
+ +

Управление анимацией

+ +

Фигуры отрисовываются на canvas либо напрямую — при помощи методов canvas, либо с помощью сторонних функций. В нормальной ситуации результат станет виден на canvas после окончания выполнения скрипта. К примеру, цикл for использовать для анимации нельзя. 

+ +

Это значит, нужен способ выполнения функций отрисовки через интервалы времени. Есть два способа для управления такой анимацией.

+ +

Запланированные обновления

+ +

Первый — это функции {{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}}, и {{domxref("window.requestAnimationFrame()")}}, которые могут быть использованы для вызова некоторой функции, через заданный промежуток времени.

+ +
+
{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}
+
Начинает периодически исполнять функцию function каждые delay миллисекунд.
+
{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}
+
Запускает выполнение указанной функции function через delay миллисекунд.
+
{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}
+
Сообщает браузеру, что вы хотите выполнить анимацию, и запрашивает, чтобы браузер вызвал указанную функцию callback для обновления анимации перед следующей перерисовкой.
+
+ +

Если вы не планируете никакого взаимодействия с пользователем, вы можете использовать функцию setInterval() , которая многократно выполняет, предоставленный ей код. Если же вы планиуете создать игру, в которой контроль анимации осуществляется мышью или клавиатурой, то необходимо использовать  setTimeout(). Установив {{domxref("EventListener")}}, вы можете перехватываете любые действия пользователя и запустить соответствующие функции анимации.

+ +
+

В примерах ниже мы будем использовать функцию {{domxref("window.requestAnimationFrame()")}} для контроля анимации. Функция requestAnimationFrame является более эффективной для создания анимации, так как новая итерация вызывается, когда система готова к отрисовке нового кадра. Количество вызовов в секунду примерно равно 60 и уменьшается, когда вкладка неактивна. Для более подробного изучения цикла анимации, особенно для игр, прочитайте статью Анатомия видеоигр В Зоне разработке игр.

+
+ +

Анимированная солнечная система

+ +

В этом примере анимируется небольшая модель солнечной системы.

+ +
var sun = new Image();
+var moon = new Image();
+var earth = new Image();
+function init(){
+  sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
+  moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
+  earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
+  window.requestAnimationFrame(draw);
+}
+
+function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  ctx.globalCompositeOperation = 'destination-over';
+  ctx.clearRect(0,0,300,300); // clear canvas
+
+  ctx.fillStyle = 'rgba(0,0,0,0.4)';
+  ctx.strokeStyle = 'rgba(0,153,255,0.4)';
+  ctx.save();
+  ctx.translate(150,150);
+
+  // Earth
+  var time = new Date();
+  ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
+  ctx.translate(105,0);
+  ctx.fillRect(0,-12,50,24); // Shadow
+  ctx.drawImage(earth,-12,-12);
+
+  // Moon
+  ctx.save();
+  ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
+  ctx.translate(0,28.5);
+  ctx.drawImage(moon,-3.5,-3.5);
+  ctx.restore();
+
+  ctx.restore();
+
+  ctx.beginPath();
+  ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
+  ctx.stroke();
+
+  ctx.drawImage(sun,0,0,300,300);
+
+  window.requestAnimationFrame(draw);
+}
+
+init();
+
+ + + +

{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}

+ +

Анимированные часы

+ +

В этом примере создаются анимированные часы, показывающие правильное время.

+ +
function clock(){
+  var now = new Date();
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.save();
+  ctx.clearRect(0,0,150,150);
+  ctx.translate(75,75);
+  ctx.scale(0.4,0.4);
+  ctx.rotate(-Math.PI/2);
+  ctx.strokeStyle = "black";
+  ctx.fillStyle = "white";
+  ctx.lineWidth = 8;
+  ctx.lineCap = "round";
+
+  // Hour marks
+  ctx.save();
+  for (var i=0;i<12;i++){
+    ctx.beginPath();
+    ctx.rotate(Math.PI/6);
+    ctx.moveTo(100,0);
+    ctx.lineTo(120,0);
+    ctx.stroke();
+  }
+  ctx.restore();
+
+  // Minute marks
+  ctx.save();
+  ctx.lineWidth = 5;
+  for (i=0;i<60;i++){
+    if (i%5!=0) {
+      ctx.beginPath();
+      ctx.moveTo(117,0);
+      ctx.lineTo(120,0);
+      ctx.stroke();
+    }
+    ctx.rotate(Math.PI/30);
+  }
+  ctx.restore();
+
+  var sec = now.getSeconds();
+  var min = now.getMinutes();
+  var hr  = now.getHours();
+  hr = hr>=12 ? hr-12 : hr;
+
+  ctx.fillStyle = "black";
+
+  // write Hours
+  ctx.save();
+  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
+  ctx.lineWidth = 14;
+  ctx.beginPath();
+  ctx.moveTo(-20,0);
+  ctx.lineTo(80,0);
+  ctx.stroke();
+  ctx.restore();
+
+  // write Minutes
+  ctx.save();
+  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
+  ctx.lineWidth = 10;
+  ctx.beginPath();
+  ctx.moveTo(-28,0);
+  ctx.lineTo(112,0);
+  ctx.stroke();
+  ctx.restore();
+
+  // Write seconds
+  ctx.save();
+  ctx.rotate(sec * Math.PI/30);
+  ctx.strokeStyle = "#D40000";
+  ctx.fillStyle = "#D40000";
+  ctx.lineWidth = 6;
+  ctx.beginPath();
+  ctx.moveTo(-30,0);
+  ctx.lineTo(83,0);
+  ctx.stroke();
+  ctx.beginPath();
+  ctx.arc(0,0,10,0,Math.PI*2,true);
+  ctx.fill();
+  ctx.beginPath();
+  ctx.arc(95,0,10,0,Math.PI*2,true);
+  ctx.stroke();
+  ctx.fillStyle = "rgba(0,0,0,0)";
+  ctx.arc(0,0,3,0,Math.PI*2,true);
+  ctx.fill();
+  ctx.restore();
+
+  ctx.beginPath();
+  ctx.lineWidth = 14;
+  ctx.strokeStyle = '#325FA2';
+  ctx.arc(0,0,142,0,Math.PI*2,true);
+  ctx.stroke();
+
+  ctx.restore();
+
+  window.requestAnimationFrame(clock);
+}
+
+window.requestAnimationFrame(clock);
+ + + +

{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}

+ +

Зацикленная панорама

+ +

В этом примере панорама прокручивается слева направо. Мы используем фото национального парка Йосемити взятое из Википедии, но вы можете использовать любое изображение, большее элемента canvas.

+ +
var img = new Image();
+
+// User Variables - customize these to change the image being scrolled, its
+// direction, and the speed.
+
+img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
+var CanvasXSize = 800;
+var CanvasYSize = 200;
+var speed = 30; //lower is faster
+var scale = 1.05;
+var y = -4.5; //vertical offset
+
+// Main program
+
+var dx = 0.75;
+var imgW;
+var imgH;
+var x = 0;
+var clearX;
+var clearY;
+var ctx;
+
+img.onload = function() {
+    imgW = img.width*scale;
+    imgH = img.height*scale;
+    if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
+    if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
+    else { clearX = CanvasXSize; }
+    if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
+    else { clearY = CanvasYSize; }
+    //Get Canvas Element
+    ctx = document.getElementById('canvas').getContext('2d');
+    //Set Refresh Rate
+    return setInterval(draw, speed);
+}
+
+function draw() {
+    //Clear Canvas
+    ctx.clearRect(0,0,clearX,clearY);
+    //If image is <= Canvas Size
+    if (imgW <= CanvasXSize) {
+        //reset, start from beginning
+        if (x > (CanvasXSize)) { x = 0; }
+        //draw aditional image
+        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
+    }
+    //If image is > Canvas Size
+    else {
+        //reset, start from beginning
+        if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
+        //draw aditional image
+        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
+    }
+    //draw image
+    ctx.drawImage(img,x,y,imgW,imgH);
+    //amount to move
+    x += dx;
+}
+
+ +

Заметьте, что ширина и высота должны совпадать  со значениями CanvasXZSize и CanvasYSize.

+ +
<canvas id="canvas" width="800" height="200"></canvas>
+ +

{{EmbedLiveSample("A_looping_panorama", "830", "230")}}

+ +

Другие примеры

+ +
+
A basic ray-caster
+
Хороший пример того, как сделать управляемую анимацию с клавиатуры.
+
Advanced animations
+
Мы рассмотрим некоторые продвинутые методы анимации и физику в следующей главе.
+
+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}

diff --git a/files/ru/web/api/canvas_api/tutorial/compositing/index.html b/files/ru/web/api/canvas_api/tutorial/compositing/index.html new file mode 100644 index 0000000000..264cc7e544 --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/compositing/index.html @@ -0,0 +1,108 @@ +--- +title: Композиция и обрезка +slug: Web/API/Canvas_API/Tutorial/Композиции +tags: + - канвас +translation_of: Web/API/Canvas_API/Tutorial/Compositing +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}
+ +
+

Во всех наших предыдущих примерах, фигуры всегда были нарисованы одна поверх другой. Это более чем достаточно для большинства ситуаций, но это ограничивает порядок, в котором построены композиционные формы. Однако, мы можем изменить это поведение, установив свойство globalCompositeOperation. Кроме того, свойства clip позволяет скрыть нежелательные части формы.

+
+ +

globalCompositeOperation

+ +

Мы можем не только рисовать новые фигуры за существующие формы, но мы также можем использовать его, чтобы замаскировать определенные участки, очистить разделы от холста (не ограничивается прямоугольниками, как{{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}} method does) и другое.

+ +
+
{{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation = type")}}
+
Это задает Тип операции композиции для применения при разработке новых форм, где Тип является строкой, идентифицирующей, какие из двенадцати операций композитинг в использовании.
+
+ +

См.  примеры компоновки кода из следующих примеров.

+ +

{{EmbedLiveSample("Compositing_example", 750, 6750, "" ,"Web/API/Canvas_API/Tutorial/Compositing/Example")}}

+ +

Обрезка контуров

+ +

Отсеченный контур похож на обычную форму холста, но он действует как маска, чтобы скрыть нежелательные части фигур. Это визуализируется на изображении справа. Форма красной звезды - наша отправочная дорожка. Все, что выходит за пределы этого пути, не будет нарисовано на холсте.

+ +

Если мы сравниваем отсеченный контур со свойством globalCompositeOperation на изображении, мы видим два режима композитинга, которые достигают более или менее того же эффекта в исходном и исходном состоянии.   Наиболее важные различия между ними заключаются в том, что отсечение контура фактически  никогда не обращается к холсту и контур обрезки никогда не влияет добавление новых форм. Это делает обрезку контура идеальным для рисования нескольких фигур в ограниченной области.

+ +

В главе о рисовании форм, я назвал только stroke() и fill() методы, но есть третий способ можно использовать с контурами, так называемый clip().

+ +
+
{{domxref("CanvasRenderingContext2D.clip", "clip()")}}
+
Преобразует текущий выстраиваемый контур в отсечённый контур.
+
+ +

Используйте clip() вместо closePath() для закрытия контура и его преобразования в отсечённый контур вместо создания заполняющего  или обрамляющего контура.

+ +

По умолчанию элемент {{HTMLElement("canvas")}} использует отсечённый контур, который в точности совпадает по размеру с размером самого холста. Это означает, что никакого отсечения попросту не произойдёт.

+ +

Пример обрезки

+ +

В этом примере мы будем использовать круговую обрезку контура, чтобы ограничить рисование набора случайных звезд определенной областью.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.fillRect(0, 0, 150, 150);
+  ctx.translate(75, 75);
+
+  // Create a circular clipping path
+  ctx.beginPath();
+  ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
+  ctx.clip();
+
+  // draw background
+  var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
+  lingrad.addColorStop(0, '#232256');
+  lingrad.addColorStop(1, '#143778');
+
+  ctx.fillStyle = lingrad;
+  ctx.fillRect(-75, -75, 150, 150);
+
+  // draw stars
+  for (var j = 1; j < 50; j++) {
+    ctx.save();
+    ctx.fillStyle = '#fff';
+    ctx.translate(75 - Math.floor(Math.random() * 150),
+                  75 - Math.floor(Math.random() * 150));
+    drawStar(ctx, Math.floor(Math.random() * 4) + 2);
+    ctx.restore();
+  }
+
+}
+
+function drawStar(ctx, r) {
+  ctx.save();
+  ctx.beginPath();
+  ctx.moveTo(r, 0);
+  for (var i = 0; i < 9; i++) {
+    ctx.rotate(Math.PI / 5);
+    if (i % 2 === 0) {
+      ctx.lineTo((r / 0.525731) * 0.200811, 0);
+    } else {
+      ctx.lineTo(r, 0);
+    }
+  }
+  ctx.closePath();
+  ctx.fill();
+  ctx.restore();
+}
+
+ + + +

В первых нескольких строках кода мы рисуем черный прямоугольник размером с холстом в качестве фона, а затем переводим начало координат в центр. Затем мы создаем круговой обтравочный контур, рисуя дугу и вызывающий clip(). Обрезанные контуры также являются частью состояния сохранения холста. Если бы мы хотели сохранить исходный обтравочный контур, мы могли бы сохранить состояние холста перед созданием нового.

+ +

Все, что нарисовано после создания отсеченного контура, появится только внутри этого пути. Вы можете видеть это четко в линейном градиенте, который нарисован далее. После этого набирается набор из 50 случайно расположенных и масштабированных звезд, используя drawStar(). Снова звезды появляются только в пределах определенного обтравочного контура.

+ +

{{EmbedLiveSample("A_clip_example", "180", "180", "https://mdn.mozillademos.org/files/208/Canvas_clip.png")}}

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}

diff --git a/files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html b/files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html new file mode 100644 index 0000000000..f6ca6c23ef --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/drawing_shapes/index.html @@ -0,0 +1,582 @@ +--- +title: Рисование фигур с помощью canvas +slug: Web/API/Canvas_API/Tutorial/Рисование_фигур +translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
+ +
+

Теперь, установив наше окружение canvas, мы можем погрузиться в детали того, как рисовать в canvas. К концу этой статьи, Вы научитесь рисовать прямоугольники, треугольники, линии, дуги и кривые, при условии что Вы хорошо знакомы с основными геометрическими фигурами. Работа с путями весьма важна, когда рисуете объекты на canvas и мы увидим как это может быть сделано.

+
+ +

Сетка

+ +

Перед тем, как мы начнем рисовать, нам нужно поговорить о сетке canvas или координатной плоскости. Наш HTML каркас из предыдущей страницы включал в себя элемент canvas 150 пикселей в ширину и 150 пикселей в высоту. Справа можно увидеть этот canvas с сеткой, накладываемой по умолчанию. Обычно 1 единица на сетке соответствует 1 пикселю на canvas. Начало координат этой сетки расположено в верхнем левом углу в координате (0,0 ). Все элементы размещены относительно этого начала. Таким образом, положение верхнего левого угла синего квадрата составляет х пикселей слева и у пикселей сверху, на координате , у). Позже в этом уроке мы увидим, как можно перевести начало координат в другое место, вращать сетку и даже масштабировать ее, но сейчас мы будем придерживаться настроек сетки по умолчанию.

+ +

Рисование прямоугольников

+ +

В отличие от {{Glossary("SVG")}}, {{HTMLElement("canvas")}} поддерживает только одну примитивную фигуру: прямоугольник. Все другие фигуры должны быть созданы комбинацией одного или большего количества контуров (paths), набором точек, соединенных в линии. К счастью в ассортименте рисования контуров у нас есть  функции, которые делают возможным составление очень сложных фигур.

+ +

Сначала рассмотрим прямоугольник. Ниже представлены три функции рисования прямоугольников в canvas:

+ +
+
{{domxref("CanvasRenderingContext2D.fillRect", "fillRect(x, y, width, height)")}}
+
Рисование заполненного прямоугольника.
+
{{domxref("CanvasRenderingContext2D.strokeRect", "strokeRect(x, y, width, height)")}}
+
Рисование прямоугольного контура.
+
{{domxref("CanvasRenderingContext2D.clearRect", "clearRect(x, y, width, height)")}}
+
Очистка  прямоугольной области, делая содержимое совершенно прозрачным.
+
+ +

Каждая из приведенных функций принимает несколько параметров: 

+ + + +

Ниже приведена функция draw(), использующая эти три функции.

+ +

Пример создания прямоугольных фигур

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    ctx.fillRect(25,25,100,100);
+    ctx.clearRect(45,45,60,60);
+    ctx.strokeRect(50,50,50,50);
+  }
+}
+ +

Этот пример изображен ниже.

+ +

{{EmbedLiveSample("Пример_создания_прямоугольных_фигур", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}

+ +

Функция fillRect() рисует большой чёрный квадрат со стороной 100 px. Функция clearRect() вырезает квадрат 60х60 из центра, а функция strokeRect() создает прямоугольный контур 50х50 пикселей внутри очищенного квадрата.

+ +

На следующей странице мы рассмотрим две альтернативы методу clearRect(), и также увидим, как можно изменять цвет и стиль контура отображаемых фигур.

+ +

В отличие от функций создания контуров, которые будут рассмотрены в следующем разделе, все три функции создания прямоугольника сразу же отображаются на canvas.

+ +

Рисование контуров (path)

+ +

Остальные примитивные фигуры создаются контурами. Контур - это набор точек, которые, соединяясь в отрезки линий, могут образовывать различные фигуры, изогнутые или нет, разной ширины и разного цвета. Контур (или субконтур) может быть закрытым.

+ +

Создание фигур используя контуры происходит в несколько важных шагов:

+ +
    +
  1. Сначала вы создаете контур.
  2. +
  3. Затем, используя команды рисования, рисуете контур.
  4. +
  5. Потом закрываете контур.
  6. +
  7. Созданный контур вы можете обвести или залить для его отображения.
  8. +
+ +

Здесь приведены функции, которые можно использовать в описанных шагах:

+ +
+
{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}
+
Создает новый контур. После создания используется в дальнейшем командами рисования при построении контуров.
+
Path методы
+
Методы для установки различных контуров объекта.
+
{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}
+
Закрывает контур, так что будущие команды рисования вновь направлены контекст.
+
{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}
+
Рисует фигуру с внешней обводкой.
+
{{domxref("CanvasRenderingContext2D.fill", "fill()")}}
+
Рисует фигуру с заливкой внутренней области.
+
+ +

Первый шаг создания контура заключается в вызове функции beginPath(). Внутри содержатся контуры в виде набора суб-контуров (линии, дуги и др.), которые вместе образуют форму фигуры. Каждый вызов этого метода очищает набор, и мы можем начинать рисовать новые фигуры.

+ +
Note:  если текущий контур пуст (например, как после вызова beginPath() или на вновь созданном canvas), первой командой построения контура всегда является функция  moveTo(). Поэтому мы всегда можем установить начальную позицию рисования контура после перезагрузки.
+ +

Вторым шагом является вызов методов, определяемых видом контура, который нужно нарисовать. Их мы рассмотрим позднее.

+ +

Третий и необязательный шаг - это вызов closePath(). Этот метод пытается закрыть фигуру, рисуя прямую линию из текущей точки в начальную. Если фигура была уже закрыта или является просто точкой, то функция ничего не делает.

+ +
Note: Когда вы вызываете fill(), то каждая открытая фигура закрывается автоматически, так что вы можете не использовать closePath(). Это обстоятельство не имеет место в случае вызова stroke().
+ +

Рисование треугольника

+ +

Например, код для рисования треугольника будет выглядеть как-то так:

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    ctx.beginPath();
+    ctx.moveTo(75,50);
+    ctx.lineTo(100,75);
+    ctx.lineTo(100,25);
+    ctx.fill();
+  }
+}
+
+ +

Результат выглядит так:

+ +

{{EmbedLiveSample("Рисование_треугольника", 110, 110, "https://mdn.mozillademos.org/files/9847/triangle.png")}}

+ +

Передвижение пера

+ +

Одна очень полезная функция, которая ничего не рисует, но связана по смыслу с вышеописанными функциями  - это moveTo(). Вы можете представить это как отрыв (подъем) пера от бумаги и его перемещение в другое место.

+ +
+
{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}
+
Перемещает перо в точку с координатами x и y.
+
+ +

При инициализации canvas или при вызове beginPath(), вы захотите использовать функцию moveTo() для перемещения в точку начала рисования. Можно использовать moveTo() и для рисования несвязанного(незакрытого) контура. Посмотрите на смайлик ниже.

+ +

Вы можете проверить это сами, используя участок кода ниже. Просто вставьте в функцию draw(), рассмотренную ранее.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+     var ctx = canvas.getContext('2d');
+
+    ctx.beginPath();
+    ctx.arc(75,75,50,0,Math.PI*2,true); // Внешняя окружность
+    ctx.moveTo(110,75);
+    ctx.arc(75,75,35,0,Math.PI,false);  // рот (по часовой стрелке)
+    ctx.moveTo(65,65);
+    ctx.arc(60,65,5,0,Math.PI*2,true);  // Левый глаз
+    ctx.moveTo(95,65);
+    ctx.arc(90,65,5,0,Math.PI*2,true);  // Правый глаз
+    ctx.stroke();
+  }
+}
+
+ +

Результат этого ниже:

+ +

{{EmbedLiveSample("Передвижение_пера", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}

+ +

Если вы захотите увидеть соединные линии, то можете удалить вызов moveTo().

+ +
+

Note: Подробнее о функции arc(),посмотрите {{anch("Дуги")}} .

+
+ +

Линии

+ +

Для рисования прямых линий используйте метод lineTo().

+ +
+
{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}
+
Рисует линию с текущей позиции до позиции, определенной x и y.
+
+ +

Этот метод принимает два аргумента x и y, которые являются координатами конечной точки линии. Начальная точка зависит от ранее нарисованных путей, причём конечная точка предыдущего пути является начальной точкой следующего и т. д. Начальная точка также может быть изменена с помощью метода moveTo().

+ +

Пример ниже рисует два треугольника, один закрашенный и другой обведен контуром.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    // Filled triangle
+    ctx.beginPath();
+    ctx.moveTo(25,25);
+    ctx.lineTo(105,25);
+    ctx.lineTo(25,105);
+    ctx.fill();
+
+    // Stroked triangle
+    ctx.beginPath();
+    ctx.moveTo(125,125);
+    ctx.lineTo(125,45);
+    ctx.lineTo(45,125);
+    ctx.closePath();
+    ctx.stroke();
+  }
+}
+
+ +

Отрисовка начинается с вызова beginPath(), чтобы начать рисовать путь новой фигуры. Затем мы используем метод moveTo(), чтобы переместить начальную точку в нужное положение. Ниже рисуются две линии, которые образуют две стороны треугольника.

+ +

{{EmbedLiveSample("Линии", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}

+ +

Вы заметите разницу между закрашенным и обведенным контуром треугольниками. Это, как упоминалось выше, из-за того, что фигуры автоматически закрываются, когда путь заполнен (т. е. закрашен), но не тогда, когда он очерчен (т. е. обведен контуром). Если бы мы не учли closePath() для очерченного треугольника, тогда только две линии были бы нарисованы, а не весь треугольник.

+ +

Дуги

+ +

Для рисования дуг и окружностей, используем методы arc() и arcTo().

+ +
+
{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}}
+
Рисуем дугу с центром в точке (x,y) радиусом radius, начиная с угла startAngle и заканчивая в endAngle в направлении против часовой стрелки anticlockwise (по умолчанию по ходу движения часовой стрелки).
+
{{domxref("CanvasRenderingContext2D.arcTo", "arcTo(x1, y1, x2, y2, radius)")}}
+
Рисуем дугу с заданными контрольными точками и радиусом, соединяя эти точки прямой линией.
+
+ +

Рассмотрим детальнее метод arc(), который имеет пять параметров: x и y — это координаты центра окружности, в которой должна быть нарисована дуга. radius — не требует пояснений. Углы startAngle и endAngle определяют начальную и конечную точки дуги в радианах вдоль кривой окружности. Отсчет происходит от оси x. Параметр anticlockwise — логическое значение, которое, если true, то рисование дуги совершается против хода часовой стрелки; иначе рисование происходит по ходу часовой стрелки.

+ +
+

Note: Углы в функции arc() измеряют в радианах, не в градусах. Для перевода градусов в радианы вы можете использовать JavaScript-выражение: radians = (Math.PI/180)*degrees.

+
+ +

Следующий пример немного сложнее, чем мы рассматривали ранее. Здесь нарисованы 12 различных дуг с разными углами и заливками.

+ +

Два for цикла размещают дуги по столбцам и строкам. Для каждой дуги, мы начинаем новый контур, вызывая beginPath(). В этом коде каждый параметр дуги для большей ясности задан в виде переменной, но вам не обязательно делать так в реальных проектах.

+ +

Координаты x и y  должны быть достаточно ясны. radius and startAngle — фиксированы. endAngle начинается со 180 градусов (полуокружность) в первой колонке и, увеличиваясь с шагом 90 градусов, достигает кульминации полноценной окружностью в последнем столбце.

+ +

Установка параметра clockwise определяет результат; в первой и третьей строках рисование дуг происходит по часовой стрелке, а во второй и четвертой - против часовой стрелки. Благодаря if-условию верхняя половина дуг образуется с контуром, (обводкой), а нижняя половина дуг - с заливкой.

+ +
+

Note: Этот пример требует немного большего холста (canvas), чем другие на этой странице: 150 x 200 pixels.

+
+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    for(var i=0;i<4;i++){
+      for(var j=0;j<3;j++){
+        ctx.beginPath();
+        var x = 25+j*50; // x coordinate
+        var y = 25+i*50; // y coordinate
+        var radius = 20; // Arc radius
+        var startAngle = 0; // Starting point on circle
+        var endAngle = Math.PI+(Math.PI*j)/2; // End point on circle
+        var anticlockwise = i%2==0 ? false : true; // clockwise or anticlockwise
+
+        ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
+
+        if (i>1){
+          ctx.fill();
+        } else {
+          ctx.stroke();
+        }
+      }
+    }
+  }
+}
+
+ +

{{EmbedLiveSample("Дуги", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}}

+ +

Безье и квадратичные кривые

+ +

Следующим типом доступных контуров являются  кривые Безье, и к тому же доступны в кубическом и квадратичном вариантах. Обычно они используются при рисовании сложных составных фигур.

+ +
+
{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}
+
Рисуется квадратичная кривая Безье с текущей позиции пера в конечную точку с координатами x и y, используя контрольную точку с координатами cp1x и cp1y.
+
{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}
+
Рисуется кубическая кривая Безье с текущей позиции пера в конечную точку с координатами x и y, используя две контрольные точки с координатами (cp1x, cp1y) и (cp2x, cp2y).
+
+ +

Различие между ними можно увидеть на рисунке, изображенном справа. Квадратичная кривая Безье имеет стартовую и конечную точки (синие точки) и всего одну контрольную точку (красная точка), в то время как кубическая кривая Безье использует две контрольные точки.

+ +

Параметры x и y в этих двух методах являются координатами конечной точки. cp1x и cp1y — координаты первой контрольной точки, а cp2x и cp2y — координаты второй контрольной точки.

+ +

Использование квадратичных или кубических кривых Безье может быть  спорным выходом, так как в отличие от приложений векторной графики типа Adobe Illustrator, мы не имеем полной видимой обратной связи с тем, что мы делаем. Этот факт делает довольно сложным процесс рисования сложных фигур. В следующем примере мы нарисуем совсем простую составную фигуру, но, если у вас есть время и ещё больше терпения, можно создать более сложные составные фигуры.

+ +

В этом примере нет ничего слишком тяжелого. В обоих случаях мы видим последовательность кривых, рисуя которые, в результате получим составную фигуру.

+ +

Квадратичные кривые Безье

+ +

В этом примере многократно используются квадратичные кривые Безье для рисования речевой выноски.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    // Quadratric curves example
+    ctx.beginPath();
+    ctx.moveTo(75,25);
+    ctx.quadraticCurveTo(25,25,25,62.5);
+    ctx.quadraticCurveTo(25,100,50,100);
+    ctx.quadraticCurveTo(50,120,30,125);
+    ctx.quadraticCurveTo(60,120,65,100);
+    ctx.quadraticCurveTo(125,100,125,62.5);
+    ctx.quadraticCurveTo(125,25,75,25);
+    ctx.stroke();
+  }
+}
+
+ +

{{EmbedLiveSample("Квадратичные_кривые_Безье", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}

+ +

Кубические кривые Безье

+ +

В этом примере нарисовано сердце с использованием кубических кривых Безье.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    // Cubic curves example
+    ctx.beginPath();
+    ctx.moveTo(75,40);
+    ctx.bezierCurveTo(75,37,70,25,50,25);
+    ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
+    ctx.bezierCurveTo(20,80,40,102,75,120);
+    ctx.bezierCurveTo(110,102,130,80,130,62.5);
+    ctx.bezierCurveTo(130,62.5,130,25,100,25);
+    ctx.bezierCurveTo(85,25,75,37,75,40);
+    ctx.fill();
+  }
+}
+
+ +

{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}

+ +

Прямоугольники

+ +

Все эти методы мы видели в  {{anch("Рисование прямоугольников")}}, которые рисуют прямоугольники сразу в canvas, так же есть метод rect(), который не отображает, а только добавляет контур рисования (path) заданного прямоугольника к последнему открытому контуру.

+ +
+
{{domxref("CanvasRenderingContext2D.rect", "rect(x, y, width, height)")}}
+

+ Добавляет в path прямоугольник, верхний левый угол которого указан с помощью (x, y) с вашими width и height
+
+
+ +

Когда этот метод вызван, автоматически вызывается метод moveTo() с параметрами (x, y). Другими словами, позиция курсора устанавливается в начало добавленного прямоугольника.

+ +

Создание комбинаций

+ +

До сих пор, в каждом примере использовался только один тип функции контуров для каждой фигуры.
+ Однако, нет никаких ограничений на количество или типы контуров, которые вы можете использовать для создания фигур. Давайте в этом примере объединим все вышеперечисленные  функции контуров, чтобы создать набор очень известных игровых персонажей.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    roundedRect(ctx,12,12,150,150,15);
+    roundedRect(ctx,19,19,150,150,9);
+    roundedRect(ctx,53,53,49,33,10);
+    roundedRect(ctx,53,119,49,16,6);
+    roundedRect(ctx,135,53,49,33,10);
+    roundedRect(ctx,135,119,25,49,10);
+
+    ctx.beginPath();
+    ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false);
+    ctx.lineTo(31,37);
+    ctx.fill();
+
+    for(var i=0;i<8;i++){
+      ctx.fillRect(51+i*16,35,4,4);
+    }
+
+    for(i=0;i<6;i++){
+      ctx.fillRect(115,51+i*16,4,4);
+    }
+
+    for(i=0;i<8;i++){
+      ctx.fillRect(51+i*16,99,4,4);
+    }
+
+    ctx.beginPath();
+    ctx.moveTo(83,116);
+    ctx.lineTo(83,102);
+    ctx.bezierCurveTo(83,94,89,88,97,88);
+    ctx.bezierCurveTo(105,88,111,94,111,102);
+    ctx.lineTo(111,116);
+    ctx.lineTo(106.333,111.333);
+    ctx.lineTo(101.666,116);
+    ctx.lineTo(97,111.333);
+    ctx.lineTo(92.333,116);
+    ctx.lineTo(87.666,111.333);
+    ctx.lineTo(83,116);
+    ctx.fill();
+
+    ctx.fillStyle = "white";
+    ctx.beginPath();
+    ctx.moveTo(91,96);
+    ctx.bezierCurveTo(88,96,87,99,87,101);
+    ctx.bezierCurveTo(87,103,88,106,91,106);
+    ctx.bezierCurveTo(94,106,95,103,95,101);
+    ctx.bezierCurveTo(95,99,94,96,91,96);
+    ctx.moveTo(103,96);
+    ctx.bezierCurveTo(100,96,99,99,99,101);
+    ctx.bezierCurveTo(99,103,100,106,103,106);
+    ctx.bezierCurveTo(106,106,107,103,107,101);
+    ctx.bezierCurveTo(107,99,106,96,103,96);
+    ctx.fill();
+
+    ctx.fillStyle = "black";
+    ctx.beginPath();
+    ctx.arc(101,102,2,0,Math.PI*2,true);
+    ctx.fill();
+
+    ctx.beginPath();
+    ctx.arc(89,102,2,0,Math.PI*2,true);
+    ctx.fill();
+  }
+}
+
+// A utility function to draw a rectangle with rounded corners.
+
+function roundedRect(ctx,x,y,width,height,radius){
+  ctx.beginPath();
+  ctx.moveTo(x,y+radius);
+  ctx.lineTo(x,y+height-radius);
+  ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
+  ctx.lineTo(x+width-radius,y+height);
+  ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
+  ctx.lineTo(x+width,y+radius);
+  ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
+  ctx.lineTo(x+radius,y);
+  ctx.quadraticCurveTo(x,y,x,y+radius);
+  ctx.stroke();
+}
+
+ +

Конечное изображение выглядит так:

+ +

{{EmbedLiveSample("Создание_комбинаций", 160, 160, "https://mdn.mozillademos.org/files/9849/combinations.png")}}

+ +

Мы не будем подробно останавливаться на том, так как это на самом деле удивительно просто. Наиболее важные вещи, которые следует отметить, это использование свойства fillStyle в контексте рисования и использование функции утилиты (в данном случае roundedRect()). Использование функций утилиты для битов чертежа часто может быть очень полезным и сократить количество необходимого кода, а также его сложность.

+ +

Позже, в этом уроке, мы еще раз рассмотрим fillStyle, но более подробно. Здесь же мы используем его для изменения цвета заливки путей вместо цвета по умолчанию от черного до белого, а затем обратно.

+ +

Path2D объекты

+ +

Как мы видели в последнем примере, есть серия путей и команд для рисования объектов на вашем холсте. Чтобы упростить код и повысить производительность, объект {{domxref("Path2D")}}, доступный в последних версиях браузеров, позволяет вам кэшировать или записывать эти команды рисования. Вы можете быстро запускать свои пути.
+ Давайте посмотрим, как мы можем построить объект Path2D :

+ +
+
{{domxref("Path2D.Path2D", "Path2D()")}}
+
Конструктор Path2D() возвращает вновь созданный объект Path2D  необязательно с другим путем в качестве аргумента (создает копию) или необязательно со строкой, состоящей из данных пути SVG path .
+
+ +
new Path2D();     // пустой path объект
+new Path2D(path); // копирование из другого path
+new Path2D(d);    // path из SVG
+ +

Все  методы path , такие как  moveTo,  rect,  arc, или quadraticCurveTo,  итп, которые мы уже знаем, доступны для объектов Path2D

+ +

API Path2D также добавляет способ комбинирования путей с использованием метода addPath. Это может быть полезно, если вы хотите, например, создавать объекты из нескольких компонентов.

+ +
+
{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}}
+
Добавляет путь к текущему пути с необязательной матрицей преобразования.
+
+ +

Path2D пример

+ +

В этом примере мы создаем прямоугольник и круг. Оба они сохраняются как объект Path2D, поэтому они доступны для последующего использования. С новым API Path2D несколько методов были обновлены, чтобы при необходимости принять объект Path2D для использования вместо текущего пути. Здесь stroke и fill используются с аргументом пути, например, для рисования обоих объектов на холст.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext){
+    var ctx = canvas.getContext('2d');
+
+    var rectangle = new Path2D();
+    rectangle.rect(10, 10, 50, 50);
+
+    var circle = new Path2D();
+    circle.moveTo(125, 35);
+    circle.arc(100, 35, 25, 0, 2 * Math.PI);
+
+    ctx.stroke(rectangle);
+    ctx.fill(circle);
+  }
+}
+
+ +

{{EmbedLiveSample("Path2D_example", 130, 110, "https://mdn.mozillademos.org/files/9851/path2d.png")}}

+ +

Использование SVG путей

+ +

Еще одна мощная функция нового Canvas Path2D API использует данные пути SVG, SVG path data, для инициализации путей на вашем холсте. Это может позволить вам передавать данные пути и повторно использовать их как в SVG, так и в холсте.

+ +

Путь перемещается в точку (M10 10), а затем горизонтально перемещается на 80 пунктов вправо (h 80), затем на 80 пунктов вниз (v 80), затем на 80 пунктов влево (h -80), а затем обратно на start (z). 
+ Этот пример можно увидеть на странице  Path2D constructor.

+ +
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
+ +
{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
diff --git a/files/ru/web/api/canvas_api/tutorial/drawing_text/index.html b/files/ru/web/api/canvas_api/tutorial/drawing_text/index.html new file mode 100644 index 0000000000..90915c5e09 --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/drawing_text/index.html @@ -0,0 +1,166 @@ +--- +title: Рисование текста +slug: Web/API/Canvas_API/Tutorial/Рисование_текста +tags: + - Canvas + - Графика + - Примеры + - Рукводовство + - мануал +translation_of: Web/API/Canvas_API/Tutorial/Drawing_text +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}
+ +
+

После того, как мы увидели в предыдущей главе, как применять стили и цвета, взглянем на написание текста в canvas.

+
+ +

Рисование текста

+ +

Контекст рендеринга canvas предоставляет два метода для рисования текста:

+ +
+
{{domxref("CanvasRenderingContext2D.fillText", "fillText(text, x, y [, maxWidth])")}}
+
Вставляет заданный текст в положении (x,y). Опционально может быть указана максимальная ширина.
+
{{domxref("CanvasRenderingContext2D.strokeText", "strokeText(text, x, y [, maxWidth])")}}
+
Вставляет контур заданного текста в положении (x,y). Опционально может быть указана максимальная ширина.
+
+ +

Пример fillText

+ +

Текст вставлен с использованием текущего fillStyle.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.font = "48px serif";
+  ctx.fillText("Hello world", 10, 50);
+}
+ + + +

{{EmbedLiveSample("A_fillText_example", 310, 110)}}

+ +

Пример strokeText

+ +

Текст вставлен с использованием текущего strokeStyle.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.font = "48px serif";
+  ctx.strokeText("Hello world", 10, 50);
+}
+ + + +

{{EmbedLiveSample("A_strokeText_example", 310, 110)}}

+ +

Стилизация текста

+ +

В примерах выше мы уже использовали свойство font для изменения размера текста. Кроме него существуют еще несколько свойств, позволяющие настроить вывод текста на canvas:

+ +
+
{{domxref("CanvasRenderingContext2D.font", "font = value")}}
+
Это основной стиль, который будет использоваться для вывода текста. Строка имеет такой же синтаксис, как CSS-свойство {{cssxref("font")}}. По умолчанию - sans-serif высотой 10px.
+
{{domxref("CanvasRenderingContext2D.textAlign", "textAlign = value")}}
+
Настройка выравнивания текста. Возможные значения: start, end, left, right или center. По умолчанию - start.
+
{{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline = value")}}
+
Настройка выравнивания текста по вертикали. Возможные значения: top, hanging, middle, alphabetic, ideographic, bottom. По умолчанию - alphabetic.
+
{{domxref("CanvasRenderingContext2D.direction", "direction = value")}}
+
Направление текста. Возможные значения: ltr, rtl, inherit. По умолчанию - inherit.
+
+ +

Эти свойства могут быть вам знакомы если вы работали с CSS.

+ +

Изображение от WHATWG ниже показывает различные варианты свойства textBaseline.The top of the em square is
+roughly at the top of the glyphs in a font, the hanging baseline is
+where some glyphs like आ are anchored, the middle is half-way
+between the top of the em square and the bottom of the em square,
+the alphabetic baseline is where characters like Á, ÿ,
+f, and Ω are anchored, the ideographic baseline is
+where glyphs like 私 and 達 are anchored, and the bottom
+of the em square is roughly at the bottom of the glyphs in a
+font. The top and bottom of the bounding box can be far from these
+baselines, due to glyphs extending far outside the em square.

+ +

Пример textBaseline

+ +

Редактируя код ниже, вы можете видеть, как меняется отображение текста на canvas в реальном времени:

+ +
ctx.font = "48px serif";
+ctx.textBaseline = "hanging";
+ctx.strokeText("Hello world!", 0, 100);
+
+ + + +

{{ EmbedLiveSample('Playable_code', 700, 360) }}

+ +

Измерение ширины текста

+ +

Для измерения ширины текста (без рисования его на canvas) можно воспользоваться следующим методом:

+ +
+
{{domxref("CanvasRenderingContext2D.measureText", "measureText()")}}
+
Возвращает объект {{domxref("TextMetrics")}}, содержащий ширину текста в пикселах, до отрисовки на canvas.
+
+ +

Пример ниже показывает, как можно измерить ширину текста.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var text = ctx.measureText("foo"); // TextMetrics object
+  text.width; // 16;
+}
+
+ +

Примечания

+ +

В ранних версиях Gecko (движок рендеринга в Firefox, Firefox OS и других приложениях Mozilla) были реализованы методы API с префиксами для рисования текста на canvas. На данный момент они устарели и уже, возможно, удалены, поэтому их правильная работа не гарантируется.

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}

diff --git a/files/ru/web/api/canvas_api/tutorial/using_images/index.html b/files/ru/web/api/canvas_api/tutorial/using_images/index.html new file mode 100644 index 0000000000..3ce4b8384e --- /dev/null +++ b/files/ru/web/api/canvas_api/tutorial/using_images/index.html @@ -0,0 +1,333 @@ +--- +title: Использование изображений +slug: Web/API/Canvas_API/Tutorial/Использование_изображений +tags: + - Графика +translation_of: Web/API/Canvas_API/Tutorial/Using_images +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Трансформации")}}
+ +
+

До сих пор мы создавали наши собственные фигуры и применяли стили к ним. Одна из самых впечатляющих функций {{HTMLElement("canvas")}} это возможность использования изображений. Они могут быть использованы для динамического композитинга фото или как фоны графиков, для спрайтов в играх, и так далее. Внешние изображения могут быть использованы в любых поддерживаемых браузером форматах, таких как PNG, GIF, или JPEG. Вы можете даже использовать изображение, произведенное другими canvas элементами на той же странице как источник!

+
+ +

Импортирование изображений в canvas в основном состоит из 2 этапов:

+ +
    +
  1. Дав ссылку на {{domxref("HTMLImageElement")}} объект или для другого canvas элемента как источник. Также можно использовать изображение дав ссылку на URL.
  2. +
  3. Для рисования изображения на canvas используется функция drawImage().
  4. +
+ +

Давайте посмотрим как это сделать.

+ +

Использование изображений для рисования

+ +

Canvas API может использовать все перечисленные далее типы данных как источник изображения:

+ +
+
{{domxref("HTMLImageElement")}}
+
Эти изображения созданы, используя конструктор Image(), также как все{{HTMLElement("img")}} элементы.
+
{{domxref("HTMLVideoElement")}}
+
Используя HTML {{HTMLElement("video")}} элемент как источник изображения захватывает текущий кадр из видео и использует его как изображение.
+
{{domxref("HTMLCanvasElement")}}
+
Вы можете использовать другой {{HTMLElement("canvas")}} элемент как источник изображения.
+
+ +

Эти источники совместно именуемые по типу {{domxref("CanvasImageSource")}}.

+ +

Есть несколько способов, чтобы получить изображения для использования на холсте.

+ +

Использование изображений из той же страницы

+ +

Мы можем получить ссылку на изображение, на той же странице, на canvas с используя  один из способов: 

+ + + +

Использование изображений из других доменов

+ +

Использование {{htmlattrxref("crossorigin", "img")}} атрибута {{HTMLElement("img")}} элемент (отображается  {{domxref("HTMLImageElement.crossOrigin")}} свойства), вы можете запросить разрешение на загрузку другого домена для использования в drawImage(). Если хостинг домен разрешает доступ к междоменному изображению, то изображение может быть использовано в вашем canvas без  without tainting it;иначе он может испортить ваш canvas.

+ +

Использование других canvas элементов

+ +

Как и с обычными изображениями, мы можем получить доступ к другим canvas элементам используя либо {{domxref("document.getElementsByTagName()")}} либо {{domxref("document.getElementById()")}} метод. Проверьте, что в canvas источнике уже что-то нарисовано, прежде чем использовать его в целевом изображении canvas.

+ +

Одним из удобных способов было бы использование второго элемента canvas  в качестве миниатюры другого большего изображения canvas.

+ +

Создание изображений с нуля

+ +

Другой способ это создать новые {{domxref("HTMLImageElement")}} объекты в нашем скрипте.  Чтобы это сделать, вы можете использовать удобный Image() конструктор:

+ +
var img = new Image();   // Создает новый элемент изображения
+img.src = 'myImage.png'; // Устанавливает путь
+
+ +

Когда этот скрипт выполнится, изображение начнет загружаться.

+ +

Если вы попытаетесь вызвать функцию drawImage() перед тем как изображение загрузится, то скрипт ничего не сделает (или, в старых браузерах, может даже выдать исключение). Поэтому вам необходимо использовать событие load, чтобы вы не пытались сделать это прежде, чем изображение загрузится:

+ +
var img = new Image();   // Создает новое изображение
+img.addEventListener("load", function() {
+  // здесь выполняет drawImage функцию
+}, false);
+img.src = 'myImage.png'; // Устанавливает источник файла
+
+ +

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

+ +

Вложение изображения с помощью данных: URL

+ +

Другой возможный способ включить изображение это через data: url. Data URLs позволяет вам полностью определить изображение как Base64 кодированную строку символов прямо в ваш код.

+ +
var img = new Image();   // Создает новый элемент img
+img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';
+
+ +

Одним из преимуществ data URLs  это то что полученное изображение доступно сразу без других запросов туда-обратно на сервер. Другое потенциальное преимущество в том, что также можно инкапсулировать всё в одном файле все ваши CSS, JavaScript, HTML, и изображения, что делает его более портативным в других местах.

+ +

Некоторые недостатки этого метода в том что ваше изображение не кешировано, и для изображений с большим размером кодированние url может стать очень долгим процессом.

+ +

Использование кадров из видео

+ +

Вы также можете использовать кадры из видео представленных {{HTMLElement("video")}} элементом (даже если видео не видно). Например, если у вас есть  {{HTMLElement("video")}} элемент с  ID "myvideo", вы можете сделать:

+ +
function getMyVideo() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    return document.getElementById('myvideo');
+  }
+}
+
+ +

Эта функция вернет {{domxref("HTMLVideoElement")}} объект для этого видео, который, как мы упоминали ранее, является одним из объектов, который можно использовать как CanvasImageSource.

+ +

Рисование изображений

+ +

Как только мы получили ссылку на источник объекта изображения, мы можем использовать метод drawImage() для включения его в  canvas. Как мы увидим далее, метод drawImage() перегружен и у него есть несколько вариантов. В базовом варианте он выглядит как:

+ +
+
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y)")}}
+
Рисует  изображение, указанное в CanvasImageSource в координатах  (x, y).
+
+ +
+

SVG изображения должны указывать ширину и высоту корневого  <svg> элемента.

+
+ +

Пример: Простой линейный график

+ +

В следующем примере, мы будем использовать внешнее изображение в качестве фона для небольшого линейного графика. Использование фонов может сделать ваш скрипт значительно меньше, потому что мы можем избежать необходимости писать код для создания фона. В этом примере мы используем только один образ, поэтому я использую обработчик событий изображения объекта загрузки для выполнения операторов рисования. drawImage() метод определяющий место фона с координатами (0, 0), которые привязаны к верхнему левому углу canvas.

+ + + +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var img = new Image();
+  img.onload = function(){
+    ctx.drawImage(img,0,0);
+    ctx.beginPath();
+    ctx.moveTo(30,96);
+    ctx.lineTo(70,66);
+    ctx.lineTo(103,76);
+    ctx.lineTo(170,15);
+    ctx.stroke();
+  };
+  img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png';
+}
+ +

Получившийся график выглядит так:

+ +

{{EmbedLiveSample("Example_A_simple_line_graph", 220, 160, "https://mdn.mozillademos.org/files/206/Canvas_backdrop.png")}}

+ +

Изменение размеров

+ +

Второй вариант метода drawImage() добавляет два новых параметра и позволяет разместить изображение в  canvas с измененными размерами.

+ +
+
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y, width, height)")}}
+
Это добавляет параметр ширины и высоты, которые указывают до какого размера нужно изменить изображение при рисовании его в  canvas.
+
+ +

Пример: Тайлинг изображения

+ +

В этом примере, мы будем использовать изображение в качестве обоев и повторим его в canvas несколько раз. Это может быть сделано просто через цикл, располагая измененные изображения на разных позициях. В коде внизу, первый цикл for проходит по рядам. Второй цикл for проходит по колонкам. Изображение уменьшено на треть от реального размера, которое было  50x38 пикселей.

+ +
+

Обратите внимание: Изображения могут стать размытыми, при большом увеличении или зернистыми при значительном уменьшении. Возможно, лучше всего не изменять размеры изображения, если на них есть текст, который должен остаться читаемым. 

+
+ + + +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var img = new Image();
+  img.onload = function(){
+    for (var i=0;i<4;i++){
+      for (var j=0;j<3;j++){
+        ctx.drawImage(img,j*50,i*38,50,38);
+      }
+    }
+  };
+  img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
+}
+ +

Получившийся рисунок canvas выглядит так:

+ +

{{EmbedLiveSample("Example_Tiling_an_image", 160, 160, "https://mdn.mozillademos.org/files/251/Canvas_scale_image.png")}}

+ +

Нарезка

+ +

У третьего и последнего варианта метода drawImage() в дополнении к источнику изображения есть еще восемь параметров . Он позволяет нам вырезать кусок из изображения, затем изменить его размер и нарисовать его в canvas.

+ +
+
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)")}}
+
В данном изображении, эта функция берет фрагмент из изображения, в виде прямоугольника, левый верхний угол которого -  (sx, sy), ширина и высота -  sWidth и sHeight и рисует  в  canvas, располагая его в точке  (dx, dy) и изменяя его размер на указанные величины в  dWidth и dHeight.
+
+ +

Чтобы понять что  делает нарезка, можно посмотреть на изображение справа. Первые четыре параметра определяют местоположение и размер фрагмента исходного изображения.  Последние четыре параметра определяют прямоугольник, в который будет вписано изображение на целевом рисунке  canvas.

+ +

Нарезка может быть полезным инструментом, когда вы захотите сделать композицию.  Вы могли бы собрать все элементы в одном файле изображения и использовать этот метод для создания композиции. Например, если вы захотите сделать график, вы могли бы сделать PNG изображение, содержащее все необходимые тексты в одном файле и в зависимости от ваших данных, могли бы достаточно просто изменять график. Другим преимуществом является то, что нет необходимости загружать каждое изображение по отдельности, получив возможность увеличить скорость загрузки.

+ +

Пример: Обрамление изображения

+ +

В этом примере, мы будем использовать того же носорога, что и в предыдущем примере, но мы отрежем его голову и включим ее в рамку. Изображение рамки это 24-х битный PNG, который включает падающую тень. Так как в 24-х битные PNG изображения включается полный 8-ми битный альфа-канал, в отличие от GIF и 8-битных PNG изображений, он может быть помещен в любой фон, без беспокойства о матовом цвете. 

+ +
<html>
+ <body onload="draw();">
+   <canvas id="canvas" width="150" height="150"></canvas>
+   <div style="display:none;">
+     <img id="source" src="https://mdn.mozillademos.org/files/5397/rhino.jpg" width="300" height="227">
+     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
+   </div>
+ </body>
+</html>
+
+ +
function draw() {
+  var canvas = document.getElementById('canvas');
+  var ctx = canvas.getContext('2d');
+
+  // Рисуем фрагмент
+  ctx.drawImage(document.getElementById('source'),
+                33, 71, 104, 124, 21, 20, 87, 104);
+
+  // Рисуем рамку
+  ctx.drawImage(document.getElementById('frame'),0,0);
+}
+ +

В этот раз мы применили другой способ загрузки изображения. Вместо загрузки методом создания новых {{domxref("HTMLImageElement")}} объектов, мы включили их как  {{HTMLElement("img")}} тэги прямо в наш HTML файл и из них выбрали изображения. Изображения скрыты с помощью  CSS свойства {{cssxref("display")}}, установленного в "none" для этих изображений.

+ +

{{EmbedLiveSample("Example_Framing_an_image", 160, 160, "https://mdn.mozillademos.org/files/226/Canvas_drawimage2.jpg")}}

+ +

Скрипт, сам по себе, очень простой. Каждому {{HTMLElement("img")}} присвоен атрибут ID, который  делает удобным их выбор с использованием {{domxref("document.getElementById()")}}. Потом мы просто используем функцию  drawImage(), чтобы из первого изображения вырезать фрагмент носорога и вставить его в canvas, затем рисуем рамку сверху, используя второй вызов функции drawImage().

+ +

Пример галереи искусства

+ +

В последнем примере этой главы, мы построим небольшую галлерею искусств. Галерея состоит из таблицы, включающей несколько изображений. Когда страница загрузится,  {{HTMLElement("canvas")}}  элемент вставится в каждое изображение, а вокруг будет нарисована рамка. 

+ +

В этом случае, у каждого изображения фиксированная ширина и высота, такая же, как и у рамки нарисованной вокруг них.  Вы могли бы усовершенствовать этот скрипт так, чтобы он использовал ширину и высоту изображения, чтобы рамка идеально его окружила.

+ +

Код ниже должен говорить сам за себя. Мы проходим циклом через {{domxref("document.images")}} контейнер и соответственно добавляем новые элементы  canvas. Возможно следует упомянуть для тех, кто не слишком хорошо знаком с DOM, что для этого используется {{domxref("Node.insertBefore")}} метод. insertBefore() это метод родительского узла (ячейки таблицы) элемента (изображения) перед которым мы хотим вставить наш новый узел  (элемент canvas).

+ +
<html>
+ <body onload="draw();">
+     <table>
+      <tr>
+        <td><img src="https://mdn.mozillademos.org/files/5399/gallery_1.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5401/gallery_2.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5403/gallery_3.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5405/gallery_4.jpg"></td>
+      </tr>
+      <tr>
+        <td><img src="https://mdn.mozillademos.org/files/5407/gallery_5.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5409/gallery_6.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5411/gallery_7.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5413/gallery_8.jpg"></td>
+      </tr>
+     </table>
+     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
+ </body>
+</html>
+
+ +

И сюда какую-нибудь CSS для украшения:

+ +
body {
+  background: 0 -100px repeat-x url(https://mdn.mozillademos.org/files/5415/bg_gallery.png) #4F191A;
+  margin: 10px;
+}
+
+img {
+  display: none;
+}
+
+table {
+  margin: 0 auto;
+}
+
+td {
+  padding: 15px;
+}
+
+ +

Связывая все вместе  JavaScript рисует наши изображения в рамках:

+ +
function draw() {
+
+  // Цикл по всем изображениям
+  for (var i=0;i<document.images.length;i++){
+
+    // Не добавляет canvas для изображения рамки
+    if (document.images[i].getAttribute('id')!='frame'){
+
+      // Создает элемент canvas
+      var canvas = document.createElement('canvas');
+      canvas.setAttribute('width',132);
+      canvas.setAttribute('height',150);
+
+      // Вставляет перед изображением
+      document.images[i].parentNode.insertBefore(canvas,document.images[i]);
+
+      var ctx = canvas.getContext('2d');
+
+      // Рисует изображение в canvas
+      ctx.drawImage(document.images[i],15,20);
+
+      // Добавляет рамку
+      ctx.drawImage(document.getElementById('frame'),0,0);
+    }
+  }
+}
+ +

{{EmbedLiveSample("Art_gallery_example", 725, 400)}}

+ +

Контроль изменений размеров изображения

+ +

Как было отмечено ранее, изменение размеров изображений может привести к размытости или к шуму в процессе преобразования. Вы можете использовать контекст рисования {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} свойства, чтобы контролировать использование сглаживающего алгоритма, когда изменяющиеся изображения в вашем контексте. Обычно это свойство установлено в  true, означая, что изображения будут сглажены во время изменения размеров. Вы можете отключить это свойство так:

+ +
ctx.mozImageSmoothingEnabled = false;
+ctx.webkitImageSmoothingEnabled = false;
+ctx.msImageSmoothingEnabled = false;
+ctx.imageSmoothingEnabled = false;
+
+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Transformations")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\320\271/index.html" "b/files/ru/web/api/canvas_api/tutorial/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\320\271/index.html" deleted file mode 100644 index 3ce4b8384e..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\270\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\320\271/index.html" +++ /dev/null @@ -1,333 +0,0 @@ ---- -title: Использование изображений -slug: Web/API/Canvas_API/Tutorial/Использование_изображений -tags: - - Графика -translation_of: Web/API/Canvas_API/Tutorial/Using_images ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Трансформации")}}
- -
-

До сих пор мы создавали наши собственные фигуры и применяли стили к ним. Одна из самых впечатляющих функций {{HTMLElement("canvas")}} это возможность использования изображений. Они могут быть использованы для динамического композитинга фото или как фоны графиков, для спрайтов в играх, и так далее. Внешние изображения могут быть использованы в любых поддерживаемых браузером форматах, таких как PNG, GIF, или JPEG. Вы можете даже использовать изображение, произведенное другими canvas элементами на той же странице как источник!

-
- -

Импортирование изображений в canvas в основном состоит из 2 этапов:

- -
    -
  1. Дав ссылку на {{domxref("HTMLImageElement")}} объект или для другого canvas элемента как источник. Также можно использовать изображение дав ссылку на URL.
  2. -
  3. Для рисования изображения на canvas используется функция drawImage().
  4. -
- -

Давайте посмотрим как это сделать.

- -

Использование изображений для рисования

- -

Canvas API может использовать все перечисленные далее типы данных как источник изображения:

- -
-
{{domxref("HTMLImageElement")}}
-
Эти изображения созданы, используя конструктор Image(), также как все{{HTMLElement("img")}} элементы.
-
{{domxref("HTMLVideoElement")}}
-
Используя HTML {{HTMLElement("video")}} элемент как источник изображения захватывает текущий кадр из видео и использует его как изображение.
-
{{domxref("HTMLCanvasElement")}}
-
Вы можете использовать другой {{HTMLElement("canvas")}} элемент как источник изображения.
-
- -

Эти источники совместно именуемые по типу {{domxref("CanvasImageSource")}}.

- -

Есть несколько способов, чтобы получить изображения для использования на холсте.

- -

Использование изображений из той же страницы

- -

Мы можем получить ссылку на изображение, на той же странице, на canvas с используя  один из способов: 

- - - -

Использование изображений из других доменов

- -

Использование {{htmlattrxref("crossorigin", "img")}} атрибута {{HTMLElement("img")}} элемент (отображается  {{domxref("HTMLImageElement.crossOrigin")}} свойства), вы можете запросить разрешение на загрузку другого домена для использования в drawImage(). Если хостинг домен разрешает доступ к междоменному изображению, то изображение может быть использовано в вашем canvas без  without tainting it;иначе он может испортить ваш canvas.

- -

Использование других canvas элементов

- -

Как и с обычными изображениями, мы можем получить доступ к другим canvas элементам используя либо {{domxref("document.getElementsByTagName()")}} либо {{domxref("document.getElementById()")}} метод. Проверьте, что в canvas источнике уже что-то нарисовано, прежде чем использовать его в целевом изображении canvas.

- -

Одним из удобных способов было бы использование второго элемента canvas  в качестве миниатюры другого большего изображения canvas.

- -

Создание изображений с нуля

- -

Другой способ это создать новые {{domxref("HTMLImageElement")}} объекты в нашем скрипте.  Чтобы это сделать, вы можете использовать удобный Image() конструктор:

- -
var img = new Image();   // Создает новый элемент изображения
-img.src = 'myImage.png'; // Устанавливает путь
-
- -

Когда этот скрипт выполнится, изображение начнет загружаться.

- -

Если вы попытаетесь вызвать функцию drawImage() перед тем как изображение загрузится, то скрипт ничего не сделает (или, в старых браузерах, может даже выдать исключение). Поэтому вам необходимо использовать событие load, чтобы вы не пытались сделать это прежде, чем изображение загрузится:

- -
var img = new Image();   // Создает новое изображение
-img.addEventListener("load", function() {
-  // здесь выполняет drawImage функцию
-}, false);
-img.src = 'myImage.png'; // Устанавливает источник файла
-
- -

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

- -

Вложение изображения с помощью данных: URL

- -

Другой возможный способ включить изображение это через data: url. Data URLs позволяет вам полностью определить изображение как Base64 кодированную строку символов прямо в ваш код.

- -
var img = new Image();   // Создает новый элемент img
-img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';
-
- -

Одним из преимуществ data URLs  это то что полученное изображение доступно сразу без других запросов туда-обратно на сервер. Другое потенциальное преимущество в том, что также можно инкапсулировать всё в одном файле все ваши CSS, JavaScript, HTML, и изображения, что делает его более портативным в других местах.

- -

Некоторые недостатки этого метода в том что ваше изображение не кешировано, и для изображений с большим размером кодированние url может стать очень долгим процессом.

- -

Использование кадров из видео

- -

Вы также можете использовать кадры из видео представленных {{HTMLElement("video")}} элементом (даже если видео не видно). Например, если у вас есть  {{HTMLElement("video")}} элемент с  ID "myvideo", вы можете сделать:

- -
function getMyVideo() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    return document.getElementById('myvideo');
-  }
-}
-
- -

Эта функция вернет {{domxref("HTMLVideoElement")}} объект для этого видео, который, как мы упоминали ранее, является одним из объектов, который можно использовать как CanvasImageSource.

- -

Рисование изображений

- -

Как только мы получили ссылку на источник объекта изображения, мы можем использовать метод drawImage() для включения его в  canvas. Как мы увидим далее, метод drawImage() перегружен и у него есть несколько вариантов. В базовом варианте он выглядит как:

- -
-
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y)")}}
-
Рисует  изображение, указанное в CanvasImageSource в координатах  (x, y).
-
- -
-

SVG изображения должны указывать ширину и высоту корневого  <svg> элемента.

-
- -

Пример: Простой линейный график

- -

В следующем примере, мы будем использовать внешнее изображение в качестве фона для небольшого линейного графика. Использование фонов может сделать ваш скрипт значительно меньше, потому что мы можем избежать необходимости писать код для создания фона. В этом примере мы используем только один образ, поэтому я использую обработчик событий изображения объекта загрузки для выполнения операторов рисования. drawImage() метод определяющий место фона с координатами (0, 0), которые привязаны к верхнему левому углу canvas.

- - - -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var img = new Image();
-  img.onload = function(){
-    ctx.drawImage(img,0,0);
-    ctx.beginPath();
-    ctx.moveTo(30,96);
-    ctx.lineTo(70,66);
-    ctx.lineTo(103,76);
-    ctx.lineTo(170,15);
-    ctx.stroke();
-  };
-  img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png';
-}
- -

Получившийся график выглядит так:

- -

{{EmbedLiveSample("Example_A_simple_line_graph", 220, 160, "https://mdn.mozillademos.org/files/206/Canvas_backdrop.png")}}

- -

Изменение размеров

- -

Второй вариант метода drawImage() добавляет два новых параметра и позволяет разместить изображение в  canvas с измененными размерами.

- -
-
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y, width, height)")}}
-
Это добавляет параметр ширины и высоты, которые указывают до какого размера нужно изменить изображение при рисовании его в  canvas.
-
- -

Пример: Тайлинг изображения

- -

В этом примере, мы будем использовать изображение в качестве обоев и повторим его в canvas несколько раз. Это может быть сделано просто через цикл, располагая измененные изображения на разных позициях. В коде внизу, первый цикл for проходит по рядам. Второй цикл for проходит по колонкам. Изображение уменьшено на треть от реального размера, которое было  50x38 пикселей.

- -
-

Обратите внимание: Изображения могут стать размытыми, при большом увеличении или зернистыми при значительном уменьшении. Возможно, лучше всего не изменять размеры изображения, если на них есть текст, который должен остаться читаемым. 

-
- - - -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var img = new Image();
-  img.onload = function(){
-    for (var i=0;i<4;i++){
-      for (var j=0;j<3;j++){
-        ctx.drawImage(img,j*50,i*38,50,38);
-      }
-    }
-  };
-  img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
-}
- -

Получившийся рисунок canvas выглядит так:

- -

{{EmbedLiveSample("Example_Tiling_an_image", 160, 160, "https://mdn.mozillademos.org/files/251/Canvas_scale_image.png")}}

- -

Нарезка

- -

У третьего и последнего варианта метода drawImage() в дополнении к источнику изображения есть еще восемь параметров . Он позволяет нам вырезать кусок из изображения, затем изменить его размер и нарисовать его в canvas.

- -
-
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)")}}
-
В данном изображении, эта функция берет фрагмент из изображения, в виде прямоугольника, левый верхний угол которого -  (sx, sy), ширина и высота -  sWidth и sHeight и рисует  в  canvas, располагая его в точке  (dx, dy) и изменяя его размер на указанные величины в  dWidth и dHeight.
-
- -

Чтобы понять что  делает нарезка, можно посмотреть на изображение справа. Первые четыре параметра определяют местоположение и размер фрагмента исходного изображения.  Последние четыре параметра определяют прямоугольник, в который будет вписано изображение на целевом рисунке  canvas.

- -

Нарезка может быть полезным инструментом, когда вы захотите сделать композицию.  Вы могли бы собрать все элементы в одном файле изображения и использовать этот метод для создания композиции. Например, если вы захотите сделать график, вы могли бы сделать PNG изображение, содержащее все необходимые тексты в одном файле и в зависимости от ваших данных, могли бы достаточно просто изменять график. Другим преимуществом является то, что нет необходимости загружать каждое изображение по отдельности, получив возможность увеличить скорость загрузки.

- -

Пример: Обрамление изображения

- -

В этом примере, мы будем использовать того же носорога, что и в предыдущем примере, но мы отрежем его голову и включим ее в рамку. Изображение рамки это 24-х битный PNG, который включает падающую тень. Так как в 24-х битные PNG изображения включается полный 8-ми битный альфа-канал, в отличие от GIF и 8-битных PNG изображений, он может быть помещен в любой фон, без беспокойства о матовом цвете. 

- -
<html>
- <body onload="draw();">
-   <canvas id="canvas" width="150" height="150"></canvas>
-   <div style="display:none;">
-     <img id="source" src="https://mdn.mozillademos.org/files/5397/rhino.jpg" width="300" height="227">
-     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
-   </div>
- </body>
-</html>
-
- -
function draw() {
-  var canvas = document.getElementById('canvas');
-  var ctx = canvas.getContext('2d');
-
-  // Рисуем фрагмент
-  ctx.drawImage(document.getElementById('source'),
-                33, 71, 104, 124, 21, 20, 87, 104);
-
-  // Рисуем рамку
-  ctx.drawImage(document.getElementById('frame'),0,0);
-}
- -

В этот раз мы применили другой способ загрузки изображения. Вместо загрузки методом создания новых {{domxref("HTMLImageElement")}} объектов, мы включили их как  {{HTMLElement("img")}} тэги прямо в наш HTML файл и из них выбрали изображения. Изображения скрыты с помощью  CSS свойства {{cssxref("display")}}, установленного в "none" для этих изображений.

- -

{{EmbedLiveSample("Example_Framing_an_image", 160, 160, "https://mdn.mozillademos.org/files/226/Canvas_drawimage2.jpg")}}

- -

Скрипт, сам по себе, очень простой. Каждому {{HTMLElement("img")}} присвоен атрибут ID, который  делает удобным их выбор с использованием {{domxref("document.getElementById()")}}. Потом мы просто используем функцию  drawImage(), чтобы из первого изображения вырезать фрагмент носорога и вставить его в canvas, затем рисуем рамку сверху, используя второй вызов функции drawImage().

- -

Пример галереи искусства

- -

В последнем примере этой главы, мы построим небольшую галлерею искусств. Галерея состоит из таблицы, включающей несколько изображений. Когда страница загрузится,  {{HTMLElement("canvas")}}  элемент вставится в каждое изображение, а вокруг будет нарисована рамка. 

- -

В этом случае, у каждого изображения фиксированная ширина и высота, такая же, как и у рамки нарисованной вокруг них.  Вы могли бы усовершенствовать этот скрипт так, чтобы он использовал ширину и высоту изображения, чтобы рамка идеально его окружила.

- -

Код ниже должен говорить сам за себя. Мы проходим циклом через {{domxref("document.images")}} контейнер и соответственно добавляем новые элементы  canvas. Возможно следует упомянуть для тех, кто не слишком хорошо знаком с DOM, что для этого используется {{domxref("Node.insertBefore")}} метод. insertBefore() это метод родительского узла (ячейки таблицы) элемента (изображения) перед которым мы хотим вставить наш новый узел  (элемент canvas).

- -
<html>
- <body onload="draw();">
-     <table>
-      <tr>
-        <td><img src="https://mdn.mozillademos.org/files/5399/gallery_1.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5401/gallery_2.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5403/gallery_3.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5405/gallery_4.jpg"></td>
-      </tr>
-      <tr>
-        <td><img src="https://mdn.mozillademos.org/files/5407/gallery_5.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5409/gallery_6.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5411/gallery_7.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5413/gallery_8.jpg"></td>
-      </tr>
-     </table>
-     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
- </body>
-</html>
-
- -

И сюда какую-нибудь CSS для украшения:

- -
body {
-  background: 0 -100px repeat-x url(https://mdn.mozillademos.org/files/5415/bg_gallery.png) #4F191A;
-  margin: 10px;
-}
-
-img {
-  display: none;
-}
-
-table {
-  margin: 0 auto;
-}
-
-td {
-  padding: 15px;
-}
-
- -

Связывая все вместе  JavaScript рисует наши изображения в рамках:

- -
function draw() {
-
-  // Цикл по всем изображениям
-  for (var i=0;i<document.images.length;i++){
-
-    // Не добавляет canvas для изображения рамки
-    if (document.images[i].getAttribute('id')!='frame'){
-
-      // Создает элемент canvas
-      var canvas = document.createElement('canvas');
-      canvas.setAttribute('width',132);
-      canvas.setAttribute('height',150);
-
-      // Вставляет перед изображением
-      document.images[i].parentNode.insertBefore(canvas,document.images[i]);
-
-      var ctx = canvas.getContext('2d');
-
-      // Рисует изображение в canvas
-      ctx.drawImage(document.images[i],15,20);
-
-      // Добавляет рамку
-      ctx.drawImage(document.getElementById('frame'),0,0);
-    }
-  }
-}
- -

{{EmbedLiveSample("Art_gallery_example", 725, 400)}}

- -

Контроль изменений размеров изображения

- -

Как было отмечено ранее, изменение размеров изображений может привести к размытости или к шуму в процессе преобразования. Вы можете использовать контекст рисования {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} свойства, чтобы контролировать использование сглаживающего алгоритма, когда изменяющиеся изображения в вашем контексте. Обычно это свойство установлено в  true, означая, что изображения будут сглажены во время изменения размеров. Вы можете отключить это свойство так:

- -
ctx.mozImageSmoothingEnabled = false;
-ctx.webkitImageSmoothingEnabled = false;
-ctx.msImageSmoothingEnabled = false;
-ctx.imageSmoothingEnabled = false;
-
- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Transformations")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\320\272\320\276\320\274\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" "b/files/ru/web/api/canvas_api/tutorial/\320\272\320\276\320\274\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" deleted file mode 100644 index 264cc7e544..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\320\272\320\276\320\274\320\277\320\276\320\267\320\270\321\206\320\270\320\270/index.html" +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: Композиция и обрезка -slug: Web/API/Canvas_API/Tutorial/Композиции -tags: - - канвас -translation_of: Web/API/Canvas_API/Tutorial/Compositing ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}
- -
-

Во всех наших предыдущих примерах, фигуры всегда были нарисованы одна поверх другой. Это более чем достаточно для большинства ситуаций, но это ограничивает порядок, в котором построены композиционные формы. Однако, мы можем изменить это поведение, установив свойство globalCompositeOperation. Кроме того, свойства clip позволяет скрыть нежелательные части формы.

-
- -

globalCompositeOperation

- -

Мы можем не только рисовать новые фигуры за существующие формы, но мы также можем использовать его, чтобы замаскировать определенные участки, очистить разделы от холста (не ограничивается прямоугольниками, как{{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}} method does) и другое.

- -
-
{{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation = type")}}
-
Это задает Тип операции композиции для применения при разработке новых форм, где Тип является строкой, идентифицирующей, какие из двенадцати операций композитинг в использовании.
-
- -

См.  примеры компоновки кода из следующих примеров.

- -

{{EmbedLiveSample("Compositing_example", 750, 6750, "" ,"Web/API/Canvas_API/Tutorial/Compositing/Example")}}

- -

Обрезка контуров

- -

Отсеченный контур похож на обычную форму холста, но он действует как маска, чтобы скрыть нежелательные части фигур. Это визуализируется на изображении справа. Форма красной звезды - наша отправочная дорожка. Все, что выходит за пределы этого пути, не будет нарисовано на холсте.

- -

Если мы сравниваем отсеченный контур со свойством globalCompositeOperation на изображении, мы видим два режима композитинга, которые достигают более или менее того же эффекта в исходном и исходном состоянии.   Наиболее важные различия между ними заключаются в том, что отсечение контура фактически  никогда не обращается к холсту и контур обрезки никогда не влияет добавление новых форм. Это делает обрезку контура идеальным для рисования нескольких фигур в ограниченной области.

- -

В главе о рисовании форм, я назвал только stroke() и fill() методы, но есть третий способ можно использовать с контурами, так называемый clip().

- -
-
{{domxref("CanvasRenderingContext2D.clip", "clip()")}}
-
Преобразует текущий выстраиваемый контур в отсечённый контур.
-
- -

Используйте clip() вместо closePath() для закрытия контура и его преобразования в отсечённый контур вместо создания заполняющего  или обрамляющего контура.

- -

По умолчанию элемент {{HTMLElement("canvas")}} использует отсечённый контур, который в точности совпадает по размеру с размером самого холста. Это означает, что никакого отсечения попросту не произойдёт.

- -

Пример обрезки

- -

В этом примере мы будем использовать круговую обрезку контура, чтобы ограничить рисование набора случайных звезд определенной областью.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.fillRect(0, 0, 150, 150);
-  ctx.translate(75, 75);
-
-  // Create a circular clipping path
-  ctx.beginPath();
-  ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
-  ctx.clip();
-
-  // draw background
-  var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
-  lingrad.addColorStop(0, '#232256');
-  lingrad.addColorStop(1, '#143778');
-
-  ctx.fillStyle = lingrad;
-  ctx.fillRect(-75, -75, 150, 150);
-
-  // draw stars
-  for (var j = 1; j < 50; j++) {
-    ctx.save();
-    ctx.fillStyle = '#fff';
-    ctx.translate(75 - Math.floor(Math.random() * 150),
-                  75 - Math.floor(Math.random() * 150));
-    drawStar(ctx, Math.floor(Math.random() * 4) + 2);
-    ctx.restore();
-  }
-
-}
-
-function drawStar(ctx, r) {
-  ctx.save();
-  ctx.beginPath();
-  ctx.moveTo(r, 0);
-  for (var i = 0; i < 9; i++) {
-    ctx.rotate(Math.PI / 5);
-    if (i % 2 === 0) {
-      ctx.lineTo((r / 0.525731) * 0.200811, 0);
-    } else {
-      ctx.lineTo(r, 0);
-    }
-  }
-  ctx.closePath();
-  ctx.fill();
-  ctx.restore();
-}
-
- - - -

В первых нескольких строках кода мы рисуем черный прямоугольник размером с холстом в качестве фона, а затем переводим начало координат в центр. Затем мы создаем круговой обтравочный контур, рисуя дугу и вызывающий clip(). Обрезанные контуры также являются частью состояния сохранения холста. Если бы мы хотели сохранить исходный обтравочный контур, мы могли бы сохранить состояние холста перед созданием нового.

- -

Все, что нарисовано после создания отсеченного контура, появится только внутри этого пути. Вы можете видеть это четко в линейном градиенте, который нарисован далее. После этого набирается набор из 50 случайно расположенных и масштабированных звезд, используя drawStar(). Снова звезды появляются только в пределах определенного обтравочного контура.

- -

{{EmbedLiveSample("A_clip_example", "180", "180", "https://mdn.mozillademos.org/files/208/Canvas_clip.png")}}

- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\320\276\321\201\320\275\320\276\320\262\321\213_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" "b/files/ru/web/api/canvas_api/tutorial/\320\276\321\201\320\275\320\276\320\262\321\213_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" deleted file mode 100644 index a47b8b734e..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\320\276\321\201\320\275\320\276\320\262\321\213_\320\260\320\275\320\270\320\274\320\260\321\206\320\270\320\270/index.html" +++ /dev/null @@ -1,308 +0,0 @@ ---- -title: Простые анимации -slug: Web/API/Canvas_API/Tutorial/Основы_анимации -tags: - - HTML - - HTML5 - - Графика - - Обучение - - Средний уровень - - Холст -translation_of: Web/API/Canvas_API/Tutorial/Basic_animations ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}
- -
-

Поскольку для управления элементами {{HTMLElement ("canvas")}} используется JavaScript, не составляет труда сделать (интерактивные) анимации. В этой главе мы рассмотрим, как делаются некоторые базовые анимации.

-
- -

Вероятно, самым большим ограничением является то, что когда фигура нарисована, её уже нельзя двигать. Чтобы изобразить движение нам нужно перерисовать фигуру и всё, что было нарисовано до неё. Перерисовка сложных кадров занимает много времени, и производительность сильно зависит от скорости компьютера, на котором она выполняется.

- -

Основные шаги анимации

- -

Ниже перечислены необходимые шаги для того, чтобы нарисовать кадр:

- -
    -
  1. Очистить canvas
    - Если фигура, которую вы собираетесь нарисовать, не занимает всю площадь canvas (как фон, например), то всё что было нарисовано ранее необходимо стереть. Проще всего это сделать при помощи метода {{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}.
  2. -
  3. Сохранить изначальное состояние canvas
    - Если вы изменяете любые настройки (такие как стили, трансформации и т.п.), которые затрагивают состояние canvas и вы хотите убедиться, что оригинальное состояние используется каждый раз, когда был отрисован кадр, то вам следует сохранить это оригинальное состояние.
  4. -
  5. Нарисовать анимированные фигуры
    - Шаг на котором вы собственно отрисовываете кадр.
  6. -
  7. Восстановить состояние canvas
    - Если вы сохраняли состояние, восстановите его, прежде чем отрисовывать новый кадр.
  8. -
- -

Управление анимацией

- -

Фигуры отрисовываются на canvas либо напрямую — при помощи методов canvas, либо с помощью сторонних функций. В нормальной ситуации результат станет виден на canvas после окончания выполнения скрипта. К примеру, цикл for использовать для анимации нельзя. 

- -

Это значит, нужен способ выполнения функций отрисовки через интервалы времени. Есть два способа для управления такой анимацией.

- -

Запланированные обновления

- -

Первый — это функции {{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}}, и {{domxref("window.requestAnimationFrame()")}}, которые могут быть использованы для вызова некоторой функции, через заданный промежуток времени.

- -
-
{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}
-
Начинает периодически исполнять функцию function каждые delay миллисекунд.
-
{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}
-
Запускает выполнение указанной функции function через delay миллисекунд.
-
{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}
-
Сообщает браузеру, что вы хотите выполнить анимацию, и запрашивает, чтобы браузер вызвал указанную функцию callback для обновления анимации перед следующей перерисовкой.
-
- -

Если вы не планируете никакого взаимодействия с пользователем, вы можете использовать функцию setInterval() , которая многократно выполняет, предоставленный ей код. Если же вы планиуете создать игру, в которой контроль анимации осуществляется мышью или клавиатурой, то необходимо использовать  setTimeout(). Установив {{domxref("EventListener")}}, вы можете перехватываете любые действия пользователя и запустить соответствующие функции анимации.

- -
-

В примерах ниже мы будем использовать функцию {{domxref("window.requestAnimationFrame()")}} для контроля анимации. Функция requestAnimationFrame является более эффективной для создания анимации, так как новая итерация вызывается, когда система готова к отрисовке нового кадра. Количество вызовов в секунду примерно равно 60 и уменьшается, когда вкладка неактивна. Для более подробного изучения цикла анимации, особенно для игр, прочитайте статью Анатомия видеоигр В Зоне разработке игр.

-
- -

Анимированная солнечная система

- -

В этом примере анимируется небольшая модель солнечной системы.

- -
var sun = new Image();
-var moon = new Image();
-var earth = new Image();
-function init(){
-  sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
-  moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
-  earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
-  window.requestAnimationFrame(draw);
-}
-
-function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  ctx.globalCompositeOperation = 'destination-over';
-  ctx.clearRect(0,0,300,300); // clear canvas
-
-  ctx.fillStyle = 'rgba(0,0,0,0.4)';
-  ctx.strokeStyle = 'rgba(0,153,255,0.4)';
-  ctx.save();
-  ctx.translate(150,150);
-
-  // Earth
-  var time = new Date();
-  ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
-  ctx.translate(105,0);
-  ctx.fillRect(0,-12,50,24); // Shadow
-  ctx.drawImage(earth,-12,-12);
-
-  // Moon
-  ctx.save();
-  ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
-  ctx.translate(0,28.5);
-  ctx.drawImage(moon,-3.5,-3.5);
-  ctx.restore();
-
-  ctx.restore();
-
-  ctx.beginPath();
-  ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
-  ctx.stroke();
-
-  ctx.drawImage(sun,0,0,300,300);
-
-  window.requestAnimationFrame(draw);
-}
-
-init();
-
- - - -

{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}

- -

Анимированные часы

- -

В этом примере создаются анимированные часы, показывающие правильное время.

- -
function clock(){
-  var now = new Date();
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.save();
-  ctx.clearRect(0,0,150,150);
-  ctx.translate(75,75);
-  ctx.scale(0.4,0.4);
-  ctx.rotate(-Math.PI/2);
-  ctx.strokeStyle = "black";
-  ctx.fillStyle = "white";
-  ctx.lineWidth = 8;
-  ctx.lineCap = "round";
-
-  // Hour marks
-  ctx.save();
-  for (var i=0;i<12;i++){
-    ctx.beginPath();
-    ctx.rotate(Math.PI/6);
-    ctx.moveTo(100,0);
-    ctx.lineTo(120,0);
-    ctx.stroke();
-  }
-  ctx.restore();
-
-  // Minute marks
-  ctx.save();
-  ctx.lineWidth = 5;
-  for (i=0;i<60;i++){
-    if (i%5!=0) {
-      ctx.beginPath();
-      ctx.moveTo(117,0);
-      ctx.lineTo(120,0);
-      ctx.stroke();
-    }
-    ctx.rotate(Math.PI/30);
-  }
-  ctx.restore();
-
-  var sec = now.getSeconds();
-  var min = now.getMinutes();
-  var hr  = now.getHours();
-  hr = hr>=12 ? hr-12 : hr;
-
-  ctx.fillStyle = "black";
-
-  // write Hours
-  ctx.save();
-  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
-  ctx.lineWidth = 14;
-  ctx.beginPath();
-  ctx.moveTo(-20,0);
-  ctx.lineTo(80,0);
-  ctx.stroke();
-  ctx.restore();
-
-  // write Minutes
-  ctx.save();
-  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
-  ctx.lineWidth = 10;
-  ctx.beginPath();
-  ctx.moveTo(-28,0);
-  ctx.lineTo(112,0);
-  ctx.stroke();
-  ctx.restore();
-
-  // Write seconds
-  ctx.save();
-  ctx.rotate(sec * Math.PI/30);
-  ctx.strokeStyle = "#D40000";
-  ctx.fillStyle = "#D40000";
-  ctx.lineWidth = 6;
-  ctx.beginPath();
-  ctx.moveTo(-30,0);
-  ctx.lineTo(83,0);
-  ctx.stroke();
-  ctx.beginPath();
-  ctx.arc(0,0,10,0,Math.PI*2,true);
-  ctx.fill();
-  ctx.beginPath();
-  ctx.arc(95,0,10,0,Math.PI*2,true);
-  ctx.stroke();
-  ctx.fillStyle = "rgba(0,0,0,0)";
-  ctx.arc(0,0,3,0,Math.PI*2,true);
-  ctx.fill();
-  ctx.restore();
-
-  ctx.beginPath();
-  ctx.lineWidth = 14;
-  ctx.strokeStyle = '#325FA2';
-  ctx.arc(0,0,142,0,Math.PI*2,true);
-  ctx.stroke();
-
-  ctx.restore();
-
-  window.requestAnimationFrame(clock);
-}
-
-window.requestAnimationFrame(clock);
- - - -

{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}

- -

Зацикленная панорама

- -

В этом примере панорама прокручивается слева направо. Мы используем фото национального парка Йосемити взятое из Википедии, но вы можете использовать любое изображение, большее элемента canvas.

- -
var img = new Image();
-
-// User Variables - customize these to change the image being scrolled, its
-// direction, and the speed.
-
-img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
-var CanvasXSize = 800;
-var CanvasYSize = 200;
-var speed = 30; //lower is faster
-var scale = 1.05;
-var y = -4.5; //vertical offset
-
-// Main program
-
-var dx = 0.75;
-var imgW;
-var imgH;
-var x = 0;
-var clearX;
-var clearY;
-var ctx;
-
-img.onload = function() {
-    imgW = img.width*scale;
-    imgH = img.height*scale;
-    if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
-    if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
-    else { clearX = CanvasXSize; }
-    if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
-    else { clearY = CanvasYSize; }
-    //Get Canvas Element
-    ctx = document.getElementById('canvas').getContext('2d');
-    //Set Refresh Rate
-    return setInterval(draw, speed);
-}
-
-function draw() {
-    //Clear Canvas
-    ctx.clearRect(0,0,clearX,clearY);
-    //If image is <= Canvas Size
-    if (imgW <= CanvasXSize) {
-        //reset, start from beginning
-        if (x > (CanvasXSize)) { x = 0; }
-        //draw aditional image
-        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
-    }
-    //If image is > Canvas Size
-    else {
-        //reset, start from beginning
-        if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
-        //draw aditional image
-        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
-    }
-    //draw image
-    ctx.drawImage(img,x,y,imgW,imgH);
-    //amount to move
-    x += dx;
-}
-
- -

Заметьте, что ширина и высота должны совпадать  со значениями CanvasXZSize и CanvasYSize.

- -
<canvas id="canvas" width="800" height="200"></canvas>
- -

{{EmbedLiveSample("A_looping_panorama", "830", "230")}}

- -

Другие примеры

- -
-
A basic ray-caster
-
Хороший пример того, как сделать управляемую анимацию с клавиатуры.
-
Advanced animations
-
Мы рассмотрим некоторые продвинутые методы анимации и физику в следующей главе.
-
- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\320\277\321\200\320\270\320\274\320\265\320\275\320\265\320\275\320\270\320\265_\321\201\321\202\320\270\320\273\320\265\320\271_\320\270_\321\206\320\262\320\265\321\202\320\276\320\262/index.html" "b/files/ru/web/api/canvas_api/tutorial/\320\277\321\200\320\270\320\274\320\265\320\275\320\265\320\275\320\270\320\265_\321\201\321\202\320\270\320\273\320\265\320\271_\320\270_\321\206\320\262\320\265\321\202\320\276\320\262/index.html" deleted file mode 100644 index 2c9eeaae78..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\320\277\321\200\320\270\320\274\320\265\320\275\320\265\320\275\320\270\320\265_\321\201\321\202\320\270\320\273\320\265\320\271_\320\270_\321\206\320\262\320\265\321\202\320\276\320\262/index.html" +++ /dev/null @@ -1,726 +0,0 @@ ---- -title: Применение стилей и цветов -slug: Web/API/Canvas_API/Tutorial/Применение_стилей_и_цветов -translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}
- -
-

В главе о рисовании фигур, мы использовали для линий и заполнения только стили по умолчанию. Здесь мы будем исследовать опции canvas, которые мы имеем в нашем распоряжении, чтобы сделать наши рисунки немного более привлекательными. Вы узнаете, как добавлять различные цвета, стили линий, градиенты, узоры и тени вашим рисункам.

-
- -

Цвета

- -

До сих пор мы видели только методы рисования контекста. Если мы хотим применить цвета к фигуре, то есть два важных свойства, которые мы можем использовать: fillStyle и strokeStyle.

- -
-
{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}
-
Устанавливает стиль для фона фигур.
-
{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}
-
Устанавливает стиль контура фигуры. 
-
- -

color может быть цветом, (строка, представленная в CSS {{cssxref("<color>")}}), градиентом или паттерном. Градиенты и паттерны мы рассмотрим позже. По умолчанию цвет фона и контура  — черный (значение CSS цвета  #000000).

- -
-

На заметку: Когда вы устанавливаете  значения strokeStyle и/или fillStyle, то новое значение становится стандартным для всех фигур, которые будут нарисованы с этого момента. Когда вам нужен другой цвет, вы должны перезаписать значение в fillStyle или в strokeStyle для каждой фигуры.

-
- -

Чтобы строка color считалась валидной, она должна соответствовать CSS {{cssxref("<color>")}}. Далее приведены примеры того, как можно по-разному задать один и тот же цвет. 

- -
// these all set the fillStyle to 'orange'
-
-ctx.fillStyle = "orange";
-ctx.fillStyle = "#FFA500";
-ctx.fillStyle = "rgb(255,165,0)";
-ctx.fillStyle = "rgba(255,165,0,1)";
-
- -

Пример fillStyle

- -

В этом примере мы опять воспользуемся двойным циклом, чтобы нарисовать сетку из прямоугольников, каждый из которых имеет свой цвет. Окончательное изображение должно иметь вид, как показано на скриншоте. Здесь не происходит ничего сверхъестественного. Мы используем две переменные i и j для генерации уникального RGB цвета для каждого квадрата и изменяем только красные и зеленые значения. Синий канал представляет собой фиксированное значение. Путем изменения каналов вы можете генерировать всю палитру. Увеличив количество шагов вы можете достигнуть такого вида палитры, какая используется в Photoshop.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i=0;i<6;i++){
-    for (var j=0;j<6;j++){
-      ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' +
-                       Math.floor(255-42.5*j) + ',0)';
-      ctx.fillRect(j*25,i*25,25,25);
-    }
-  }
-}
- - - -

Результат выглядит так:

- -

{{EmbedLiveSample("Пример_fillStyle", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}

- -

Пример strokeStyle

- -

Этот пример похож на предыдущий, но мы используем свойство strokeStyle чтобы изменить цвета очертаний фигур. Так же мы используем метод arc() для рисования окружностей вместо квадратов.

- -
  function draw() {
-    var ctx = document.getElementById('canvas').getContext('2d');
-    for (var i=0;i<6;i++){
-      for (var j=0;j<6;j++){
-        ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' +
-                         Math.floor(255-42.5*j) + ')';
-        ctx.beginPath();
-        ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
-        ctx.stroke();
-      }
-    }
-  }
-
- - - -

Результат выглядит так:

- -

{{EmbedLiveSample("Пример_strokeStyle", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}

- -

Прозрачность

- -

В дополнении к рисованию непрозрачных фигур, мы также можем рисовать прозрачные (полупрозрачные) фигуры.  Это делается через установку свойства globalAlpha или задачи полупрозрачного цвета фона или контура.

- -
-
{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}
-
Для применения, указывается значения прозрачности для всех будущих фигур, что будут нарисованы на canvas. Значение полупрозрачности могут быть между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность). Значение 1.0 (полная непрозрачность) установлено по умолчанию.
-
- -

Свойство globalAlpha может быть использовано, если вы хотите рисовать формы с одинаковой прозрачностью, но в иной ситуации, обычно устанавливают прозрачность индивидуально к каждой форме, когда указывают их цвет.

- -

Так как свойства strokeStyle и fillStyle принимают цветовые значения rgba через CSS, мы можем использовать следующее обозначение  для назначения прозрачных цветов.

- -
// Assigning transparent colors to stroke and fill style
-
-ctx.strokeStyle = "rgba(255,0,0,0.5)";
-ctx.fillStyle = "rgba(255,0,0,0.5)";
-
- -

Функция rgba() похожа на функцию rgb(), но имеет один дополнительный параметр. Последний параметр устанавливает значение прозрачности для конкретного цвета. Действующий диапозон значений находится между 0.0 (полная прозрачность) и 1.0 (полная непрозрачность).

- -

Пример globalAlpha

- -

В данном примере мы нарисуем фон и четыре квадрата с различными цветами.  Сверху изображения будет выведен набор полупрозрачных кругов. Установим свойство globalAlpha значением 0.2, которое будет использовано для всех последующих форм. Каждый шаг цикла рисует круг с большим радиусом. По окончанию получим радиальный градиент. Накладывая еще больше кругов друг на друга, мы фактически сможем уменьшить прозрачность ранее нарисованных кругов. Увеличив счетчик итераций, при этом рисуя еще круги, мы сможем добиться исчезновение центра изображения.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  // фон изображения
-  ctx.fillStyle = '#FD0';
-  ctx.fillRect(0,0,75,75);
-  ctx.fillStyle = '#6C0';
-  ctx.fillRect(75,0,75,75);
-  ctx.fillStyle = '#09F';
-  ctx.fillRect(0,75,75,75);
-  ctx.fillStyle = '#F30';
-  ctx.fillRect(75,75,75,75);
-  ctx.fillStyle = '#FFF';
-
-  // устанавливаем значение прозрачности
-  ctx.globalAlpha = 0.2;
-
-  // Рисуем полупрозрачные круги
-  for (i=0;i<7;i++){
-    ctx.beginPath();
-    ctx.arc(75,75,10+10*i,0,Math.PI*2,true);
-    ctx.fill();
-  }
-}
- - - -

{{EmbedLiveSample("Пример_globalAlpha", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}

- -

Пример использования rgba()

- -

В этом втором примере мы делаем что-то похожее на предыдущее, но вместо рисования кругов друг над другом, я рисовал маленькие прямоугольники с увеличением непрозрачности. Использование rgba() добавляет контроля и гибкости, поскольку мы можем индивидуально настраивать стиль заливки и штриха.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // Нарисовать фон
-  ctx.fillStyle = 'rgb(255,221,0)';
-  ctx.fillRect(0,0,150,37.5);
-  ctx.fillStyle = 'rgb(102,204,0)';
-  ctx.fillRect(0,37.5,150,37.5);
-  ctx.fillStyle = 'rgb(0,153,255)';
-  ctx.fillRect(0,75,150,37.5);
-  ctx.fillStyle = 'rgb(255,51,0)';
-  ctx.fillRect(0,112.5,150,37.5);
-
-  // Нарисовать полупрозрачные прямоугольники
-  for (var i=0;i<10;i++){
-    ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
-    for (var j=0;j<4;j++){
-      ctx.fillRect(5+i*14,5+j*37.5,14,27.5);
-    }
-  }
-}
- - - -

{{EmbedLiveSample("Пример_использования_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}

- -

Стили линий

- -

Есть несколько свойств, которые позволяют нам стилизовать линии.

- -
-
{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}
-
Устанавливает ширину линий, рисуемых в будущем.
-
{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}
-
Устанавливает внешний вид концов линий.
-
{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}
-
Устанавливает внешний вид «углов», где встречаются линии.
-
{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}
-
Устанавливает ограничение на митру, когда две линии соединяются под острым углом, чтобы вы могли контролировать её толщину.
-
{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}
-
Возвращает текущий массив тире штриховки, содержащий четное число неотрицательных чисел.
-
{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}
-
Устанавливает текущий пунктир линии.
-
{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}
-
Указывает, где следует начинать тире массива в строке.
-
- -

Вы лучше поймете, что они делают, глядя на приведенные ниже примеры.

- -

Пример lineWidth

- -

Это свойство задает толщину текущей строки. Значения должны быть положительными. По умолчанию для этого значения установлено 1.0 единицы.

- -

Ширина линии - это толщина хода, центрированного по данному пути. Другими словами, область, которая нарисована, простирается до половины ширины линии по обе стороны пути. Поскольку координаты холста не напрямую ссылаются на пиксели, особое внимание следует уделять получению четких горизонтальных и вертикальных линий.

- -

В приведенном ниже примере 10 прямых линий рисуются с увеличением ширины линий. Линия в крайнем левом углу - 1.0 единицы. Тем не менее, толщина левой и всех других линий нечетной ширины не выглядят четкими из-за позиционирования пути.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i = 0; i < 10; i++){
-    ctx.lineWidth = 1+i;
-    ctx.beginPath();
-    ctx.moveTo(5+i*14,5);
-    ctx.lineTo(5+i*14,140);
-    ctx.stroke();
-  }
-}
-
- - - -

{{EmbedLiveSample("Пример_lineWidth", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}

- -

Получение четких строк требует понимания путей сглаживания. На рисунках ниже представлена сетка координат холста. Квадраты между сетками являются фактическими экранными пикселями. В первом изображении сетки ниже прямоугольник от (2, 1) до (5, 5) заполняется. Вся область между ними (светло-красный) падает на границы пикселей, поэтому полученный заполненный прямоугольник будет иметь четкие края.

- -

- -

Если вы рассмотрите путь от (3, 1) до (3, 5) с толщиной строки 1.0, вы получите ситуацию во втором изображении. Фактическая заполняемая область, (синяя), распространяется только наполовину в пикселях по обе стороны пути. Приблизительно это означает, что частично затенённые пиксели приводят к заполнению всей области (светло-голубой и синей) цветом, только наполовину темным, чем фактический цвет штриха. Это то, что происходит с линией шириной 1.0 в предыдущем примере кода.

- -

Чтобы исправить это, вы должны быть более точными при создании пути. Зная, что линия шириной 1.0 занимает половину единицы по обе стороны пути, создание пути от (3.5, 1) до (3.5, 5) приведёт к ситуации в третьем изображении - ширина линии 1.0 закончится верно, точно заполняя вертикальную линию с одним пикселем.

- -
-

Примечание: Имейте в виду, что в нашем примере с вертикальной линией позиция Y по-прежнему ссылается на целочисленную позицию сетки - иначе мы увидели бы пиксели с половинным охватом в конечных точках (также обратите внимание, что это поведение зависит от текущего стиля lineCap,  значение по умолчанию - butt; вы можете вычислить согласованные штрихи с полупиксельными координатами для линий с нечетной шириной, установив стиль lineCap в square, чтобы внешняя граница вокруг конечной точки линии автоматически расширялась, охватывая весь пиксель в точку).

- -

Также обратите внимание, что затронуты только начальные и конечные  точки пути: если путь закрыт с помощью closePath(), - нет начальной и конечной точки; вместо этого все конечные точки в пути подключены к их прикрепленному предыдущему и следующему сегментам и при текущей настройке стиля lineJoin в значении по умолчанию - miter, с эффектом автоматического расширения внешних границ подключенных сегментов до их точки пересечения - обработанный ход будет точно покрывать полные пиксели с центром в каждой конечной точке, если эти связанные сегменты горизонтальны и/или вертикальны). См. следующие два раздела, демонстрирующие эти дополнительные стили.

-
- -

Для линий с четной шириной каждая половина заканчивается как целое количество пикселей, поэтому вам нужен путь, который находится между пикселями (то есть (3,1) - (3,5)), вместо середины пикселей.

- -

Хотя это и необычно, когда изначально работаешь с масштабируемой 2D-графикой, обращая внимание на сетку пикселей и положение путей, но вы убедитесь, что ваши рисунки будут выглядеть правильно, независимо от масштабирования или любых других преобразований. Вертикальная линия ширины 1,0, построенная таким образом, станет четкой 2-пиксельной линией при увеличении на 2 и появится в правильном положении.

- -

Пример lineCap

- -

Свойство lineCap определяет, как выводятся конечные точки каждой строки. Для этого свойства есть три возможных значения: butt, round и square. По умолчанию для этого свойства установлено значение butt.

- -

- -
-
butt
-
Концы линий соответствуют крайним точкам.
-
round
-
Концы линий округлены.
-
square
-
Концы линий описаны квадратом с равной шириной и половиной высоты толщины линии.
-
- -

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

- -

Строка слева использует butt опцию по умолчанию. Вы заметите, что она полностью очищена от направляющих. Второй вариант -  round опция. Это добавляет полукруг к концу, который имеет радиус, равный половине ширины линии. Строка справа использует square опцию. Это добавляет поле с равной шириной и половиной высоты толщины линии.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var lineCap = ['butt','round','square'];
-
-  // Draw guides
-  ctx.strokeStyle = '#09f';
-  ctx.beginPath();
-  ctx.moveTo(10,10);
-  ctx.lineTo(140,10);
-  ctx.moveTo(10,140);
-  ctx.lineTo(140,140);
-  ctx.stroke();
-
-  // Draw lines
-  ctx.strokeStyle = 'black';
-  for (var i=0;i<lineCap.length;i++){
-    ctx.lineWidth = 15;
-    ctx.lineCap = lineCap[i];
-    ctx.beginPath();
-    ctx.moveTo(25+i*50,10);
-    ctx.lineTo(25+i*50,140);
-    ctx.stroke();
-  }
-}
-
- - - -

{{EmbedLiveSample("Пример_lineCap", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}

- -

Пример lineJoin

- -

Свойство lineJoin определяет, как соединяются два сегмента (линий, дуг или кривых) с ненулевой длиной в форме (вырожденные сегменты с нулевой длиной, заданные конечные точки и контрольные точки находятся точно в том же положении - пропущены).

- -

Для этого свойства есть три возможных значения: round, bevel и miter. По умолчанию для этого свойства установлено значение miter. Обратите внимание, что настройка lineJoin не действует, если два связанных сегмента имеют одно и то же направление, потому что в этом случае не будет добавлена ​​область соединения.

- -

- -
-
round
-
Радиус заполняемой части для скругленных углов равен половине ширины линии. центр этого радиуса совпадает с концами подключенных сегментов.
-
bevel
-
Заполняет дополнительную треугольную область между общей конечной точкой подключенных сегментов и отдельными внешними прямоугольными углами каждого сегмента. 
-
miter
-
Подключенные сегменты соединяются путем расширения их внешних краев для соединения в одной точке с эффектом заполнения дополнительной области в форме пастилки. Эта настройка выполняется с помощью свойства miterLimit, которое объясняется ниже.
-
- -

В приведенном ниже примере показаны три разных пути, демонстрирующие каждый из этих трех свойств lineJoin; результат - выше. 

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var lineJoin = ['round','bevel','miter'];
-  ctx.lineWidth = 10;
-  for (var i=0;i<lineJoin.length;i++){
-    ctx.lineJoin = lineJoin[i];
-    ctx.beginPath();
-    ctx.moveTo(-5,5+i*40);
-    ctx.lineTo(35,45+i*40);
-    ctx.lineTo(75,5+i*40);
-    ctx.lineTo(115,45+i*40);
-    ctx.lineTo(155,5+i*40);
-    ctx.stroke();
-  }
-}
-
- - - -

{{EmbedLiveSample("Пример_lineJoin", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}

- -

Демонстрация свойства miterLimit

- -

Как вы видели в предыдущем примере, при объединении двух строк с опцией miter внешние края двух соединительных линий расширены до точки, где они встречаются. Для линий, которые находятся под большими углами друг с другом, эта точка находится недалеко от внутренней точки соединения. Однако, поскольку углы между каждой линией уменьшаются, расстояние (длина меча) между этими точками увеличивается экспоненциально.

- -

Свойство miterLimit определяет, как далеко можно установить внешнюю точку соединения из внутренней точки подключения. Если две линии превышают это значение, вместо этого получается привязка конуса. Обратите внимание, что максимальная длина митра является произведением ширины линии, измеренной в текущей системе координат, значением этого свойства miterLimit (значение по умолчанию 10,0 в HTML {{HTMLElement("canvas")}}), поэтому miterLimit может устанавливаться независимо от текущей шкалы дисплея или любых аффинных преобразований путей: она влияет только на эффективно визуализированную форму ребер линии.

- -

Точнее, предел митры является максимально допустимым отношением длины расширения (в холсте HTML он измеряется между внешним углом соединенных краев линии и общей конечной точкой соединительных сегментов, указанными на пути), до половины ширины линии. Его можно равнозначно определить как максимально допустимое отношение расстояния между внутренней и внешней точками перехода краев к общей ширине линии. Затем он равен косекансу с половиной минимального внутреннего угла соединительных сегментов, ниже которого не будет создано ни одного соединения митра, а только скос соединяется:

- - - -

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

- -

Если вы укажете в этой демонстрации значение miterLimit ниже 4.2, ни один из видимых углов не присоединится к расширению митры, но только с небольшим скосом рядом с синими линиями; с отметкой miterLimit выше 10, большинство углов в этой демонстрации должны соединяться с митрой, удаленной от синих линий, высота которой уменьшается между углами слева направо, потому что они соединяются с растущими углами; с промежуточными значениями углы с левой стороны будут соединяться только с скосом рядом с синими линиями, а углы с правой стороны с удлинителем митры (также с уменьшающейся высотой).

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // Clear canvas
-  ctx.clearRect(0,0,150,150);
-
-  // Draw guides
-  ctx.strokeStyle = '#09f';
-  ctx.lineWidth   = 2;
-  ctx.strokeRect(-5,50,160,50);
-
-  // Set line styles
-  ctx.strokeStyle = '#000';
-  ctx.lineWidth = 10;
-
-  // check input
-  if (document.getElementById('miterLimit').value.match(/\d+(\.\d+)?/)) {
-    ctx.miterLimit = parseFloat(document.getElementById('miterLimit').value);
-  } else {
-    alert('Value must be a positive number');
-  }
-
-  // Draw lines
-  ctx.beginPath();
-  ctx.moveTo(0,100);
-  for (i=0;i<24;i++){
-    var dy = i%2==0 ? 25 : -25 ;
-    ctx.lineTo(Math.pow(i,1.5)*2,75+dy);
-  }
-  ctx.stroke();
-  return false;
-}
-
- - - -

{{EmbedLiveSample("Демонстрация_свойства_miterLimit", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}

- -

Использование штрихов

- -

Метод setLineDash и свойство lineDashOffset задают шаблон штрихов для линий. Метод setLineDash принимает список чисел, который определяет расстояния для попеременного рисования линии и разрыва, а свойство lineDashOffset устанавливает смещение, с которого начинается шаблон.

- -

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

- - - -
var ctx = document.getElementById('canvas').getContext('2d');
-var offset = 0;
-
-function draw() {
-  ctx.clearRect(0,0, canvas.width, canvas.height);
-  ctx.setLineDash([4, 2]);
-  ctx.lineDashOffset = -offset;
-  ctx.strokeRect(10,10, 100, 100);
-}
-
-function march() {
-  offset++;
-  if (offset > 16) {
-    offset = 0;
-  }
-  draw();
-  setTimeout(march, 20);
-}
-
-march();
- -

{{EmbedLiveSample("Используемый штрих", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}

- -

Градиенты

- -

Just like any normal drawing program, we can fill and stroke shapes using linear and radial gradients. We create a {{domxref("CanvasGradient")}} object by using one of the following methods. We can then assign this object to the fillStyle or strokeStyle properties.

- -
-
{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}
-
Creates a linear gradient object with a starting point of (x1, y1) and an end point of (x2, y2).
-
{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}
-
Creates a radial gradient. The parameters represent two circles, one with its center at (x1, y1) and a radius of r1, and the other with its center at (x2, y2) with a radius of r2.
-
- -

For example:

- -
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
-var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
-
- -

Once we've created a CanvasGradient object we can assign colors to it by using the addColorStop() method.

- -
-
{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}
-
Creates a new color stop on the gradient object. The position is a number between 0.0 and 1.0 and defines the relative position of the color in the gradient, and the color argument must be a string representing a CSS {{cssxref("<color>")}}, indicating the color the gradient should reach at that offset into the transition.
-
- -

You can add as many color stops to a gradient as you need. Below is a very simple linear gradient from white to black.

- -
var lineargradient = ctx.createLinearGradient(0,0,150,150);
-lineargradient.addColorStop(0, 'white');
-lineargradient.addColorStop(1, 'black');
-
- -

Пример createLinearGradient

- -

In this example, we'll create two different gradients. As you can see here, both the strokeStyle and fillStyle properties can accept a canvasGradient object as valid input.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // Create gradients
-  var lingrad = ctx.createLinearGradient(0,0,0,150);
-  lingrad.addColorStop(0, '#00ABEB');
-  lingrad.addColorStop(0.5, '#fff');
-  lingrad.addColorStop(0.5, '#26C000');
-  lingrad.addColorStop(1, '#fff');
-
-  var lingrad2 = ctx.createLinearGradient(0,50,0,95);
-  lingrad2.addColorStop(0.5, '#000');
-  lingrad2.addColorStop(1, 'rgba(0,0,0,0)');
-
-  // assign gradients to fill and stroke styles
-  ctx.fillStyle = lingrad;
-  ctx.strokeStyle = lingrad2;
-
-  // draw shapes
-  ctx.fillRect(10,10,130,130);
-  ctx.strokeRect(50,50,50,50);
-
-}
-
- - - -

The first is a background gradient. As you can see, we assigned two colors at the same position. You do this to make very sharp color transitions—in this case from white to green. Normally, it doesn't matter in what order you define the color stops, but in this special case, it does significantly. If you keep the assignments in the order you want them to appear, this won't be a problem.

- -

In the second gradient, we didn't assign the starting color (at position 0.0) since it wasn't strictly necessary, because it will automatically assume the color of the next color stop. Therefore, assigning the black color at position 0.5 automatically makes the gradient, from the start to this stop, black.

- -

{{EmbedLiveSample("Пример_createLinearGradient", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}

- -

Пример createRadialGradient

- -

In this example, we'll define four different radial gradients. Because we have control over the start and closing points of the gradient, we can achieve more complex effects than we would normally have in the "classic" radial gradients we see in, for instance, Photoshop (that is, a gradient with a single center point where the gradient expands outward in a circular shape).

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // Create gradients
-  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
-  radgrad.addColorStop(0, '#A7D30C');
-  radgrad.addColorStop(0.9, '#019F62');
-  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
-
-  var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
-  radgrad2.addColorStop(0, '#FF5F98');
-  radgrad2.addColorStop(0.75, '#FF0188');
-  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
-
-  var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
-  radgrad3.addColorStop(0, '#00C9FF');
-  radgrad3.addColorStop(0.8, '#00B5E2');
-  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');
-
-  var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
-  radgrad4.addColorStop(0, '#F4F201');
-  radgrad4.addColorStop(0.8, '#E4C700');
-  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
-
-  // draw shapes
-  ctx.fillStyle = radgrad4;
-  ctx.fillRect(0,0,150,150);
-  ctx.fillStyle = radgrad3;
-  ctx.fillRect(0,0,150,150);
-  ctx.fillStyle = radgrad2;
-  ctx.fillRect(0,0,150,150);
-  ctx.fillStyle = radgrad;
-  ctx.fillRect(0,0,150,150);
-}
-
- - - -

In this case, we've offset the starting point slightly from the end point to achieve a spherical 3D effect. It's best to try to avoid letting the inside and outside circles overlap because this results in strange effects which are hard to predict.

- -

The last color stop in each of the four gradients uses a fully transparent color. If you want to have a nice transition from this to the previous color stop, both colors should be equal. This isn't very obvious from the code because it uses two different CSS color methods as a demonstration, but in the first gradient #019F62 = rgba(1,159,98,1).

- -

{{EmbedLiveSample("Пример_createRadialGradient", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}

- -

Шаблоны

- -

В одном из предыдущих примеров мы использовали несколько циклов, чтобы создать шаблон из повторяющихся изображений. Однако, есть более простой способ сделать подобное - метод createPattern().

- -
-
{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}
-
Создает и возвращает новый canvas объект - шаблон (pattern). image - {{domxref("CanvasImageSource")}} (то есть {{domxref ("HTMLImageElement")}}, другой холст, элемент {{HTMLElement ("video")}} или подобный  объект. type - строка, указывающая, как использовать image.
-
- -

Тип указывает, как использовать image для создания шаблона и должен быть одним из следующих значений:

- -
-
repeat
-
Повторяет изображение в вертикальном и горизонтальном направлениях.
-
repeat-x
-
Повторяет изображение по горизонтали, но не по вертикали.
-
repeat-y
-
Повторяет изображение по вертикали, но не по горизонтали.
-
no-repeat
-
Не повторяет изображение. Используется только один раз.
-
- -

Мы используем этот метод, чтобы создать {{domxref("CanvasPattern")}} объект, который очень похож на методы градиента, рассмотренные ранее. Как только мы создали шаблон, мы можем назначить ему свойства fillStyle или strokeStyle. Например:

- -
var img = new Image();
-img.src = 'someimage.png';
-var ptrn = ctx.createPattern(img,'repeat');
-
- -
-

Примечание: По аналогии с методом drawImage(), вы должны убедиться, что изображение, которое вы используете, загружено до вызова этого метода. Иначе шаблон может быть отрисован некорректно.

-
- -

Пример createPattern

- -

In this last example, we'll create a pattern to assign to the fillStyle property. The only thing worth noting is the use of the image's onload handler. This is to make sure the image is loaded before it is assigned to the pattern.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // create new image object to use as pattern
-  var img = new Image();
-  img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
-  img.onload = function(){
-
-    // create pattern
-    var ptrn = ctx.createPattern(img,'repeat');
-    ctx.fillStyle = ptrn;
-    ctx.fillRect(0,0,150,150);
-
-  }
-}
-
- - - -

{{EmbedLiveSample("Пример_createPattern", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}

- -

Тени

- -

Using shadows involves just four properties:

- -
-
{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}
-
Indicates the horizontal distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
-
{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}
-
Indicates the vertical distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.
-
{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}
-
Indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.
-
{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}
-
A standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.
-
- -

The properties shadowOffsetX and shadowOffsetY indicate how far the shadow should extend from the object in the X and Y directions; these values aren't affected by the current transformation matrix. Use negative values to cause the shadow to extend up or to the left, and positive values to cause the shadow to extend down or to the right. These are both 0 by default.

- -

The shadowBlur property indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.

- -

The shadowColor property is a standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.

- -
-

Note: Shadows are only drawn for source-over compositing operations.

-
- -

Пример текста с тенью

- -

This example draws a text string with a shadowing effect.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  ctx.shadowOffsetX = 2;
-  ctx.shadowOffsetY = 2;
-  ctx.shadowBlur = 2;
-  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
-
-  ctx.font = "20px Times New Roman";
-  ctx.fillStyle = "Black";
-  ctx.fillText("Sample String", 5, 30);
-}
-
- - - -

{{EmbedLiveSample("Пример_текста_с_тенью", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}

- -

We will look at the font property and fillText method in the next chapter about drawing text.

- -

Canvas fill rules

- -

When using fill (or {{domxref("CanvasRenderingContext2D.clip", "clip")}} and {{domxref("CanvasRenderingContext2D.isPointInPath", "isPointinPath")}}) you can optionally provide a fill rule algorithm by which to determine if a point is inside or outside a path and thus if it gets filled or not. This is useful when a path intersetcs itself or is nested.
-
- Two values are possible:

- - - -

In this example we are using the evenodd rule.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.beginPath();
-  ctx.arc(50, 50, 30, 0, Math.PI*2, true);
-  ctx.arc(50, 50, 15, 0, Math.PI*2, true);
-  ctx.fill("evenodd");
-}
- - - -

{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}

- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\202\320\265\320\272\321\201\321\202\320\260/index.html" "b/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\202\320\265\320\272\321\201\321\202\320\260/index.html" deleted file mode 100644 index 90915c5e09..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\202\320\265\320\272\321\201\321\202\320\260/index.html" +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: Рисование текста -slug: Web/API/Canvas_API/Tutorial/Рисование_текста -tags: - - Canvas - - Графика - - Примеры - - Рукводовство - - мануал -translation_of: Web/API/Canvas_API/Tutorial/Drawing_text ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}
- -
-

После того, как мы увидели в предыдущей главе, как применять стили и цвета, взглянем на написание текста в canvas.

-
- -

Рисование текста

- -

Контекст рендеринга canvas предоставляет два метода для рисования текста:

- -
-
{{domxref("CanvasRenderingContext2D.fillText", "fillText(text, x, y [, maxWidth])")}}
-
Вставляет заданный текст в положении (x,y). Опционально может быть указана максимальная ширина.
-
{{domxref("CanvasRenderingContext2D.strokeText", "strokeText(text, x, y [, maxWidth])")}}
-
Вставляет контур заданного текста в положении (x,y). Опционально может быть указана максимальная ширина.
-
- -

Пример fillText

- -

Текст вставлен с использованием текущего fillStyle.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.font = "48px serif";
-  ctx.fillText("Hello world", 10, 50);
-}
- - - -

{{EmbedLiveSample("A_fillText_example", 310, 110)}}

- -

Пример strokeText

- -

Текст вставлен с использованием текущего strokeStyle.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.font = "48px serif";
-  ctx.strokeText("Hello world", 10, 50);
-}
- - - -

{{EmbedLiveSample("A_strokeText_example", 310, 110)}}

- -

Стилизация текста

- -

В примерах выше мы уже использовали свойство font для изменения размера текста. Кроме него существуют еще несколько свойств, позволяющие настроить вывод текста на canvas:

- -
-
{{domxref("CanvasRenderingContext2D.font", "font = value")}}
-
Это основной стиль, который будет использоваться для вывода текста. Строка имеет такой же синтаксис, как CSS-свойство {{cssxref("font")}}. По умолчанию - sans-serif высотой 10px.
-
{{domxref("CanvasRenderingContext2D.textAlign", "textAlign = value")}}
-
Настройка выравнивания текста. Возможные значения: start, end, left, right или center. По умолчанию - start.
-
{{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline = value")}}
-
Настройка выравнивания текста по вертикали. Возможные значения: top, hanging, middle, alphabetic, ideographic, bottom. По умолчанию - alphabetic.
-
{{domxref("CanvasRenderingContext2D.direction", "direction = value")}}
-
Направление текста. Возможные значения: ltr, rtl, inherit. По умолчанию - inherit.
-
- -

Эти свойства могут быть вам знакомы если вы работали с CSS.

- -

Изображение от WHATWG ниже показывает различные варианты свойства textBaseline.The top of the em square is
-roughly at the top of the glyphs in a font, the hanging baseline is
-where some glyphs like आ are anchored, the middle is half-way
-between the top of the em square and the bottom of the em square,
-the alphabetic baseline is where characters like Á, ÿ,
-f, and Ω are anchored, the ideographic baseline is
-where glyphs like 私 and 達 are anchored, and the bottom
-of the em square is roughly at the bottom of the glyphs in a
-font. The top and bottom of the bounding box can be far from these
-baselines, due to glyphs extending far outside the em square.

- -

Пример textBaseline

- -

Редактируя код ниже, вы можете видеть, как меняется отображение текста на canvas в реальном времени:

- -
ctx.font = "48px serif";
-ctx.textBaseline = "hanging";
-ctx.strokeText("Hello world!", 0, 100);
-
- - - -

{{ EmbedLiveSample('Playable_code', 700, 360) }}

- -

Измерение ширины текста

- -

Для измерения ширины текста (без рисования его на canvas) можно воспользоваться следующим методом:

- -
-
{{domxref("CanvasRenderingContext2D.measureText", "measureText()")}}
-
Возвращает объект {{domxref("TextMetrics")}}, содержащий ширину текста в пикселах, до отрисовки на canvas.
-
- -

Пример ниже показывает, как можно измерить ширину текста.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var text = ctx.measureText("foo"); // TextMetrics object
-  text.width; // 16;
-}
-
- -

Примечания

- -

В ранних версиях Gecko (движок рендеринга в Firefox, Firefox OS и других приложениях Mozilla) были реализованы методы API с префиксами для рисования текста на canvas. На данный момент они устарели и уже, возможно, удалены, поэтому их правильная работа не гарантируется.

- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}

diff --git "a/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\204\320\270\320\263\321\203\321\200/index.html" "b/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\204\320\270\320\263\321\203\321\200/index.html" deleted file mode 100644 index f6ca6c23ef..0000000000 --- "a/files/ru/web/api/canvas_api/tutorial/\321\200\320\270\321\201\320\276\320\262\320\260\320\275\320\270\320\265_\321\204\320\270\320\263\321\203\321\200/index.html" +++ /dev/null @@ -1,582 +0,0 @@ ---- -title: Рисование фигур с помощью canvas -slug: Web/API/Canvas_API/Tutorial/Рисование_фигур -translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
- -
-

Теперь, установив наше окружение canvas, мы можем погрузиться в детали того, как рисовать в canvas. К концу этой статьи, Вы научитесь рисовать прямоугольники, треугольники, линии, дуги и кривые, при условии что Вы хорошо знакомы с основными геометрическими фигурами. Работа с путями весьма важна, когда рисуете объекты на canvas и мы увидим как это может быть сделано.

-
- -

Сетка

- -

Перед тем, как мы начнем рисовать, нам нужно поговорить о сетке canvas или координатной плоскости. Наш HTML каркас из предыдущей страницы включал в себя элемент canvas 150 пикселей в ширину и 150 пикселей в высоту. Справа можно увидеть этот canvas с сеткой, накладываемой по умолчанию. Обычно 1 единица на сетке соответствует 1 пикселю на canvas. Начало координат этой сетки расположено в верхнем левом углу в координате (0,0 ). Все элементы размещены относительно этого начала. Таким образом, положение верхнего левого угла синего квадрата составляет х пикселей слева и у пикселей сверху, на координате , у). Позже в этом уроке мы увидим, как можно перевести начало координат в другое место, вращать сетку и даже масштабировать ее, но сейчас мы будем придерживаться настроек сетки по умолчанию.

- -

Рисование прямоугольников

- -

В отличие от {{Glossary("SVG")}}, {{HTMLElement("canvas")}} поддерживает только одну примитивную фигуру: прямоугольник. Все другие фигуры должны быть созданы комбинацией одного или большего количества контуров (paths), набором точек, соединенных в линии. К счастью в ассортименте рисования контуров у нас есть  функции, которые делают возможным составление очень сложных фигур.

- -

Сначала рассмотрим прямоугольник. Ниже представлены три функции рисования прямоугольников в canvas:

- -
-
{{domxref("CanvasRenderingContext2D.fillRect", "fillRect(x, y, width, height)")}}
-
Рисование заполненного прямоугольника.
-
{{domxref("CanvasRenderingContext2D.strokeRect", "strokeRect(x, y, width, height)")}}
-
Рисование прямоугольного контура.
-
{{domxref("CanvasRenderingContext2D.clearRect", "clearRect(x, y, width, height)")}}
-
Очистка  прямоугольной области, делая содержимое совершенно прозрачным.
-
- -

Каждая из приведенных функций принимает несколько параметров: 

- - - -

Ниже приведена функция draw(), использующая эти три функции.

- -

Пример создания прямоугольных фигур

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    ctx.fillRect(25,25,100,100);
-    ctx.clearRect(45,45,60,60);
-    ctx.strokeRect(50,50,50,50);
-  }
-}
- -

Этот пример изображен ниже.

- -

{{EmbedLiveSample("Пример_создания_прямоугольных_фигур", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}

- -

Функция fillRect() рисует большой чёрный квадрат со стороной 100 px. Функция clearRect() вырезает квадрат 60х60 из центра, а функция strokeRect() создает прямоугольный контур 50х50 пикселей внутри очищенного квадрата.

- -

На следующей странице мы рассмотрим две альтернативы методу clearRect(), и также увидим, как можно изменять цвет и стиль контура отображаемых фигур.

- -

В отличие от функций создания контуров, которые будут рассмотрены в следующем разделе, все три функции создания прямоугольника сразу же отображаются на canvas.

- -

Рисование контуров (path)

- -

Остальные примитивные фигуры создаются контурами. Контур - это набор точек, которые, соединяясь в отрезки линий, могут образовывать различные фигуры, изогнутые или нет, разной ширины и разного цвета. Контур (или субконтур) может быть закрытым.

- -

Создание фигур используя контуры происходит в несколько важных шагов:

- -
    -
  1. Сначала вы создаете контур.
  2. -
  3. Затем, используя команды рисования, рисуете контур.
  4. -
  5. Потом закрываете контур.
  6. -
  7. Созданный контур вы можете обвести или залить для его отображения.
  8. -
- -

Здесь приведены функции, которые можно использовать в описанных шагах:

- -
-
{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}
-
Создает новый контур. После создания используется в дальнейшем командами рисования при построении контуров.
-
Path методы
-
Методы для установки различных контуров объекта.
-
{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}
-
Закрывает контур, так что будущие команды рисования вновь направлены контекст.
-
{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}
-
Рисует фигуру с внешней обводкой.
-
{{domxref("CanvasRenderingContext2D.fill", "fill()")}}
-
Рисует фигуру с заливкой внутренней области.
-
- -

Первый шаг создания контура заключается в вызове функции beginPath(). Внутри содержатся контуры в виде набора суб-контуров (линии, дуги и др.), которые вместе образуют форму фигуры. Каждый вызов этого метода очищает набор, и мы можем начинать рисовать новые фигуры.

- -
Note:  если текущий контур пуст (например, как после вызова beginPath() или на вновь созданном canvas), первой командой построения контура всегда является функция  moveTo(). Поэтому мы всегда можем установить начальную позицию рисования контура после перезагрузки.
- -

Вторым шагом является вызов методов, определяемых видом контура, который нужно нарисовать. Их мы рассмотрим позднее.

- -

Третий и необязательный шаг - это вызов closePath(). Этот метод пытается закрыть фигуру, рисуя прямую линию из текущей точки в начальную. Если фигура была уже закрыта или является просто точкой, то функция ничего не делает.

- -
Note: Когда вы вызываете fill(), то каждая открытая фигура закрывается автоматически, так что вы можете не использовать closePath(). Это обстоятельство не имеет место в случае вызова stroke().
- -

Рисование треугольника

- -

Например, код для рисования треугольника будет выглядеть как-то так:

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    ctx.beginPath();
-    ctx.moveTo(75,50);
-    ctx.lineTo(100,75);
-    ctx.lineTo(100,25);
-    ctx.fill();
-  }
-}
-
- -

Результат выглядит так:

- -

{{EmbedLiveSample("Рисование_треугольника", 110, 110, "https://mdn.mozillademos.org/files/9847/triangle.png")}}

- -

Передвижение пера

- -

Одна очень полезная функция, которая ничего не рисует, но связана по смыслу с вышеописанными функциями  - это moveTo(). Вы можете представить это как отрыв (подъем) пера от бумаги и его перемещение в другое место.

- -
-
{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}
-
Перемещает перо в точку с координатами x и y.
-
- -

При инициализации canvas или при вызове beginPath(), вы захотите использовать функцию moveTo() для перемещения в точку начала рисования. Можно использовать moveTo() и для рисования несвязанного(незакрытого) контура. Посмотрите на смайлик ниже.

- -

Вы можете проверить это сами, используя участок кода ниже. Просто вставьте в функцию draw(), рассмотренную ранее.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-     var ctx = canvas.getContext('2d');
-
-    ctx.beginPath();
-    ctx.arc(75,75,50,0,Math.PI*2,true); // Внешняя окружность
-    ctx.moveTo(110,75);
-    ctx.arc(75,75,35,0,Math.PI,false);  // рот (по часовой стрелке)
-    ctx.moveTo(65,65);
-    ctx.arc(60,65,5,0,Math.PI*2,true);  // Левый глаз
-    ctx.moveTo(95,65);
-    ctx.arc(90,65,5,0,Math.PI*2,true);  // Правый глаз
-    ctx.stroke();
-  }
-}
-
- -

Результат этого ниже:

- -

{{EmbedLiveSample("Передвижение_пера", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}

- -

Если вы захотите увидеть соединные линии, то можете удалить вызов moveTo().

- -
-

Note: Подробнее о функции arc(),посмотрите {{anch("Дуги")}} .

-
- -

Линии

- -

Для рисования прямых линий используйте метод lineTo().

- -
-
{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}
-
Рисует линию с текущей позиции до позиции, определенной x и y.
-
- -

Этот метод принимает два аргумента x и y, которые являются координатами конечной точки линии. Начальная точка зависит от ранее нарисованных путей, причём конечная точка предыдущего пути является начальной точкой следующего и т. д. Начальная точка также может быть изменена с помощью метода moveTo().

- -

Пример ниже рисует два треугольника, один закрашенный и другой обведен контуром.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    // Filled triangle
-    ctx.beginPath();
-    ctx.moveTo(25,25);
-    ctx.lineTo(105,25);
-    ctx.lineTo(25,105);
-    ctx.fill();
-
-    // Stroked triangle
-    ctx.beginPath();
-    ctx.moveTo(125,125);
-    ctx.lineTo(125,45);
-    ctx.lineTo(45,125);
-    ctx.closePath();
-    ctx.stroke();
-  }
-}
-
- -

Отрисовка начинается с вызова beginPath(), чтобы начать рисовать путь новой фигуры. Затем мы используем метод moveTo(), чтобы переместить начальную точку в нужное положение. Ниже рисуются две линии, которые образуют две стороны треугольника.

- -

{{EmbedLiveSample("Линии", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}

- -

Вы заметите разницу между закрашенным и обведенным контуром треугольниками. Это, как упоминалось выше, из-за того, что фигуры автоматически закрываются, когда путь заполнен (т. е. закрашен), но не тогда, когда он очерчен (т. е. обведен контуром). Если бы мы не учли closePath() для очерченного треугольника, тогда только две линии были бы нарисованы, а не весь треугольник.

- -

Дуги

- -

Для рисования дуг и окружностей, используем методы arc() и arcTo().

- -
-
{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}}
-
Рисуем дугу с центром в точке (x,y) радиусом radius, начиная с угла startAngle и заканчивая в endAngle в направлении против часовой стрелки anticlockwise (по умолчанию по ходу движения часовой стрелки).
-
{{domxref("CanvasRenderingContext2D.arcTo", "arcTo(x1, y1, x2, y2, radius)")}}
-
Рисуем дугу с заданными контрольными точками и радиусом, соединяя эти точки прямой линией.
-
- -

Рассмотрим детальнее метод arc(), который имеет пять параметров: x и y — это координаты центра окружности, в которой должна быть нарисована дуга. radius — не требует пояснений. Углы startAngle и endAngle определяют начальную и конечную точки дуги в радианах вдоль кривой окружности. Отсчет происходит от оси x. Параметр anticlockwise — логическое значение, которое, если true, то рисование дуги совершается против хода часовой стрелки; иначе рисование происходит по ходу часовой стрелки.

- -
-

Note: Углы в функции arc() измеряют в радианах, не в градусах. Для перевода градусов в радианы вы можете использовать JavaScript-выражение: radians = (Math.PI/180)*degrees.

-
- -

Следующий пример немного сложнее, чем мы рассматривали ранее. Здесь нарисованы 12 различных дуг с разными углами и заливками.

- -

Два for цикла размещают дуги по столбцам и строкам. Для каждой дуги, мы начинаем новый контур, вызывая beginPath(). В этом коде каждый параметр дуги для большей ясности задан в виде переменной, но вам не обязательно делать так в реальных проектах.

- -

Координаты x и y  должны быть достаточно ясны. radius and startAngle — фиксированы. endAngle начинается со 180 градусов (полуокружность) в первой колонке и, увеличиваясь с шагом 90 градусов, достигает кульминации полноценной окружностью в последнем столбце.

- -

Установка параметра clockwise определяет результат; в первой и третьей строках рисование дуг происходит по часовой стрелке, а во второй и четвертой - против часовой стрелки. Благодаря if-условию верхняя половина дуг образуется с контуром, (обводкой), а нижняя половина дуг - с заливкой.

- -
-

Note: Этот пример требует немного большего холста (canvas), чем другие на этой странице: 150 x 200 pixels.

-
- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    for(var i=0;i<4;i++){
-      for(var j=0;j<3;j++){
-        ctx.beginPath();
-        var x = 25+j*50; // x coordinate
-        var y = 25+i*50; // y coordinate
-        var radius = 20; // Arc radius
-        var startAngle = 0; // Starting point on circle
-        var endAngle = Math.PI+(Math.PI*j)/2; // End point on circle
-        var anticlockwise = i%2==0 ? false : true; // clockwise or anticlockwise
-
-        ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
-
-        if (i>1){
-          ctx.fill();
-        } else {
-          ctx.stroke();
-        }
-      }
-    }
-  }
-}
-
- -

{{EmbedLiveSample("Дуги", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}}

- -

Безье и квадратичные кривые

- -

Следующим типом доступных контуров являются  кривые Безье, и к тому же доступны в кубическом и квадратичном вариантах. Обычно они используются при рисовании сложных составных фигур.

- -
-
{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}
-
Рисуется квадратичная кривая Безье с текущей позиции пера в конечную точку с координатами x и y, используя контрольную точку с координатами cp1x и cp1y.
-
{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}
-
Рисуется кубическая кривая Безье с текущей позиции пера в конечную точку с координатами x и y, используя две контрольные точки с координатами (cp1x, cp1y) и (cp2x, cp2y).
-
- -

Различие между ними можно увидеть на рисунке, изображенном справа. Квадратичная кривая Безье имеет стартовую и конечную точки (синие точки) и всего одну контрольную точку (красная точка), в то время как кубическая кривая Безье использует две контрольные точки.

- -

Параметры x и y в этих двух методах являются координатами конечной точки. cp1x и cp1y — координаты первой контрольной точки, а cp2x и cp2y — координаты второй контрольной точки.

- -

Использование квадратичных или кубических кривых Безье может быть  спорным выходом, так как в отличие от приложений векторной графики типа Adobe Illustrator, мы не имеем полной видимой обратной связи с тем, что мы делаем. Этот факт делает довольно сложным процесс рисования сложных фигур. В следующем примере мы нарисуем совсем простую составную фигуру, но, если у вас есть время и ещё больше терпения, можно создать более сложные составные фигуры.

- -

В этом примере нет ничего слишком тяжелого. В обоих случаях мы видим последовательность кривых, рисуя которые, в результате получим составную фигуру.

- -

Квадратичные кривые Безье

- -

В этом примере многократно используются квадратичные кривые Безье для рисования речевой выноски.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    // Quadratric curves example
-    ctx.beginPath();
-    ctx.moveTo(75,25);
-    ctx.quadraticCurveTo(25,25,25,62.5);
-    ctx.quadraticCurveTo(25,100,50,100);
-    ctx.quadraticCurveTo(50,120,30,125);
-    ctx.quadraticCurveTo(60,120,65,100);
-    ctx.quadraticCurveTo(125,100,125,62.5);
-    ctx.quadraticCurveTo(125,25,75,25);
-    ctx.stroke();
-  }
-}
-
- -

{{EmbedLiveSample("Квадратичные_кривые_Безье", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}

- -

Кубические кривые Безье

- -

В этом примере нарисовано сердце с использованием кубических кривых Безье.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    // Cubic curves example
-    ctx.beginPath();
-    ctx.moveTo(75,40);
-    ctx.bezierCurveTo(75,37,70,25,50,25);
-    ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
-    ctx.bezierCurveTo(20,80,40,102,75,120);
-    ctx.bezierCurveTo(110,102,130,80,130,62.5);
-    ctx.bezierCurveTo(130,62.5,130,25,100,25);
-    ctx.bezierCurveTo(85,25,75,37,75,40);
-    ctx.fill();
-  }
-}
-
- -

{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}

- -

Прямоугольники

- -

Все эти методы мы видели в  {{anch("Рисование прямоугольников")}}, которые рисуют прямоугольники сразу в canvas, так же есть метод rect(), который не отображает, а только добавляет контур рисования (path) заданного прямоугольника к последнему открытому контуру.

- -
-
{{domxref("CanvasRenderingContext2D.rect", "rect(x, y, width, height)")}}
-

- Добавляет в path прямоугольник, верхний левый угол которого указан с помощью (x, y) с вашими width и height
-
-
- -

Когда этот метод вызван, автоматически вызывается метод moveTo() с параметрами (x, y). Другими словами, позиция курсора устанавливается в начало добавленного прямоугольника.

- -

Создание комбинаций

- -

До сих пор, в каждом примере использовался только один тип функции контуров для каждой фигуры.
- Однако, нет никаких ограничений на количество или типы контуров, которые вы можете использовать для создания фигур. Давайте в этом примере объединим все вышеперечисленные  функции контуров, чтобы создать набор очень известных игровых персонажей.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    roundedRect(ctx,12,12,150,150,15);
-    roundedRect(ctx,19,19,150,150,9);
-    roundedRect(ctx,53,53,49,33,10);
-    roundedRect(ctx,53,119,49,16,6);
-    roundedRect(ctx,135,53,49,33,10);
-    roundedRect(ctx,135,119,25,49,10);
-
-    ctx.beginPath();
-    ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false);
-    ctx.lineTo(31,37);
-    ctx.fill();
-
-    for(var i=0;i<8;i++){
-      ctx.fillRect(51+i*16,35,4,4);
-    }
-
-    for(i=0;i<6;i++){
-      ctx.fillRect(115,51+i*16,4,4);
-    }
-
-    for(i=0;i<8;i++){
-      ctx.fillRect(51+i*16,99,4,4);
-    }
-
-    ctx.beginPath();
-    ctx.moveTo(83,116);
-    ctx.lineTo(83,102);
-    ctx.bezierCurveTo(83,94,89,88,97,88);
-    ctx.bezierCurveTo(105,88,111,94,111,102);
-    ctx.lineTo(111,116);
-    ctx.lineTo(106.333,111.333);
-    ctx.lineTo(101.666,116);
-    ctx.lineTo(97,111.333);
-    ctx.lineTo(92.333,116);
-    ctx.lineTo(87.666,111.333);
-    ctx.lineTo(83,116);
-    ctx.fill();
-
-    ctx.fillStyle = "white";
-    ctx.beginPath();
-    ctx.moveTo(91,96);
-    ctx.bezierCurveTo(88,96,87,99,87,101);
-    ctx.bezierCurveTo(87,103,88,106,91,106);
-    ctx.bezierCurveTo(94,106,95,103,95,101);
-    ctx.bezierCurveTo(95,99,94,96,91,96);
-    ctx.moveTo(103,96);
-    ctx.bezierCurveTo(100,96,99,99,99,101);
-    ctx.bezierCurveTo(99,103,100,106,103,106);
-    ctx.bezierCurveTo(106,106,107,103,107,101);
-    ctx.bezierCurveTo(107,99,106,96,103,96);
-    ctx.fill();
-
-    ctx.fillStyle = "black";
-    ctx.beginPath();
-    ctx.arc(101,102,2,0,Math.PI*2,true);
-    ctx.fill();
-
-    ctx.beginPath();
-    ctx.arc(89,102,2,0,Math.PI*2,true);
-    ctx.fill();
-  }
-}
-
-// A utility function to draw a rectangle with rounded corners.
-
-function roundedRect(ctx,x,y,width,height,radius){
-  ctx.beginPath();
-  ctx.moveTo(x,y+radius);
-  ctx.lineTo(x,y+height-radius);
-  ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
-  ctx.lineTo(x+width-radius,y+height);
-  ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
-  ctx.lineTo(x+width,y+radius);
-  ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
-  ctx.lineTo(x+radius,y);
-  ctx.quadraticCurveTo(x,y,x,y+radius);
-  ctx.stroke();
-}
-
- -

Конечное изображение выглядит так:

- -

{{EmbedLiveSample("Создание_комбинаций", 160, 160, "https://mdn.mozillademos.org/files/9849/combinations.png")}}

- -

Мы не будем подробно останавливаться на том, так как это на самом деле удивительно просто. Наиболее важные вещи, которые следует отметить, это использование свойства fillStyle в контексте рисования и использование функции утилиты (в данном случае roundedRect()). Использование функций утилиты для битов чертежа часто может быть очень полезным и сократить количество необходимого кода, а также его сложность.

- -

Позже, в этом уроке, мы еще раз рассмотрим fillStyle, но более подробно. Здесь же мы используем его для изменения цвета заливки путей вместо цвета по умолчанию от черного до белого, а затем обратно.

- -

Path2D объекты

- -

Как мы видели в последнем примере, есть серия путей и команд для рисования объектов на вашем холсте. Чтобы упростить код и повысить производительность, объект {{domxref("Path2D")}}, доступный в последних версиях браузеров, позволяет вам кэшировать или записывать эти команды рисования. Вы можете быстро запускать свои пути.
- Давайте посмотрим, как мы можем построить объект Path2D :

- -
-
{{domxref("Path2D.Path2D", "Path2D()")}}
-
Конструктор Path2D() возвращает вновь созданный объект Path2D  необязательно с другим путем в качестве аргумента (создает копию) или необязательно со строкой, состоящей из данных пути SVG path .
-
- -
new Path2D();     // пустой path объект
-new Path2D(path); // копирование из другого path
-new Path2D(d);    // path из SVG
- -

Все  методы path , такие как  moveTo,  rect,  arc, или quadraticCurveTo,  итп, которые мы уже знаем, доступны для объектов Path2D

- -

API Path2D также добавляет способ комбинирования путей с использованием метода addPath. Это может быть полезно, если вы хотите, например, создавать объекты из нескольких компонентов.

- -
-
{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}}
-
Добавляет путь к текущему пути с необязательной матрицей преобразования.
-
- -

Path2D пример

- -

В этом примере мы создаем прямоугольник и круг. Оба они сохраняются как объект Path2D, поэтому они доступны для последующего использования. С новым API Path2D несколько методов были обновлены, чтобы при необходимости принять объект Path2D для использования вместо текущего пути. Здесь stroke и fill используются с аргументом пути, например, для рисования обоих объектов на холст.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext){
-    var ctx = canvas.getContext('2d');
-
-    var rectangle = new Path2D();
-    rectangle.rect(10, 10, 50, 50);
-
-    var circle = new Path2D();
-    circle.moveTo(125, 35);
-    circle.arc(100, 35, 25, 0, 2 * Math.PI);
-
-    ctx.stroke(rectangle);
-    ctx.fill(circle);
-  }
-}
-
- -

{{EmbedLiveSample("Path2D_example", 130, 110, "https://mdn.mozillademos.org/files/9851/path2d.png")}}

- -

Использование SVG путей

- -

Еще одна мощная функция нового Canvas Path2D API использует данные пути SVG, SVG path data, для инициализации путей на вашем холсте. Это может позволить вам передавать данные пути и повторно использовать их как в SVG, так и в холсте.

- -

Путь перемещается в точку (M10 10), а затем горизонтально перемещается на 80 пунктов вправо (h 80), затем на 80 пунктов вниз (v 80), затем на 80 пунктов влево (h -80), а затем обратно на start (z). 
- Этот пример можно увидеть на странице  Path2D constructor.

- -
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
- -
{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
diff --git a/files/ru/web/api/crypto/getrandomvalues/index.html b/files/ru/web/api/crypto/getrandomvalues/index.html new file mode 100644 index 0000000000..c59f5dde54 --- /dev/null +++ b/files/ru/web/api/crypto/getrandomvalues/index.html @@ -0,0 +1,73 @@ +--- +title: RandomSource.getRandomValues() +slug: Web/API/RandomSource/getRandomValues +tags: + - АПИ + - Криптография + - Справка + - метод +translation_of: Web/API/Crypto/getRandomValues +--- +

{{APIRef("Web Crypto API")}}

+ +

Метод RandomSource.getRandomValues() позволяет вам получать криптографически стойкие числа. Массив, переданный как параметр, заполняется случайными числами (случайными в криптографическом смысле).

+ +

Для того, чтобы гарантировать достаточную производительность, реализации используют не настоящий генератор случайных чисел (RNG, en - Random Number Generator), а генератор псевдо-случайных чисел, которому предоставлено начальное зерно (wiki - https://en.wikipedia.org/wiki/Random_seed) с достаточной энтропией (http://cryptography.ru/ref/энтропия). Реализация генератора псевдо-случайных чисел (PRNG, en - PseudoRandom Number Generator) отличается от других реализаций RNG, но она больше подходит для использования в криптографии. Реализации также требуют использование начального зерна с достаточной энтропией, как источник системно-уровневой энтропии.

+ +

Синтаксис

+ +
cryptoObj.getRandomValues(typedArray);
+ +

Параметры

+ +
+
typedArray
+
Целочисленный массив {{jsxref("TypedArray")}}, например {{jsxref("Int8Array")}}, {{jsxref("Uint8Array")}}, {{jsxref("Uint16Array")}}, {{jsxref("Int32Array")}}, или {{jsxref("Uint32Array")}}. Все элементы массива замещаются случайными числами.
+
+ +

Исключения

+ + + +

Пример

+ +
/* Предполагается что функция window.crypto.getRandomValues доступна */
+
+var array = new Uint32Array(10);
+window.crypto.getRandomValues(array);
+
+console.log("Ваше счастливое число:");
+for (var i = 0; i < array.length; i++) {
+    console.log(array[i]);
+}
+
+ +

Спецификация

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('Web Crypto API', '#RandomSource-method-getRandomValues')}}{{Spec2('Web Crypto API')}}Изначальное определение
+ +

Совместимость с браузерами

+ +

{{Compat("api.Crypto.getRandomValues")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/css_object_model/managing_screen_orientation/index.html b/files/ru/web/api/css_object_model/managing_screen_orientation/index.html new file mode 100644 index 0000000000..a6b16cba4a --- /dev/null +++ b/files/ru/web/api/css_object_model/managing_screen_orientation/index.html @@ -0,0 +1,183 @@ +--- +title: Разбираемся с ориентацией экрана +slug: Web/API/CSS_Object_Model/ориентация_экрана +tags: + - Ориентация экрана + - Положение экрана + - Руководство +translation_of: Web/API/CSS_Object_Model/Managing_screen_orientation +--- +

{{DefaultAPISidebar("Screen Orientation API")}}{{SeeCompatTable}}

+ +

Ориентация экрана не идентична ориентации устройства. +Даже если устройство не способно определить свое положение в пространстве — экран может всегда. А когда устройство знает свою ориентацию, хорошо бы иметь возможность управлять ориентацией экрана для +сохранения или адаптации интерфейса веб-приложения.

+ +

Управление ориентацией экрана доступно в CSS и JavaScript. +Например, использование медиа-запросов позволяет контенту адаптироваться с помощью CSS в зависимости от того, в каком режиме просмотра находится браузер: альбомный (горизонтальный, когда ширина экрана больше высоты) или портретный (вертикальный, высота экрана больше ширины).

+ +

Для определения положения экрана и его блокировки можно воспользоваться JavaScript Screen orientation API.

+ +

Настройка раскладки содержимого по ориентации экрана

+ +

Допустим Вы хотите связать отображение содержимого с ориентацией экрана. Например, добавить панель, растягивающуюся по наибольшему направлению дисплея устройства. Это довольно просто реализовать с помощью медиа запросов.

+ +

Пример. Имеется HTML страница:

+ +
<ul id="toolbar">
+  <li>A</li>
+  <li>B</li>
+  <li>C</li>
+</ul>
+
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis lacinia nisi nec sem viverra vitae fringilla nulla ultricies. In ac est dolor, quis tincidunt leo. Cras commodo quam non tortor consectetur eget rutrum dolor ultricies. Ut interdum tristique dapibus. Nullam quis malesuada est.</p>
+
+ +

Соответствующий CSS:

+ +
/* Сначала зададим простые стили */
+
+html, body {
+  width : 100%;
+  height: 100%;
+}
+
+body {
+  border: 1px solid black;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+p {
+  font   : 1em sans-serif;
+  margin : 0;
+  padding: .5em;
+}
+
+ul {
+  list-style: none;
+
+  font   : 1em monospace;
+  margin : 0;
+  padding: .5em;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+
+  background: black;
+}
+
+li {
+  display: inline-block;
+  margin : 0;
+  padding: 0.5em;
+  background: white;
+}
+
+ +

Теперь разберемся с поведением страницы в различных случаях ориентации.

+ +
/* Для портретного режима отправим панель на верхнюю часть области отображения */
+
+@media screen and (orientation: portrait) {
+  #toolbar {
+    width: 100%;
+  }
+}
+
+/* Для альбомного режима пускай панель отображается слева */
+
+@media screen and (orientation: landscape) {
+  #toolbar {
+    position: fixed;
+    width: 2.65em;
+    height: 100%;
+  }
+
+  p {
+    margin-left: 2em;
+  }
+
+  li + li {
+    margin-top: .5em;
+  }
+}
+
+ +

Результат:

+ + + + + + + + + + + + + + +
Портреный режим просмотраАльбомный режим просмотра
+
{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 180, 350) }}
+
+
{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 350, 180) }}
+
+ +
+

Примечание: Медиа запрос по ориентации ссылается на окно браузера (соотношение его размеров), а не на ориентацию устройства.

+
+ +

Блокировка ориентации экрана

+ +
+

Предупреждение: Этот API вводится в экспериментальном режиме и доступен в Firefox OS и Firefox для Android с приставкой moz, а также для Internet Explorer на Windows 8.1 и выше с приставкой ms.

+
+ +

Некоторые устройства (в основном мобильные) могут изменять ориентацию экрана в соответствии с ориентацией самого устройства для удобства восприятия информации пользователем. +Это хорошо подходит для текста, но на некоторое содержимое такое поведение может оказать негативное воздействие. Например, это трагичная ситуация для игры, разработанной под определенную ориентацию.

+ +

Урегулировать вопрос, связанный с изменением положения экрана, поможет интерфейс Screen Orientation API.

+ +

Отслеживание изменения ориентации

+ +

Событие {{event("orientationchange")}} возникает каждый раз, когда устройство изменяет ориентацию экрана и самого себя, и может быть отслежено свойством {{domxref("Screen.orientation")}}.

+ +
screen.addEventListener("orientationchange", function () {
+  console.log("The orientation of the screen is: " + screen.orientation);
+});
+
+ +

Запрещаем поворот экрана

+ +

Любое веб-приложение может заблокировать положение экрана. Методом {{domxref("Screen.lockOrientation()")}} положение блокируется. Разблокирование осуществляется методом {{domxref("Screen.unlockOrientation()")}}.

+ +

Метод {{domxref("Screen.lockOrientation()")}} принимает одну или несколько строк для определения типа блокировки: portrait-primary, portrait-secondary, landscape-primary, landscape-secondary, portrait, landscape. Подробнее: {{domxref("Screen.lockOrientation")}}.

+ +
screen.lockOrientation('landscape');
+ +
+

Примечание: Положение экрана зависит от конкретной настройки приложения. Если в приложении A экран блокируется на альбомную ориентацию (landscape), а приложение B блокирует экран на портретный режим (portrait), +то переход из приложения A в приложение B (или наоборот) не вызовет событие изменения ориентации экрана {{event("orientationchange")}}, т. к. оба приложения сохраняют заданную ориентацию.

+ +

В то же время, событие {{event("orientationchange")}} может возникнуть в момент блокировки ориентации, если для удовлетворения заданному параметру блокировки изменяется положение экрана.

+
+ +

Firefox OS и Android: блокирование ориентации через манифест

+ +

Для Firefox OS и Firefox Android (скоро заработает и в десктопном Firefox) существует более специфичный способ: в файле манифеста Вашего приложения можно указать ориентацию:

+ +
"orientation": "portrait"
+ +

См. также

+ + diff --git "a/files/ru/web/api/css_object_model/\320\276\321\200\320\270\320\265\320\275\321\202\320\260\321\206\320\270\321\217_\321\215\320\272\321\200\320\260\320\275\320\260/index.html" "b/files/ru/web/api/css_object_model/\320\276\321\200\320\270\320\265\320\275\321\202\320\260\321\206\320\270\321\217_\321\215\320\272\321\200\320\260\320\275\320\260/index.html" deleted file mode 100644 index a6b16cba4a..0000000000 --- "a/files/ru/web/api/css_object_model/\320\276\321\200\320\270\320\265\320\275\321\202\320\260\321\206\320\270\321\217_\321\215\320\272\321\200\320\260\320\275\320\260/index.html" +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: Разбираемся с ориентацией экрана -slug: Web/API/CSS_Object_Model/ориентация_экрана -tags: - - Ориентация экрана - - Положение экрана - - Руководство -translation_of: Web/API/CSS_Object_Model/Managing_screen_orientation ---- -

{{DefaultAPISidebar("Screen Orientation API")}}{{SeeCompatTable}}

- -

Ориентация экрана не идентична ориентации устройства. -Даже если устройство не способно определить свое положение в пространстве — экран может всегда. А когда устройство знает свою ориентацию, хорошо бы иметь возможность управлять ориентацией экрана для -сохранения или адаптации интерфейса веб-приложения.

- -

Управление ориентацией экрана доступно в CSS и JavaScript. -Например, использование медиа-запросов позволяет контенту адаптироваться с помощью CSS в зависимости от того, в каком режиме просмотра находится браузер: альбомный (горизонтальный, когда ширина экрана больше высоты) или портретный (вертикальный, высота экрана больше ширины).

- -

Для определения положения экрана и его блокировки можно воспользоваться JavaScript Screen orientation API.

- -

Настройка раскладки содержимого по ориентации экрана

- -

Допустим Вы хотите связать отображение содержимого с ориентацией экрана. Например, добавить панель, растягивающуюся по наибольшему направлению дисплея устройства. Это довольно просто реализовать с помощью медиа запросов.

- -

Пример. Имеется HTML страница:

- -
<ul id="toolbar">
-  <li>A</li>
-  <li>B</li>
-  <li>C</li>
-</ul>
-
-<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis lacinia nisi nec sem viverra vitae fringilla nulla ultricies. In ac est dolor, quis tincidunt leo. Cras commodo quam non tortor consectetur eget rutrum dolor ultricies. Ut interdum tristique dapibus. Nullam quis malesuada est.</p>
-
- -

Соответствующий CSS:

- -
/* Сначала зададим простые стили */
-
-html, body {
-  width : 100%;
-  height: 100%;
-}
-
-body {
-  border: 1px solid black;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-p {
-  font   : 1em sans-serif;
-  margin : 0;
-  padding: .5em;
-}
-
-ul {
-  list-style: none;
-
-  font   : 1em monospace;
-  margin : 0;
-  padding: .5em;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-
-  background: black;
-}
-
-li {
-  display: inline-block;
-  margin : 0;
-  padding: 0.5em;
-  background: white;
-}
-
- -

Теперь разберемся с поведением страницы в различных случаях ориентации.

- -
/* Для портретного режима отправим панель на верхнюю часть области отображения */
-
-@media screen and (orientation: portrait) {
-  #toolbar {
-    width: 100%;
-  }
-}
-
-/* Для альбомного режима пускай панель отображается слева */
-
-@media screen and (orientation: landscape) {
-  #toolbar {
-    position: fixed;
-    width: 2.65em;
-    height: 100%;
-  }
-
-  p {
-    margin-left: 2em;
-  }
-
-  li + li {
-    margin-top: .5em;
-  }
-}
-
- -

Результат:

- - - - - - - - - - - - - - -
Портреный режим просмотраАльбомный режим просмотра
-
{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 180, 350) }}
-
-
{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 350, 180) }}
-
- -
-

Примечание: Медиа запрос по ориентации ссылается на окно браузера (соотношение его размеров), а не на ориентацию устройства.

-
- -

Блокировка ориентации экрана

- -
-

Предупреждение: Этот API вводится в экспериментальном режиме и доступен в Firefox OS и Firefox для Android с приставкой moz, а также для Internet Explorer на Windows 8.1 и выше с приставкой ms.

-
- -

Некоторые устройства (в основном мобильные) могут изменять ориентацию экрана в соответствии с ориентацией самого устройства для удобства восприятия информации пользователем. -Это хорошо подходит для текста, но на некоторое содержимое такое поведение может оказать негативное воздействие. Например, это трагичная ситуация для игры, разработанной под определенную ориентацию.

- -

Урегулировать вопрос, связанный с изменением положения экрана, поможет интерфейс Screen Orientation API.

- -

Отслеживание изменения ориентации

- -

Событие {{event("orientationchange")}} возникает каждый раз, когда устройство изменяет ориентацию экрана и самого себя, и может быть отслежено свойством {{domxref("Screen.orientation")}}.

- -
screen.addEventListener("orientationchange", function () {
-  console.log("The orientation of the screen is: " + screen.orientation);
-});
-
- -

Запрещаем поворот экрана

- -

Любое веб-приложение может заблокировать положение экрана. Методом {{domxref("Screen.lockOrientation()")}} положение блокируется. Разблокирование осуществляется методом {{domxref("Screen.unlockOrientation()")}}.

- -

Метод {{domxref("Screen.lockOrientation()")}} принимает одну или несколько строк для определения типа блокировки: portrait-primary, portrait-secondary, landscape-primary, landscape-secondary, portrait, landscape. Подробнее: {{domxref("Screen.lockOrientation")}}.

- -
screen.lockOrientation('landscape');
- -
-

Примечание: Положение экрана зависит от конкретной настройки приложения. Если в приложении A экран блокируется на альбомную ориентацию (landscape), а приложение B блокирует экран на портретный режим (portrait), -то переход из приложения A в приложение B (или наоборот) не вызовет событие изменения ориентации экрана {{event("orientationchange")}}, т. к. оба приложения сохраняют заданную ориентацию.

- -

В то же время, событие {{event("orientationchange")}} может возникнуть в момент блокировки ориентации, если для удовлетворения заданному параметру блокировки изменяется положение экрана.

-
- -

Firefox OS и Android: блокирование ориентации через манифест

- -

Для Firefox OS и Firefox Android (скоро заработает и в десктопном Firefox) существует более специфичный способ: в файле манифеста Вашего приложения можно указать ориентацию:

- -
"orientation": "portrait"
- -

См. также

- - diff --git a/files/ru/web/api/document/activeelement/index.html b/files/ru/web/api/document/activeelement/index.html deleted file mode 100644 index 71db5bc678..0000000000 --- a/files/ru/web/api/document/activeelement/index.html +++ /dev/null @@ -1,165 +0,0 @@ ---- -title: Document.activeElement -slug: Web/API/Document/activeElement -tags: - - API - - Document - - HTML DOM - - Property - - Reference -translation_of: Web/API/DocumentOrShadowRoot/activeElement -translation_of_original: Web/API/Document/activeElement ---- -

{{ ApiRef() }}

- -

Анотация

- -

Возвращает текущий сфокусированный элемент, то есть элемент, на котором будут вызываться события клавиатуры, если пользователь начнёт с неё ввод. Этот атрибут доступен только для чтения.

- -

Часто возвращается {{ HTMLElement("input") }} или {{ HTMLElement("textarea") }} объект, если он содержит в себе выделенный в данный момент текст. При этом вы можете получить более подробные сведения, используя свойства элемента  selectionStart и selectionEnd.  В других случаях сфокусированным элементом может быть {{ HTMLElement("select") }} элемент (меню) или {{ HTMLElement("input") }} элемент типа button, checkbox или radio.

- -

{{ Note("На Mac, элементы, не являющиеся текстовыми полями, как правило, не получают фокус.") }}

- -

Как правило, пользователь может нажать клавишу табуляции для перемещения по фокусируемым элементам страницы, и использовать пробел для их активации (нажать кнопку button, выбрать переключатель radio).

- -

Не следует путать фокус с выделением документа, состоящего в основном из статических текстовых узлов. См. {{ domxref("window.getSelection()") }}. 

- -

Когда выделение отсутствует, активным элементом является {{ HTMLElement("body") }} страницы или null. 

- -

{{ Note("Этот атрибут является частью разрабатываемой спецификации HTML 5.") }}

- -

Синтаксис

- -
var curElement = document.activeElement;
-
- -

Пример

- -
<!DOCTYPE HTML>
-<html>
-<head>
-    <script type="text/javascript" charset="utf-8">
-    function init() {
-
-        function onMouseUp(e) {
-            console.log(e);
-            var outputElement = document.getElementById('output-element');
-            var outputText = document.getElementById('output-text');
-            var selectedTextArea = document.activeElement;
-            var selection = selectedTextArea.value.substring(
-            selectedTextArea.selectionStart, selectedTextArea.selectionEnd);
-            outputElement.innerHTML = selectedTextArea.id;
-            outputText.innerHTML = selection;
-        }
-
-        document.getElementById("ta-example-one").addEventListener("mouseup", onMouseUp, false);
-        document.getElementById("ta-example-two").addEventListener("mouseup", onMouseUp, false);
-    }
-    </script>
-</head>
-<body onload="init()">
-<div>
-    Выделите текст в одном из текстовых полей ниже:
-</div>
-<form id="frm-example" action="#" accept-charset="utf-8">
-<textarea name="ta-example-one" id="ta-example-one" rows="8" cols="40">
-Это текстовое поле 1:
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt, lorem a porttitor molestie, odio nibh iaculis libero, et accumsan nunc orci eu dui.
-</textarea>
-<textarea name="ta-example-two" id="ta-example-two" rows="8" cols="40">
-Это текстовое поле 2:
-Fusce ullamcorper, nisl ac porttitor adipiscing, urna orci egestas libero, ut accumsan orci lacus laoreet diam. Morbi sed euismod diam.
-</textarea>
-</form>
-ID активного элемента: <span id="output-element"></span><br/>
-Выделенный текст: <span id="output-text"></span>
-
-</body>
-</html>
-
- -

Посмотреть на JSFiddle

- -

Примечания

- -

Первоначально введенное как собственное расширение DOM в Internet Explorer 4, это свойство также поддерживается в Opera и Safari (в версии 4).

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'interaction.html#dom-document-activeelement', 'activeElement')}}{{Spec2('HTML WHATWG')}} 
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support23.04 [1]9.64.0
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

[1]: В IE9 наблюдается баг: при попытке получения доступа к activeElement в {{domxref("window.parent")}} {{domxref("Document")}} из {{HTMLElement("iframe")}} (т.е. parent.document.activeElement) выбрасывается ошибка.

- -

Связанные события

- - diff --git a/files/ru/web/api/document/async/index.html b/files/ru/web/api/document/async/index.html deleted file mode 100644 index 2ff21f28af..0000000000 --- a/files/ru/web/api/document/async/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Document.async -slug: Web/API/Document/async -translation_of: Web/API/XMLDocument/async ---- -

{{APIRef("DOM")}}{{Deprecated_header}} {{Non-standard_header}}

- -

document.async может быть установлен, для того, чтобы определить, что вызов {{domxref("document.load")}} должен быть выполнен синхронно или не синхронно. true - стандартное значение, определяющее, асинхронно ли должны быть загружены документы.

- -

(Загружать документы синхронно стало возможно с версии 1.4 alpha.)

- -

Пример

- -
function loadXMLData(e) {
-  alert(new XMLSerializer().serializeToString(e.target)); // Gives querydata.xml contents as string
-}
-
-var xmlDoc = document.implementation.createDocument("", "test", null);
-
-xmlDoc.async = false;
-xmlDoc.onload = loadXMLData;
-xmlDoc.load('querydata.xml');
- -

Спецификация

- - - -

Смотрите также

- - diff --git a/files/ru/web/api/document/createelement/index.html b/files/ru/web/api/document/createelement/index.html new file mode 100644 index 0000000000..15542d751d --- /dev/null +++ b/files/ru/web/api/document/createelement/index.html @@ -0,0 +1,82 @@ +--- +title: document.createElement +slug: DOM/document.createElement +tags: + - DOM + - Gecko +translation_of: Web/API/Document/createElement +--- +

{{ ApiRef() }}

+ +

Общая информация

+ +

В HTML-документах создает элемент c тем тегом, что указан в аргументе или HTMLUnknownElement, если имя тега не распознаётся.

+ +

В XUL-документах создает указанный в аргументе элемент XUL.

+ +

В остальных случаях создаёт элемент с нулевым NamespaceURI.

+ +

Параметры

+ +
var element = document.createElement(tagName, [options]);
+
+ + + +

Пример

+ +

Данный пример создает новый элемент <div> и вставляет его перед элементом с идентификатором org_div1:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<title>||Работа с элементами||</title>
+</head>
+
+<body>
+<div><h1>Привет!</h1></div>
+<div id='org_div1'>Текст выше сгенерирован автоматически.</div>
+</body>
+
+<script>
+  document.body.onload = addElement;
+  var my_div = newDiv = null;
+
+  function addElement() {
+
+    // Создаем новый элемент div
+    // и добавляем в него немного контента
+
+    var newDiv = document.createElement("div");
+        newDiv.innerHTML = "<h1>Привет!</h1>";
+
+    // Добавляем только что созданый элемент в дерево DOM
+
+    my_div = document.getElementById("org_div1");
+    document.body.insertBefore(newDiv, my_div);
+  }
+</script>
+</html>
+
+ +

Заметки

+ +

Если существуют атрибуты со значениями по умолчанию, атрибуты узлов предоставляющие их создаются автоматически и применяются к элементу.

+ +

Для создания элементов с заданым пространством имен используйте метод createElementNS.

+ +

Реализация createElement в Gecko не соответствует DOM спецификации для XUL и XHTML документов: localName и namespaceURI не устанавливаются в  null в созданном документе. Смотрите {{ Bug(280692) }} для подробностей.

+ +

Для обратной совместимости с предыдущими версиями спецификации пользовательских элементов некоторые браузеры позволяют передавать здесь строку вместо объекта, где значением строки является имя тега пользовательского элемента.

+ +

Спецификации

+ +

DOM 2 Модуль: createElement

+ +

{{ languages( { "fr": "fr/DOM/document.createElement", "it": "it/DOM/document.createElement", "pl": "pl/DOM/document.createElement" } ) }}

diff --git a/files/ru/web/api/document/getselection/index.html b/files/ru/web/api/document/getselection/index.html deleted file mode 100644 index c57695e055..0000000000 --- a/files/ru/web/api/document/getselection/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Document.getSelection() -slug: Web/API/Document/getSelection -translation_of: Web/API/DocumentOrShadowRoot/getSelection -translation_of_original: Web/API/Document/getSelection ---- -

{{APIRef("DOM")}}

- -

Этот метод работает в точности так же, как {{domxref("Window.getSelection()")}}; он возвращает объект {{domxref("Selection")}}, в котором содержатся данные о тексте, выделенном в документе на данный момент.

diff --git a/files/ru/web/api/document/images/index.html b/files/ru/web/api/document/images/index.html new file mode 100644 index 0000000000..c9ba4ac1e2 --- /dev/null +++ b/files/ru/web/api/document/images/index.html @@ -0,0 +1,29 @@ +--- +title: document.images +slug: DOM/document.images +tags: + - DOM + - JavaScript +translation_of: Web/API/Document/images +--- +

{{ ApiRef() }}

+

Кратко об обьекте

+

document.images возвращает коллекцию изображений в текущем HTML документе.

+

Синтаксис

+
var htmlCollection = document.images;
+
+

Пример

+
var images = document.images;
+
+for(var i = 0; i < images.length; i++) {
+    if(images[i].src == "banner.gif") {
+      alert('Баннер найден!');
+    };
+};
+
+

Примечания

+

document.images.length — возвращает количество изображений на странице.

+

document.images является частью DOM HTML, и работает только в HTML документах.

+

Спецификация

+

DOM Level 2 HTML: HTMLDocument.images

+

{{ languages( { "en": "en/DOM/document.images", "fr": "fr/DOM/document.images", "pl": "pl/DOM/document.images","ru":"ru/DOM/document.images" } ) }}

diff --git a/files/ru/web/api/document/readystatechange_event/index.html b/files/ru/web/api/document/readystatechange_event/index.html new file mode 100644 index 0000000000..5a268b033f --- /dev/null +++ b/files/ru/web/api/document/readystatechange_event/index.html @@ -0,0 +1,90 @@ +--- +title: readystatechange +slug: Web/Events/readystatechange +tags: + - события +translation_of: Web/API/Document/readystatechange_event +--- +

{{ApiRef}}

+ +

Событие readystatechange срабатывает, когда изменяется атрибут документа readyState.

+ +

Основная информация

+ +
+
Спецификация
+
HTML5
+
 
+
Интерфейс
+
Event
+
Всплывает
+
Нет
+
Отменяемое
+
Нет
+
Цель
+
Document
+
Действие по умолчаанию
+
Нет
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}Цель события (Самая верхняя цель в дереве DOM).
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Всплывает ли событие.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
+ +

Примеры

+ +
document.readyState === "complete";
+// true
+
+
+// Альтернатива DOMContentLoaded
+document.onreadystatechange = function () {
+    if (document.readyState === "interactive") {
+        initApplication();
+    }
+}
+
+ +

Поддержка браузерами

+ +

Данное событие давно поддерживается Internet Explorer и может быть использовано в качестве альтернативы событию DOMContentLoaded (см. примечание [2] в разделе  Поддержка браузерами).

+ +

Связанные события

+ + diff --git a/files/ru/web/api/document_object_model/events/index.html b/files/ru/web/api/document_object_model/events/index.html new file mode 100644 index 0000000000..eeadb57328 --- /dev/null +++ b/files/ru/web/api/document_object_model/events/index.html @@ -0,0 +1,80 @@ +--- +title: Events and the DOM +slug: DOM/DOM_Reference/Events +translation_of: Web/API/Document_Object_Model/Events +--- +

Вступление

+ +

Вступление

+ +

В этой главе описывается модель событий DOM. Топ скрыть Интерфейс сам по себе описано, а также интерфейсы для регистрации событий на узлах в DOM, Также а слушатели события Главного , Также а Несколько больше Примеры, которые показывают, как Различные интерфейсы связаны друг события Главного с другом.

+ +

Существует отличная диаграмма, которая четко объясняет события трех этапов через DOM в проекте DOM Level 3 Events .

+ +

Также см. Пример 5: Распространение событий в главе «Примеры» для более подробного примера.

+ +

Регистрация слушателей событий

+ +

Есть 3 способа регистрации обработанных событий для элемента DOM.

+ +

EventTarget.addEventListener

+ +
// Предполагая, что myButton является элементом кнопки
+myButton.addEventListener ('click', greet, false);
+function greet (event) {
+    // распечатать и посмотреть на объект события
+    // всегда печатать аргументы в случае пропуска любых других аргументов
+    console.log ('greet:', arguments);
+    оповещение («Привет, мир»);
+}
+
+ +

Это метод, который вы должны использовать на современных веб-страницах.

+ +

Примечание. Internet Explorer 6-8 не поддерживает этот метод, предлагая аналогичный {{domxref ("EventTarget.attachEvent")}} API. Для кросс-браузерной совместимости используйте одну из множества доступных библиотек JavaScript.

+ +

Дополнительную информацию можно найти на справочной странице {{domxref ("EventTarget.addEventListener")}}.

+ +

Атрибут HTML

+ +
<button onclick = "alert ('Hello world!')">
+
+ +

Код JavaScript в атрибуте передается объекту Event через eventпараметр. Возвращаемое значение обрабатывается особым образом, описанным в спецификации HTML .

+ +

Этого пути следует избегать. Это делает разметку больше и менее читаемой. Проблемы содержания / структуры и поведения плохо разделены, что затрудняет поиск ошибки.

+ +

Свойства элемента DOM

+ +
// Предполагая, что myButton является элементом кнопки
+myButton.onclick = function(event){alert('Hello world');};
+
+ +

Функция может быть определена для получения eventпараметра. Возвращаемое значение обрабатывается особым образом, описанным в спецификации HTML .

+ +

Проблема этого метода в том, что для каждого элемента и для каждого события может быть установлен только один обработчик.

+ +

Доступ к интерфейсам событий

+ +

Обработчики событий могут быть присоединены к различным объектам, включая элементы DOM, документ, объект окна и т. Д. Когда происходит событие, объект события создается и последовательно передается слушателям события.

+ +

Интерфейс {{domxref ("Event")}} доступен из функции-обработчика через объект события, переданный в качестве первого аргумента. В следующем простом примере показано, как объект события передается в функцию-обработчик события и может использоваться из одной такой функции.

+ +
function print(evt) {
+  // параметру evt автоматически назначается объект события
+  // позаботимся о различиях в console.log и alert
+  console.log('print:', evt);
+  alert(evt);
+}
+// любая функция должна иметь подходящее имя, это то, что называется семантическим
+table_el.onclick = print; 
+
+ + + + diff --git a/files/ru/web/api/document_object_model/examples/index.html b/files/ru/web/api/document_object_model/examples/index.html new file mode 100644 index 0000000000..a3332f7585 --- /dev/null +++ b/files/ru/web/api/document_object_model/examples/index.html @@ -0,0 +1,382 @@ +--- +title: Examples of web and XML development using the DOM +slug: DOM/DOM_Reference/Examples +translation_of: Web/API/Document_Object_Model/Examples +--- +

В этой главе представлены более длинные примеры разработки веб-сайтов и XML с использованием DOM. По возможности, примеры используют общие API, трюки и шаблоны в JavaScript для управления объектом документа.

+ +

Пример 1: высота и ширина

+ +

В следующем примере показано использование свойств высоты и ширины для изображений разных размеров:
+  

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>width/height example</title>
+<script>
+function init() {
+  var arrImages = new Array(3);
+
+  arrImages[0] = document.getElementById("image1");
+  arrImages[1] = document.getElementById("image2");
+  arrImages[2] = document.getElementById("image3");
+
+  var objOutput = document.getElementById("output");
+  var strHtml = "<ul>";
+
+  for (var i = 0; i < arrImages.length; i++) {
+    strHtml += "<li>image" + (i+1) +
+            ": height=" + arrImages[i].height +
+            ", width=" + arrImages[i].width +
+            ", style.height=" + arrImages[i].style.height +
+            ", style.width=" + arrImages[i].style.width +
+            "<\/li>";
+  }
+
+  strHtml += "<\/ul>";
+
+  objOutput.innerHTML = strHtml;
+}
+</script>
+</head>
+<body onload="init();">
+
+<p>Image 1: no height, width, or style
+  <img id="image1" src="http://www.mozilla.org/images/mozilla-banner.gif">
+</p>
+
+<p>Image 2: height="50", width="500", but no style
+  <img id="image2"
+       src="http://www.mozilla.org/images/mozilla-banner.gif"
+       height="50" width="500">
+</p>
+
+<p>Image 3: no height, width, but style="height: 50px; width: 500px;"
+  <img id="image3"
+       src="http://www.mozilla.org/images/mozilla-banner.gif"
+       style="height: 50px; width: 500px;">
+</p>
+
+<div id="output"> </div>
+</body>
+</html>
+
+ +

Пример 2: Аттрибуты Изображения

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Modifying an image border</title>
+
+<script>
+function setBorderWidth(width) {
+  document.getElementById("img1").style.borderWidth = width + "px";
+}
+</script>
+</head>
+
+<body>
+<p>
+  <img id="img1"
+       src="image1.gif"
+       style="border: 5px solid green;"
+       width="100" height="100" alt="border test">
+</p>
+
+<form name="FormName">
+  <input type="button" value="Make border 20px-wide" onclick="setBorderWidth(20);" />
+  <input type="button" value="Make border 5px-wide"  onclick="setBorderWidth(5);" />
+</form>
+
+</body>
+</html>
+
+ +

Пример 3: Управление Стилями

+ +

В этом простом примере, некоторые базовые свойства стиля элемента абзаца HTML доступны с помощью объекта стиля элемента и свойств стиля CSS этого объекта, который можно получить и установить из DOM. В этом случае вы напрямую управляете отдельными стилями. В следующем примере (см. Пример 4), вы можете использовать таблицы стилей и их правила для изменения стилей для целых документов.

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Changing color and font-size example</title>
+
+<script>
+function changeText() {
+  var p = document.getElementById("pid");
+
+  p.style.color = "blue"
+  p.style.fontSize = "18pt"
+}
+</script>
+</head>
+<body>
+
+<p id="pid" onclick="window.location.href = 'http://www.cnn.com/';">linker</p>
+
+<form>
+  <p><input value="rec" type="button" onclick="changeText();" /></p>
+</form>
+
+</body>
+</html>
+
+ +

Пример 4: Использование Стилей

+ +

Свойство styleSheets объекта документа возвращает список таблиц стилей, которые были загружены в этот документ. Вы можете получить доступ к этим таблицам стилей и их правилам индивидуально, используя объекты таблицы стилей, стилей и CSS правил объекта, как показано в этом примере, который выводит все селектора правил стиля в консоль.

+ +
var ss = document.styleSheets;
+
+for(var i = 0; i < ss.length; i++) {
+  for(var j = 0; j < ss[i].cssRules.length; j++) {
+    dump( ss[i].cssRules[j].selectorText + "\n" );
+  }
+}
+ +

Для документа с единой таблицей стилей, в которой определены следующие три правила:

+ +
body { background-color: darkblue; }
+p { font-face: Arial; font-size: 10pt; margin-left: .125in; }
+#lumpy { display: none; }
+
+ +

Этот скрипт выводит следующее:

+ +
BODY
+P
+#LUMPY
+
+ +

Пример 5: Распространение Событий

+ +

Этот пример демонстрирует, как события срабатывают и обрабатываются в DOM очень простым путём. Когда загружается BODY в составе HTML-документа, обработчик событий регистрируется в верхней строке таблицы TABLE. Обработчик событий реагирует на событие запуском функции stopEvent, изменяющей значение в нижней ячейке.

+ +

Однако, stopEvent также вызывает метод объекта событий, {{domxref("event.stopPropagation")}}, что препятствует дальнейшему всплытию события в DOM. Обратите внимание, что сама таблица имеет {{domxref("element.onclick","onclick")}} обработчик событий, который должен отображать сообщение при нажатии на таблицу. Но метод stopEvent метод прекратил распространение, и поэтому после обновления данных в таблице фаза события эффективно завершается, и отображается окно предупреждения для подтверждения.

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Event Propagation</title>
+
+<style>
+#t-daddy { border: 1px solid red }
+#c1 { background-color: pink; }
+</style>
+
+<script>
+function stopEvent(ev) {
+  c2 = document.getElementById("c2");
+  c2.innerHTML = "hello";
+
+  // this ought to keep t-daddy from getting the click.
+  ev.stopPropagation();
+  alert("event propagation halted.");
+}
+
+function load() {
+  elem = document.getElementById("tbl1");
+  elem.addEventListener("click", stopEvent, false);
+}
+</script>
+</head>
+
+<body onload="load();">
+
+<table id="t-daddy" onclick="alert('hi');">
+  <tr id="tbl1">
+    <td id="c1">one</td>
+  </tr>
+  <tr>
+    <td id="c2">two</td>
+  </tr>
+</table>
+
+</body>
+</html>
+
+ +

Пример 6: getComputedStyle

+ +

Этот пример показывает как {{domxref("window.getComputedStyle")}} метод может использоваться для получения стилей элемента, которые не заданы с помощью атрибута style или с помощью JavaScript (e.g., elt.style.backgroundColor="rgb(173, 216, 230)"). Эти последние типы стилей можно получить с помощью более прямых {{domxref("element.style", "elt.style")}} свойств, которые указаны в DOM CSS Properties List.

+ +

getComputedStyle () возвращает объект ComputedCSSStyleDeclaration, свойства индивидуального стиля которого могут ссылаться на метод getPropertyValue () этого объекта, как показано в следующем примере документа.

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+
+<title>getComputedStyle example</title>
+
+<script>
+function cStyles() {
+  var RefDiv = document.getElementById("d1");
+  var txtHeight = document.getElementById("t1");
+  var h_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("height");
+
+  txtHeight.value = h_style;
+
+  var txtWidth = document.getElementById("t2");
+  var w_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("width");
+
+  txtWidth.value = w_style;
+
+  var txtBackgroundColor = document.getElementById("t3");
+  var b_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("background-color");
+
+  txtBackgroundColor.value = b_style;
+}
+</script>
+
+<style>
+#d1 {
+  margin-left: 10px;
+  background-color: rgb(173, 216, 230);
+  height: 20px;
+  max-width: 20px;
+}
+</style>
+
+</head>
+
+<body>
+
+<div id="d1">&nbsp;</div>
+
+<form action="">
+  <p>
+    <button type="button" onclick="cStyles();">getComputedStyle</button>
+    height<input id="t1" type="text" value="1" />
+    max-width<input id="t2" type="text" value="2" />
+    bg-color<input id="t3" type="text" value="3" />
+  </p>
+</form>
+
+</body>
+</html>
+
+ +

Пример 7: Отображение Свойств Событий Объекта

+ + + +

В этом примере используются методы DOM для отображения всех свойств объекта {{domxref ("window.onload")}} {{domxref ("event")}} и их значений в таблице. Он также показывает полезный метод использования цикла for..in для итерации по свойствам объекта для получения их значений.

+ +

Свойства объектов событий сильно различаются между браузерами, WHATWG DOM Standard перечисляет стандартные свойства, однако многие браузеры значительно расширили их.

+ +

Поместите следующий код в пустой текстовый файл и загрузите его в различные браузеры, вы будете удивлены различным количеством и именами свойств. Вы также можете добавить некоторые элементы на страницу и вызвать эту функцию из разных обработчиков событий.

+ + + +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8"/>
+<title>Show Event properties</title>
+
+<style>
+table { border-collapse: collapse; }
+thead { font-weight: bold; }
+td { padding: 2px 10px 2px 10px; }
+
+.odd { background-color: #efdfef; }
+.even { background-color: #ffffff; }
+</style>
+
+<script>
+
+function showEventProperties(e) {
+  function addCell(row, text) {
+    var cell = row.insertCell(-1);
+    cell.appendChild(document.createTextNode(text));
+  }
+
+  var e = e || window.event;
+  document.getElementById('eventType').innerHTML = e.type;
+
+  var table = document.createElement('table');
+  var thead = table.createTHead();
+  var row = thead.insertRow(-1);
+  var lableList = ['#', 'Property', 'Value'];
+  var len = lableList.length;
+
+  for (var i=0; i<len; i++) {
+    addCell(row, lableList[i]);
+  }
+
+  var tbody = document.createElement('tbody');
+  table.appendChild(tbody);
+
+  for (var p in e) {
+    row = tbody.insertRow(-1);
+    row.className = (row.rowIndex % 2)? 'odd':'even';
+    addCell(row, row.rowIndex);
+    addCell(row, p);
+    addCell(row, e[p]);
+  }
+
+  document.body.appendChild(table);
+}
+
+window.onload = function(event){
+  showEventProperties(event);
+}
+</script>
+</head>
+
+<body>
+<h1>Properties of the DOM <span id="eventType"></span> Event Object</h1>
+</body>
+
+</html>
+
+ +

Пример 8: Использование интерфейса таблицы DOM

+ + + +

Интерфейс DOM HTMLTableElement предоставляет некоторые удобные методы для создания и управления таблицами. Два часто используемых метода: {{domxref ("HTMLTableElement.insertRow")}} и {{domxref ("tableRow.insertCell")}}.

+ +

Чтобы добавить строку и некоторые ячейки в существующую таблицу:

+ + + +
<table id="table0">
+ <tr>
+  <td>Row 0 Cell 0</td>
+  <td>Row 0 Cell 1</td>
+ </tr>
+</table>
+
+<script>
+var table = document.getElementById('table0');
+var row = table.insertRow(-1);
+var cell,
+    text;
+
+for (var i = 0; i < 2; i++) {
+  cell = row.insertCell(-1);
+  text = 'Row ' + row.rowIndex + ' Cell ' + i;
+  cell.appendChild(document.createTextNode(text));
+}
+</script>
+
+ +

Заметки

+ + + + + + diff --git a/files/ru/web/api/document_object_model/index.html b/files/ru/web/api/document_object_model/index.html new file mode 100644 index 0000000000..db06b01dd8 --- /dev/null +++ b/files/ru/web/api/document_object_model/index.html @@ -0,0 +1,387 @@ +--- +title: Руководство по DOM +slug: DOM/DOM_Reference +tags: + - DOM + - DOM Reference + - DOM интерфейс + - Intermediate + - Руководство +translation_of: Web/API/Document_Object_Model +--- +

Объектная Модель Документа (DOM) является программным интерфейсом для HTML, XML и SVG документов. Это обеспечивает структурированное представление документа (дерева), и определяет способ, по которому структура может быть доступна для программы, для изменения структуры документа, его стиля и содержания. DOM обеспечивает представление документа в виде структурированной группы узлов и объектов, которые имеют свойства и методы. По сути, она связывает веб -страницы со скриптами или языками программирования.

+ +

DOM чаще всего используется в JavaScript, но не является его частью, поэтому иногда с DOM работают в других языках.

+ +

Введение в DOM доступно.

+ +

DOM интерфейсы

+ +
+ +
+ +

Устаревшие интерфейсы

+ +

Объектная модель документа находится в процессе значительного упрощения. Для того, чтобы достигнуть этого следующие интерфейсы, присутствующие на различных DOM level 3 или более ранних спецификациях были удалены. До сих пор неясно, будут ли некоторые из них возвращены, но на данный момент они должны быть рассмотрены как устаревшие, и их использования следует избегать:

+ +
+ +
+ +

HTML интерфейсы

+ +

Документ, содержащий HTML описывается с помощью {{domxref("HTMLDocument")}} интерфейса. Обратите внимание, что HTML спецификация также расширяет {{domxref("Document")}} интерфейс.

+ +

Объект HTMLDocument также даёт доступ к следующим возможностям браузера: вкладки, окна, в которых отрисовывается страница, используя интерфейс {{domxref("Window")}}, асcоциированный с ним {{domxref("window.style", "Style")}} (обычно CSS), история браузера, относящаяся к контексту, {{domxref("window.history", "History")}}, в конце концов, {{domxref("Selection")}} в документе.

+ +

Интерфейсы HTML элементов

+ +
+ +
+ +

Другие интерфейсы

+ +
+ +
+ +

Устаревшие HTML интерфейсы

+ +
+ +
+ +

SVG интерфейсы

+ +

Интерфейсы SVG элементов

+ +
+ +
+ +

Интерфейсы SVG данных

+ +

DOM API для типов данных, используемых в определениях SVG свойств и атрибутов.

+ +
+

Замечание: Начиная с {{Gecko("5.0")}}, следующие относящиеся к SVG DOM интерфейсы, представляя списки объектов, индексируются и к ним можно иметь доступ как к массивам; к тому же, у них есть свойство длины, обозначающее количество элементов в списках: {{domxref("SVGLengthList")}}, {{domxref("SVGNumberList")}}, {{domxref("SVGPathSegList")}} и {{domxref("SVGPointList")}}.

+
+ +

Статический тип

+ +
+ +
+ +

Анимированный тип

+ +
+ +
+ +

Относящиеся к SMIL

+ +
+ +
+ +

Другие SVG интерфейсы

+ +
+ +
+ +

Смотрите также

+ + + +
+
+
diff --git a/files/ru/web/api/document_object_model/introduction/index.html b/files/ru/web/api/document_object_model/introduction/index.html new file mode 100644 index 0000000000..3c02e5799f --- /dev/null +++ b/files/ru/web/api/document_object_model/introduction/index.html @@ -0,0 +1,230 @@ +--- +title: Введение +slug: DOM/DOM_Reference/Введение +tags: + - DOM +translation_of: Web/API/Document_Object_Model/Introduction +--- +
+

Этот раздел представляет краткое знакомство с Объектной Моделью Документа (DOM) - что такое DOM, каким образом предоставляются структуры HTML и XML документов, и как взаимодействовать с ними. Данный раздел содержит справочную информацию и примеры.

+ +

Что такое Объектная Модель Документа (DOM)?

+ +

Объектная Модель Документа (DOM) – это программный интерфейс (API) для HTML и XML документов. DOM предоставляет структурированное представление документа и определяет то, как эта структура может быть доступна из программ, которые могут изменять содержимое, стиль и структуру документа. Представление DOM состоит из структурированной группы узлов и объектов, которые имеют свойства и методы. По существу, DOM соединяет веб-страницу с языками описания сценариев либо языками программирования.
+
+ Веб-страница – это документ. Документ может быть представлен как в окне браузера, так и в самом HTML-коде. В любом случае, это один и тот же документ. DOM предоставляет другой способ представления, хранения и управления этого документа. DOM полностью поддерживает объектно-ориентированнное представление веб-страницы, делая возможным её изменение при помощи языка описания сценариев наподобие JavaScript.
+
+ Стандарты W3C DOM и WHATWG DOM формируют основы DOM, реализованные в большинстве современных браузеров. Многие браузеры предлагают расширения за пределами данного стандарта, поэтому необходимо проверять работоспособность тех или иных возможностей DOM для каждого конкретного браузера.

+ +

Например: стандарт DOM описывает, что метод getElementsByTagName в коде, указанном ниже, должен возращать список всех элементов <p> в документе.

+ +
paragraphs = document.getElementsByTagName("P");
+// paragraphs[0] это первый <p> элемент
+// paragraphs[1] это второй <p> элемент и т.д.
+alert(paragraphs[0].nodeName);
+ +

Все свойства, методы и события, доступные для управления и создания новых страниц, организованы в виде объектов. Например, объект document, который представляет сам документ, объект table, который реализует специальный интерфейс DOM HTMLTableElement, необходимый для доступа к HTML-таблицам, и так далее. Данная документация даёт справку об объектах DOM, реализованных Gecko-подобных браузерах.

+ +

DOM и JavaScript

+ +

Небольшой пример выше, как почти все примеры в этой справке – это JavaScript. То есть пример написан на JavaScript, но при этом используется DOM для доступа к документу и его элементам. DOM не является языком программирования, но без него JavaScript не имел бы никакой модели или представления о веб-странице, HTML-документе, XML-документе и их элементах. Каждый элемент в документе - весь документ в целом, заголовок, таблицы внутри документа, заголовки таблицы, текст внутри ячеек таблицы - это части объектной документной модели для этого документа, поэтому все они могут быть доступны и могут изменяться с помощью DOM и скриптового языка наподобие JavaScript.

+ +

Вначале JavaScript и DOM были тесно связаны, но впоследствии они развились в различные сущности. Содержимое страницы хранится в DOM и может быть доступно и изменяться с использованием JavaScript, поэтому мы можем записать это в виде приблизительного равенства:

+ +

API (веб либо XML страница) = DOM + JS (язык описания скриптов)

+ +

DOM спроектирован таким образом, чтобы быть независимым от любого конкретного языка программирования, обеспечивая структурное представление документа согласно единому и последовательному API. Хотя мы всецело сфокусированы на JavaScript в этой справочной документации, реализация DOM может быть построена для любого языка, как в следующем примере на Python:

+
+ +
# Пример DOM на языке Python
+import xml.dom.minidom as m
+doc = m.parse("C:\\Projects\\Py\\chap1.xml");
+doc.nodeName # Свойство объекта документа DOM;
+p_list = doc.getElementsByTagName("para");
+ +

Для подробной информации о том, какие технологии участвуют в написании JavaScript для веб, смотрите обзорную статью JavaScript technologies overview.

+ +

Каким образом доступен DOM? 

+ +

Вы не должны делать ничего особенного для работы с DOM. Различные браузеры имеют различную реализацию DOM, эти реализации показывают различную степень соответсвия с действительным стандартом DOM (это тема, которую мы пытались не затрагивать в данной документации), но каждый браузер использует свой DOM, чтобы сделать веб страницы доступными для взаимодествия с языками сценариев.

+ +

При создании сценария с использованием элемента <script>, либо включая в веб страницу инструкцию для загрузки скрипта, вы можете немедленно приступить к использованию программного интерфейса (API), используя элементы document или window для взаимодействия с самим документом, либо для получения потомков этого документа, т.е. различных элементов на странице. Ваше программирование DOM может быть чем-то простым, например, вывод сообщения с использованием функции alert() объекта window, или использовать более сложные методы DOM, которые создают новое содержимое, как показанно в следующем примере:

+ +
<body onload="window.alert('добро пожаловать на мою домашнюю страницу!');">
+
+ +

В следующем примере внутри элемента <script> определен код JavaScript, данный код устанавливает функцию при загрузке документа (когда весь DOM доступен для использования). Эта функция создает новый элемент H1, добавляет текст в данный элемент, а затем добавляет H1 в дерево документа:

+ +
<html>
+  <head>
+    <script>
+    // запуск данной функции при загрузке документа
+       window.onload = function() {
+    // создание нескольких элементов
+    // в пустой HTML странице
+       heading = document.createElement("h1");
+       heading_text = document.createTextNode("Big Head!");
+       heading.appendChild(heading_text);
+       document.body.appendChild(heading);
+      }
+    </script>
+  </head>
+  <body>
+  </body>
+</html>
+ +

Важные типы данных

+ +

Данный раздел предназначен для краткого описания различных типов и объектов в простой и доступной манере. Существует некоторое количество различных типов данных, которые используются в API, на которые вы должны обратить внимание. Для простоты, синтаксис примеров в данном разделе обычно ссылается на узлы как на elements, на массивы узлов как на nodeLists ( либо просто elements ) и на атрибуты узла, просто как на attributes.

+ +

Ниже таблица с кратким описанием этих типов данных.

+ + + + + + + + + + + + + + + + + + + + + + + + +
documentКогда член возвращает объект типа document (например, свойство элемента ownerDocument возвращает документ к которому он относится), этот обьект document является собственным корневым обьектом. В DOM document Reference разделе описан объект document.
+ element   
elementобозначает элемент или узел типа element, возвращаемый членом DOM API. Вместо того, чтобы говорить, что метод document.createElement() возвращает ссылку на node, мы просто скажем, что этот элемент возвращает element, который просто был создан в DOM. Объекты element реализуют DOM element интерфейс и также более общий Node интерфейс. Оба интерфейса включены в эту справку.
+ nodeList
NodeList +

массив элементов, как тот, что возвращается методом Document.getElementsByTagName(). Конкретные элементы в массиве доступны по индексу двумя способами:

+ +
    +
  •     list.item(1)
  • +
  •     list[1]
  • +
+ +

Эти способы эквивалентны. В первом способе item() - единственный метод объекта NodeList. Последний использует обычный синтаксис массивов, чтобы получить второе значение в списке.

+
attributeКогда attribute возвращается членом API (например, метод createAttribute()) - это будет ссылка на объект, который предоставляет специальный (хоть и небольшой) интерфейс для атрибутов. Атрибуты - это узлы в DOM, как и элементы, хотя вы можете редко использовать их в таком виде.
namedNodeMapnamedNodeMap подобна массиву, но элементы доступны по имени или индексу. Доступ по индексу - это лишь для удобства перечисления, т.к. элементы не имеют определенног порядка в списке. Этот тип данных имеет метод item() для этих целей и вы можете также добавлять и удалять элементы из namedNodeMap
+ + + +

DOM-интерфейсы (DOM interfaces)

+ + + +

Это руководство об объектах и реальных вещах, которые вы можете использовать для управления DOM-иерархией. Есть много моментов, где понимание того, как это работает, может удивлять. Например, объект, представляющий HTML form элемент, берет своё свойство name из интерфейса HTMLFormElement, а свойство className - из интерфейса HTMLElement. В обоих случаях свойство, которое вы хотите, находится в этом объекте формы.

+ +

Кроме того, отношение между объектами и интерфейсами, которые они реализуют в DOM может быть удивительным и этот раздел пытается рассказать немного о существующих интерфейсах в DOM и о том, как они могут быть доступны.

+ +

Интерфейсы и объекты (Interfaces and objects)

+ +

Многие объекты реализуют действия из нескольких интерфейсов. Объект таблицы, например, реализует специальный HTML Table Element Interface, который включает такие методы как createCaption и insertRow. Но так как это таблица - это ещё и HTML-элемент, table реализует интерфейс Element, описанный в разделе DOM element Reference. Наконец, так как HTML-элемент (в смысле DOM) - это узел (node) в дереве, которое составляет объектную модель для HTML- или XML-страницы, табличный элемент также реализует более общий интерфейс Node, из которого происходит Element.

+ +

Когда вы получаете ссылку на объект table, как в следующем примере, вы обычно используете все три интерфейса этого объекта, вероятно, даже не зная этого.

+ +
var table = document.getElementById("table");
+var tableAttrs = table.attributes; // Node/Element interface
+for (var i = 0; i < tableAttrs.length; i++) {
+  // HTMLTableElement interface: border attribute
+  if(tableAttrs[i].nodeName.toLowerCase() == "border")
+    table.border = "1";
+}
+// HTMLTableElement interface: summary attribute
+table.summary = "note: increased border";
+ +

Основные интерфейсы в DOM (Core interfaces in the DOM)

+ +

Этот раздел перечисляет несколько самых распространенных интерфейсов в DOM. Идея не в том чтобы описать, что делают эти методы API, но в том чтобы дать вам несколько мыслей насчет видов методов и свойств, которые вы будете часто видеть, используя DOM. Эти распространенные части API использованы в большинстве примеров раздела DOM Examples в конце этой справки.

+ +

Document, window - это объекты, чьи интерфейсы вы, как правило, очень часто используете в программировании DOM. Говоря простыми словами, объект window представляет что-то вроде браузера, а объект document - корень самого документа. Element наследуется от общего интерфейса Node, и эти интерфейсы вместе предоставляют много методов и свойств, которые можно применять у отдельных элементов. Эти элементы также могут иметь отдельные интерфейсы для работы с типами данных, которые эти элементы содержат, как в примере с объектом table в предыдущем случае.

+ +

Ниже представлен краткий список распространненых членов API, используемых в программировании веб- и XML-страниц с использованием DOM:

+ + + +

Тестирование DOM API

+ +

Этот документ содержит примеры для каждого интерфейса, который вы можете использовать в своей разработке. В некоторых случаях примеры - полноценные веб-страницы с доступом к DOM в элементе <script>, также перечислены элементы, необходимые чтобы запустить скрипт в форме, и HTML-элементы, над которыми будут производиться операции DOM. Когда встречается такой случай, можно просто копировать и вставить пример в новый HTML-документ, сохранить и запустить его в браузере.

+ +

Есть случаи, однако, где примеры более лаконичные. Чтобы запустить примеры, которые лишь демонстрируют основы взаимодействия интерфейсов с HTML-элементами, вы можете подготовить тестовую страницу, в которую будете помещать функции внутрь скриптов. Следующая очень простая веб-страница содержит элемент <script> в заголовке, в который вы можете поместить функции, чтобы протестировать интерфейс. Страница содержит несколько элементов с атрибутами, которые можно возвращать, устанавливать или, другими словами, манипулировать и содержит пользовательский интерфейс, необходимый, чтобы вызывать нужные функции из браузера.

+ +

Вы можете использовать эту тестовую страницу или похожую для проверки интерфейсов DOM, которые вас интересуют и просмотра того, как они работают в браузерах. Вы можете обновить содержмое функции test() при необходимости, создать больше кнопок или добавить элементы при необходимости.

+ +
<html>
+  <head>
+    <title>DOM Tests</title>
+    <script type="application/javascript">
+    function setBodyAttr(attr, value){
+      if (document.body) eval('document.body.'+attr+'="'+value+'"');
+      else notSupported();
+    }
+    </script>
+  </head>
+  <body>
+    <div style="margin: .5in; height: 400;">
+      <p><b><tt>text</tt></b></p>
+      <form>
+        <select onChange="setBodyAttr('text',
+        this.options[this.selectedIndex].value);">
+          <option value="black">black
+          <option value="darkblue">darkblue
+        </select>
+        <p><b><tt>bgColor</tt></b></p>
+        <select onChange="setBodyAttr('bgColor',
+        this.options[this.selectedIndex].value);">
+          <option value="white">white
+          <option value="lightgrey">gray
+        </select>
+        <p><b><tt>link</tt></b></p>
+        <select onChange="setBodyAttr('link',
+        this.options[this.selectedIndex].value);">
+          <option value="blue">blue
+          <option value="green">green
+        </select>  <small>
+        <a href="http://www.brownhen.com/dom_api_top.html" id="sample">
+        (sample link)</a></small><br>
+      </form>
+      <form>
+        <input type="button" value="version" onclick="ver()" />
+      </form>
+    </div>
+  </body>
+</html>
+ +

Чтобы протестировать много интерфейсов на одной странице, набор свойств, которые изменяют цвета веб-страницы, можно создать похожую веб-страницу с целой "консолью" кнопок, текстовых полей и других элементов. Следующий скриншот даёт идею, как интерфейсы могут быть сгруппированы вместе для тестирования

+ +

+ +

В этом примере выпадающее меню динамически обновляет доступные из DOM части веб-страницы (например, фоновый цвет, цвет ссылок и цвет текста). Однако при разработке тестовых страниц, тестирование интерфейсов, как вы об этом прочитали, важная часть изучения эффективной работы с DOM.

+ +

Другие статьи

+ + diff --git a/files/ru/web/api/document_object_model/locating_dom_elements_using_selectors/index.html b/files/ru/web/api/document_object_model/locating_dom_elements_using_selectors/index.html new file mode 100644 index 0000000000..73538e8616 --- /dev/null +++ b/files/ru/web/api/document_object_model/locating_dom_elements_using_selectors/index.html @@ -0,0 +1,50 @@ +--- +title: Locating DOM elements using selectors +slug: DOM/DOM_Reference/Locating_DOM_elements_using_selectors +translation_of: Web/API/Document_object_model/Locating_DOM_elements_using_selectors +--- +
{{ gecko_minversion_header("1.9.1") }}
+ +
Selectors API предоставляет методы, с помощью которых можно быстро и просто получить доступ к узлам Element из DOM путем сопоставления с набором селекторов. Это намного быстрее, чем прошлые техники, где надо было, например, использовать цикл в JS-коде, чтобы найти конкретные элементы.
+ +
 
+ +

Интерфейс NodeSelector (The NodeSelector interface)

+ +

Эта спецификация добавляет два новых метода к любым объектам, реализующим интерфейс Document, DocumentFragment, или Element:

+ +
+
querySelector
+
Возвращает первый совпадающий узел Element внутри поддерева. Если совпадающих узлов нет, будет возвращен null.
+
querySelectorAll
+
Возвращает NodeList, содержащий все подходящие узлы Element внутри поддерева узлов. Или возвращает пустой NodeList, если совпадений не найдено.
+
+ +
Замечание: NodeList, возвращаемый методом querySelectorAll(), не настоящий. Этот список отличается от других методов поиска DOM, которые возвращают настоящие (живые) узлы.
+ +

Вы можете найти примеры и детали, прочитав документацию для методов querySelector() и querySelectorAll(), а также в статье Code snippets for querySelector.

+ +

Selectors

+ +

Селекторные методы принимают один или больше селекторов, разделенных запятыми, чтобы определить, какие элементы должны быть возвращены. Например, чтобы все параграфы в документе, которые имеют классы warning или note, можно сделать следующее:

+ +
var special = document.querySelectorAll( "p.warning, p.note" );
+ +

Также можно искать по ID. Например:

+ +
var el = document.querySelector( "#main, #basic, #exclamation" );
+ +

После выполнения кода выше, el будет содержать первый элемент в документе, чей ID main, basic или exclamation

+ +

Вы можете использовать любые CSS-селекторы в методах querySelector(), querySelectorAll()

+ +

See also

+ + diff --git a/files/ru/web/api/documentorshadowroot/activeelement/index.html b/files/ru/web/api/documentorshadowroot/activeelement/index.html new file mode 100644 index 0000000000..71db5bc678 --- /dev/null +++ b/files/ru/web/api/documentorshadowroot/activeelement/index.html @@ -0,0 +1,165 @@ +--- +title: Document.activeElement +slug: Web/API/Document/activeElement +tags: + - API + - Document + - HTML DOM + - Property + - Reference +translation_of: Web/API/DocumentOrShadowRoot/activeElement +translation_of_original: Web/API/Document/activeElement +--- +

{{ ApiRef() }}

+ +

Анотация

+ +

Возвращает текущий сфокусированный элемент, то есть элемент, на котором будут вызываться события клавиатуры, если пользователь начнёт с неё ввод. Этот атрибут доступен только для чтения.

+ +

Часто возвращается {{ HTMLElement("input") }} или {{ HTMLElement("textarea") }} объект, если он содержит в себе выделенный в данный момент текст. При этом вы можете получить более подробные сведения, используя свойства элемента  selectionStart и selectionEnd.  В других случаях сфокусированным элементом может быть {{ HTMLElement("select") }} элемент (меню) или {{ HTMLElement("input") }} элемент типа button, checkbox или radio.

+ +

{{ Note("На Mac, элементы, не являющиеся текстовыми полями, как правило, не получают фокус.") }}

+ +

Как правило, пользователь может нажать клавишу табуляции для перемещения по фокусируемым элементам страницы, и использовать пробел для их активации (нажать кнопку button, выбрать переключатель radio).

+ +

Не следует путать фокус с выделением документа, состоящего в основном из статических текстовых узлов. См. {{ domxref("window.getSelection()") }}. 

+ +

Когда выделение отсутствует, активным элементом является {{ HTMLElement("body") }} страницы или null. 

+ +

{{ Note("Этот атрибут является частью разрабатываемой спецификации HTML 5.") }}

+ +

Синтаксис

+ +
var curElement = document.activeElement;
+
+ +

Пример

+ +
<!DOCTYPE HTML>
+<html>
+<head>
+    <script type="text/javascript" charset="utf-8">
+    function init() {
+
+        function onMouseUp(e) {
+            console.log(e);
+            var outputElement = document.getElementById('output-element');
+            var outputText = document.getElementById('output-text');
+            var selectedTextArea = document.activeElement;
+            var selection = selectedTextArea.value.substring(
+            selectedTextArea.selectionStart, selectedTextArea.selectionEnd);
+            outputElement.innerHTML = selectedTextArea.id;
+            outputText.innerHTML = selection;
+        }
+
+        document.getElementById("ta-example-one").addEventListener("mouseup", onMouseUp, false);
+        document.getElementById("ta-example-two").addEventListener("mouseup", onMouseUp, false);
+    }
+    </script>
+</head>
+<body onload="init()">
+<div>
+    Выделите текст в одном из текстовых полей ниже:
+</div>
+<form id="frm-example" action="#" accept-charset="utf-8">
+<textarea name="ta-example-one" id="ta-example-one" rows="8" cols="40">
+Это текстовое поле 1:
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt, lorem a porttitor molestie, odio nibh iaculis libero, et accumsan nunc orci eu dui.
+</textarea>
+<textarea name="ta-example-two" id="ta-example-two" rows="8" cols="40">
+Это текстовое поле 2:
+Fusce ullamcorper, nisl ac porttitor adipiscing, urna orci egestas libero, ut accumsan orci lacus laoreet diam. Morbi sed euismod diam.
+</textarea>
+</form>
+ID активного элемента: <span id="output-element"></span><br/>
+Выделенный текст: <span id="output-text"></span>
+
+</body>
+</html>
+
+ +

Посмотреть на JSFiddle

+ +

Примечания

+ +

Первоначально введенное как собственное расширение DOM в Internet Explorer 4, это свойство также поддерживается в Opera и Safari (в версии 4).

+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'interaction.html#dom-document-activeelement', 'activeElement')}}{{Spec2('HTML WHATWG')}} 
+ +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support23.04 [1]9.64.0
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

[1]: В IE9 наблюдается баг: при попытке получения доступа к activeElement в {{domxref("window.parent")}} {{domxref("Document")}} из {{HTMLElement("iframe")}} (т.е. parent.document.activeElement) выбрасывается ошибка.

+ +

Связанные события

+ + diff --git a/files/ru/web/api/documentorshadowroot/getselection/index.html b/files/ru/web/api/documentorshadowroot/getselection/index.html new file mode 100644 index 0000000000..c57695e055 --- /dev/null +++ b/files/ru/web/api/documentorshadowroot/getselection/index.html @@ -0,0 +1,9 @@ +--- +title: Document.getSelection() +slug: Web/API/Document/getSelection +translation_of: Web/API/DocumentOrShadowRoot/getSelection +translation_of_original: Web/API/Document/getSelection +--- +

{{APIRef("DOM")}}

+ +

Этот метод работает в точности так же, как {{domxref("Window.getSelection()")}}; он возвращает объект {{domxref("Selection")}}, в котором содержатся данные о тексте, выделенном в документе на данный момент.

diff --git a/files/ru/web/api/element/accesskey/index.html b/files/ru/web/api/element/accesskey/index.html deleted file mode 100644 index 0230ecc9e0..0000000000 --- a/files/ru/web/api/element/accesskey/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Element.accessKey -slug: Web/API/Element/accessKey -translation_of: Web/API/HTMLElement/accessKey -translation_of_original: Web/API/Element/accessKey ---- -
{{APIRef("DOM")}}
- -
 
- -

Описание

- -

Свойство accessKey позволяет перейти к элементу с помощью сочетания клавиш - заданной им и тех, что назначит браузер.

- -
-

По сути, accessKey задает значение для одноименного атрибута...

-
- -
-

Данное свойство использовать не рекоммендуется, поскольку в браузерах уже заданы подобные привязки и неосторожное обращение может привести к жестокому конфликту.

-
- -

 

- -

Синтаксис

- -
var key = elem.accessKey;
-elem.accessKey = key;
-
- -

 

- -

Пример

- -
var elem = document.getElementById("id");
-elem.accessKey = "w";
-
- -

Немного информации

- -

Фокусировка на элемент произойдет при нажатии следующих клавиш (,где acesskey - значение свойства acessKey).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

      Браузер

-
-

      Сочетание

-
Firefox[Alt] [Shift] + accesskey
Internet Explorer[Alt] + accesskey
Chrome[Alt] + accesskey
Safari[Alt] + accesskey
Opera[Shift] [Esc] + accesskey
diff --git a/files/ru/web/api/element/blur_event/index.html b/files/ru/web/api/element/blur_event/index.html new file mode 100644 index 0000000000..a29fa0debc --- /dev/null +++ b/files/ru/web/api/element/blur_event/index.html @@ -0,0 +1,153 @@ +--- +title: blur (event) +slug: Web/Events/blur +tags: + - DOM + - DOM Events +translation_of: Web/API/Element/blur_event +--- +

Событие blur вызывается когда элемент теряет фокус. Главное отличие между этим событием и  focusout только в том что у последнего есть фаза всплытия.

+ +

Основная информация

+ +
+
Спецификация
+
DOM L3
+
Интерфейс
+
{{domxref("FocusEvent")}}
+
Всплытие
+
Нет
+
Отменяемый
+
Нет
+
Цель
+
Элемент
+
Действие по умолчанию
+
Нет
+
+ +

{{NoteStart}}Значение {{domxref("Document.activeElement")}} меняется в зависимости от браузера во время выполнения этого события ({{bug(452307)}}): IE10 устанавливает его к элементу на который будет перемещен фокус, в то время как Firefox и Chrome обычно устанавливают его к body документа{{NoteEnd}}

+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target (DOM element)
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)null
+ +

Делегирование события

+ +

Есть два способа реализовать делегирование этого события: использовать событие focusout в браузерах которые поддерживают его (все браузеры, Firefox с 52+), или установить параметр "useCapture" метода addEventListener на true:

+ +

HTML Content

+ +
<form id="form">
+  <input type="text" placeholder="text input">
+  <input type="password" placeholder="password">
+</form>
+ +

JavaScript Content

+ +
var form = document.getElementById("form");
+form.addEventListener("focus", function( event ) {
+  event.target.style.background = "pink";
+}, true);
+form.addEventListener("blur", function( event ) {
+  event.target.style.background = "";
+}, true);
+ +

{{EmbedLiveSample('Event_delegation')}}

+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatVersionUnknown}}[1]612.15.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.053{{CompatUnknown}}10.012.15.1
+
+ +

[1] В Gecko до 24 {{geckoRelease(24)}} интефейс для этого события был {{domxref("Event")}}, не {{domxref("FocusEvent")}}. Смотреть ({{bug(855741)}}).

+ +

Похожие события

+ + diff --git a/files/ru/web/api/element/error_event/index.html b/files/ru/web/api/element/error_event/index.html new file mode 100644 index 0000000000..787fb9a4fa --- /dev/null +++ b/files/ru/web/api/element/error_event/index.html @@ -0,0 +1,95 @@ +--- +title: error +slug: Web/Events/error +tags: + - DOM + - UI события + - Видео + - Запись + - Медия + - Обработка ошибок + - Ошибки + - Событие + - аудио + - события +translation_of: Web/API/Element/error_event +--- +

Событие error возникает, когда произошла какая-либо ошибка. Точные обстоятельства могут быть различными, потому что события с этим именем используются множеством различных API.

+ +

Общая информация

+ +
+
Спецификация
+
DOM L3
+
Интерфейс
+
{{domxref("UIEvent")}} если создается элементом пользовательского интерфейса, {{domxref("MediaRecorderErrorEvent")}} если генерируется API записи MediaStream, и {{domxref("Event")}} иначе.
+
Вплывающее
+
Нет
+
Отменяемое
+
Нет
+
Цель
+
Элемент
+
Действие по умолчанию
+
Нет
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}EventTargetЦель события (наиболее верхлежащий элемент в DOM дереве).
type {{readonlyInline}}DOMStringТип события.
bubbles {{readonlyInline}}BooleanЯвляется ли событие вплывающим в стандартных условиях или нет.
cancelable {{readonlyInline}}BooleanЯвляется ли событие отменяемым или нет.
view {{readonlyInline}}WindowProxydocument.defaultView (свойство window объекта document)
detail {{readonlyInline}}long (float)0.
+ +

Для MediaStream Recording событий

+ +

Эти события типа {{domxref("MediaRecorderErrorEvent")}}.

+ +

{{page("/en-US/docs/Web/API/MediaRecorderErrorEvent", "Properties")}}

+ +

Смотрите также

+ +
+
{{domxref("GlobalEventHandlers.onerror")}}
+
События отсылаются в {{domxref("Window.onerror")}} и {{domxref("Element.onerror")}}
+
{{domxref("HTMLMediaElement.onerror")}}
+
События отсылаются в {{domxref("HTMLMediaElement")}}, включая {{HTMLElement("audio")}} и {{HTMLElement("video")}}
+
{{domxref("MediaRecorder.onerror")}}
+
События отсылаются в {{domxref("MediaRecorder.onerror")}}, типа {{domxref("MediaRecorderErrorEvent")}}
+
diff --git a/files/ru/web/api/element/focusin_event/index.html b/files/ru/web/api/element/focusin_event/index.html new file mode 100644 index 0000000000..02f27b66fb --- /dev/null +++ b/files/ru/web/api/element/focusin_event/index.html @@ -0,0 +1,123 @@ +--- +title: focusin +slug: Web/Events/focusin +translation_of: Web/API/Element/focusin_event +--- +

Событие focusin срабатывает, когда элемент получает фокус. Главное отличие от focus в том, что последний не всплывает.

+ +

Общая информация

+ +
+
Specification
+
DOM L3
+
Interface
+
{{domxref("FocusEvent")}}
+
Bubbles
+
Yes
+
Cancelable
+
No
+
Target
+
Element
+
Default Action
+
None.
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target losing focus.
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)Event target receiving focus.
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatNo}}[1]{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatNo}}[1]{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
+
+ +

[1] Событие пока что не поддерживается в Firefox, см. {{Bug("687787")}}. Вместо него можно использовать событие focus, которое совместимо с делегированием событий.

+ + + + diff --git a/files/ru/web/api/element/focusout_event/index.html b/files/ru/web/api/element/focusout_event/index.html new file mode 100644 index 0000000000..742f52af03 --- /dev/null +++ b/files/ru/web/api/element/focusout_event/index.html @@ -0,0 +1,126 @@ +--- +title: focusout +slug: Web/Events/focusout +translation_of: Web/API/Element/focusout_event +--- +

Событие focusout вызывается перед потерей элементом фокуса. Главное отличие между этим событием и blur в том, что у последнего нет фазы всплытия.

+ +

 

+ +

Основная информация

+ +
+
Спецификация
+
DOM L3
+
Интерфейс
+
{{domxref("FocusEvent")}}
+
Всплытие
+
Да
+
Отменяемый
+
Нет
+
Цель
+
Элемент
+
Действие по умолчанию
+
Нет.
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}Цель события, теряющая фокус.
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Всплывает ли событие при нормальных условиях.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM-элемент)Цель события, получающая фокус.
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoDesktop(52)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile(52)}}{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
+
+ + + + diff --git a/files/ru/web/api/elementcssinlinestyle/style/index.html b/files/ru/web/api/elementcssinlinestyle/style/index.html new file mode 100644 index 0000000000..683bfa1101 --- /dev/null +++ b/files/ru/web/api/elementcssinlinestyle/style/index.html @@ -0,0 +1,78 @@ +--- +title: HTMLElement.style +slug: Web/API/HTMLElement/style +tags: + - API + - HTML DOM + - HTMLElement + - NeedsBrowserAgnosticism + - NeedsBrowserCompatibility + - NeedsMarkupWork + - NeedsSpecTable + - Свойство + - Ссылки +translation_of: Web/API/ElementCSSInlineStyle/style +--- +

Кратко

+ +
+
{{ APIRef("HTML DOM") }}
+
+ +

Свойство HTMLElement.style используется для получения и установки инлайновых стилей. При получении возвращается объект CSSStyleDeclaration , который содержит список из всех свойств стилей для этого элемента с значениями заданными  для атрибутов , что определенны  в инлайновом стиле (см. атрибут стиля) элемента. См. CSS Properties Reference для получения списка CSS свойств применимых вместе со style.  

+ +

Настройка стилей

+ +

Свойство style имеет тот же приоритет (и выше) в каскаде CSS как и прямая декларация стиля через атрибут style, полезен для настройки стиля отдельного специфичного элемента.

+ +

Стили не следует устанавливать непосредственно через свойство style (например elt.style = "color: blue;"), поскольку оно считается доступным только для чтения и атрибут style возвращает объект CSSStyleDeclaration который доступен только для чтения. Вместо этого стили могут быть установлены путем присвоения значений свойствам style. Для добавления определенных стилей для элемента без изменения других свойств стилей предпочтительно использовать отдельные свойства style (например elt.style.color = '...'). +При использовании
elt.style.cssText = '...' или elt.setAttribute('style','...') устанавливаются стили перезаписывая уже существующие. Обратите внимание, что имена свойств стилей задаются в camel-case а не в kebab-case elt.style.<property> (т.е., elt.style.fontSize, а не elt.style.font-size).

+ +

Объявленные стили сбрасываются присваиванием значения null,
elt.style.color = null

+ +

Примеры

+ +
// Устанавливает несколько стилей в одном выражении
+elt.style.cssText = "color: blue; border: 1px solid black";
+// Или
+elt.setAttribute("style", "color:red; border: 1px solid blue;");
+
+// Устанавливает определенный стиль оставляя другие значения стиля нетронутыми
+elt.style.color = "blue";
+ +

Получение стиль-информации

+ +

Свойство style в основном не имеет пользы в части информации о стиле элемента, оно только олицетворяет собой набор CSS деклараций атрибутов style элемента, а не тех которые проистекают из стиль-правил откуда-либо ещё, таких как стилевые правила раздела {{HTMLElement("head")}}, или внешней таблицы стилей. Для получения значений всех CSS свойств элемента вы должны использовать вместо этого {{domxref("window.getComputedStyle()")}}.

+ +
+
var div = document.getElementById("div1");
+div.style.marginTop = ".25in";
+
+ +

Следующий код показывает имена всех свойств стиля, значений, заданных явно для элемента elt и унаследованных "расчитанных" значений:

+ +
var elt = document.getElementById("elementIdHere");
+var out = "";
+var st = elt.style;
+var cs = window.getComputedStyle(elt, null);
+for (x in st) {
+  out += "  " + x + " = '" + st[x] + "' > '" + cs[x] + "'\n";
+}
+ +

Спецификация

+ +

DOM Level 2 Style: ElementCSSInlineStyle.style

+ +

CSSOM: ElementCSSInlineStyle

+ +

Совместимость

+ + + +

{{Compat("api.HTMLElement.style")}}

+ +

См. также

+ + diff --git a/files/ru/web/api/eventtarget/attachevent/index.html b/files/ru/web/api/eventtarget/attachevent/index.html deleted file mode 100644 index a428f9724c..0000000000 --- a/files/ru/web/api/eventtarget/attachevent/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: EventTarget.attachEvent() -slug: Web/API/EventTarget/attachEvent -tags: - - Junk -translation_of: Web/API/EventTarget/addEventListener -translation_of_original: Web/API/EventTarget/attachEvent ---- -

{{DOMxRef("EventTarget.addEventListener","EventTarget.addEventListener()")}}

diff --git a/files/ru/web/api/eventtarget/detachevent/index.html b/files/ru/web/api/eventtarget/detachevent/index.html deleted file mode 100644 index 9a62ecb63c..0000000000 --- a/files/ru/web/api/eventtarget/detachevent/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: EventTarget.detachEvent() -slug: Web/API/EventTarget/detachEvent -translation_of: Web/API/EventTarget/removeEventListener -translation_of_original: Web/API/EventTarget/detachEvent ---- -

{{APIRef("DOM Events")}}

- -

{{ Non-standard_header() }}

- -

Кратко

- -

Это проприетарная альтернатива методу {{domxref("EventTarget.removeEventListener()")}}  в Microsoft Internet Explorer.

- -

Синтаксис

- -
target.detachEvent(eventNameWithOn, callback)
-
- -
-
target
-
DOM елемент, для которого надо убрать обработчик.
-
eventNameWithOn
-
Название ивента, начинающийся на "on" (так если бы это был колбэк атрибут), чей обработчик должен быть убран. Например, вам следует использовать "onclick" для удаления обработчика для данного "click" ивента.
-
callback
-
Функция, которую стоит убрать.
-
- -

Спецификация

- -

Не является частью спецификации.

- -

Microsoft содержит описание на MSDN.

- -

Поддержка браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка{{ CompatNo() }}{{ CompatNo() }}6 thru 10 [1]{{ CompatUnknown() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{ CompatNo() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatNo() }}
-
- -

[1]: detachEvent() больше не поддерживается в IE11+. {{domxref("EventTarget.removeEventListener()")}} поддерживается в IE9+.

- -

Смотрите так-же

- - diff --git a/files/ru/web/api/file_and_directory_entries_api/introduction/index.html b/files/ru/web/api/file_and_directory_entries_api/introduction/index.html new file mode 100644 index 0000000000..e5c76758c1 --- /dev/null +++ b/files/ru/web/api/file_and_directory_entries_api/introduction/index.html @@ -0,0 +1,291 @@ +--- +title: Введение в API файлов и каталогов +slug: Web/API/File_and_Directory_Entries_API/Введение +translation_of: Web/API/File_and_Directory_Entries_API/Introduction +--- +
{{DefaultAPISidebar("File System API")}}{{Non-standard_header}}
+ +

API файлов и каталогов эмулирует для веб-приложений локальную файловую систему. У вас есть возможность создания приложений, которые могут читать, записывать и создавать файлы и директории в изолированной виртуальной файловой системе.

+ +

API файлов и каталогов взаимодействует с другими API. Оно было создано на основе File Writer API, который в свою очередь использует File API. Каждое API реализует разную функциональность. Данные программные интерфейсы являются огромным эволюционным скачком для веб-приложений, которые теперь могут кешировать и обрабатывать большие объемы данных. 

+ +

Об этом документе

+ +

В данном документе приведены основные концепции и терминология API файлов и каталогов, которые должны показать общую картину и ключевые идеи. Также описаны ограничения, несоблюдение которых может привести к появлению ошибок безопасности. Используемая терминология описана в разделе Определений.

+ +

Ссылки на страницы данного API приведены в Ссылочном справочнике.

+ +

Спецификация находится на стадии разработки и будет изменяться в будущем.

+ +

Обзор

+ +

Программный интерфейс файлов и каталогов включает асинхронные и синхронные методы. Асинхронное API может быть использовано в тех случаях, когда нежелательно, чтобы длительные вычисления блокировали весь пользовательский интерфейс. В свою очередь синхронное API предлагает более простую модель программирования, однако оно должно использоваться только с объектами WebWorkers.

+ +

Применимость API

+ +

API файлов и каталогов является важным программным интерфейсом по следующим причинам:

+ + + +

Примеры таких приложений приведены в разделе Примеры использования.

+ +

API файлов и каталогов и другие программные интерфейсы хранения данных

+ +

API файлов и каталогов является альтернативой для других интерфейсов хранения данных, таких как IndexedDB, WebSQL (признано устаревшим с 18 ноября 2010 г.) и AppCache. Тем не менее данное API является более хорошим выбором для приложений, обрабатывающим большие объемы данных, по следующим причинам:

+ + + +

Примеры использования

+ +

Далее приведены лишь некоторые случаи, в которых можно использовать API файлов и каталогов:

+ + + +

Big concepts

+ +

Before you start using the File and Directory Entries API, you need to understand a few concepts:

+ + + +

The File and Directory Entries API is a virtual representation of a file system

+ +

The API doesn't give you access to the local file system, nor is the sandbox really a section of the file system. Instead, it is a virtualized file system that looks like a full-fledged file system to the web app. It does not necessarily have a relationship to the local file system outside the browser. 

+ +

What this means is that a web app and a desktop app cannot share the same file at the same time. The API does not let your web app reach outside the browser to files that desktop apps can also work on. You can, however, export a file from a web app to a desktop app. For example, you can use the File API, create a blob, redirect an iframe to the blob, and invoke the download manager.

+ +

The File and Directory Entries API can use different storage types

+ +

An application can request temporary or persistent storage. Temporary storage is easier to get, because the browser just gives it to you, but it is limited and can be deleted by the browser when it runs out of space. Persistent storage, on the other hand, might offer you larger space that can only be deleted by the user, but it requires the user to grant you permission.

+ +

Use temporary storage for caching and persistent storage for data that you want your app to keep—such as user-generated or unique data.

+ +

Browsers impose storage quotas

+ +

To prevent a web app from using up the entire disk, browsers might impose a quota for each app and allocate storage among web apps.

+ +

How storage space is granted or allocated and how you can manage storage are idiosyncratic to the browser, so you need to check the respective documentation of the browser. Google Chrome, for example, allows temporary storage beyond the 5 MB required in the specifications and supports the Quota Management API. To learn more about the Chrome-specific implementation, see Managing HTML5 Offline Storage.

+ +

The File and Directory Entries API has asynchronous and synchronous versions

+ +

The File and Directory Entries API comes with asynchronous and synchronous versions. Both versions of the API offer the same capabilities and features. In fact, they are almost alike, except for a few differences.

+ + + +

The synchronous API can be simpler for some tasks. Its direct, in-order programming model can make code easier to read. The drawback of synchronous API has to do with its interactions with Web Workers, which has some limitations.

+ +

When using the asynchronous API, always use the error callbacks

+ +

When using the asynchronous API, always use the error callbacks. Although the error callbacks for the methods are optional parameters, they are not optional for your sanity. You want to know why your calls failed. At minimum, handle the errors to provide error messages, so you'll have an idea of what's going on.

+ +

The File and Directory Entries API interacts with other APIs

+ +

The File and Directory Entries API is designed to be used with other APIs and elements on the web platform. For example, you are likely to use one of the following:

+ + + +

The File and Directory Entries API is case sensitive

+ +
The filesystem API is case-sensitive, and case-preserving. 
+ +

 

+ +

Ограничения

+ +

For security reasons, browsers impose restrictions on file access. If you ignore them, you will get security errors.

+ + + +

The File and Directory Entries API adheres to the same-origin policy

+ +

An origin is the domain, application layer protocol, and port of a URL of the document where the script is being executed. Each origin has its own associated set of file systems.

+ +

The security boundary imposed on file system prevents applications from accessing data with a different origin. This protects private data by preventing access and deletion. For example, while an app or a page in http://www.example.com/app/ can access files from http://www.example.com/dir/, because they have the same origin, it cannot retrieve files from http://www.example.com:8080/dir/ (different port) or https://www.example.com/dir/ (different protocol).

+ +

The File and Directory Entries API does not let you create and rename executable files

+ +

To prevent malicious apps from running hostile executables, you cannot create executable files within the sandbox of the File and Directory Entries API. 

+ +

The file system is sandboxed

+ +

Because the file system is sandboxed, a web app cannot access another app's files. You also cannot read or write files to an arbitrary folder (for example, My Pictures and My Documents) on the user's hard drive.

+ +

You cannot run your app from file://

+ +

You cannot run your app locally from file://. If you do so, the browser throws errors or your app fails silently. This restriction also applies to many of the file APIs, including BlobBuilder and FileReader.

+ +

For testing purposes, you can bypass the restriction on Chrome by starting the browser with the --allow-file-access-from-files flag. Use this flag only for this purpose.

+ +

Определения

+ +

This section defines and explains terms used in the File and Directory Entries API.

+ +
+
blob
+
Stands for binary large object. A blob is a set of binary data that is stored a single object. It is a general-purpose way to reference binary data in web applications. A blob can be an image or an audio file.
+
Blob
+
Blob—with a capital B—is a data structure that is immutable, which means that binary data referenced by a Blob cannot be modified directly. This makes Blobs act predictably when they are passed to asynchronous APIs.
+
persistent storage
+
Persistent storage is storage that stays in the browser unless the user expunges it or the app deletes it. 
+
temporary storage
+
Transient storage is available to any web app. It is automatic and does not need to be requested, but the browser can delete the storage without warning.
+
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('File System API')}}{{Spec2('File System API')}}Draft of proposed API
+ +

This API has no official W3C or WHATWG specification.

+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Asynchronous API13 {{ property_prefix("webkit") }}{{ CompatGeckoDesktop(50) }}[1]{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
Synchronous API13 {{ property_prefix("webkit") }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Asynchronous API{{ CompatNo }}{{ CompatVersionUnknown }} {{ property_prefix("webkit") }}{{ CompatGeckoMobile(50) }}[1]{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
Synchronous API{{ CompatNo }}{{ CompatVersionUnknown }} {{ property_prefix("webkit") }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
+
+ +

[1] Firefox 50 introduces partial support for the File and Directory Entries API. Be sure to check the compatibility tables for individual interfaces and methods before using them, to ensure that they're supported, before you use them.

+ +

See also

+ + diff --git "a/files/ru/web/api/file_and_directory_entries_api/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" "b/files/ru/web/api/file_and_directory_entries_api/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index e5c76758c1..0000000000 --- "a/files/ru/web/api/file_and_directory_entries_api/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,291 +0,0 @@ ---- -title: Введение в API файлов и каталогов -slug: Web/API/File_and_Directory_Entries_API/Введение -translation_of: Web/API/File_and_Directory_Entries_API/Introduction ---- -
{{DefaultAPISidebar("File System API")}}{{Non-standard_header}}
- -

API файлов и каталогов эмулирует для веб-приложений локальную файловую систему. У вас есть возможность создания приложений, которые могут читать, записывать и создавать файлы и директории в изолированной виртуальной файловой системе.

- -

API файлов и каталогов взаимодействует с другими API. Оно было создано на основе File Writer API, который в свою очередь использует File API. Каждое API реализует разную функциональность. Данные программные интерфейсы являются огромным эволюционным скачком для веб-приложений, которые теперь могут кешировать и обрабатывать большие объемы данных. 

- -

Об этом документе

- -

В данном документе приведены основные концепции и терминология API файлов и каталогов, которые должны показать общую картину и ключевые идеи. Также описаны ограничения, несоблюдение которых может привести к появлению ошибок безопасности. Используемая терминология описана в разделе Определений.

- -

Ссылки на страницы данного API приведены в Ссылочном справочнике.

- -

Спецификация находится на стадии разработки и будет изменяться в будущем.

- -

Обзор

- -

Программный интерфейс файлов и каталогов включает асинхронные и синхронные методы. Асинхронное API может быть использовано в тех случаях, когда нежелательно, чтобы длительные вычисления блокировали весь пользовательский интерфейс. В свою очередь синхронное API предлагает более простую модель программирования, однако оно должно использоваться только с объектами WebWorkers.

- -

Применимость API

- -

API файлов и каталогов является важным программным интерфейсом по следующим причинам:

- - - -

Примеры таких приложений приведены в разделе Примеры использования.

- -

API файлов и каталогов и другие программные интерфейсы хранения данных

- -

API файлов и каталогов является альтернативой для других интерфейсов хранения данных, таких как IndexedDB, WebSQL (признано устаревшим с 18 ноября 2010 г.) и AppCache. Тем не менее данное API является более хорошим выбором для приложений, обрабатывающим большие объемы данных, по следующим причинам:

- - - -

Примеры использования

- -

Далее приведены лишь некоторые случаи, в которых можно использовать API файлов и каталогов:

- - - -

Big concepts

- -

Before you start using the File and Directory Entries API, you need to understand a few concepts:

- - - -

The File and Directory Entries API is a virtual representation of a file system

- -

The API doesn't give you access to the local file system, nor is the sandbox really a section of the file system. Instead, it is a virtualized file system that looks like a full-fledged file system to the web app. It does not necessarily have a relationship to the local file system outside the browser. 

- -

What this means is that a web app and a desktop app cannot share the same file at the same time. The API does not let your web app reach outside the browser to files that desktop apps can also work on. You can, however, export a file from a web app to a desktop app. For example, you can use the File API, create a blob, redirect an iframe to the blob, and invoke the download manager.

- -

The File and Directory Entries API can use different storage types

- -

An application can request temporary or persistent storage. Temporary storage is easier to get, because the browser just gives it to you, but it is limited and can be deleted by the browser when it runs out of space. Persistent storage, on the other hand, might offer you larger space that can only be deleted by the user, but it requires the user to grant you permission.

- -

Use temporary storage for caching and persistent storage for data that you want your app to keep—such as user-generated or unique data.

- -

Browsers impose storage quotas

- -

To prevent a web app from using up the entire disk, browsers might impose a quota for each app and allocate storage among web apps.

- -

How storage space is granted or allocated and how you can manage storage are idiosyncratic to the browser, so you need to check the respective documentation of the browser. Google Chrome, for example, allows temporary storage beyond the 5 MB required in the specifications and supports the Quota Management API. To learn more about the Chrome-specific implementation, see Managing HTML5 Offline Storage.

- -

The File and Directory Entries API has asynchronous and synchronous versions

- -

The File and Directory Entries API comes with asynchronous and synchronous versions. Both versions of the API offer the same capabilities and features. In fact, they are almost alike, except for a few differences.

- - - -

The synchronous API can be simpler for some tasks. Its direct, in-order programming model can make code easier to read. The drawback of synchronous API has to do with its interactions with Web Workers, which has some limitations.

- -

When using the asynchronous API, always use the error callbacks

- -

When using the asynchronous API, always use the error callbacks. Although the error callbacks for the methods are optional parameters, they are not optional for your sanity. You want to know why your calls failed. At minimum, handle the errors to provide error messages, so you'll have an idea of what's going on.

- -

The File and Directory Entries API interacts with other APIs

- -

The File and Directory Entries API is designed to be used with other APIs and elements on the web platform. For example, you are likely to use one of the following:

- - - -

The File and Directory Entries API is case sensitive

- -
The filesystem API is case-sensitive, and case-preserving. 
- -

 

- -

Ограничения

- -

For security reasons, browsers impose restrictions on file access. If you ignore them, you will get security errors.

- - - -

The File and Directory Entries API adheres to the same-origin policy

- -

An origin is the domain, application layer protocol, and port of a URL of the document where the script is being executed. Each origin has its own associated set of file systems.

- -

The security boundary imposed on file system prevents applications from accessing data with a different origin. This protects private data by preventing access and deletion. For example, while an app or a page in http://www.example.com/app/ can access files from http://www.example.com/dir/, because they have the same origin, it cannot retrieve files from http://www.example.com:8080/dir/ (different port) or https://www.example.com/dir/ (different protocol).

- -

The File and Directory Entries API does not let you create and rename executable files

- -

To prevent malicious apps from running hostile executables, you cannot create executable files within the sandbox of the File and Directory Entries API. 

- -

The file system is sandboxed

- -

Because the file system is sandboxed, a web app cannot access another app's files. You also cannot read or write files to an arbitrary folder (for example, My Pictures and My Documents) on the user's hard drive.

- -

You cannot run your app from file://

- -

You cannot run your app locally from file://. If you do so, the browser throws errors or your app fails silently. This restriction also applies to many of the file APIs, including BlobBuilder and FileReader.

- -

For testing purposes, you can bypass the restriction on Chrome by starting the browser with the --allow-file-access-from-files flag. Use this flag only for this purpose.

- -

Определения

- -

This section defines and explains terms used in the File and Directory Entries API.

- -
-
blob
-
Stands for binary large object. A blob is a set of binary data that is stored a single object. It is a general-purpose way to reference binary data in web applications. A blob can be an image or an audio file.
-
Blob
-
Blob—with a capital B—is a data structure that is immutable, which means that binary data referenced by a Blob cannot be modified directly. This makes Blobs act predictably when they are passed to asynchronous APIs.
-
persistent storage
-
Persistent storage is storage that stays in the browser unless the user expunges it or the app deletes it. 
-
temporary storage
-
Transient storage is available to any web app. It is automatic and does not need to be requested, but the browser can delete the storage without warning.
-
- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('File System API')}}{{Spec2('File System API')}}Draft of proposed API
- -

This API has no official W3C or WHATWG specification.

- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Asynchronous API13 {{ property_prefix("webkit") }}{{ CompatGeckoDesktop(50) }}[1]{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
Synchronous API13 {{ property_prefix("webkit") }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Asynchronous API{{ CompatNo }}{{ CompatVersionUnknown }} {{ property_prefix("webkit") }}{{ CompatGeckoMobile(50) }}[1]{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
Synchronous API{{ CompatNo }}{{ CompatVersionUnknown }} {{ property_prefix("webkit") }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
-
- -

[1] Firefox 50 introduces partial support for the File and Directory Entries API. Be sure to check the compatibility tables for individual interfaces and methods before using them, to ensure that they're supported, before you use them.

- -

See also

- - diff --git a/files/ru/web/api/fullscreen_api/index.html b/files/ru/web/api/fullscreen_api/index.html new file mode 100644 index 0000000000..ad21d6d20e --- /dev/null +++ b/files/ru/web/api/fullscreen_api/index.html @@ -0,0 +1,198 @@ +--- +title: Fullscreen API +slug: DOM/Using_fullscreen_mode +translation_of: Web/API/Fullscreen_API +--- +
{{DefaultAPISidebar("Fullscreen API")}}
+ +

The Fullscreen API adds methods to present a specific {{DOMxRef("Element")}} (and its descendants) in full-screen mode, and to exit full-screen mode once it is no longer needed. This makes it possible to present desired content—such as an online game—using the user's entire screen, removing all browser user interface elements and other applications from the screen until full-screen mode is shut off.

+ +

See the article Guide to the Fullscreen API for details on how to use the API.

+ +
+

Note: Support for this API varies somewhat across browsers, with many requiring vendor prefixes and/or not implementing the latest specification. See the {{anch("Browser compatibility")}} section below for details on support for this API. You may wish to consider using a library such as Fscreen for vendor agnostic access to the Fullscreen API.

+
+ +

Interfaces

+ +

The Fullscreen API has no interfaces of its own. Instead, it augments several other interfaces to add the methods, properties, and event handlers needed to provide full-screen functionality. These are listed in the following sections.

+ +

Methods

+ +

The Fullscreen API adds methods to the {{DOMxRef("Document")}} and {{DOMxRef("Element")}} interfaces to allow turning off and on full-screen mode.

+ +

Methods on the Document interface

+ +
+
{{DOMxRef("Document.exitFullscreen()")}}
+
Requests that the {{Glossary("user agent")}} switch from full-screen mode back to windowed mode. Returns a {{jsxref("Promise")}} which is resolved once full-screen mode has been completely shut off.
+
+ +

Methods on the Element interface

+ +
+
{{DOMxRef("Element.requestFullscreen()")}}
+
Asks the user agent to place the specified element (and, by extension, its descendants) into full-screen mode, removing all of the browser's UI elements as well as all other applications from the screen. Returns a {{jsxref("Promise")}} which is resolved once full-screen mode has been activated.
+
+ +

Properties

+ +

The {{DOMxRef("Document")}} interface provides properties that can be used to determine if full-screen mode is supported and available, and if full-screen mode is currently active, which element is using the screen.

+ +
+
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}
+
The fullscreenElement property tells you the {{DOMxRef("Element")}} that's currently being displayed in full-screen mode on the DOM (or shadow DOM). If this is null, the document is not in full-screen mode.
+
{{DOMxRef("Document.fullscreenEnabled")}}
+
The fullscreenEnabled property tells you whether or not it is possible to engage full-screen mode. This is false if full-screen mode is not available for any reason (such as the "fullscreen" feature not being allowed, or full-screen mode not being supported).
+
+ +

Event handlers

+ +

The Fullscreen API defines two events which can be used to detect when full-screen mode is turned on and off, as well as when errors occur during the process of changing between full-screen and windowed modes. Event handlers for these events are available on the {{DOMxRef("Document")}} and {{DOMxRef("Element")}} interfaces.

+ +
+

Note: These event handler properties are not available as HTML content attributes. In other words, you cannot specify event handlers for {{Event("fullscreenchange")}} and {{Event("fullscreenerror")}} in the HTML content. They must be added by JavaScript code.

+
+ +

Event handlers on documents

+ +
+
{{DOMxRef("Document.onfullscreenchange")}}
+
An event handler for the {{Event("fullscreenchange")}} event that's sent to a {{DOMxRef("Document")}} when that document is placed into full-screen mode, or when that document exits full-screen mode. This handler is called only when the entire document is presented in full-screen mode.
+
{{DOMxRef("Document.onfullscreenerror")}}
+
An event handler for the {{Event("fullscreenerror")}} event that gets sent to a {{DOMxRef("Document")}} when an error occurs while trying to enable or disable full-screen mode for the entire document.
+
+ +

Event handlers on elements

+ +
+
{{DOMxRef("Element.onfullscreenchange")}}
+
An event handler which is called when the {{Event("fullscreenchange")}} event is sent to the element, indicating that the element has been placed into, or removed from, full-screen mode.
+
{{DOMxRef("Element.onfullscreenerror")}}
+
An event handler for the {{Event("fullscreenerror")}} event when sent to an element which has encountered an error while transitioning into or out of full-screen mode.
+
+ +

Obsolete properties

+ +
+
{{DOMxRef("Document.fullscreen")}} {{Deprecated_Inline}}
+
A Boolean value which is true if the document has an element currently being displayed in full-screen mode; otherwise, this returns false. +
Note: Use the {{DOMxRef("Document.fullscreenElement", "fullscreenElement")}} property on the {{DOMxRef("Document")}} or {{DOMxRef("ShadowRoot")}} instead; if it's not null, then it's an {{DOMxRef("Element")}} currently being displayed in full-screen mode.
+
+
+ +

Events

+ +

The Fullscreen API defines two events which can be used to detect when full-screen mode is turned on and off, as well as when errors occur during the process of changing between full-screen and windowed modes.

+ +
+
{{Event("fullscreenchange")}}
+
Sent to a {{DOMxRef("Document")}} or {{DOMxRef("Element")}} when it transitions into or out of full-screen mode.
+
{{Event("fullscreenerror")}}
+
Sent to a Document or Element if an error occurs while attempting to switch it into or out of full-screen mode.
+
+ +

Dictionaries

+ +
+
{{DOMxRef("FullscreenOptions")}}
+
Provides optional settings you can specify when calling {{DOMxRef("Element.requestFullscreen", "requestFullscreen()")}}.
+
+ +

Controlling access

+ +

The availability of full-screen mode can be controlled using Feature Policy. The full-screen mode feature is identified by the string "fullscreen", with a default allow-list value of "self", meaning that full-screen mode is permitted in top-level document contexts, as well as to nested browsing contexts loaded from the same origin as the top-most document.

+ +

See Using Feature Policy to learn more about using Feature Policy to control access to an API.

+ +

Usage notes

+ +

Users can choose to exit full-screen mode simply by pressing the ESC (or F11) key, rather than waiting for the site or app to programmatically do so. Make sure you provide, somewhere in your user interface, appropriate user interface elements that inform the user that this option is available to them.

+ +
+

Note: Navigating to another page, changing tabs, or switching to another application using any application switcher (or Alt-Tab) will likewise exit full-screen mode.

+
+ +

Example

+ +

In this example, a video is presented in a web page. Pressing the Return or Enter key lets the user toggle between windowed and full-screen presentation of the video.

+ +

View Live Examples

+ +

Watching for the Enter key

+ +

When the page is loaded, this code is run to set up an event listener to watch for the Enter key.

+ +
document.addEventListener("keypress", function(e) {
+  if (e.keyCode === 13) {
+    toggleFullScreen();
+  }
+}, false);
+
+ +

Toggling full-screen mode

+ +

This code is called by the event handler above when the user hits the Enter key.

+ +
function toggleFullScreen() {
+  if (!document.fullscreenElement) {
+      document.documentElement.requestFullscreen();
+  } else {
+    if (document.exitFullscreen) {
+      document.exitFullscreen();
+    }
+  }
+}
+ +

This starts by looking at the value of the {{DOMxRef("Document", "document")}}'s fullscreenElement attribute. In a real-world deployment, at this time, you'll want to check for prefixed versions of this (mozFullScreenElement, msFullscreenElement, or webkitFullscreenElement, for example). If the value is null, the document is currently in windowed mode, so we need to switch to full-screen mode; otherwise, it's the element that's currently in full-screen mode. Switching to full-screen mode is done by calling {{DOMxRef("Element.requestFullscreen()")}} on the {{HTMLElement("video")}} element.

+ +

If full-screen mode is already active (fullscreenElement is not null), we call {{DOMxRef("Document.exitFullscreen", "exitFullscreen()")}} on the document to shut off full-screen mode.

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}}Initial version.
+ +

Browser compatibility

+ +

Document.fullscreen

+ +
+ + +

{{Compat("api.Document.fullscreen")}}

+
+ +

Document.fullscreenEnabled

+ +
+ + +

{{Compat("api.Document.fullscreenEnabled")}}

+
+ +

See also

+ + diff --git a/files/ru/web/api/geolocation/using_geolocation/index.html b/files/ru/web/api/geolocation/using_geolocation/index.html deleted file mode 100644 index 39847dedc5..0000000000 --- a/files/ru/web/api/geolocation/using_geolocation/index.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Использование геолокации -slug: Web/API/Geolocation/Using_geolocation -tags: - - Geolocation API - - Guide - - Intermediate -translation_of: Web/API/Geolocation_API ---- -
{{securecontext_header}}{{DefaultAPISidebar("Geolocation API")}}
- -

Geolocation API позволяет пользователю предоставлять свое местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.

- -

Концепты и использование

- -

Вы часто хотите получать информацию о местоположении пользователя в своём веб приложении, например, для отображения участка на карте, либо для того, чтобы показывать информацию, основанную на местоположении посетителя.

- -

API геолокации может быть вызвано через {{domxref("Navigator.geolocation")}}; это заставит браузер пользователя вывести уведомление с запросом для доступа к текущему местоположению. Если его одобрят, то браузер сможет даст весь доступный функционал для работы с информацией о местонахождении (например, GPS).

- -

Тогда разработчику станут доступны несколько разных способов получения соответствующей информации:

- - - -

В обоих случая, методы принимают три аргумента:

- - - -

Интерфейсы

- -
-
{{domxref("Geolocation")}}
-
Главный класс этого API — содержит методы для получения текущего местоположения пользователя, наблюдает за его изменениями и удаляет функции-наблюдатели.
-
{{domxref("GeolocationPosition")}}
-
Предоставляет месторасположение пользователя. Экземпляр GeolocationPosition, полученный при успешном вызове одного из методов {{domxref("Geolocation")}}, внутри callback-функции при успехе, содержит метку времени плюс экземпляр объекта {{domxref("GeolocationCoordinates")}}.
-
{{domxref("GeolocationCoordinates")}}
-
Предоставлять координаты пользователя; Экземпляр GeolocationCoordinates содержит широту, долготу и прочую важную подобную информацию.
-
{{domxref("GeolocationPositionError")}}
-
GeolocationPositionError возвращается при неуспешном вызове методов, содержащихся в {{domxref("Geolocation")}}, внутри callback-функции при ошибке, содержит код ошибки и сообщение.
-
{{domxref("Navigator.geolocation")}}
-
Точка входа в API. Возвращает экземпляр объекта {{domxref("Geolocation")}}, из которого становятся доступны все функции и методы.
-
- -

Словари

- -
-
{{domxref("PositionOptions")}}
-
Предоставляет объект, содержащий опции, которые можно передать как параметр в  {{domxref("Geolocation.getCurrentPosition()")}} и {{domxref("Geolocation.watchPosition()")}}.
-
- -

Примеры

- -

{{page("/ru/docs/Web/API/Geolocation_API/Using","Examples")}}

- -

Спецификации

- - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName("Geolocation")}}{{Spec2("Geolocation")}}
- -

Поддержка браузерами

- -

{{Compat("api.Geolocation")}}

- -

Доступность

- -

Так как местоположение, основанное на WiFi, часто предоставляется Google, API местоположения может быть не доступен в Китае. Вы можете использовать местных провайдеров, таких как Baidu, Autonavi или Tencent. Эти сервисы используют IP-адресс пользователя и/или приложение для предоставления наиболее точной позиции.

- -

Смотрите также

- - diff --git a/files/ru/web/api/geolocation/using_geolocation/using_the_geolocation_api/index.html b/files/ru/web/api/geolocation/using_geolocation/using_the_geolocation_api/index.html deleted file mode 100644 index 5fa1055292..0000000000 --- a/files/ru/web/api/geolocation/using_geolocation/using_the_geolocation_api/index.html +++ /dev/null @@ -1,170 +0,0 @@ ---- -title: Использование Geolocation API -slug: Web/API/Geolocation/Using_geolocation/Using_the_Geolocation_API -tags: - - Geolocation API - - Guide - - Tutorial -translation_of: Web/API/Geolocation_API/Using_the_Geolocation_API ---- -
{{securecontext_header}}{{DefaultAPISidebar("Geolocation API")}}
- -

Geolocation API позволяет пользователю предоставлять свое местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.

- -

Объект геолокации

- -

API геолокации доступен через объект {{domxref("navigator.geolocation")}}.

- -

Если объект существует, функции определения местоположения доступны. Вы можете проверить это слеюущим образом:

- -
if ("geolocation" in navigator) {
-  /* местоположение доступно */
-} else {
-  /* местоположение НЕ доступно */
-}
-
- -

Получение текущего местоположения

- -

Чтобы получить текущее местоположение пользователя, вы должны вызвать метод {{domxref("geolocation.getCurrentPosition()","getCurrentPosition()")}}. Это инициирует асихронный запрос для обнаружения местоположения пользователя, и запрашивает аппаратные средства позиционирования, чтобы получить последнюю актуальную информацию. Когда местоположение определено, выполняется callback. По желанию вы можете указать вторую callback функцию для обработки ошибки, которая запустится в случае ошибки. Третий, опциональный параметр - объект с опциями, где вы можете настроить максимальное значение возвращаемых данных, время ожидания ответа на запрос, и, при желании, точность возвращаемых данных.

- -
-

Note: По умолчанию {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}} пытается вернуть результат так быстро, как это возможно, за счёт чего даёт не очень точный результат. Это может быть полезно, если вам нужно быстро получить ответ, при этом не важна точность. Устройства с GPS, например, могут пытаться скорректировать данные GPS около минуты и даже больше, поэтому в самом начале могут вернуться менее точные данные (местоположение IP или wifi-сети), полученные {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}.

-
- -
navigator.geolocation.getCurrentPosition(function(position) {
-  do_something(position.coords.latitude, position.coords.longitude);
-});
- -

Функция do_something(), в примере выше, будет вызвана лишь тогда, когда данные о местоположении будут получены.

- -

Наблюдение за текущим местоположением

- -

Если данные о местоположении меняются (либо устройство находится в движении, либо пришли более точные данные о геопозиции), вы можете указать callback функцию, которая будет вызывается при любом обновлении данных о местоположении. Это делается с использованием функции {{domxref("Geolocation.watchPosition()","watchPosition()")}}, которая имеет несколько входных параметров: {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}. Эта функция вызывается много раз, позволяя браузеру обновлять данные о текущей локации либо во время движения, либо после получения более точной информации о местоположении (после применения более точных приемов). Функция, которая вызывается при ошибке, для {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}, при желании, может быть вызвана неоднократно.

- -
-

Примечание: Вы можете использовать {{domxref("Geolocation.watchPosition()","watchPosition()")}} без вызова {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}.

-
- -
var watchID = navigator.geolocation.watchPosition(function(position) {
-  do_something(position.coords.latitude, position.coords.longitude);
-});
- -

Метод {{domxref("Geolocation.watchPosition()","watchPosition()")}} возвращает числовой ID, который может быть использован для идентификации наблюдателя за местоположением; используйте его вместе с методом {{domxref("Geolocation.clearWatch()","clearWatch()")}}, чтобы перестать получать новые данные о местоположении.

- -
navigator.geolocation.clearWatch(watchID);
-
- -

Точная настройка отклика

- -

{{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}} и {{domxref("Geolocation.watchPosition()","watchPosition()")}} принимают callback-функцию при успехе, необязательную callback-функцию при ошибке и необязательный объект PositionOptions.

- -

Этот объект позволяет вам включить возможность определения позиции с высокой точностью, указать максимальное время кэширования значения позиции (при повторных запросах, пока время не вышло, вам будет возвращается кэшированное значение; после браузер будет запрашивать актуальные данные), а также указать значение, устанавливающее интервал — как часто браузер должен пытаться получить данные о местоположении, прежде чем выйдет время.

- -

Вызов {{domxref("Geolocation.watchPosition()","watchPosition")}} может выглядит следующим образом:

- -
function geo_success(position) {
-  do_something(position.coords.latitude, position.coords.longitude);
-}
-
-function geo_error() {
-  alert("Извините, нет доступной позиции.");
-}
-
-var geo_options = {
-  enableHighAccuracy: true,
-  maximumAge        : 30000,
-  timeout           : 27000
-};
-
-var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, geo_options);
- -

Описание позиции

- -

Местоположение пользователя содержится в экземпляре объекта {{domxref("GeolocationPosition")}}, содержащего внутри экземпляр другого объекта — {{domxref("GeolocationCoordinates")}}.

- -

Экземпляр GeolocationPosition содержит только две вещи, свойство coords, внутри которого GeolocationCoordinates и свойство timestamp, внутри которого экземпляр {{domxref("DOMTimeStamp")}}, предоставляющее метку времени, созданную при получении данные.

- -

Экземпляр GeolocationCoordinates содержит некоторое количество свойств, двое из которых вы будете чаще всего использовать: latitude и longitude, которые помогут вам отобразить полученную позицию на карте. Поэтому многие callback-функции с успешным получением позиции выглядят очень просто:

- -
function success(position) {
-  const latitude  = position.coords.latitude;
-  const longitude = position.coords.longitude;
-
-  // Дальше код, который что-то делает с широтой(latitude) и долготой(longitude)
-}
- -

Однако, вы также можете получить и другую информацию из объекта GeolocationCoordinates, такую как высота над уровнем моря, скорость, направление устройства и точные данные о высоте, долготе и широте.

- -

Обработка ошибок

- -

Callback-функция для ошибок, если она была передана в getCurrentPosition() или watchPosition(), ожидает экземпляр объекта GeolocationPositionError в качестве первого аргумента. Он будет содержать два свойства, code, который укажет на то, какая именно ошибка произошла и понятное для человека message, описывающее значение поля code.

- -

Функция может выглядеть примерно так:

- -
function errorCallback(error) {
-  alert('ERROR(' + error.code + '): ' + error.message);
-};
-
- -

Примеры

- -

Следующий пример использует Geolocation API для того, чтобы получить широту и долготу пользователя. При успешном выполнении, ссылка будет вести на openstreetmap.org, который отобразит пользовательскую позицию на карте.

- - - -

HTML

- -
<button id = "find-me">Show my location</button><br/>
-<p id = "status"></p>
-<a id = "map-link" target="_blank"></a>
-
- -

JavaScript

- -
function geoFindMe() {
-
-  const status = document.querySelector('#status');
-  const mapLink = document.querySelector('#map-link');
-
-  mapLink.href = '';
-  mapLink.textContent = '';
-
-  function success(position) {
-    const latitude  = position.coords.latitude;
-    const longitude = position.coords.longitude;
-
-    status.textContent = '';
-    mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
-    mapLink.textContent = `Широта: ${latitude} °, Долгота: ${longitude} °`;
-  }
-
-  function error() {
-    status.textContent = 'Невозможно получить ваше местоположение';
-  }
-
-  if (!navigator.geolocation) {
-    status.textContent = 'Geolocation не поддерживается вашим браузером';
-  } else {
-    status.textContent = 'Определение местоположения…';
-    navigator.geolocation.getCurrentPosition(success, error);
-  }
-
-}
-
-document.querySelector('#find-me').addEventListener('click', geoFindMe);
-
- -

Демо

- -

{{EmbedLiveSample('Examples', 350, 150, "", "", "", "geolocation")}}

diff --git a/files/ru/web/api/geolocation_api/index.html b/files/ru/web/api/geolocation_api/index.html new file mode 100644 index 0000000000..39847dedc5 --- /dev/null +++ b/files/ru/web/api/geolocation_api/index.html @@ -0,0 +1,91 @@ +--- +title: Использование геолокации +slug: Web/API/Geolocation/Using_geolocation +tags: + - Geolocation API + - Guide + - Intermediate +translation_of: Web/API/Geolocation_API +--- +
{{securecontext_header}}{{DefaultAPISidebar("Geolocation API")}}
+ +

Geolocation API позволяет пользователю предоставлять свое местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.

+ +

Концепты и использование

+ +

Вы часто хотите получать информацию о местоположении пользователя в своём веб приложении, например, для отображения участка на карте, либо для того, чтобы показывать информацию, основанную на местоположении посетителя.

+ +

API геолокации может быть вызвано через {{domxref("Navigator.geolocation")}}; это заставит браузер пользователя вывести уведомление с запросом для доступа к текущему местоположению. Если его одобрят, то браузер сможет даст весь доступный функционал для работы с информацией о местонахождении (например, GPS).

+ +

Тогда разработчику станут доступны несколько разных способов получения соответствующей информации:

+ + + +

В обоих случая, методы принимают три аргумента:

+ + + +

Интерфейсы

+ +
+
{{domxref("Geolocation")}}
+
Главный класс этого API — содержит методы для получения текущего местоположения пользователя, наблюдает за его изменениями и удаляет функции-наблюдатели.
+
{{domxref("GeolocationPosition")}}
+
Предоставляет месторасположение пользователя. Экземпляр GeolocationPosition, полученный при успешном вызове одного из методов {{domxref("Geolocation")}}, внутри callback-функции при успехе, содержит метку времени плюс экземпляр объекта {{domxref("GeolocationCoordinates")}}.
+
{{domxref("GeolocationCoordinates")}}
+
Предоставлять координаты пользователя; Экземпляр GeolocationCoordinates содержит широту, долготу и прочую важную подобную информацию.
+
{{domxref("GeolocationPositionError")}}
+
GeolocationPositionError возвращается при неуспешном вызове методов, содержащихся в {{domxref("Geolocation")}}, внутри callback-функции при ошибке, содержит код ошибки и сообщение.
+
{{domxref("Navigator.geolocation")}}
+
Точка входа в API. Возвращает экземпляр объекта {{domxref("Geolocation")}}, из которого становятся доступны все функции и методы.
+
+ +

Словари

+ +
+
{{domxref("PositionOptions")}}
+
Предоставляет объект, содержащий опции, которые можно передать как параметр в  {{domxref("Geolocation.getCurrentPosition()")}} и {{domxref("Geolocation.watchPosition()")}}.
+
+ +

Примеры

+ +

{{page("/ru/docs/Web/API/Geolocation_API/Using","Examples")}}

+ +

Спецификации

+ + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName("Geolocation")}}{{Spec2("Geolocation")}}
+ +

Поддержка браузерами

+ +

{{Compat("api.Geolocation")}}

+ +

Доступность

+ +

Так как местоположение, основанное на WiFi, часто предоставляется Google, API местоположения может быть не доступен в Китае. Вы можете использовать местных провайдеров, таких как Baidu, Autonavi или Tencent. Эти сервисы используют IP-адресс пользователя и/или приложение для предоставления наиболее точной позиции.

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/geolocation_api/using_the_geolocation_api/index.html b/files/ru/web/api/geolocation_api/using_the_geolocation_api/index.html new file mode 100644 index 0000000000..5fa1055292 --- /dev/null +++ b/files/ru/web/api/geolocation_api/using_the_geolocation_api/index.html @@ -0,0 +1,170 @@ +--- +title: Использование Geolocation API +slug: Web/API/Geolocation/Using_geolocation/Using_the_Geolocation_API +tags: + - Geolocation API + - Guide + - Tutorial +translation_of: Web/API/Geolocation_API/Using_the_Geolocation_API +--- +
{{securecontext_header}}{{DefaultAPISidebar("Geolocation API")}}
+ +

Geolocation API позволяет пользователю предоставлять свое местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.

+ +

Объект геолокации

+ +

API геолокации доступен через объект {{domxref("navigator.geolocation")}}.

+ +

Если объект существует, функции определения местоположения доступны. Вы можете проверить это слеюущим образом:

+ +
if ("geolocation" in navigator) {
+  /* местоположение доступно */
+} else {
+  /* местоположение НЕ доступно */
+}
+
+ +

Получение текущего местоположения

+ +

Чтобы получить текущее местоположение пользователя, вы должны вызвать метод {{domxref("geolocation.getCurrentPosition()","getCurrentPosition()")}}. Это инициирует асихронный запрос для обнаружения местоположения пользователя, и запрашивает аппаратные средства позиционирования, чтобы получить последнюю актуальную информацию. Когда местоположение определено, выполняется callback. По желанию вы можете указать вторую callback функцию для обработки ошибки, которая запустится в случае ошибки. Третий, опциональный параметр - объект с опциями, где вы можете настроить максимальное значение возвращаемых данных, время ожидания ответа на запрос, и, при желании, точность возвращаемых данных.

+ +
+

Note: По умолчанию {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}} пытается вернуть результат так быстро, как это возможно, за счёт чего даёт не очень точный результат. Это может быть полезно, если вам нужно быстро получить ответ, при этом не важна точность. Устройства с GPS, например, могут пытаться скорректировать данные GPS около минуты и даже больше, поэтому в самом начале могут вернуться менее точные данные (местоположение IP или wifi-сети), полученные {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}.

+
+ +
navigator.geolocation.getCurrentPosition(function(position) {
+  do_something(position.coords.latitude, position.coords.longitude);
+});
+ +

Функция do_something(), в примере выше, будет вызвана лишь тогда, когда данные о местоположении будут получены.

+ +

Наблюдение за текущим местоположением

+ +

Если данные о местоположении меняются (либо устройство находится в движении, либо пришли более точные данные о геопозиции), вы можете указать callback функцию, которая будет вызывается при любом обновлении данных о местоположении. Это делается с использованием функции {{domxref("Geolocation.watchPosition()","watchPosition()")}}, которая имеет несколько входных параметров: {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}. Эта функция вызывается много раз, позволяя браузеру обновлять данные о текущей локации либо во время движения, либо после получения более точной информации о местоположении (после применения более точных приемов). Функция, которая вызывается при ошибке, для {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}, при желании, может быть вызвана неоднократно.

+ +
+

Примечание: Вы можете использовать {{domxref("Geolocation.watchPosition()","watchPosition()")}} без вызова {{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}}.

+
+ +
var watchID = navigator.geolocation.watchPosition(function(position) {
+  do_something(position.coords.latitude, position.coords.longitude);
+});
+ +

Метод {{domxref("Geolocation.watchPosition()","watchPosition()")}} возвращает числовой ID, который может быть использован для идентификации наблюдателя за местоположением; используйте его вместе с методом {{domxref("Geolocation.clearWatch()","clearWatch()")}}, чтобы перестать получать новые данные о местоположении.

+ +
navigator.geolocation.clearWatch(watchID);
+
+ +

Точная настройка отклика

+ +

{{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}} и {{domxref("Geolocation.watchPosition()","watchPosition()")}} принимают callback-функцию при успехе, необязательную callback-функцию при ошибке и необязательный объект PositionOptions.

+ +

Этот объект позволяет вам включить возможность определения позиции с высокой точностью, указать максимальное время кэширования значения позиции (при повторных запросах, пока время не вышло, вам будет возвращается кэшированное значение; после браузер будет запрашивать актуальные данные), а также указать значение, устанавливающее интервал — как часто браузер должен пытаться получить данные о местоположении, прежде чем выйдет время.

+ +

Вызов {{domxref("Geolocation.watchPosition()","watchPosition")}} может выглядит следующим образом:

+ +
function geo_success(position) {
+  do_something(position.coords.latitude, position.coords.longitude);
+}
+
+function geo_error() {
+  alert("Извините, нет доступной позиции.");
+}
+
+var geo_options = {
+  enableHighAccuracy: true,
+  maximumAge        : 30000,
+  timeout           : 27000
+};
+
+var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, geo_options);
+ +

Описание позиции

+ +

Местоположение пользователя содержится в экземпляре объекта {{domxref("GeolocationPosition")}}, содержащего внутри экземпляр другого объекта — {{domxref("GeolocationCoordinates")}}.

+ +

Экземпляр GeolocationPosition содержит только две вещи, свойство coords, внутри которого GeolocationCoordinates и свойство timestamp, внутри которого экземпляр {{domxref("DOMTimeStamp")}}, предоставляющее метку времени, созданную при получении данные.

+ +

Экземпляр GeolocationCoordinates содержит некоторое количество свойств, двое из которых вы будете чаще всего использовать: latitude и longitude, которые помогут вам отобразить полученную позицию на карте. Поэтому многие callback-функции с успешным получением позиции выглядят очень просто:

+ +
function success(position) {
+  const latitude  = position.coords.latitude;
+  const longitude = position.coords.longitude;
+
+  // Дальше код, который что-то делает с широтой(latitude) и долготой(longitude)
+}
+ +

Однако, вы также можете получить и другую информацию из объекта GeolocationCoordinates, такую как высота над уровнем моря, скорость, направление устройства и точные данные о высоте, долготе и широте.

+ +

Обработка ошибок

+ +

Callback-функция для ошибок, если она была передана в getCurrentPosition() или watchPosition(), ожидает экземпляр объекта GeolocationPositionError в качестве первого аргумента. Он будет содержать два свойства, code, который укажет на то, какая именно ошибка произошла и понятное для человека message, описывающее значение поля code.

+ +

Функция может выглядеть примерно так:

+ +
function errorCallback(error) {
+  alert('ERROR(' + error.code + '): ' + error.message);
+};
+
+ +

Примеры

+ +

Следующий пример использует Geolocation API для того, чтобы получить широту и долготу пользователя. При успешном выполнении, ссылка будет вести на openstreetmap.org, который отобразит пользовательскую позицию на карте.

+ + + +

HTML

+ +
<button id = "find-me">Show my location</button><br/>
+<p id = "status"></p>
+<a id = "map-link" target="_blank"></a>
+
+ +

JavaScript

+ +
function geoFindMe() {
+
+  const status = document.querySelector('#status');
+  const mapLink = document.querySelector('#map-link');
+
+  mapLink.href = '';
+  mapLink.textContent = '';
+
+  function success(position) {
+    const latitude  = position.coords.latitude;
+    const longitude = position.coords.longitude;
+
+    status.textContent = '';
+    mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
+    mapLink.textContent = `Широта: ${latitude} °, Долгота: ${longitude} °`;
+  }
+
+  function error() {
+    status.textContent = 'Невозможно получить ваше местоположение';
+  }
+
+  if (!navigator.geolocation) {
+    status.textContent = 'Geolocation не поддерживается вашим браузером';
+  } else {
+    status.textContent = 'Определение местоположения…';
+    navigator.geolocation.getCurrentPosition(success, error);
+  }
+
+}
+
+document.querySelector('#find-me').addEventListener('click', geoFindMe);
+
+ +

Демо

+ +

{{EmbedLiveSample('Examples', 350, 150, "", "", "", "geolocation")}}

diff --git a/files/ru/web/api/html_drag_and_drop_api/drag_operations/index.html b/files/ru/web/api/html_drag_and_drop_api/drag_operations/index.html new file mode 100644 index 0000000000..2dcdb6babb --- /dev/null +++ b/files/ru/web/api/html_drag_and_drop_api/drag_operations/index.html @@ -0,0 +1,314 @@ +--- +title: Drag Operations +slug: Web/Guide/HTML/Drag_and_drop/Drag_operations +translation_of: Web/API/HTML_Drag_and_Drop_API/Drag_operations +--- +

{{DefaultAPISidebar("HTML Drag and Drop API")}}

+ +

Ниже описаны шаги, которые происходят при drag and drop операции.

+ +

Drag операции описываются в документе, используя {{domxref("DataTransfer")}} интерфейс. Этот документ не использует не{{domxref("DataTransferItem")}} интерфейс, не{{domxref("DataTransferItemList")}} интерфейс.

+ +

draggable атрибуты

+ +

На веб-странице, в некоторых случаях используется поведение drag (перетаскивания) по умолчанию. Включая выделенный текст, изображения и ссылки. Когда изображение иои ссылка переносятся, URL изображения или ссылки устанавливается в качестве данных drag и перетаскивание начинается. Для других элементов, они должны быть частью выделения для выполнения перетаскивания по умолчанию. Чтобы увидеть это в действии, выделите область веб-страницы, а затем нажмите и удерживайте кнопку мыши и перетащите выделение. Появится специфичный для ОС рендеринг выделенного фрагмента и будет следовать за указателем мыши при перетаскивании. Однако это поведение является только drag поведением по умолчанию, если нет слушателей, определяющих данные для перетаскивания.

+ +

В HTML, кроме поведения по умолчанию изображений, ссылок и выделенных областей, ноикакие другие элементы по умолчанию не переносятся.

+ +

Для перетаскивания других HTML-элементов, должны быть выполнены три пункта :

+ +
    +
  1. Установить {{htmlattrxref("draggable")}}="true" на элемент, который вы хотите сделать перетаскиваемым.
  2. +
  3. Добавить слушатель события {{event("dragstart")}}.
  4. +
  5. Установить данные перетаскивания в слушатель выше.
  6. +
+ +

Вот пример, который позволяет перетаскивать часть содержимого.

+ +
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
+  This text <strong>may</strong> be dragged.
+</p>
+
+ +

Атрибут {{htmlattrxref("draggable")}} установлен в  "true", т.о. этот элемент становится перетаскиваемым. Если этот атрибут был опущен или установлен в "false", то элемент не может быть перенесен, и вместо этого будет выбран текст.

+ +

Атрибут {{htmlattrxref("draggable")}} может быть использован для любого элемента, включаяизображения и ссылки. Однако, для последних двух, значение по умолчанию - true, т.о. вы можете только использвать атрибут  {{htmlattrxref("draggable")}} со значением false для отключение перетаскивания этих элементов.

+ +
+

Примечание: Когда элемент становится перетаскиваемыми, tтекст или другие элементы в нем больше не могут быть выбраны обычным способом, щелкая и перетаскивая мышью. Вместо этого пользователь должен удерживать клавишу Alt  чтобы выбрать текст с помощью мыши или клавиатуры.

+
+ +

Начало операции перетаскивания

+ +

В примере, слушатель добавлен для события {{event("dragstart")}} с использованием атрибута{{domxref("GlobalEventHandlers.ondragstart","ondragstart")}}.

+ +
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
+  This text <strong>may</strong> be dragged.
+</p>
+
+ +

Когда пользователь начинает перетаскивание, запускается событиеdrag, the {{event("dragstart")}}.

+ +

В этом примере слушатель {{event("dragstart")}} добавлен к самому перемещаемом элементу. Однако, вы можете слушать более высокого предка, так как событие перетаскивание высплывает вверх как и большинство событий.

+ +

Внутри события {{event("dragstart")}}, вы можете указать drag данные, изображжение отклика, drag-эффекты, все это описано ниже. Однако, обязательны только drag данные. (Изображение и drag-эффекты по умолчанию, подходят в большинстве ситуаций)

+ +

Drag-данные

+ +

Все {{domxref("DragEvent","drag events")}} имеют свойство, называемое{{domxref("DragEvent.dataTransfer","dataTransfer")}}, которое содержит drag-данные (dataTransfer это {{domxref("DataTransfer")}} object).

+ +

Когда происходит перетаскивание, данные должны быть связаны с перетаскиванием, которое определяет, что перетаскивается. Например, при перетаскивании выделенного текста в текстовое поле данные, связанные с элементом данных перетаскивания, являются самим текстом. Аналогично, при перетаскивании ссылки на веб-странице элемент данных перетаскивания является URL-адресом ссылки.

+ +

{{domxref("DataTransfer","drag data")}} содержит два параметра, тип (или формат) данных, и значение данных. Формат это строковый тип (такой как text/plain текстовых данных), значение - строка текста. Когда начинается перетаскивание, вы добавляете данные, предоставляя тип и данные. Во время перетаскивания в слушателе события для событий {{event("dragenter")}} и {{event("dragover")}} , вы используете типы данных перетаскиваемых данных, чтобы проверить, разрешено ли удаление. Например, цель drop, которая принимает ссылки, будет проверять тип text/uri-list. В течение события drop, слушатель будет получать данные тащат и вставить его на место.

+ +

Свойство {{domxref("DataTransfer","drag data's")}} {{domxref("DataTransfer.types","types")}} возвращает список MIME-типов {{domxref("DOMString")}}, таких как text/plain или image/jpeg. Вы также можете создавать свои собственные типы. Большинство основные используемых типов описаны в  Recommended Drag Types.

+ +

Перетаскивание может включать элементы данных нескольких различных типов. Это позволяет предоставлять данные в более специфических типах, часто пользовательских, но по предоставляет резервные данные для drop, которые не поддерживают более специфические типы. Как правило, наименее специфичным типом будут обычные текстовые данные, использующие тип text/plain. Эти данные будут простым текстовым представлением.

+ +

Установка элементов drag-данных {{domxref("DragEvent.dataTransfer","dataTransfer")}}, используя метод {{domxref("DataTransfer.setData","setData()")}}. Требуется два аргумента: тип данных и значение данных. Например:

+ +
event.dataTransfer.setData("text/plain", "Text to drag");
+
+ +

Здесь, значение -  "Text to drag", формат -  text/plain.

+ +

Вы можете предусмотреть данные в нескольких форматах. Сделаем это, вызовем метод  {{domxref("DataTransfer.setData","setData()")}} несколько раз с различными форматами. Вы должны вызывать его с форматами от большей специфичности к меньшей.

+ +
const dt = event.dataTransfer;
+dt.setData("application/x.bookmark", bookmarkString);
+dt.setData("text/uri-list", "https://www.mozilla.org");
+dt.setData("text/plain", "https://www.mozilla.org");
+
+ +

Добавлены данные трех различных форматов. Первый тип - application/x.bookmark, пользовательский тип.Другие приложения не поддерживают данный тип, но вы можете использовать пользовательский тип для перетаскивания между областями в одном приложениее или на одной странице.

+ +

Предоставляя данные и в других типах, мы также можем поддерживать перетаскивание в другие приложения в менее специфичных формах. Тип application/x.bookmark может предоставлять данные с  более подробной информацией для использования в приложении, в то время как другие типы могут включать только один URL-адрес или текстовую версию.

+ +

Обратите внимание, что и text/uri-list и text/plain cодержат одни и те же данные в этом примере.  Это часто бывает так, но это не обязательно.

+ +

Если вы попытаетесь добавить данные дважды с тем же форматом, новые данные заменят старые данные, но в той же позиции в списке типов, что и старые данные.

+ +

Вы можете очистить данные, используя метод {{domxref("DataTransfer.clearData","clearData()")}}, который принимает один аргумент: тип данных для удаления.

+ +
event.dataTransfer.clearData("text/uri-list");
+
+ +

Аргумент type в методе {{domxref("DataTransfer.clearData","clearData()")}} опционален. Если type не указан, данные, связанные со всеми типами, удаляются. Если перетаскивание не содержит элементов данных перетаскивания или все элементы были впоследствии очищены, то перетаскивание не произойдет.

+ +

Настройка изображения отклика drag

+ +

Когда происходит перетаскивание, полупрозрачное изображение генерируется из цели перетаскивания (событие "{{event("dragstart")}}" элемента срабатывает), и следует за указателем пользователя во время перетаскивания. Это изображение создается автоматически, поэтому вам не нужно создавать его самостоятельно. Однако вы можете использовать {{domxref("DataTransfer.setDragImage","setDragImage()")}} для задания пользовательского изображения отклика перетаскивания.

+ +
event.dataTransfer.setDragImage(image, xOffset, yOffset);
+
+ +

Необходимы три аргумента. Первый - это ссылка на изображение. Эта ссылка обычно относится к элементу <img>, но также может относиться к элементу <canvas> или любому другому элементу. Изображение отклика будет генерироваться из того, как изображение выглядит на экране, для изображений они будут нарисованы в их первоначальном размере. Второй и третий аргументы метода {{domxref("DataTransfer.setDragImage","setDragImage()")}} - это смещения, в которых изображение должно появляться относительно указателя мыши.

+ +

Также можно использовать изображения и canvas, которых нет в документе. Этот метод полезен при рисовании пользовательских изображений перетаскивания с помощью элемента canvas, как показано в следующем примере:

+ +
function dragWithCustomImage(event) {
+  const canvas = document.createElement("canvas");
+  canvas.width = canvas.height = 50;
+
+  const ctx = canvas.getContext("2d");
+  ctx.lineWidth = 4;
+  ctx.moveTo(0, 0);
+  ctx.lineTo(50, 50);
+  ctx.moveTo(0, 50);
+  ctx.lineTo(50, 0);
+  ctx.stroke();
+
+  const dt = event.dataTransfer;
+  dt.setData('text/plain', 'Data to Drag');
+  dt.setDragImage(canvas, 25, 25);
+}
+
+ +

В этом примере мы делаем один canvas перетаскивания. Поскольку размер холста составляет 50×50 пикселей, мы используем смещение половины этого (25), чтобы изображение было центрировано на указателе мыши.

+ +

Drag эффекты

+ +

При перетаскивании можно выполнить несколько операций. Операция  copy используется для указания на то, что перетаскиваемые данные будут скопированы из текущего местоположения в место перетаскивания. Операция move используется для указания на то, что перетаскиваемые данные будут перемещены, а операция link используется для указания на то, что между исходным и удаляемым местоположениями будет создана некоторая форма связи или соединения.

+ +

Вы можете указать, какая из трех операций разрешена для источника перетаскивания, установив свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}} в слушателе событий{{event("dragstart")}}.

+ +
event.dataTransfer.effectAllowed = "copy";
+
+ +

В этом примере разрешена только копия.

+ +

Вы можете комбинировать значения различными способами:

+ +
+
none
+
никакая операция не разрешена
+
copy
+
только copy
+
move
+
только move
+
link
+
только link
+
copyMove
+
только copy или move
+
copyLink
+
только copy или link
+
linkMove
+
только link или move
+
all
+
только copy, move, или link
+
uninitialized
+
Значение по умолчанию all.
+
+ +

Обратите внимание, что эти значения должны использоваться так, как указано выше. Например, установка свойства {{domxref("DataTransfer.effectAllowed","effectAllowed")}} на copyMove позволяет выполнять операцию копирования или перемещения, но не позволяет пользователю выполнять операцию связывания. Если вы не измените свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}},  то любая операция разрешена, как и со значением 'all'. Поэтому вам не нужно настраивать это свойство, если вы не хотите исключить определенные типы.

+ +

Во время операции перетаскивания, слушатель для событий {{event("dragenter")}} или {{event("dragover")}} может проверить свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}} , какие операции разрешены. Связанное свойство,  {{domxref("DataTransfer.dropEffect","dropEffect")}}, должно быть установлено в пределах одного из этих событий, чтобы указать, какая единственная операция должна быть выполнена. Допустимые значения для {{domxref("DataTransfer.dropEffect","dropEffect")}} - none, copy, move, или link. Комбинированные значения для этого свойства не используются.

+ +

С событиями {{event("dragenter")}} и {{event("dragover")}}, свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} инициализируется в соответствии с запросом пользователя. Пользователь может изменить желаемый эффект, нажав клавиши-модификаторы. Хотя точные используемые клавиши различаются в зависимости от платформы, обычно клавиши  Shift и Control используются для переключения между копированием, перемещением и связыванием. Указатель мыши изменится, чтобы указать, какая операция требуется. Например, для copy курсор может появиться со знаком плюс рядом с ним.

+ +

Вы можете изменять свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} во время событий {{event("dragenter")}} или {{event("dragover")}}, например, определенная drop-цель поддерживает только определенные операции. Вы можете изменить свойство {{domxref("DataTransfer.dropEffect","dropEffect")}}, чтобы переопределить действие пользователя, и обеспечить выполнение специфичной  операции перетаскивания при ее наступлении. Обратите внимание, что этот эффект должен быть указан в списке свойств {{domxref("DataTransfer.effectAllowed","effectAllowed")}}. В противном случае ему будет присвоено другое допустимое значение.

+ +
event.dataTransfer.dropEffect = "copy";
+
+ +

В этом примере выполняется эффект копирования.

+ +

Вы можете использовать значение none, чтобы указать, что в этом месте не допускается удаление, хотя в этом случае лучше не отменять событие.

+ +

В событиях {{event("drop")}} и {{event("dragend")}}, yвы можете проверить свойства {{domxref("DataTransfer.dropEffect","dropEffect")}} для определения того, какой эффект был в конечном итоге выбран.  Если выбран эффект "move",то исходные данные должны быть удалены из источника перетаскивания в событии{{event("dragend")}}.

+ +

Указание drop-целей

+ +

Слушатель для событий {{event("dragenter")}} и {{event("dragover")}} используются для указания допустимых drop-целей, то есть мест, где могут быть сброшены перетаскиваемые элементы. Большинство областей веб-страницы или приложения не являются допустимыми местами для сброса данных. Таким образом, обработка этих событий по умолчанию не допускает сброса перетаскиваемых данных.

+ +

Если вы хотите разрешить сброс переносимых данных, вы должны предотвратить обработку по умолчанию, отменив оба события dragenter и dragover.  Это можно сделать, либо вернув false из определенных атрибутом слушателя событий, либо вызвав метод {{domxref("Event.preventDefault","preventDefault()")}} событие. Последнее может быть более осуществимо в функции, определенной в отдельном скрипте.

+ +
<div ondragover="return false">
+<div ondragover="event.preventDefault()">
+
+ +

Вызывая метод {{domxref("Event.preventDefault","preventDefault()")}} во время обоих событий {{event("dragenter")}} и {{event("dragover")}} укажите, что падение разрешено в этом месте. Однако обычно вы захотите вызвать метод  {{domxref("Event.preventDefault","preventDefault()")}} события только в определенных ситуациях (например, только при перетаскивании ссылки).

+ +

Для этого вызовите функцию, которая проверяет условие и отменяет событие только при его выполнении. Если условие не выполнено, не отменяйте событие, и сброс перетаскиваемых данных не произойдет, если пользователь отпустит кнопку мыши.

+ +

Наиболее распространенным является принятие или отклонение сброса в зависимости от типа данных перетаскивания при передаче данных — например, разрешение для изображений, ссылок или и того, и другого. Для этого вы можете проверить свойство {{domxref("DataTransfer.types","types")}} события {{domxref("DragEvent.dataTransfer","dataTransfer")}} (свойство). Свойство {{domxref("DataTransfer.types","types")}} возвращает массив из строк, добавленных при начале перетаскивания, в порядке от наиболее значимого к наименее значимому.

+ +
function doDragOver(event) {
+  const isLink = event.dataTransfer.types.includes("text/uri-list");
+  if (isLink) {
+    event.preventDefault();
+  }
+}
+ +

В этом примере мы используем метод includes  чтобы проверить, присутствует ли тип text/uri-list в списке типов. Если это так, мы отменим событие, так что сброс становится разрешен. Если перетаскиваемые данные не содержат ссылки, событие не будет отменено, и сброс не может произойти в этом месте.

+ +

Вы также можете установить либо свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}}, либо свойство{{domxref("DataTransfer.dropEffect","dropEffect")}}, либо оба одновременно, если вы хотите указать более конкретные сведения о типе операции, которая будет выполнена. Естественно, изменение любого свойства не будет иметь никакого эффекта, если вы не отмените событие.

+ +

Drop Feedback

+ +

There are several ways in which you can indicate to the user that a drop is allowed at a certain location. The mouse pointer will update as necessary depending on the value of the {{domxref("DataTransfer.dropEffect","dropEffect")}} property.

+ +

Although the exact appearance depends on the user's platform, typically a plus sign icon will appear for a 'copy' for example, and a 'cannot drop here' icon will appear when a drop is not allowed. This mouse pointer feedback is sufficient in many cases.

+ +

However, you can also update the user interface with an insertion point or highlight as needed. For simple highlighting, you can use the :-moz-drag-over CSS pseudoclass on a drop target.

+ +
.droparea:-moz-drag-over {
+  outline: 1px solid black;
+}
+
+ +

In this example, the element with the class droparea will receive a 1 pixel black outline while it is a valid drop target, that is, if the {{domxref("Event.preventDefault","preventDefault()")}} method was called during the {{event("dragenter")}} event.

+ +
+

Note: You must cancel the {{event("dragenter")}} event for this pseudoclass to apply, as this state is not checked for the {{event("dragover")}} event.

+
+ +

For more complex visual effects, you can also perform other operations during the {{event("dragenter")}} event. For example, by inserting an element at the location where the drop will occur. This might be an insertion marker, or an element that represents the dragged element in its new location. To do this, you could create an image or separator element and simply insert it into the document during the {{event("dragenter")}} event.

+ +

The {{event("dragover")}} event will fire at the element the mouse is pointing at. Naturally, you may need to move the insertion marker around a {{event("dragover")}} event as well. You can use the event's {{domxref("MouseEvent.clientX","clientX")}} and {{domxref("MouseEvent.clientY","clientY")}} properties as with other mouse events to determine the location of the mouse pointer.

+ +

Finally, the {{event("dragleave")}} event will fire at an element when the drag leaves the element. This is the time when you should remove any insertion markers or highlighting. You do not need to cancel this event. Any highlighting or other visual effects specified using the :-moz-drag-over pseudoclass will be removed automatically. The {{event("dragleave")}} event will always fire, even if the drag is cancelled, so you can always ensure that any insertion point cleanup can be done during this event.

+ +

Performing a Drop

+ +

When the user releases the mouse, the drag and drop operation ends.

+ +

If the mouse is released over an element that is a valid drop target, that is, one that cancelled the last {{event("dragenter")}} or {{event("dragover")}} event, then the drop will be successful, and a {{event("drop")}} event will fire at the target. Otherwise, the drag operation is cancelled, and no {{event("drop")}} event is fired.

+ +

During the {{event("drop")}} event, you should retrieve that data that was dropped from the event and insert it at the drop location. You can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine which drag operation was desired.

+ +

As with all drag-related events, the event's {{domxref("DataTransfer","dataTransfer")}} property will hold the data that is being dragged. The {{domxref("DataTransfer.getData","getData()")}} method may be used to retrieve the data again.

+ +
function onDrop(event) {
+  const data = event.dataTransfer.getData("text/plain");
+  event.target.textContent = data;
+  event.preventDefault();
+}
+
+ +

The {{domxref("DataTransfer.getData","getData()")}} method takes one argument, the type of data to retrieve. It will return the string value that was set when {{domxref("DataTransfer.setData","setData()")}} was called at the beginning of the drag operation. An empty string will be returned if data of that type does not exist. (Naturally, though, you would likely know that the right type of data was available, as it was previously checked during a {{event("dragover")}} event.)

+ +

In the example here, once the data has been retrieved, we insert the string as the textual content of the target. This has the effect of inserting the dragged text where it was dropped, assuming that the drop target is an area of text such as a p or div element.

+ +

In a web page, you should call the {{domxref("Event.preventDefault","preventDefault()")}} method of the event if you have accepted the drop, so that the browser's default handling is not triggered by the dropped data as well. For example, when a link is dragged to a web page, Firefox will open the link. By cancelling the event, this behavior will be prevented.

+ +

You can retrieve other types of data as well. If the data is a link, it should have the type text/uri-list. You could then insert a link into the content.

+ +
function doDrop(event) {
+  const lines = event.dataTransfer.getData("text/uri-list").split("\n");
+  lines.filter(line => !line.startsWith("#"))
+    .forEach(line => {
+      const link = document.createElement("a");
+      link.href = line;
+      link.textContent = line;
+      event.target.appendChild(link);
+    })
+  event.preventDefault();
+}
+
+ +

This example inserts a link from the dragged data. As the name implies, the text/uri-list type actually may contain a list of URLs, each on a separate line. The above code uses split to break the string into lines, then iterates over the list of lines, and inserts each as a link into the document. (Note also that links starting with a number sign (#) are skipped, as these are comments.)

+ +

For simple cases, you can use the special type URL just to retrieve the first valid URL in the list. For example:

+ +
const link = event.dataTransfer.getData("URL");
+
+ +

This eliminates the need to check for comments or iterate through lines yourself. However, it is limited to only the first URL in the list.

+ +

The URL type is a special type. It is used only as a shorthand, and it does not appear within the list of types specified in the {{domxref("DataTransfer.types","types")}} property.

+ +

Sometimes you may support some different formats, and you want to retrieve the data that is most specific that is supported. In the following example, three formats are supported by a drop target.

+ +

The following example returns the data associated with the best-supported format:

+ +
function doDrop(event) {
+  const supportedTypes = ["application/x-moz-file", "text/uri-list", "text/plain"];
+  const types = event.dataTransfer.types.filter(type => supportedTypes.includes(type));
+  if (types.length) {
+    const data = event.dataTransfer.getData(types[0]);
+  }
+  event.preventDefault();
+}
+
+ +

Окончание перетаскивания

+ +

Как только перетаскивание завершено, событие {{event("dragend")}} запускается в источнике перетаскивания (тот же элемент, который получил событие {{event("dragstart")}}). Это событие сработает, если перетаскивание было успешным[1] или если оно было отменено. Однако вы можете использовать свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} для определения, какая операция удаления произошла.

+ +

Если свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} имеет значение none во время события {{event("dragend")}}, то перетаскивание было отменено. В противном случае эффект указывает, какая операция была выполнена. Источник может использовать эту информацию после операции перемещения для удаления перетаскиваемого элемента из старого расположения. Свойство {{domxref("DataTransfer.mozUserCancelled","mozUserCancelled")}} будет присвоено значение true, если пользователь отменил перетаскивание (нажав Escape), и false если перетаскивание было отменено по другим причинам, таким как недопустимая цель перетаскивания, или если оно было успешным.

+ +

Сброс может произойти внутри того же окна или над другим приложением. Событие{{event("dragend")}}будет срабатывать всегда, независимо от этого. Свойство события {{domxref("MouseEvent.screenX","screenX")}} и {{domxref("MouseEvent.screenY","screenY")}} будут установлены в координаты экрана, где произошел сброс.

+ +

Когда событие {{event("dragend")}} завершило распространение, операция перетаскивания завершена.

+ +

[1]: В Gecko, {{event("dragend")}} не отправляется, если исходный узел движется или удаляется во время перетаскивания (например, при сбрасывании или {{event("dragover")}}). Bug 460801

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/html_drag_and_drop_api/index.html b/files/ru/web/api/html_drag_and_drop_api/index.html new file mode 100644 index 0000000000..86467501fd --- /dev/null +++ b/files/ru/web/api/html_drag_and_drop_api/index.html @@ -0,0 +1,72 @@ +--- +title: Drag and drop +slug: Web/Guide/HTML/Drag_and_drop +translation_of: Web/API/HTML_Drag_and_Drop_API +--- +

Firefox и прочие приложения компании Mozilla имеют ряд возможностей для управления drag и drop. Это позволяет пользователю нажать и удерживая зажатой кнопку мыши над элементом, переместить его на другую позицию, отпустив кнопку мыши пользователь может оставить элемент на новой позиции. На протяжении всей операции перемещения полупрозрачное представление элемента следует за курсором мыши. Новая позиция элемента может располагаться в совершенно другом приложении. Веб сайты, и XUL приложения могут использовать эту функциональность для того, чтобы определить какие элементы страницы могут быть перемещены, а также определить элементы куда первые могут быть перемещены.

+ +
Эта часть покрывает функциональность drag и drop в Firefox 3.5 (Gecko 1.9.1) а также последующие версии. Для старого API для Firefox 3.0 и ранее, в котором нет соответствующей поддержки данной функциональности, смотрите older API documentation.
+ +

Основы Drag и Drop

+ +

Использование функциональности drag и drop подразумевает выполнения следующих шагов:

+ + + +

Mozilla и Firefox поддерживают ряд возможностей, которые выходят за рамку стандартной модели спецификации. Они позволяют пользователю перемещать несколько элементов и перемещать нестроковые данные. Для детальной информации смотрите Dragging and Dropping Multiple Items.

+ +

Для того, чтобы ознакомиться с общим списком данных поддерживаемых операцией drag and drop смотрите Recommended Drag Types.

+ +

Также доступны примеры с лучшей практикой использования операции drag and drop для перемещения данных разных типов:

+ + + +

Смотри DataTransfer для ссылки на объект DataTransfer.

+ +

События Drag

+ +

Ряд событий срабатывают на протяжении всей процедуры drag and drop. Запомните, что только drag-события срабатывают на протяжении операции перемещения; события мыши, такие как mousemove - нет. Также запомните, что события dragstart и dragend не срабатывают при попытке перенести файл из операционной системы в браузер.

+ +

Свойство dataTransfer всех событий перемещения содержит данные про все drag и drop операции.

+ +
+
dragstart
+
Срабатывает когда элeмент начал перемещаться. В момент срабатывания события dragstart пользователь начинает перетаскивание элемента. Обработчик данного события может быть использован для сохранения информации о перемещаемом объекте, а также для изменения изображения, которое будет ассоциировано с перемещением. Дaнное событие не срабатывает, когда некоторый файл будет переноситься из операционной системы в браузер. Для детальной информации Starting a Drag Operation.
+
dragenter
+
Срабатывает, когда перемещаемый элемент попадает на элемент-назначение. Обработчик этого события показывает, что элемент находится над объектом на который он может быть перенесен. Если же обработчика нет, либо он не совершает никаких действий перемещение по умолчанию запрещено. Это событие также используется для того, чтобы подсветить либо промаркировать объект над которым происходит перемещения в случае, если перемещение на данный элемент разрешено. Для детальной информации смотрите Specifying Drop Targets.
+
dragover
+
Данное событие срабатывает каждые несколько сотен милисекунд, когда перемещаемый элемент оказывается над зоной, принимающей перетаскиваемые элементы. Для детальной информации смотрите Specifying Drop Targets.
+
dragleave
+
Это событие запускается в момент перетаскивания, когда курсор мыши выходит за пределы элемента. Обработчикам следует убрать любую подсветку или иные индикаторы, указывавшие на присутствие курсора, чтобы тем самым обозначить реакцию на прекращение перетаскивания.
+
drag
+
Запускается при перемещении элемента или выделенного текста.
+
drop
+
Событие drop вызывается для элемента, над которым произошло "сбрасывание" перемещаемого элемента. Событие отвечает за извлечение "сброшенных" данных и их вставку. Событие будет срабатывать только при завершении операции перетаскивания, например, событие не сработает, если пользователь отменит перетаскивание нажатием Esc, или не донесет элемент, до цели. Для детальной информации смотрите Performing a Drop.
+
dragend
+
Источник перетаскивания получит событие dragend, когда перетаскивание завершится, было оно удачным или нет. Это событие не вызывается при перетаскивании файла в браузер из ОС.   Для детальной информации смотрите Finishing a Drag.
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/api/htmlaudioelement/audio()/index.html b/files/ru/web/api/htmlaudioelement/audio()/index.html deleted file mode 100644 index 4d9e39dfab..0000000000 --- a/files/ru/web/api/htmlaudioelement/audio()/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Audio() -slug: Web/API/HTMLAudioElement/Audio() -tags: - - аудио -translation_of: Web/API/HTMLAudioElement/Audio ---- -

{{APIRef("HTML DOM")}}

- -

Конструктор Audio() создает и возвращает новый {{domxref("HTMLAudioElement")}} объект, который может быть прикреплен к документу, чтобы пользователь мог взаимодействовать и/или слушать его, либо может использоваться вне экрана для управления и воспроизведения звука.

- -

Синтаксис

- -
audioObj = new Audio(url);
- -

Параметры

- -
-
url {{optional_inline}}
-
Необязательный параметр {{domxref("DOMString")}}, содержащий URL-адрес аудиофайла, который будет связан с новым аудиоэлементом.
-
- -

Возвращаемое значение

- -

Новый {{domxref("HTMLAudioElement")}} объект, настроенный для воспроизведения файла, указанного в url. Свойство {{domxref("HTMLMediaElement.preload", "preload")}} нового объекта имеет значение по умолчанию auto, а его свойство src — указанный URL-адрес или null, если адрес не указан. Если указан URL-адрес, браузер начинает асинхронно загружать медиаресурс перед возвратом нового объекта.

- - - -

Примечания по использованию

- -

Вы также можете использовать другие методы создания элементов, такие как метод {{domxref("Document.createElement", "createElement()")}} объекта {{domxref("document")}}, для создания нового {{domxref("HTMLAudioElement")}} объекта.

- -

Определение, когда воспроизведение может начаться

- -

Существует три способа определить насколько аудио-файл загружен, чтобы начать воспроизведение:

- - - -

Лучший подход, основанный на событии:

- -
myAudioElement.addEventListener("canplaythrough", event => {
-  /* аудио может быть воспроизведено; проиграть, если позволяют разрешения */
-  myAudioElement.play();
-});
- -

Использование памяти и управление

- -

Если все ссылки на аудиоэлемент, созданные с помощью конструктора Audio() удалены, сам элемент не будет удален из памяти механизмом сборщика мусора JavaScript, если в данный момент идет воспроизведение. Вместо этого продолжится воспроизведение и объект останется в памяти до тех пор, пока не закончится аудио или оно не будет приостановлено (например, путем вызова {{domxref("HTMLMediaElement.pause", "pause()")}}). В этот момент объект подлежит уничтожению сборщиком мусора.

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', "#dom-audio", "Audio()")}}{{Spec2('HTML WHATWG')}}
- -

Поддержка браузерами

- -

Таблица совместимости на этой странице генерируется из структурированных данных. Если Вы хотите внести свой вклад в эти данные, просмотрите https://github.com/mdn/browser-compat-data и отправте нам Pull-запрос.

- -

{{Compat("api.HTMLAudioElement.Audio")}}

- -

Смотрите также

- - diff --git a/files/ru/web/api/htmlaudioelement/audio/index.html b/files/ru/web/api/htmlaudioelement/audio/index.html new file mode 100644 index 0000000000..4d9e39dfab --- /dev/null +++ b/files/ru/web/api/htmlaudioelement/audio/index.html @@ -0,0 +1,85 @@ +--- +title: Audio() +slug: Web/API/HTMLAudioElement/Audio() +tags: + - аудио +translation_of: Web/API/HTMLAudioElement/Audio +--- +

{{APIRef("HTML DOM")}}

+ +

Конструктор Audio() создает и возвращает новый {{domxref("HTMLAudioElement")}} объект, который может быть прикреплен к документу, чтобы пользователь мог взаимодействовать и/или слушать его, либо может использоваться вне экрана для управления и воспроизведения звука.

+ +

Синтаксис

+ +
audioObj = new Audio(url);
+ +

Параметры

+ +
+
url {{optional_inline}}
+
Необязательный параметр {{domxref("DOMString")}}, содержащий URL-адрес аудиофайла, который будет связан с новым аудиоэлементом.
+
+ +

Возвращаемое значение

+ +

Новый {{domxref("HTMLAudioElement")}} объект, настроенный для воспроизведения файла, указанного в url. Свойство {{domxref("HTMLMediaElement.preload", "preload")}} нового объекта имеет значение по умолчанию auto, а его свойство src — указанный URL-адрес или null, если адрес не указан. Если указан URL-адрес, браузер начинает асинхронно загружать медиаресурс перед возвратом нового объекта.

+ + + +

Примечания по использованию

+ +

Вы также можете использовать другие методы создания элементов, такие как метод {{domxref("Document.createElement", "createElement()")}} объекта {{domxref("document")}}, для создания нового {{domxref("HTMLAudioElement")}} объекта.

+ +

Определение, когда воспроизведение может начаться

+ +

Существует три способа определить насколько аудио-файл загружен, чтобы начать воспроизведение:

+ + + +

Лучший подход, основанный на событии:

+ +
myAudioElement.addEventListener("canplaythrough", event => {
+  /* аудио может быть воспроизведено; проиграть, если позволяют разрешения */
+  myAudioElement.play();
+});
+ +

Использование памяти и управление

+ +

Если все ссылки на аудиоэлемент, созданные с помощью конструктора Audio() удалены, сам элемент не будет удален из памяти механизмом сборщика мусора JavaScript, если в данный момент идет воспроизведение. Вместо этого продолжится воспроизведение и объект останется в памяти до тех пор, пока не закончится аудио или оно не будет приостановлено (например, путем вызова {{domxref("HTMLMediaElement.pause", "pause()")}}). В этот момент объект подлежит уничтожению сборщиком мусора.

+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', "#dom-audio", "Audio()")}}{{Spec2('HTML WHATWG')}}
+ +

Поддержка браузерами

+ +

Таблица совместимости на этой странице генерируется из структурированных данных. Если Вы хотите внести свой вклад в эти данные, просмотрите https://github.com/mdn/browser-compat-data и отправте нам Pull-запрос.

+ +

{{Compat("api.HTMLAudioElement.Audio")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/htmlelement/accesskey/index.html b/files/ru/web/api/htmlelement/accesskey/index.html new file mode 100644 index 0000000000..0230ecc9e0 --- /dev/null +++ b/files/ru/web/api/htmlelement/accesskey/index.html @@ -0,0 +1,74 @@ +--- +title: Element.accessKey +slug: Web/API/Element/accessKey +translation_of: Web/API/HTMLElement/accessKey +translation_of_original: Web/API/Element/accessKey +--- +
{{APIRef("DOM")}}
+ +
 
+ +

Описание

+ +

Свойство accessKey позволяет перейти к элементу с помощью сочетания клавиш - заданной им и тех, что назначит браузер.

+ +
+

По сути, accessKey задает значение для одноименного атрибута...

+
+ +
+

Данное свойство использовать не рекоммендуется, поскольку в браузерах уже заданы подобные привязки и неосторожное обращение может привести к жестокому конфликту.

+
+ +

 

+ +

Синтаксис

+ +
var key = elem.accessKey;
+elem.accessKey = key;
+
+ +

 

+ +

Пример

+ +
var elem = document.getElementById("id");
+elem.accessKey = "w";
+
+ +

Немного информации

+ +

Фокусировка на элемент произойдет при нажатии следующих клавиш (,где acesskey - значение свойства acessKey).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

      Браузер

+
+

      Сочетание

+
Firefox[Alt] [Shift] + accesskey
Internet Explorer[Alt] + accesskey
Chrome[Alt] + accesskey
Safari[Alt] + accesskey
Opera[Shift] [Esc] + accesskey
diff --git a/files/ru/web/api/htmlelement/dataset/index.html b/files/ru/web/api/htmlelement/dataset/index.html deleted file mode 100644 index 328b265afa..0000000000 --- a/files/ru/web/api/htmlelement/dataset/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: HTMLElement.dataset -slug: Web/API/HTMLElement/dataset -translation_of: Web/API/HTMLOrForeignElement/dataset ---- -

{{ APIRef("HTML DOM") }}

- -

Свойство HTMLElement.dataset предоставляет доступ как для чтения, так и для изменения всех пользовательских дата-атрибутов custom data attributes (data-*) , установленных у элемента. Это map of DOMString, одна запись для каждого пользовательского атрибута данных. Обратите внимание, свойство dataset доступно только для чтения. Для записи должны использоваться  его "свойства", которые представлены data-атрибутами. Также обратите внимание, что HTML data-атрибут и соответствующий ему DOM-dataset.property не имеют одно и то же имя, но они всегда похожи:

- - - -

Преобразование имён

- -

dash-style в camelCase: имя пользовательского дата-атрибута преобразуется в ключ для {{ domxref("DOMStringMap") }} по следующим правилам:

- - - -

camelCase в dash-style: обратное преобразование ключа в имя атрибута производится по следующим правилам:

- - - -

Ограничение в правилах гарантирует, что эти два преобразования являются обратными друг другу.

- -

Например, атрибуту data-abc-def соответствует ключ abcDef.

- -

Доступ к значениям

- - - -

Синтаксис

- - - -

Примеры

- -
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe</div>
-
-let el = document.querySelector('#user');
-
-// el.id == 'user'
-// el.dataset.id === '1234567890'
-// el.dataset.user === 'johndoe'
-// el.dataset.dateOfBirth === ''
-
-el.dataset.dateOfBirth = '1960-10-03'; // set the DOB.
-
-// 'someDataAttr' in el.dataset === false
-el.dataset.someDataAttr = 'mydata';
-// 'someDataAttr' in el.dataset === true
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML WHATWG')}}No change from latest snapshot, {{SpecName('HTML5.1')}}
{{SpecName('HTML5.1', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName('HTML WHATWG')}}, no change from {{SpecName('HTML5 W3C')}}
{{SpecName('HTML5 W3C', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5 W3C')}}Snapshot of  {{SpecName('HTML WHATWG')}}, initial definition.
- -

Совместимость с браузерами

- -

{{Compat("api.HTMLElement.dataset")}}

- -

См. также

- - diff --git a/files/ru/web/api/htmlelement/innertext/index.html b/files/ru/web/api/htmlelement/innertext/index.html new file mode 100644 index 0000000000..ef23b48d59 --- /dev/null +++ b/files/ru/web/api/htmlelement/innertext/index.html @@ -0,0 +1,46 @@ +--- +title: Node.innerText +slug: Web/API/Node/innerText +translation_of: Web/API/HTMLElement/innerText +--- +
{{APIRef("DOM")}}
+ +

Node.innerText - это свойство, позволяющее задавать или получать текстовое содержимое элемента и его потомков. В качестве геттера, свойство приближается к тексту, который пользователь получит, если он выделит содержимое элемента курсором, затем копирует его в буфер обмена.

+ +

Изначально, данное поведение было представленно Internet Explorer, и было формально специализированно в стандарте HTML в 2016 после того, как было адаптированно всеми ведущими браузерами.

+ +

{{domxref("Node.textContent")}} - это альтернативное свойство, которое имеет ряд отличий:

+ + + +

Спецификация

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'dom.html#the-innertext-idl-attribute', 'innerText')}}{{Spec2('HTML WHATWG')}}Представлено, основываясь на черновике спецификации innerText. См. whatwg/html#465 и whatwg/compat#5.
+ +

Поддержка браузерами

+ +

{{Compat("api.Node.innerText")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/htmlelement/nonce/index.html b/files/ru/web/api/htmlelement/nonce/index.html deleted file mode 100644 index e47f3aea23..0000000000 --- a/files/ru/web/api/htmlelement/nonce/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: HTMLElement.nonce -slug: Web/API/HTMLElement/nonce -translation_of: Web/API/HTMLOrForeignElement/nonce ---- -

{{SeeCompatTable}}{{APIRef("HTML DOM")}}

- -

Свойство nonce интерфейса {{domxref("HTMLElement")}} возвращает криптографический номер, который используется политикой безопасности содержимого для определения того, будет ли разрешена дальнейшая работа с данной выборкой.

- -

В более поздних реализациях элементы, имеющие атрибут nonce, предоставляют его только скриптам (а не сторонним каналам, таким как селекторы атрибутов CSS).

- -

Syntax

- -
var nonce = HTMLElement.nonce
-HTMLElement.nonce = nonce
- -

Value

- -

Криптографический код.

- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG','#attr-nonce','nonce')}}{{Spec2('HTML WHATWG')}}Первоначальное определение.
- -

Browser Compatibility

- -
- - -

{{Compat("api.HTMLElement.nonce")}}

-
diff --git a/files/ru/web/api/htmlelement/style/index.html b/files/ru/web/api/htmlelement/style/index.html deleted file mode 100644 index 683bfa1101..0000000000 --- a/files/ru/web/api/htmlelement/style/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: HTMLElement.style -slug: Web/API/HTMLElement/style -tags: - - API - - HTML DOM - - HTMLElement - - NeedsBrowserAgnosticism - - NeedsBrowserCompatibility - - NeedsMarkupWork - - NeedsSpecTable - - Свойство - - Ссылки -translation_of: Web/API/ElementCSSInlineStyle/style ---- -

Кратко

- -
-
{{ APIRef("HTML DOM") }}
-
- -

Свойство HTMLElement.style используется для получения и установки инлайновых стилей. При получении возвращается объект CSSStyleDeclaration , который содержит список из всех свойств стилей для этого элемента с значениями заданными  для атрибутов , что определенны  в инлайновом стиле (см. атрибут стиля) элемента. См. CSS Properties Reference для получения списка CSS свойств применимых вместе со style.  

- -

Настройка стилей

- -

Свойство style имеет тот же приоритет (и выше) в каскаде CSS как и прямая декларация стиля через атрибут style, полезен для настройки стиля отдельного специфичного элемента.

- -

Стили не следует устанавливать непосредственно через свойство style (например elt.style = "color: blue;"), поскольку оно считается доступным только для чтения и атрибут style возвращает объект CSSStyleDeclaration который доступен только для чтения. Вместо этого стили могут быть установлены путем присвоения значений свойствам style. Для добавления определенных стилей для элемента без изменения других свойств стилей предпочтительно использовать отдельные свойства style (например elt.style.color = '...'). -При использовании
elt.style.cssText = '...' или elt.setAttribute('style','...') устанавливаются стили перезаписывая уже существующие. Обратите внимание, что имена свойств стилей задаются в camel-case а не в kebab-case elt.style.<property> (т.е., elt.style.fontSize, а не elt.style.font-size).

- -

Объявленные стили сбрасываются присваиванием значения null,
elt.style.color = null

- -

Примеры

- -
// Устанавливает несколько стилей в одном выражении
-elt.style.cssText = "color: blue; border: 1px solid black";
-// Или
-elt.setAttribute("style", "color:red; border: 1px solid blue;");
-
-// Устанавливает определенный стиль оставляя другие значения стиля нетронутыми
-elt.style.color = "blue";
- -

Получение стиль-информации

- -

Свойство style в основном не имеет пользы в части информации о стиле элемента, оно только олицетворяет собой набор CSS деклараций атрибутов style элемента, а не тех которые проистекают из стиль-правил откуда-либо ещё, таких как стилевые правила раздела {{HTMLElement("head")}}, или внешней таблицы стилей. Для получения значений всех CSS свойств элемента вы должны использовать вместо этого {{domxref("window.getComputedStyle()")}}.

- -
-
var div = document.getElementById("div1");
-div.style.marginTop = ".25in";
-
- -

Следующий код показывает имена всех свойств стиля, значений, заданных явно для элемента elt и унаследованных "расчитанных" значений:

- -
var elt = document.getElementById("elementIdHere");
-var out = "";
-var st = elt.style;
-var cs = window.getComputedStyle(elt, null);
-for (x in st) {
-  out += "  " + x + " = '" + st[x] + "' > '" + cs[x] + "'\n";
-}
- -

Спецификация

- -

DOM Level 2 Style: ElementCSSInlineStyle.style

- -

CSSOM: ElementCSSInlineStyle

- -

Совместимость

- - - -

{{Compat("api.HTMLElement.style")}}

- -

См. также

- - diff --git a/files/ru/web/api/htmlelement/tabindex/index.html b/files/ru/web/api/htmlelement/tabindex/index.html deleted file mode 100644 index fe41116fe4..0000000000 --- a/files/ru/web/api/htmlelement/tabindex/index.html +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: HTMLElement.tabIndex -slug: Web/API/HTMLElement/tabIndex -translation_of: Web/API/HTMLOrForeignElement/tabIndex ---- -
-
{{ APIRef("HTML DOM") }}
-
- -

Свойство HTMLElement.tabIndex предоставляет возможность вызова по кнопке Tab текущего элемента.

- -
-
Вызов по табуляции происходит в следующем порядке:
- -
    -
  1. элементы с положительным tabIndex. Элементы, имеющие одинаковое значение tabIndex вызываются в порядке появления в коде.  Переход осуществляется от меньших tabIndex до больших tabIndex. 
  2. -
  3. Элементы, которые не поддерживают атрибут tabIndex или поддерживают но tabIndex установлен в "0", выбираются по Tab в порядке их появления в коде.
  4. -
- -
Элементы для которых установлена блокировка (disabled) не могут быть выбраны кнопкой Tab и не могут быть в фокусе.
- -
 
- -
Значения могут начинаться с любого числа, могут быть отрицательными и могут быть непоследовательными, однако разные браузеры можгут неправильно сработать при очень больших значениях.
- -
 
-
- -

Синтаксис

- -
elt.tabIndex = index;
-var index = elt.tabIndex;
-
- - - -

Пример

- -
var b1 = document.getElementById("button1");
-
-b1.tabIndex = 1;
-
- -

Спецификация

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКоментарии
{{SpecName('HTML WHATWG', '#dom-tabindex', 'tabindex')}}{{Spec2('HTML WHATWG')}}Не было изменений с {{SpecName('DOM2 HTML')}}.
{{SpecName('DOM2 HTML', 'html.html#ID-40676705', 'tabindex')}}{{Spec2('DOM2 HTML')}}Не было изменений с {{SpecName('DOM1')}}.
{{SpecName('DOM1', 'level-one-html.html#ID-40676705', 'tabindex')}}{{Spec2('DOM1')}}Начальное определение
- -

Поддержка в браузерах

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -

Смотрите также

- - diff --git a/files/ru/web/api/htmlelement/transitionend_event/index.html b/files/ru/web/api/htmlelement/transitionend_event/index.html new file mode 100644 index 0000000000..dfb8542da6 --- /dev/null +++ b/files/ru/web/api/htmlelement/transitionend_event/index.html @@ -0,0 +1,165 @@ +--- +title: transitionend +slug: Web/Events/transitionend +tags: + - CSS +translation_of: Web/API/HTMLElement/transitionend_event +--- +

Событие transitionend срабатывает, когда CSS transition закончил свое выполнение. В случае, когда анимация удаляется до ее завершения(например, если transition-property [en-US] удаляется), то событие не срабатывает.

+ +

Общая информация

+ +
+
Интерфейс
+
{{domxref("TransitionEvent")}}
+
Всплывает
+
Да
+
Отменяемое
+
Да
+
Элемент
+
{{domxref("document")}}, {{domxref("element")}}
+
Действие по умолчанию
+
Нет
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
propertyName {{readonlyInline}}{{domxref("DOMString")}}The name of the CSS property associated with the transition.
elapsedTime {{readonlyInline}}FloatThe amount of time the transition has been running, in seconds, as of the time the event was generated. This value is not affected by the value of transition-delay.
pseudoElement {{readonlyInline}}{{domxref("DOMString")}}The name (beginning with two colons) of the CSS pseudo-element on which the transition occured (in which case the target of the event is that pseudo-element's corresponding element), or the empty string if the transition occurred on an element (which means the target of the event is that element).
+ +

Пример

+ +
/*
+ * Прослушивать событие transitionend на определенном элементе, т.е. #slidingMenu
+ * Затем, вызвать определенную функцию, т.е. showMessage()
+ */
+function showMessage() {
+    alert('Transition закончил свое выполнение');
+}
+
+var element = document.getElementById("slidingMenu");
+element.addEventListener("transitionend", showMessage, false);
+
+ +

Спецификация

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("CSS3 Transitions", "#transition-events", "transitionend")}}{{ Spec2('CSS3 Transitions') }}Initial definition.
+ +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support1.0 as webkitTransitionEnd{{ CompatGeckoDesktop("2.0") }}1010.5 as oTransitionEnd
+ 12 as otransitionend
+ 12.10 as transitionend
3.2 as webkitTransitionEnd
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support2.1 as webkitTransitionEnd{{ CompatGeckoMobile("2.0") }}{{ CompatUnknown() }}10 as oTransitionEnd
+ 12 as otransitionend
+ 12.10 as transitionend
3.2 as webkitTransitionEnd
+
+ +

Также

+ + diff --git a/files/ru/web/api/htmlmediaelement/seeking_event/index.html b/files/ru/web/api/htmlmediaelement/seeking_event/index.html new file mode 100644 index 0000000000..5802aecadb --- /dev/null +++ b/files/ru/web/api/htmlmediaelement/seeking_event/index.html @@ -0,0 +1,80 @@ +--- +title: стримится +slug: Web/HTML/Element/video/seeking_event +translation_of: Web/API/HTMLMediaElement/seeking_event +--- +

Событие 'seeking' в случае, когда идет подгрузка видео

+ +

General info

+ +
+
Specification
+
HTML5 media
+
Interface
+
Event
+
Bubbles
+
No
+
Cancelable
+
No
+
Target
+
Element
+
Default Action
+
None.
+
+ +

Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
+ + + + diff --git a/files/ru/web/api/htmlorforeignelement/dataset/index.html b/files/ru/web/api/htmlorforeignelement/dataset/index.html new file mode 100644 index 0000000000..328b265afa --- /dev/null +++ b/files/ru/web/api/htmlorforeignelement/dataset/index.html @@ -0,0 +1,114 @@ +--- +title: HTMLElement.dataset +slug: Web/API/HTMLElement/dataset +translation_of: Web/API/HTMLOrForeignElement/dataset +--- +

{{ APIRef("HTML DOM") }}

+ +

Свойство HTMLElement.dataset предоставляет доступ как для чтения, так и для изменения всех пользовательских дата-атрибутов custom data attributes (data-*) , установленных у элемента. Это map of DOMString, одна запись для каждого пользовательского атрибута данных. Обратите внимание, свойство dataset доступно только для чтения. Для записи должны использоваться  его "свойства", которые представлены data-атрибутами. Также обратите внимание, что HTML data-атрибут и соответствующий ему DOM-dataset.property не имеют одно и то же имя, но они всегда похожи:

+ + + +

Преобразование имён

+ +

dash-style в camelCase: имя пользовательского дата-атрибута преобразуется в ключ для {{ domxref("DOMStringMap") }} по следующим правилам:

+ + + +

camelCase в dash-style: обратное преобразование ключа в имя атрибута производится по следующим правилам:

+ + + +

Ограничение в правилах гарантирует, что эти два преобразования являются обратными друг другу.

+ +

Например, атрибуту data-abc-def соответствует ключ abcDef.

+ +

Доступ к значениям

+ + + +

Синтаксис

+ + + +

Примеры

+ +
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe</div>
+
+let el = document.querySelector('#user');
+
+// el.id == 'user'
+// el.dataset.id === '1234567890'
+// el.dataset.user === 'johndoe'
+// el.dataset.dateOfBirth === ''
+
+el.dataset.dateOfBirth = '1960-10-03'; // set the DOB.
+
+// 'someDataAttr' in el.dataset === false
+el.dataset.someDataAttr = 'mydata';
+// 'someDataAttr' in el.dataset === true
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML WHATWG')}}No change from latest snapshot, {{SpecName('HTML5.1')}}
{{SpecName('HTML5.1', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName('HTML WHATWG')}}, no change from {{SpecName('HTML5 W3C')}}
{{SpecName('HTML5 W3C', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5 W3C')}}Snapshot of  {{SpecName('HTML WHATWG')}}, initial definition.
+ +

Совместимость с браузерами

+ +

{{Compat("api.HTMLElement.dataset")}}

+ +

См. также

+ + diff --git a/files/ru/web/api/htmlorforeignelement/nonce/index.html b/files/ru/web/api/htmlorforeignelement/nonce/index.html new file mode 100644 index 0000000000..e47f3aea23 --- /dev/null +++ b/files/ru/web/api/htmlorforeignelement/nonce/index.html @@ -0,0 +1,44 @@ +--- +title: HTMLElement.nonce +slug: Web/API/HTMLElement/nonce +translation_of: Web/API/HTMLOrForeignElement/nonce +--- +

{{SeeCompatTable}}{{APIRef("HTML DOM")}}

+ +

Свойство nonce интерфейса {{domxref("HTMLElement")}} возвращает криптографический номер, который используется политикой безопасности содержимого для определения того, будет ли разрешена дальнейшая работа с данной выборкой.

+ +

В более поздних реализациях элементы, имеющие атрибут nonce, предоставляют его только скриптам (а не сторонним каналам, таким как селекторы атрибутов CSS).

+ +

Syntax

+ +
var nonce = HTMLElement.nonce
+HTMLElement.nonce = nonce
+ +

Value

+ +

Криптографический код.

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG','#attr-nonce','nonce')}}{{Spec2('HTML WHATWG')}}Первоначальное определение.
+ +

Browser Compatibility

+ +
+ + +

{{Compat("api.HTMLElement.nonce")}}

+
diff --git a/files/ru/web/api/htmlorforeignelement/tabindex/index.html b/files/ru/web/api/htmlorforeignelement/tabindex/index.html new file mode 100644 index 0000000000..fe41116fe4 --- /dev/null +++ b/files/ru/web/api/htmlorforeignelement/tabindex/index.html @@ -0,0 +1,134 @@ +--- +title: HTMLElement.tabIndex +slug: Web/API/HTMLElement/tabIndex +translation_of: Web/API/HTMLOrForeignElement/tabIndex +--- +
+
{{ APIRef("HTML DOM") }}
+
+ +

Свойство HTMLElement.tabIndex предоставляет возможность вызова по кнопке Tab текущего элемента.

+ +
+
Вызов по табуляции происходит в следующем порядке:
+ +
    +
  1. элементы с положительным tabIndex. Элементы, имеющие одинаковое значение tabIndex вызываются в порядке появления в коде.  Переход осуществляется от меньших tabIndex до больших tabIndex. 
  2. +
  3. Элементы, которые не поддерживают атрибут tabIndex или поддерживают но tabIndex установлен в "0", выбираются по Tab в порядке их появления в коде.
  4. +
+ +
Элементы для которых установлена блокировка (disabled) не могут быть выбраны кнопкой Tab и не могут быть в фокусе.
+ +
 
+ +
Значения могут начинаться с любого числа, могут быть отрицательными и могут быть непоследовательными, однако разные браузеры можгут неправильно сработать при очень больших значениях.
+ +
 
+
+ +

Синтаксис

+ +
elt.tabIndex = index;
+var index = elt.tabIndex;
+
+ + + +

Пример

+ +
var b1 = document.getElementById("button1");
+
+b1.tabIndex = 1;
+
+ +

Спецификация

+ +

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКоментарии
{{SpecName('HTML WHATWG', '#dom-tabindex', 'tabindex')}}{{Spec2('HTML WHATWG')}}Не было изменений с {{SpecName('DOM2 HTML')}}.
{{SpecName('DOM2 HTML', 'html.html#ID-40676705', 'tabindex')}}{{Spec2('DOM2 HTML')}}Не было изменений с {{SpecName('DOM1')}}.
{{SpecName('DOM1', 'level-one-html.html#ID-40676705', 'tabindex')}}{{Spec2('DOM1')}}Начальное определение
+ +

Поддержка в браузерах

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/api/mediatrackconstraints/echocancellation/index.html b/files/ru/web/api/mediatrackconstraints/echocancellation/index.html new file mode 100644 index 0000000000..3e8d1f1a4e --- /dev/null +++ b/files/ru/web/api/mediatrackconstraints/echocancellation/index.html @@ -0,0 +1,77 @@ +--- +title: MediaTrackConstraints.echoCancellation +slug: Web/API/MediaTrackConstraints/Эхоподавление +tags: + - API + - Media Capture and Streams API + - Media Streams API + - MediaTrackConstrains + - WebRTC + - Медиа + - Ограничения + - Свойство + - Эхоподавление + - справочник +translation_of: Web/API/MediaTrackConstraints/echoCancellation +--- +
{{APIRef("Media Capture and Streams")}}
+ +

Свойство echoCancellation объекта {{domxref("MediaTrackConstraints")}} это {{domxref("ConstrainBoolean")}} описывающее запрашиваемые или обязательные ограничения накладываемые на ограничивающее свойство {{domxref("MediaTrackSettings.echoCancellation", "echoCancellation")}}.

+ +

При необходимости вы можете определить, поддерживается ли это ограничение, проверив значение {{domxref("MediaTrackSupportedConstraints.echoCancellation")}} как результат вызова {{domxref("MediaDevices.getSupportedConstraints()")}}. Однако, обычно в этом нет необходимости, поскольку браузеры просто игнорируют любые незнакомые им ограничения.

+ +

Поскольку {{Glossary("RTP")}} не содержит эту информцию, медиа-треки связанные с WebRTC {{domxref("RTCPeerConnection")}} некогда не будут включать это свойство.

+ +

Синтаксис

+ +
const constraintsObject = {
+  echoCancellation: constraint,
+};
+
+constraintsObject.echoCancellation = constraint;
+
+ +

Значение

+ +

Если это значение является простым true или false, пользовательский агент попытается получить медиа с включенным или отключенным эхоподавлением, если это возможно, но не вернет ошибку, если это невозможно сделать. Иначе если значение передано как объект с полем exact , то логическое значение этого поля указывает обязательную настройку для эхоподавления; если это не может быть выполненым - запрос вернет ошибку.

+ +

Пример

+ +

Смотрите {{SectionOnPage("/en-US/docs/Web/API/Media_Streams_API/Constraints", "Example: Constraint exerciser")}} для примера.

+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{ SpecName('Media Capture', '#dom-mediatrackconstraintset-echocancellation', 'echoCancellation') }}{{ Spec2('Media Capture') }}Initial specification.
+ +

Совместимость с браузерами

+ + + +

{{Compat("api.MediaTrackConstraints.echoCancellation")}}

+ +

Смотрите также

+ + diff --git "a/files/ru/web/api/mediatrackconstraints/\321\215\321\205\320\276\320\277\320\276\320\264\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" "b/files/ru/web/api/mediatrackconstraints/\321\215\321\205\320\276\320\277\320\276\320\264\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index 3e8d1f1a4e..0000000000 --- "a/files/ru/web/api/mediatrackconstraints/\321\215\321\205\320\276\320\277\320\276\320\264\320\260\320\262\320\273\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: MediaTrackConstraints.echoCancellation -slug: Web/API/MediaTrackConstraints/Эхоподавление -tags: - - API - - Media Capture and Streams API - - Media Streams API - - MediaTrackConstrains - - WebRTC - - Медиа - - Ограничения - - Свойство - - Эхоподавление - - справочник -translation_of: Web/API/MediaTrackConstraints/echoCancellation ---- -
{{APIRef("Media Capture and Streams")}}
- -

Свойство echoCancellation объекта {{domxref("MediaTrackConstraints")}} это {{domxref("ConstrainBoolean")}} описывающее запрашиваемые или обязательные ограничения накладываемые на ограничивающее свойство {{domxref("MediaTrackSettings.echoCancellation", "echoCancellation")}}.

- -

При необходимости вы можете определить, поддерживается ли это ограничение, проверив значение {{domxref("MediaTrackSupportedConstraints.echoCancellation")}} как результат вызова {{domxref("MediaDevices.getSupportedConstraints()")}}. Однако, обычно в этом нет необходимости, поскольку браузеры просто игнорируют любые незнакомые им ограничения.

- -

Поскольку {{Glossary("RTP")}} не содержит эту информцию, медиа-треки связанные с WebRTC {{domxref("RTCPeerConnection")}} некогда не будут включать это свойство.

- -

Синтаксис

- -
const constraintsObject = {
-  echoCancellation: constraint,
-};
-
-constraintsObject.echoCancellation = constraint;
-
- -

Значение

- -

Если это значение является простым true или false, пользовательский агент попытается получить медиа с включенным или отключенным эхоподавлением, если это возможно, но не вернет ошибку, если это невозможно сделать. Иначе если значение передано как объект с полем exact , то логическое значение этого поля указывает обязательную настройку для эхоподавления; если это не может быть выполненым - запрос вернет ошибку.

- -

Пример

- -

Смотрите {{SectionOnPage("/en-US/docs/Web/API/Media_Streams_API/Constraints", "Example: Constraint exerciser")}} для примера.

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{ SpecName('Media Capture', '#dom-mediatrackconstraintset-echocancellation', 'echoCancellation') }}{{ Spec2('Media Capture') }}Initial specification.
- -

Совместимость с браузерами

- - - -

{{Compat("api.MediaTrackConstraints.echoCancellation")}}

- -

Смотрите также

- - diff --git a/files/ru/web/api/navigator/connection/index.html b/files/ru/web/api/navigator/connection/index.html new file mode 100644 index 0000000000..607101a911 --- /dev/null +++ b/files/ru/web/api/navigator/connection/index.html @@ -0,0 +1,100 @@ +--- +title: NetworkInformation.connection +slug: Web/API/NetworkInformation/connection +translation_of: Web/API/Navigator/connection +--- +

{{ apiref("Network Information API") }}

+ +

{{ SeeCompatTable() }}

+ +

NetworkInformation.connection свойство только для чтения представляющее собой {{domxref("Connection")}} содержащий информацию о системном подключении, таких как текущая пропускная способность пользовательского устройства или определено ли соеденение. Это может быть использовано для выбора контента высокой плотности или контента низкой плотности в соединении пользователя.

+ +

Синтаксис

+ +
connectionInfo = navigator.connection
+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКоментарий
{{ SpecName('Network Information', '#h-the-connection-attribute', 'NetworkInformation.connection') }}{{ Spec2('Network Information') }}Первоначальная спецификация.
+ +

Доступность в браузере

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
СвойствоChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{ CompatNo() }}12.0
+ behind the flag
{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
СвойствоAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Базовая поддержка2.2 {{ property_prefix("webkit") }}12.01.4{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

Заметка для Gecko

+ + + +

Смотрите также

+ + diff --git a/files/ru/web/api/navigatorgeolocation/index.html b/files/ru/web/api/navigatorgeolocation/index.html deleted file mode 100644 index 7287eee669..0000000000 --- a/files/ru/web/api/navigatorgeolocation/index.html +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: NavigatorGeolocation -slug: Web/API/NavigatorGeolocation -translation_of: Web/API/Geolocation -translation_of_original: Web/API/NavigatorGeolocation ---- -
{{APIRef("Geolocation API")}}
- -

NavigatorGeolocation содержит метод, позволяющий объектам реализовывать его,, получая {{domxref("Geolocation")}} экземпляр объекта.

- -

Здесь нет объектов типа NavigatorGeolocation, но некоторые интерфейсы, например, {{domxref("Navigator")}} реализуют его.

- -

Свойства

- -

Интерфейс NavigatorGeolocation не наследует каких-либо свойств.

- -
-
{{domxref("NavigatorGeolocation.geolocation")}} {{readonlyInline}}
-
Возвращает объект {{domxref("Geolocation")}} позволяющий получить доступ к местоположению устройства.
-
- -

Методы

- -

Интерфейс NavigatorGeolocation ни реализует, ни наследует  никаких методов.

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('Geolocation', '#navi-geo', 'NavigatorGeolocation')}}{{Spec2('Geolocation')}}Изначальное описание
- -

Совместимость с браузерами

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
СвойствоChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка5{{CompatGeckoDesktop("1.9.1")}}910.60
- {{CompatNo}} 15.0
- 16.0
5
-
- -
- - - - - - - - - - - - - - - - - - - - - -
СвойствоAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("4")}}{{CompatUnknown}}10.60{{CompatUnknown}}
-
- -

Смотрите также

- - diff --git a/files/ru/web/api/networkinformation/connection/index.html b/files/ru/web/api/networkinformation/connection/index.html deleted file mode 100644 index 607101a911..0000000000 --- a/files/ru/web/api/networkinformation/connection/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: NetworkInformation.connection -slug: Web/API/NetworkInformation/connection -translation_of: Web/API/Navigator/connection ---- -

{{ apiref("Network Information API") }}

- -

{{ SeeCompatTable() }}

- -

NetworkInformation.connection свойство только для чтения представляющее собой {{domxref("Connection")}} содержащий информацию о системном подключении, таких как текущая пропускная способность пользовательского устройства или определено ли соеденение. Это может быть использовано для выбора контента высокой плотности или контента низкой плотности в соединении пользователя.

- -

Синтаксис

- -
connectionInfo = navigator.connection
- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКоментарий
{{ SpecName('Network Information', '#h-the-connection-attribute', 'NetworkInformation.connection') }}{{ Spec2('Network Information') }}Первоначальная спецификация.
- -

Доступность в браузере

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
СвойствоChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{ CompatNo() }}12.0
- behind the flag
{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
СвойствоAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Базовая поддержка2.2 {{ property_prefix("webkit") }}12.01.4{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -

Заметка для Gecko

- - - -

Смотрите также

- - diff --git a/files/ru/web/api/node.replacechild/index.html b/files/ru/web/api/node.replacechild/index.html deleted file mode 100644 index 6d69392c57..0000000000 --- a/files/ru/web/api/node.replacechild/index.html +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Node.replaceChild -slug: Web/API/Node.replaceChild -tags: - - API - - DOM - - DOM Elements Method - - Gecko - - Method - - Node -translation_of: Web/API/Node/replaceChild ---- -
- {{ApiRef}}
-

Аннотация

-

Заменяет дочерний элемент на выбранный. Возвращает замененный элемент.

-

Синтаксис

-
replacedNode = parentNode.replaceChild(newChild, oldChild);
-
- -

Пример

-
// <div>
-//  <span id="childSpan">foo bar</span>
-// </div>
-
-// Создаем новый пустой элемент
-// without an ID, any attributes, or any content
-var sp1 = document.createElement("span");
-
-// Присваиваем ему id 'newSpan'
-sp1.setAttribute("id", "newSpan");
-
-// Создаем строку.
-var sp1_content = document.createTextNode("new replacement span element.");
-
-// Добавляем контент в созданный нами узел
-sp1.appendChild(sp1_content);
-
-// создаем ссылку на существующий элемент который будем заменять
-var sp2 = document.getElementById("childSpan");
-var parentDiv = sp2.parentNode;
-
-// заменяем существующий элемент sp2 на созданный нами sp1
-parentDiv.replaceChild(sp1, sp2);
-
-// Результат:
-// <div>
-//   <span id="newSpan">new replacement span element.</span>
-// </div>
-
-

Спецификация

- -

См. также

- diff --git a/files/ru/web/api/node/baseuriobject/index.html b/files/ru/web/api/node/baseuriobject/index.html deleted file mode 100644 index 7f7dbfb782..0000000000 --- a/files/ru/web/api/node/baseuriobject/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Node.baseURIObject -slug: Web/API/Node/baseURIObject -translation_of: Web/API/Node -translation_of_original: Web/API/Node/baseURIObject ---- -
{{APIRef("DOM")}} {{Non-standard_header}}
- -

Свойство Node.baseURIObject возвращает {{Interface("nsIURI")}} представляющий базовый URL узла (обычно документ или элемент). Это похоже на {{domxref("Node.baseURI")}}, за исключением того, что возвращает nsIURI вместо строки.

- -

Это свойство существует на всех узлах (HTML, XUL, SVG, MathML, и т.д.), но только если скрипт пытается использовать его имея привилегии UniversalXPConnect.

- -

Смотрите {{domxref("Node.baseURI")}} для уточнения деталей что такое базовый URL.

- -

Синтаксис

- -
uriObj = node.baseURIObject
-
- -

Примечания

- -

Это свойство только для чтения; попытка записать информацию в него, будет сбрасывать исключения. Кроме того, это свойство может быть доступно только для привилегированного кода.

- -

Спецификация

- -

Нет какой-либо спецификации.

diff --git a/files/ru/web/api/node/innertext/index.html b/files/ru/web/api/node/innertext/index.html deleted file mode 100644 index ef23b48d59..0000000000 --- a/files/ru/web/api/node/innertext/index.html +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Node.innerText -slug: Web/API/Node/innerText -translation_of: Web/API/HTMLElement/innerText ---- -
{{APIRef("DOM")}}
- -

Node.innerText - это свойство, позволяющее задавать или получать текстовое содержимое элемента и его потомков. В качестве геттера, свойство приближается к тексту, который пользователь получит, если он выделит содержимое элемента курсором, затем копирует его в буфер обмена.

- -

Изначально, данное поведение было представленно Internet Explorer, и было формально специализированно в стандарте HTML в 2016 после того, как было адаптированно всеми ведущими браузерами.

- -

{{domxref("Node.textContent")}} - это альтернативное свойство, которое имеет ряд отличий:

- - - -

Спецификация

- - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'dom.html#the-innertext-idl-attribute', 'innerText')}}{{Spec2('HTML WHATWG')}}Представлено, основываясь на черновике спецификации innerText. См. whatwg/html#465 и whatwg/compat#5.
- -

Поддержка браузерами

- -

{{Compat("api.Node.innerText")}}

- -

Смотрите также

- - diff --git a/files/ru/web/api/node/nodeprincipal/index.html b/files/ru/web/api/node/nodeprincipal/index.html deleted file mode 100644 index 11b342e6c3..0000000000 --- a/files/ru/web/api/node/nodeprincipal/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Node.nodePrincipal -slug: Web/API/Node/nodePrincipal -translation_of: Web/API/Node -translation_of_original: Web/API/Node/nodePrincipal ---- -
-
{{APIRef("DOM")}}
-{{Non-standard_header}} - -

Свойство Node.nodePrincipal только для чтения, возвращающее объект {{Interface("nsIPrincipal")}}, представляющий текущий контекст безопасности узла.

- -

{{Note("Это свойство существует во всех узлах (HTML, XUL, SVG, MathML, и т.д.), но только если скрипт пытается использовать chrome привилегии.")}}

- -

Синтаксис

- -
principalObj = element.nodePrincipal
-
- -

Примечания

- -

Это свойство только для чтения; пытаясь вводить информацию в него, будет сбрасывать исключение.Кроме того, это свойство может быть доступно только для привилегированного кода.

- -

Спецификация

- -

Нет никакой спецификации.

-
- -

 

diff --git a/files/ru/web/api/node/replacechild/index.html b/files/ru/web/api/node/replacechild/index.html new file mode 100644 index 0000000000..6d69392c57 --- /dev/null +++ b/files/ru/web/api/node/replacechild/index.html @@ -0,0 +1,64 @@ +--- +title: Node.replaceChild +slug: Web/API/Node.replaceChild +tags: + - API + - DOM + - DOM Elements Method + - Gecko + - Method + - Node +translation_of: Web/API/Node/replaceChild +--- +
+ {{ApiRef}}
+

Аннотация

+

Заменяет дочерний элемент на выбранный. Возвращает замененный элемент.

+

Синтаксис

+
replacedNode = parentNode.replaceChild(newChild, oldChild);
+
+ +

Пример

+
// <div>
+//  <span id="childSpan">foo bar</span>
+// </div>
+
+// Создаем новый пустой элемент
+// without an ID, any attributes, or any content
+var sp1 = document.createElement("span");
+
+// Присваиваем ему id 'newSpan'
+sp1.setAttribute("id", "newSpan");
+
+// Создаем строку.
+var sp1_content = document.createTextNode("new replacement span element.");
+
+// Добавляем контент в созданный нами узел
+sp1.appendChild(sp1_content);
+
+// создаем ссылку на существующий элемент который будем заменять
+var sp2 = document.getElementById("childSpan");
+var parentDiv = sp2.parentNode;
+
+// заменяем существующий элемент sp2 на созданный нами sp1
+parentDiv.replaceChild(sp1, sp2);
+
+// Результат:
+// <div>
+//   <span id="newSpan">new replacement span element.</span>
+// </div>
+
+

Спецификация

+ +

См. также

+ diff --git a/files/ru/web/api/nondocumenttypechildnode/nextelementsibling/index.html b/files/ru/web/api/nondocumenttypechildnode/nextelementsibling/index.html new file mode 100644 index 0000000000..84c40445d8 --- /dev/null +++ b/files/ru/web/api/nondocumenttypechildnode/nextelementsibling/index.html @@ -0,0 +1,173 @@ +--- +title: NonDocumentTypeChildNode.nextElementSibling +slug: Web/API/NonDocumentTypeChildNode/NonDocumentTypeChildNode.nextElementSibling +translation_of: Web/API/NonDocumentTypeChildNode/nextElementSibling +--- +
{{APIRef("DOM")}}
+ +

NonDocumentTypeChildNode.nextElementSibling свойство только для чтения, возвращающее последующий элемент перед текущим, или null, если элемент является последним в своём родительском узле.

+ +

Синтаксис

+ +
var nextNode = elementNodeReference.nextElementSibling; 
+ +

Пример

+ +
<div id="div-01">Это div-01</div>
+<div id="div-02">Это div-02</div>
+
+<script type="text/javascript">
+  var el = document.getElementById('div-01').nextElementSibling;
+  console.log('Сосед div-01:');
+  while (el) {
+    console.log(el.nodeName);
+    el = el.nextElementSibling;
+  }
+</script>
+
+ +

Этот пример выведет в консоль следующее:

+ +
Сосед div-01:
+DIV
+SCRIPT
+ +

Полифилл для IE8

+ +

Данное свойство не пожддерживается до IE9. Используйте следующий полифилл, чтобы обойти этот недостаток:

+ +
// Источник: https://github.com/Alhadis/Snippets/blob/master/js/polyfills/IE8-child-elements.js
+if (!('nextElementSibling' in document.documentElement)) {
+    Object.defineProperty(Element.prototype, 'nextElementSibling', {
+        get: function() {
+            var e = this.nextSibling;
+            while (e && 1 !== e.nodeType) {
+                e = e.nextSibling;
+            }
+            return e;
+        }
+    });
+}
+ +

Полифилл для IE9+ и Safari

+ +
// Источник: https://github.com/jserz/js_piece/blob/master/DOM/NonDocumentTypeChildNode/nextElementSibling/nextElementSibling.md
+(function(arr) {
+    arr.forEach(function(item) {
+        if (item.hasOwnProperty('nextElementSibling')) {
+            return;
+        }
+        Object.defineProperty(item, 'nextElementSibling', {
+            configurable: true,
+            enumerable: true,
+            get: function() {
+                var el = this;
+                while (el = el.nextSibling) {
+                    if (el.nodeType === 1) {
+                        return el;
+                    }
+                }
+                return null;
+            },
+            set: undefined
+        });
+    });
+})([Element.prototype, CharacterData.prototype]);
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-nondocumenttypechildnode-nextelementsibling', 'ChildNodenextElementSibling')}}{{Spec2('DOM WHATWG')}}Split the ElementTraversal interface in {{domxref("ChildNode")}}, {{domxref("ParentNode")}}, and {{domxref("NonDocumentTypeChildNode")}}. This method is now defined on the former.
+ The {{domxref("Element")}} and {{domxref("CharacterData")}} interfaces implemented the new interface.
{{SpecName('Element Traversal', '#attribute-nextElementSibling', 'ElementTraversal.nextElementSibling')}}{{Spec2('Element Traversal')}}Added its initial definition to the ElementTraversal pure interface and use it on {{domxref("Element")}}.
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
БраузерыChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка ({{domxref("Element")}})4{{CompatGeckoDesktop("1.9.1")}}99.84
Поддержка {{domxref("CharacterData")}}29.0{{CompatGeckoDesktop("25")}} [1]{{CompatNo}}16.0{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
БраузерыAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка ( {{domxref("Element")}}){{CompatVersionUnknown}}{{CompatGeckoMobile("1.9.1")}}{{CompatVersionUnknown}}9.8{{CompatVersionUnknown}}
Поддержка {{domxref("CharacterData")}}{{CompatVersionUnknown}}{{CompatGeckoMobile("25")}}{{CompatNo}}16.0{{CompatNo}}
+
+ +

[1] Firefox 25 также добавил это свойство в {{domxref("DocumentType")}}, но оно было удалено в Firefox 28, из-за проблем совместимости.

+ +

См. также

+ + diff --git a/files/ru/web/api/nondocumenttypechildnode/nondocumenttypechildnode.nextelementsibling/index.html b/files/ru/web/api/nondocumenttypechildnode/nondocumenttypechildnode.nextelementsibling/index.html deleted file mode 100644 index 84c40445d8..0000000000 --- a/files/ru/web/api/nondocumenttypechildnode/nondocumenttypechildnode.nextelementsibling/index.html +++ /dev/null @@ -1,173 +0,0 @@ ---- -title: NonDocumentTypeChildNode.nextElementSibling -slug: Web/API/NonDocumentTypeChildNode/NonDocumentTypeChildNode.nextElementSibling -translation_of: Web/API/NonDocumentTypeChildNode/nextElementSibling ---- -
{{APIRef("DOM")}}
- -

NonDocumentTypeChildNode.nextElementSibling свойство только для чтения, возвращающее последующий элемент перед текущим, или null, если элемент является последним в своём родительском узле.

- -

Синтаксис

- -
var nextNode = elementNodeReference.nextElementSibling; 
- -

Пример

- -
<div id="div-01">Это div-01</div>
-<div id="div-02">Это div-02</div>
-
-<script type="text/javascript">
-  var el = document.getElementById('div-01').nextElementSibling;
-  console.log('Сосед div-01:');
-  while (el) {
-    console.log(el.nodeName);
-    el = el.nextElementSibling;
-  }
-</script>
-
- -

Этот пример выведет в консоль следующее:

- -
Сосед div-01:
-DIV
-SCRIPT
- -

Полифилл для IE8

- -

Данное свойство не пожддерживается до IE9. Используйте следующий полифилл, чтобы обойти этот недостаток:

- -
// Источник: https://github.com/Alhadis/Snippets/blob/master/js/polyfills/IE8-child-elements.js
-if (!('nextElementSibling' in document.documentElement)) {
-    Object.defineProperty(Element.prototype, 'nextElementSibling', {
-        get: function() {
-            var e = this.nextSibling;
-            while (e && 1 !== e.nodeType) {
-                e = e.nextSibling;
-            }
-            return e;
-        }
-    });
-}
- -

Полифилл для IE9+ и Safari

- -
// Источник: https://github.com/jserz/js_piece/blob/master/DOM/NonDocumentTypeChildNode/nextElementSibling/nextElementSibling.md
-(function(arr) {
-    arr.forEach(function(item) {
-        if (item.hasOwnProperty('nextElementSibling')) {
-            return;
-        }
-        Object.defineProperty(item, 'nextElementSibling', {
-            configurable: true,
-            enumerable: true,
-            get: function() {
-                var el = this;
-                while (el = el.nextSibling) {
-                    if (el.nodeType === 1) {
-                        return el;
-                    }
-                }
-                return null;
-            },
-            set: undefined
-        });
-    });
-})([Element.prototype, CharacterData.prototype]);
- -

Спецификации

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-nondocumenttypechildnode-nextelementsibling', 'ChildNodenextElementSibling')}}{{Spec2('DOM WHATWG')}}Split the ElementTraversal interface in {{domxref("ChildNode")}}, {{domxref("ParentNode")}}, and {{domxref("NonDocumentTypeChildNode")}}. This method is now defined on the former.
- The {{domxref("Element")}} and {{domxref("CharacterData")}} interfaces implemented the new interface.
{{SpecName('Element Traversal', '#attribute-nextElementSibling', 'ElementTraversal.nextElementSibling')}}{{Spec2('Element Traversal')}}Added its initial definition to the ElementTraversal pure interface and use it on {{domxref("Element")}}.
- -

Совместимость с браузерами

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
БраузерыChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка ({{domxref("Element")}})4{{CompatGeckoDesktop("1.9.1")}}99.84
Поддержка {{domxref("CharacterData")}}29.0{{CompatGeckoDesktop("25")}} [1]{{CompatNo}}16.0{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
БраузерыAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка ( {{domxref("Element")}}){{CompatVersionUnknown}}{{CompatGeckoMobile("1.9.1")}}{{CompatVersionUnknown}}9.8{{CompatVersionUnknown}}
Поддержка {{domxref("CharacterData")}}{{CompatVersionUnknown}}{{CompatGeckoMobile("25")}}{{CompatNo}}16.0{{CompatNo}}
-
- -

[1] Firefox 25 также добавил это свойство в {{domxref("DocumentType")}}, но оно было удалено в Firefox 28, из-за проблем совместимости.

- -

См. также

- - diff --git a/files/ru/web/api/notation/index.html b/files/ru/web/api/notation/index.html new file mode 100644 index 0000000000..a1f468a55d --- /dev/null +++ b/files/ru/web/api/notation/index.html @@ -0,0 +1,52 @@ +--- +title: Нотация +slug: Web/API/Нотация +tags: + - Нотация +translation_of: Web/API/Notation +--- +
{{APIRef("DOM")}}{{draft}}{{obsolete_header}}
+ +

Представляет нотацию DTD (только для чтения). Может объявлять формат неразобранного объекта или формально объявлять цели инструкции по обработке документа. Наследует методы и свойства от Node. Его nodeName - это имя нотации. Не имеет родителя.

+ +

Свойства

+ +
+
{{domxref("Notation.publicId")}} {{ReadOnlyInline}}
+
Это {{domxref("DOMString")}}.
+
{{domxref("Notation.systemId")}} {{ReadOnlyInline}}
+
Это {{domxref("DOMString")}}.
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName("DOM3 Core", "core.html#ID-5431D1B9", "Notation")}}{{Spec2("DOM3 Core")}}Без изменений
{{SpecName("DOM2 Core", "core.html#ID-5431D1B9", "Notation")}}{{Spec2("DOM2 Core")}}Без изменений
{{SpecName('DOM1', 'level-one-core.html#ID-5431D1B9', 'Notation')}}{{Spec2('DOM1')}}Первое определение
+ +

Поддержка браузерами

+ + + +

{{Compat("api.Notation")}}

diff --git a/files/ru/web/api/page_visibility_api/index.html b/files/ru/web/api/page_visibility_api/index.html new file mode 100644 index 0000000000..9b181e92d1 --- /dev/null +++ b/files/ru/web/api/page_visibility_api/index.html @@ -0,0 +1,195 @@ +--- +title: Видимость страницы API +slug: Web/API/Видимость_страницы_API +tags: + - API + - DOM + - Документ + - Показать страницу + - Скрыть страницу +translation_of: Web/API/Page_Visibility_API +--- +
{{DefaultAPISidebar("Page Visibility API")}}
+ +

При переключении между вкладками, web страница переходит в фоновый режим и поэтому не видна пользователю. Page Visibility API предоставляет события, которые вы можете отслеживать, чтобы узнать, когда страница станет видимой или скрытой, а так же возможность наблюдать текущее состояние видимости страницы.

+ +
+

Notes: The Page Visibility API особенно полезно для сбережения ресурсов и улучшения производительности, позволяя странице остановить выполнение не нужных задач, когда она не видна.

+
+ +

Когда пользователь сворачивает окно или переключается на другую вкладку, API отправляет {{event("visibilitychange")}} событие обработчикам, что состояние страницы изменилось. Вы можете отследить это событие и выполнить какие-то действия. Например, если ваше app проигрывает видео, его можно поставить на паузу, когда пользователь переключил вкладку (страница ушла в фон), а затем возобновить видео, когда пользователь вернулся на вкладку. Пользователь не теряет место на котором остановил просмотр, звук от видео не конфликтует с аудио новой вкладки, пользователь комфортно просмотрить оба видео.

+ +

Состояния видимости для {{HTMLElement("iframe")}} такие же как и для родительской страницы. Скрытие <iframe> используя CSS стили (такие как {{cssxref("display", "display: none;")}}) не вызывают события видимости и не изменяют состояние документа, содержащегося во фрейме.

+ +

Использование

+ +

Давайте рассмотрим несколько способов использования Page Visibility API.

+ + + +

Раньше у разработчиков были не удобные способы. Например, обработка {{event("blur")}} и {{event("focus")}} событий на объекте window - помогала узнать когда страница становилась не активной, но это не давало возможность понять когда страница действительно скрыта от пользователя. Page Visibility API решает эту проблему.

+ +
+

Note: Когда {{domxref("GlobalEventHandlers.onblur", "onblur")}} и {{domxref("GlobalEventHandlers.onfocus", "onfocus")}} уведомляют, что пользователь переключил окна, это не означает, что оно действительно скрыто. Страница действительно скрыта, когда пользователь переключил вкладки или свернул окно браузера с этой вкладкой.

+
+ +

Policies in place to aid background page performance

+ +

Separately from the Page Visibility API, user agents typically have a number of policies in place to mitigate the performance impact of background or hidden tabs. These may include:

+ + + +

Some processes are exempt from this throttling behavior. In these cases, you can use the Page Visibility API to reduce the tabs' performance impact while they're hidden.

+ + + +

Example

+ +

View live example (video with sound).

+ +

The example, which pauses the video when you switch to another tab and plays again when you return to its tab, was created with the following code:

+ +
// Set the name of the hidden property and the change event for visibility
+var hidden, visibilityChange;
+if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
+  hidden = "hidden";
+  visibilityChange = "visibilitychange";
+} else if (typeof document.msHidden !== "undefined") {
+  hidden = "msHidden";
+  visibilityChange = "msvisibilitychange";
+} else if (typeof document.webkitHidden !== "undefined") {
+  hidden = "webkitHidden";
+  visibilityChange = "webkitvisibilitychange";
+}
+
+var videoElement = document.getElementById("videoElement");
+
+// If the page is hidden, pause the video;
+// if the page is shown, play the video
+function handleVisibilityChange() {
+  if (document[hidden]) {
+    videoElement.pause();
+  } else {
+    videoElement.play();
+  }
+}
+
+// Warn if the browser doesn't support addEventListener or the Page Visibility API
+if (typeof document.addEventListener === "undefined" || hidden === undefined) {
+  console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
+} else {
+  // Handle page visibility change
+  document.addEventListener(visibilityChange, handleVisibilityChange, false);
+
+  // When the video pauses, set the title.
+  // This shows the paused
+  videoElement.addEventListener("pause", function(){
+    document.title = 'Paused';
+  }, false);
+
+  // When the video plays, set the title.
+  videoElement.addEventListener("play", function(){
+    document.title = 'Playing';
+  }, false);
+
+}
+
+ +

Properties added to the Document interface

+ +

The Page Visibility API adds the following properties to the {{domxref("Document")}} interface:

+ +
+
{{domxref("Document.hidden")}} {{ReadOnlyInline}}
+
Returns true if the page is in a state considered to be hidden to the user, and false otherwise.
+
{{domxref("Document.visibilityState")}} {{ReadOnlyInline}}
+
A {{domxref("DOMString")}} indicating the document's current visibility state. Possible values are: +
+
visible
+
The page content may be at least partially visible. In practice this means that the page is the foreground tab of a non-minimized window.
+
hidden
+
The page's content is not visible to the user, either due to the document's tab being in the background or part of a window that is minimized, or because the device's screen is off.
+
prerender
+
The page's content is being prerendered and is not visible to the user. A document may start in the prerender state, but will never switch to this state from any other state, since a document can only prerender once. +
Note: Not all browsers support prerendering.
+
+
unloaded
+
The page is in the process of being unloaded from memory. +
Note: Not all browsers support the unloaded value.
+
+
+
+
{{domxref("Document.onvisibilitychange")}}
+
An {{domxref("EventListener")}} providing the code to be called when the {{event("visibilitychange")}} event is fired.
+
+ +
//startSimulation and pauseSimulation defined elsewhere
+function handleVisibilityChange() {
+  if (document.hidden) {
+    pauseSimulation();
+  } else  {
+    startSimulation();
+  }
+}
+
+document.addEventListener("visibilitychange", handleVisibilityChange, false);
+
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Page Visibility API')}}{{Spec2('Page Visibility API')}}Initial definition.
+ +

Browser compatibility

+ +
+

Document.visibilityState

+ +
+ + +

{{Compat("api.Document.visibilityState")}}

+
+
+ +

See also

+ + diff --git a/files/ru/web/api/push_api/using_the_push_api/index.html b/files/ru/web/api/push_api/using_the_push_api/index.html deleted file mode 100644 index 40086e4e91..0000000000 --- a/files/ru/web/api/push_api/using_the_push_api/index.html +++ /dev/null @@ -1,420 +0,0 @@ ---- -title: Использование Push API -slug: Web/API/Push_API/Using_the_Push_API -translation_of: Web/API/Push_API -translation_of_original: Web/API/Push_API/Using_the_Push_API ---- -

W3C Push API предоставляет некоторый захватывающий новый функционал для разработчиков для использования в web-приложениях: эта статья предлагает вводную информацию о том, как настроить Push-уведомления и управлять ими, с помощью простого демо.

- -

Возможность посылать сообщения или уведомления от сервера клиенту в любое время — независимо от того, активно приложение или нет — было прерогативой нативных приложений некоторое время, и наконец пришло в Web! Поддерживается большинства возможностей Push сейчас возможна в браузерах Firefox 43+ и Chrome 42+ на настольных компьютерах, мобильные платформы, возможно, скоро присоединятся. {{domxref("PushMessageData")}} на данный момент экспериментально поддерживаются только в Firefox Nightly (44+), и реализация может меняться.

- -
-

Примечание: Ранние версии Firefox OS использовали проприетарную версию этого API вызывая Simple Push. Считается устаревшим по стандартам Push API.

-
- -

Демо: основы простого сервера чат-приложения

- -

Демо, котрые мы создали, представляет начальное описание простого чат-приложения. Оно представляет собой форму, в которую вводятся данные, и кнопку для подписки на push-сообщения . Как только кнопка будет нажата, вы подпишитесь на push-сообщения, ваши данные будут записаны на сервере, а отправленное push-сообщение сообщит всем текущим подписчикам, что кто-то подписался.

- -

На данном этапе, имя нового подписчика появится в списке подписчиков, вместе с текстовым полем и кнопкой рассылки, чтобы позволить подписчику отправить сообщение.

- -

- -

Чтобы запустить демо, следуйте инструкциям на странице push-api-demo README. Заметте, что серверная компонента все еще нуждается в небольшой доработке для запуска в Chrome и в общем запусается более разумным путем. Но аспекты Push все еще могут быть полностью понятны; мы углубимся в это после того, как просмотрим технологии в процессе.

- -

Обзор технологии

- -

Эта секция предоставляет описание того, какие технологии учавствуют в примере.

- -

Web Push-сообщения это часть семейства технологий сервис воркеров; в первую очередь, для получения push-сообщений сервис воркер должен быть активирован на странице. Сервис воркер получает push-сообщения, и затем вы сами решаете, как уведомить об этом страницу. Вы можете:

- - - -

Обычно необходима комбинация этих двух решений; демо внизу включает пример обоих.

- -
-

Примечание: Вам необходим некоторый код, запущенный на сервере, для управления конечной точкой/шифроманием данных и отправки запросов push-сообщений. В нашем демо мы собрали на скорую руку сервер, используя NodeJS.

-
- -

Сервис воркер так же должен подписаться на сервис push-сообщений. Каждой сессии предоставляется собственная уникальная конечная точка, когда она подписывается на сервис push-сообщений. Эта конечная точка получается из свойства  ({{domxref("PushSubscription.endpoint")}}) объекта подписчика. Она может быть отправлена серверу и использоваться для пересылки сообщений активному сервис воркеру сессии. Каждый браузер имеет свой собсвтенный сервер push-сообщений для  управления отправкой push-сообщений.

- -

Шифрование

- -
-

Примечание: Для интерактивного краткого обзора, попробуйте JR Conlin's Web Push Data Encryption Test Page.

-
- -

Для отправки данных с помошью push-сообщений необходимо шифрование. Для этого необходим публичный ключ, созданный с использованием метода  {{domxref("PushSubscription.getKey()")}}, который основывается на некотором комплексе механизмов шифрования, которые выполняются на стороне сервера; читайте Message Encryption for Web Push. Со временем появятся библиотеки для управления генерацией ключей и шифроманием/дешифрованием push-сообщений; для этого демо мы используем Marco Castelluccio's NodeJS web-push library.

- -
-

Примечание: Есть так же другая библиотека для управления шифрованием с помошью Node и Python, смотри encrypted-content-encoding.

-
- -

Обобщение рабочего процесса Push

- -

Общие сведения ниже это то, что необходимо для реализации push-сообщений. Вы можете найти больше информации о некоторых частях демо в последующих частях.

- -
    -
  1. Запрос на разрешение web-уведомлений или что-то другое, что вы используете и для чего необходимо разрешение.
  2. -
  3. Регистрация сервис воркера для контроля над страницей с помошью вызова {{domxref("ServiceWorkerContainer.register()")}}.
  4. -
  5. Подписка на сервис push-уведомлений с помошью {{domxref("PushManager.subscribe()")}}.
  6. -
  7. Запрашивание конечной точки, соответствующей подписчику, и генерация публичного ключа клиента ({{domxref("PushSubscription.endpoint")}} и {{domxref("PushSubscription.getKey()")}}. Заметте, что getKey() на данный момент эксперементальная технологий и доступна только в Firefox.)
  8. -
  9. Отправка данных на сервер, чтобы тот мог присылать push-сообщения, когда необходимо. Это демо использует {{domxref("XMLHttpRequest")}}, но вы можете использовать Fetch.
  10. -
  11. Если вы используете Channel Messaging API для связи с сервис воркером, установите новый канал связи ({{domxref("MessageChannel.MessageChannel()")}}) и отправте port2 сервис воркеру с помошью вызова {{domxref("Worker.postMessage()")}} для того, чтобы открыть канал связи. Вы так же должны настроить слушателя для ответов на сообщения, которые будут отправляться обратно с сервис воркера.
  12. -
  13. На стороне сервера сохраните конечную точку и все остальные необходимые данные, чтобы они были доступны, когда будет необходимо отправить push-сообщение добавленному подписчику (мы используем простой текстовый файл, но вы можете использовать базу данных или все что угодно на ваш вкус). В приложении на продакшене убедитесь, что скрываете эти данные, так что злоумышленники не смогут украсть конечную точку и разослать спам подписчикам в push-сообщениях.
  14. -
  15. Для отправки push-сообщений необходимо отослать HTTP POST конечному URL. Запрос должен включать TTL заголовок, который ограничивает время пребывания сообщения в очереди, если пользователь не в сети. Для добавления полезной информации в запросе, необходимо зашифровать ее (что включает публичнй ключ клиента). В нашем примере мы используем web-push модуль, который управляет всей тяжелой работой.
  16. -
  17. Поверх в сервис воркере настройте обработчик событий push для ответов на полученные push-сообщения. -
      -
    1. Если вы хотите отвечать отправкой сообщения канала обратно основному контексту (смотри шаг 6), необходимо сначала получить ссылку на port2, который был отправлен контексту сервис воркера ({{domxref("MessagePort")}}). Это доступно в объекте  {{domxref("MessageEvent")}}, передаваемого обработчику onmessage ({{domxref("ServiceWorkerGlobalScope.onmessage")}}). Конкретнее, он находится в свойстве ports, индекс 0. Когда это сделано, вы можете отправить сообщение обратно port1, используя {{domxref("MessagePort.postMessage()")}}.
    2. -
    3. Если вы хотитет ответить запуском системного уведомления, вы можете сделать это, вызвав {{domxref("ServiceWorkerRegistration.showNotification()")}}. Заметте, что в нашем коде мы вызываем его внутри метода {{domxref("ExtendableEvent.waitUntil()")}} — это растягивает время жизни события, пока уведомление не будет запущено, так что мы можем убедиться, что все, что мы хотели, чтобы произошло, действительно произошло.
    4. -
    -
  18. -
- -

Сборка демо

- -

Давайте пройдемся по коду для демо, чтобы понять, как все работает.

- -

HTML и CSS

- -

Нет ничего примечательного в HTML и CSS демо; HTML содержит простую форму для ввода данных для фхода в чат, кнопку для подписки на push-уведомления и двух списков, в которых перечислены подписчики и сообщения чата. После подписки появляются дополнительные средства для того, чтобы пользователь мог ввести сообщение в чат.

- -

CSS был оставлен очень минимальным, чтобы не отвлекать от объяснения того, как функционируют Push API.

- -

Основной файл JavaScript

- -

 JavaScript очевидно намного более существенный. Давайте взглянем на основной файл JavaScript.

- -

Переменные и начальные настройки

- -

Для начала определим некоторые переменные, которые будем использовать в нашем приложении:

- -
var isPushEnabled = false;
-var useNotifications = false;
-
-var subBtn = document.querySelector('.subscribe');
-var sendBtn;
-var sendInput;
-
-var controlsBlock = document.querySelector('.controls');
-var subscribersList = document.querySelector('.subscribers ul');
-var messagesList = document.querySelector('.messages ul');
-
-var nameForm = document.querySelector('#form');
-var nameInput = document.querySelector('#name-input');
-nameForm.onsubmit = function(e) {
-  e.preventDefault()
-};
-nameInput.value = 'Bob';
- -

Сначала нам необходимо создать две булевы переменные, для того чтобы отслеживать подписку на push-сообщения и подтверждение разрешения на рассылку уведомлений.

- -

Далее, мы перехватываем ссылку на {{htmlelement("button")}} подписки/отписки и задаем переменные для сохранения ссылок на наши кнопку отправки сообщения/ввода (который создастся только после успешной подписки).
-
- Следующие переменные перехватывают ссылки на три основные {{htmlelement("div")}} элемента, так что мы можем включить в них элементы (к примеру, когда появится кнопка Отправки Сообщения Чата или сообщение появится с писке Сообщений).

- -

Finally we grab references to our name selection form and {{htmlelement("input")}} element, give the input a default value, and use preventDefault() to stop the form submitting when the form is submitted by pressing return.

- -

Next, we request permission to send web notifications, using {{domxref("Notification.requestPermission","requestPermission()")}}:

- -
Notification.requestPermission();
- -

Now we run a section of code when onload is fired, to start up the process of inialising the app when it is first loaded. First of all we add a click event listener to the subscribe/unsubscribe button that runs our unsubscribe() function if we are already subscribed (isPushEnabled is true), and subscribe() otherwise:

- -
window.addEventListener('load', function() {
-  subBtn.addEventListener('click', function() {
-    if (isPushEnabled) {
-      unsubscribe();
-    } else {
-      subscribe();
-    }
-  });
- -

Next we check to see if service workers are supported. If so, we register a service worker using {{domxref("ServiceWorkerContainer.register()")}}, and run our initialiseState() function. If not, we deliver an error message to the console.

- -
  // Check that service workers are supported, if so, progressively
-  // enhance and add push messaging support, otherwise continue without it.
-  if ('serviceWorker' in navigator) {
-    navigator.serviceWorker.register('sw.js').then(function(reg) {
-      if(reg.installing) {
-        console.log('Service worker installing');
-      } else if(reg.waiting) {
-        console.log('Service worker installed');
-      } else if(reg.active) {
-        console.log('Service worker active');
-      }
-
-      initialiseState(reg);
-    });
-  } else {
-    console.log('Service workers aren\'t supported in this browser.');
-  }
-});
-
- -

The next thing in the source code is the initialiseState() function — for the full commented code, look at the initialiseState() source on Github (we are not repeating it here for brevity's sake.)

- -

initialiseState() first checks whether notifications are supported on service workers, then sets the useNotifications variable to true if so. Next, it checks whether said notifications are permitted by the user, and if push messages are supported, and reacts accordingly to each.

- -

Finally, it uses {{domxref("ServiceWorkerContainer.ready()")}} to wait until the service worker is active and ready to start doing things. Once its promise resolves, we retrieve our subscription to push messaging using the {{domxref("ServiceWorkerRegistration.pushManager")}} property, which returns a {{domxref("PushManager")}} object that we then call {{domxref("PushManager.getSubscription()")}} on. Once this second inner promise resolves, we enable the subscribe/unsubscribe button (subBtn.disabled = false;), and check that we have a subscription object to work with.

- -

If we do, then we are already subscribed. This is possible when the app is not open in the browser; the service worker can still be active in the background. If we're subscribed, we update the UI to show that we are subscribed by updating the button label, then we set isPushEnabled to true, grab the subscription endpoint from {{domxref("PushSubscription.endpoint")}}, generate a public key using {{domxref("PushSubscription.getKey()")}}, and run our updateStatus() function, which as you'll see later communicates with the server.

- -

As an added bonus, we set up a new {{domxref("MessageChannel")}} using the {{domxref("MessageChannel.MessageChannel()")}} constructor, grab a reference to the active service worker using {{domxref("ServiceworkerRegistration.active")}}, then set up a channel betweeen the main browser context and the service worker context using {{domxref("Worker.postMessage()")}}. The browser context receives messages on {{domxref("MessageChannel.port1")}}; whenever that happens, we run the handleChannelMessage() function to decide what to do with that data (see the {{anch("Handling channel messages sent from the service worker")}} section).

- -

Subscribing and unsubscribing

- -

Let's now turn our attention to the subscribe() and unsubscribe() functions used to subscribe/unsubscribe to the push notification service.

- -

In the case of subscription, we again check that our service worker is active and ready by calling {{domxref("ServiceWorkerContainer.ready()")}}. When the promise resolves, we subscribe to the service using {{domxref("PushManager.subscribe()")}}. If the subscription is successful, we get a {{domxref("PushSubscription")}} object, extract the subscription endpoint from this and generate a public key (again, {{domxref("PushSubscription.endpoint")}} and {{domxref("PushSubscription.getKey()")}}), and pass them to our updateStatus() function along with the update type (subscribe) to send the necessary details to the server.

- -

We also make the necessary updates to the app state (set isPushEnabled to true) and UI (enable the subscribe/unsubscribe button and set its label text to show that the next time it is pressed it will unsubscribe.)

- -

The unsubscribe() function is pretty similar in structure, but it basically does the opposite; the most notable difference is that it gets the current subscription using {{domxref("PushManager.getSubscription()")}}, and when that promise resolves it unsubscribes using {{domxref("PushSubscription.unsubscribe()")}}.

- -

Appropriate error handling is also provided in both functions.  

- -

We only show the subscribe() code below, for brevity; see the full subscribe/unsubscribe code on Github.

- -
function subscribe() {
-  // Disable the button so it can't be changed while
-  // we process the permission request
-
-  subBtn.disabled = true;
-
-  navigator.serviceWorker.ready.then(function(reg) {
-    reg.pushManager.subscribe({userVisibleOnly: true})
-      .then(function(subscription) {
-        // The subscription was successful
-        isPushEnabled = true;
-        subBtn.textContent = 'Unsubscribe from Push Messaging';
-        subBtn.disabled = false;
-
-        // Update status to subscribe current user on server, and to let
-        // other users know this user has subscribed
-        var endpoint = subscription.endpoint;
-        var key = subscription.getKey('p256dh');
-        updateStatus(endpoint,key,'subscribe');
-      })
-      .catch(function(e) {
-        if (Notification.permission === 'denied') {
-          // The user denied the notification permission which
-          // means we failed to subscribe and the user will need
-          // to manually change the notification permission to
-          // subscribe to push messages
-          console.log('Permission for Notifications was denied');
-
-        } else {
-          // A problem occurred with the subscription, this can
-          // often be down to an issue or lack of the gcm_sender_id
-          // and / or gcm_user_visible_only
-          console.log('Unable to subscribe to push.', e);
-          subBtn.disabled = false;
-          subBtn.textContent = 'Subscribe to Push Messaging';
-        }
-      });
-  });
-}
- -

Updating the status in the app and server

- -

The next function in our main JavaScript is updateStatus(), which updates the UI for sending chat messages when subscribing/unsubscribing and sends a request to update this information on the server.

- -

The function does one of three different things, depending on the value of the statusType parameter passed into it:

- - - -

Again, we have not included the entire function listing for brevity. Examine the full updateStatus() code on Github.

- -

Handling channel messages sent from the service worker

- -

As mentioned earlier, when a channel message is received from the service worker, our handleChannelMessage() function is called to handle it. This is done by our handler for the {{event("message")}} event, {{domxref("channel.port1.onmessage")}}:

- -
channel.port1.onmessage = function(e) {
-  handleChannelMessage(e.data);
-}
- -

This occurs when the service worker sends a channel message over.

- -

The handleChannelMessage() function looks like this:

- -
function handleChannelMessage(data) {
-  if(data.action === 'subscribe' || data.action === 'init') {
-    var listItem = document.createElement('li');
-    listItem.textContent = data.name;
-    subscribersList.appendChild(listItem);
-  } else if(data.action === 'unsubscribe') {
-    for(i = 0; i < subscribersList.children.length; i++) {
-      if(subscribersList.children[i].textContent === data.name) {
-        subscribersList.children[i].parentNode.removeChild(subscribersList.children[i]);
-      }
-    }
-    nameInput.disabled = false;
-  } else if(data.action === 'chatMsg') {
-    var listItem = document.createElement('li');
-    listItem.textContent = data.name + ": " + data.msg;
-    messagesList.appendChild(listItem);
-    sendInput.value = '';
-  }
-}
- -

What happens here depends on what the action property on the data object is set to:

- - - -
-

Note: We have to pass the data back to the main context before we do DOM updates because service workers don't have access to the DOM. You should be aware of the limitations of service workers before attemping to ue them. Read Using Service Workers for more details.

-
- -

Sending chat messages

- -

When the Send Chat Message button is clicked, the content of the associated text field is sent as a chat message. This is handled by the sendChatMessage() function (again, not shown in full for brevity). This works in a similar way to the different parts of the updateStatus() function (see {{anch("Updating the status in the app and server")}}) — we retrieve an endpoint and public key via a {{domxref("PushSubscription")}} object, which is itself retrieved via {{domxref("ServiceWorkerContainer.ready()")}} and {{domxref("PushManager.subscribe()")}}. These are sent to the server via {{domxref("XMLHttpRequest")}} in a message object, along with the name of the subscribed user, the chat message to send, and a statusType of chatMsg.

- -

The server

- -

As mentioned above, we need a server-side component in our app, to handle storing subscription details, and send out push messages when updates occur. We've hacked together a quick-and-dirty server using NodeJS (server.js), which handles the XHR requests sent by our client-side JavaScript code.

- -

It uses a text file (endpoint.txt) to store subscription details; this file starts out empty. There are four different types of request, marked by the statusType property of the object sent over in the request; these are the same as those understood client-side, and perform the required server actions for that same situation. Here's what each means in the context of the server:

- - - -

A couple more things to note:

- - - -

The service worker

- -

Now let's have a look at the service worker code (sw.js), which responds to the push messages, represented by {{Event("push")}} events. These are handled on the service worker's scope by the ({{domxref("ServiceWorkerGlobalScope.onpush")}}) event handler; its job is to work out what to do in response to each received message. We first convert the received message back into an object by calling {{domxref("PushMessageData.json()")}}. Next, we check what type of push message it is, by looking at the object's action property:

- - - -
self.addEventListener('push', function(event) {
-  var obj = event.data.json();
-
-  if(obj.action === 'subscribe' || obj.action === 'unsubscribe') {
-    fireNotification(obj, event);
-    port.postMessage(obj);
-  } else if(obj.action === 'init' || obj.action === 'chatMsg') {
-    port.postMessage(obj);
-  }
-});
- -

Next, let's look at the fireNotification() function (which is blissfully pretty simple).

- -
function fireNotification(obj, event) {
-  var title = 'Subscription change';
-  var body = obj.name + ' has ' + obj.action + 'd.';
-  var icon = 'push-icon.png';
-  var tag = 'push';
-
-  event.waitUntil(self.registration.showNotification(title, {
-    body: body,
-    icon: icon,
-    tag: tag
-  }));
-}
- -

Here we assemble the assets needed by the notification box: the title, body, and icon. Then we send a notification via the {{domxref("ServiceWorkerRegistration.showNotification()")}} method, providing that information as well as the tag "push", which we can use to identify this notification among any other notifications we might be using. When the notification is successfully sent, it manifests as a system notification dialog on the users computers/devices in whatever style system notifications look like on those systems (the following image shows a Mac OSX system notification.)

- -

- -

Note that we do this from inside an {{domxref("ExtendableEvent.waitUntil()")}} method; this is to make sure the service worker remains active until the notification has been sent. waitUntil() will extend the life cycle of the service worker until everything inside this method has completed.

- -
-

Note: Web notifications from service workers were introduced around Firefox version 42, but are likely to be removed again while the surrounding functionality (such as Clients.openWindow()) is properly implemented (see {{bug(1203324)}} for more details.)

-
- -

Handling premature subscription expiration

- -

Sometimes push subscriptions expire prematurely, without {{domxref("PushSubscription.unsubscribe()")}} being called. This can happen when the server gets overloaded, or if you are offline for a long time, for example.  This is highly server-dependent, so the exact behavior is difficult to predict. In any case, you can handle this problem by watching for the {{Event("pushsubscriptionchange")}} event, which you can listen for by providing a {{domxref("ServiceWorkerGlobalScope.onpushsubscriptionchange")}} event handler; this event is fired only in this specific case.

- -
self.addEventListener('pushsubscriptionchange', function() {
-  // do something, usually resubscribe to push and
-  // send the new subscription details back to the
-  // server via XHR or Fetch
-});
- -

Note that we don't cover this case in our demo, as a subscription ending is not a big deal for a simple chat server. But for a more complex example you'd probably want to resubscribe the user.

- -

Extra steps for Chrome support

- -

To get the app working on Chrome, we need a few extra steps, as Chrome currently relies on Google's Cloud Messaging service to work.

- -

Setting up Google Cloud Messaging

- -

To get this set up, follow these steps:

- -
    -
  1. Navigate to the Google Developers Console  and set up a new project.
  2. -
  3. Go to your project's homepage (ours is at https://console.developers.google.com/project/push-project-978, for example), then -
      -
    1. Select the Enable Google APIs for use in your apps option.
    2. -
    3. In the next screen, click Cloud Messaging for Android under the Mobile APIs section.
    4. -
    5. Click the Enable API button.
    6. -
    -
  4. -
  5. Now you need to make a note of your project number and API key because you'll need them later. To find them: -
      -
    1. Project number: click Home on the left; the project number is clearly marked at the top of your project's home page.
    2. -
    3. API key: click Credentials on the left hand menu; the API key can be found on that screen.
    4. -
    -
  6. -
- -

manifest.json

- -

You need to include a Google app-style manifest.json file in your app, which references the project number you made a note of earlier in the gcm_sender_id parameter. Here is our simple example manifest.json:

- -
{
-  "name": "Push Demo",
-  "short_name": "Push Demo",
-  "icons": [{
-        "src": "push-icon.png",
-        "sizes": "111x111",
-        "type": "image/png"
-      }],
-  "start_url": "/index.html",
-  "display": "standalone",
-  "gcm_sender_id": "224273183921"
-}
- -

You also need to reference your manifest using a {{HTMLElement("link")}} element in your HTML:

- -
<link rel="manifest" href="manifest.json">
- -

userVisibleOnly

- -

Chrome requires you to set the userVisibleOnly parameter to true when subscribing to the push service, which indicates that we are promising to show a notification whenever a push is received. This can be seen in action in our subscribe() function.

- -

See also

- - - -
-

Note: Some of the client-side code in our Push demo is heavily influenced by Matt Gaunt's excellent examples in Push Notifications on the Open Web. Thanks for the awesome work, Matt!

-
diff --git a/files/ru/web/api/randomsource/getrandomvalues/index.html b/files/ru/web/api/randomsource/getrandomvalues/index.html deleted file mode 100644 index c59f5dde54..0000000000 --- a/files/ru/web/api/randomsource/getrandomvalues/index.html +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: RandomSource.getRandomValues() -slug: Web/API/RandomSource/getRandomValues -tags: - - АПИ - - Криптография - - Справка - - метод -translation_of: Web/API/Crypto/getRandomValues ---- -

{{APIRef("Web Crypto API")}}

- -

Метод RandomSource.getRandomValues() позволяет вам получать криптографически стойкие числа. Массив, переданный как параметр, заполняется случайными числами (случайными в криптографическом смысле).

- -

Для того, чтобы гарантировать достаточную производительность, реализации используют не настоящий генератор случайных чисел (RNG, en - Random Number Generator), а генератор псевдо-случайных чисел, которому предоставлено начальное зерно (wiki - https://en.wikipedia.org/wiki/Random_seed) с достаточной энтропией (http://cryptography.ru/ref/энтропия). Реализация генератора псевдо-случайных чисел (PRNG, en - PseudoRandom Number Generator) отличается от других реализаций RNG, но она больше подходит для использования в криптографии. Реализации также требуют использование начального зерна с достаточной энтропией, как источник системно-уровневой энтропии.

- -

Синтаксис

- -
cryptoObj.getRandomValues(typedArray);
- -

Параметры

- -
-
typedArray
-
Целочисленный массив {{jsxref("TypedArray")}}, например {{jsxref("Int8Array")}}, {{jsxref("Uint8Array")}}, {{jsxref("Uint16Array")}}, {{jsxref("Int32Array")}}, или {{jsxref("Uint32Array")}}. Все элементы массива замещаются случайными числами.
-
- -

Исключения

- - - -

Пример

- -
/* Предполагается что функция window.crypto.getRandomValues доступна */
-
-var array = new Uint32Array(10);
-window.crypto.getRandomValues(array);
-
-console.log("Ваше счастливое число:");
-for (var i = 0; i < array.length; i++) {
-    console.log(array[i]);
-}
-
- -

Спецификация

- - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('Web Crypto API', '#RandomSource-method-getRandomValues')}}{{Spec2('Web Crypto API')}}Изначальное определение
- -

Совместимость с браузерами

- -

{{Compat("api.Crypto.getRandomValues")}}

- -

Смотрите также

- - diff --git a/files/ru/web/api/randomsource/index.html b/files/ru/web/api/randomsource/index.html deleted file mode 100644 index d56506a90a..0000000000 --- a/files/ru/web/api/randomsource/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: RandomSource -slug: Web/API/RandomSource -tags: - - API - - Interface - - NeedsTranslation - - RandomSource - - Reference - - TopicStub - - Web Crypto API -translation_of: Web/API/Crypto/getRandomValues -translation_of_original: Web/API/RandomSource ---- -

{{APIRef("Web Crypto API")}}

- -

RandomSource представляет собой источник криптографически безопасных случайных чисел. Он доступен через {{domxref("Crypto")}} объект глобального объекта: {{domxref("Window.crypto")}} на веб страницах, {{domxref("WorkerGlobalScope.crypto")}} для воркеров.

- -

RandomSource не является интерфейсом и объект этого типа не может быть создан.

- -

Свойства

- -

RandomSource не объявляет и не наследует никаких свойств.

- -
-
- -

Методы

- -
-
{{ domxref("RandomSource.getRandomValues()") }}
-
Наполняет {{ domxref("ArrayBufferView") }} криптографически безопасными случайными числовыми значениями.
-
- -

Спецификации

- - - - - - - - - - - - - - -
СпецификацияСтатусКоммент
{{SpecName('Web Crypto API', '#dfn-RandomSource')}}{{Spec2('Web Crypto API')}}Изначальное определение
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка11.0 {{ webkitbug("22049") }}{{CompatGeckoDesktop(21)}} [1]11.015.03.1
-
- -
- - - - - - - - - - - - - - - - - - - - - -
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{ CompatNo() }}23{{CompatGeckoMobile(21)}}{{ CompatNo() }}{{ CompatNo() }}6
-
- -

[1] Although the transparent RandomSource is only available since Firefox 26, the feature was available in Firefox 21.

- -

Смотрите также

- - diff --git a/files/ru/web/api/slotable/index.html b/files/ru/web/api/slotable/index.html deleted file mode 100644 index af6ec4765c..0000000000 --- a/files/ru/web/api/slotable/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Slotable -slug: Web/API/Slotable -tags: - - миксины -translation_of: Web/API/Slottable -translation_of_original: Web/API/Slotable ---- -

{{APIRef("Shadow DOM")}}

- -

Миксин Slotable определяет возможности, которые позволяют нодам становиться контентом элемента {{htmlelement("slot")}} — следующие возможности включены в  {{domxref("Element")}} и {{domxref("Text")}}.

- -

Свойства

- -
-
{{domxref("Slotable.assignedSlot")}} {{readonlyInline}}
-
Возвращает {{htmlelement("slot")}}, в который вставлена нода.
-
- -

Методы

- -

Нет.

- -

Спецификации

- - - - - - - - - - - - - - -
СпецификацияСтатусКомментарии
{{SpecName('DOM WHATWG','#slotable','Slotable')}}{{Spec2('DOM WHATWG')}}Первое определение.
- -

Поддержка браузерами

- - - -

{{Compat("api.Slotable")}}

diff --git a/files/ru/web/api/storage/localstorage/index.html b/files/ru/web/api/storage/localstorage/index.html deleted file mode 100644 index f0fab82609..0000000000 --- a/files/ru/web/api/storage/localstorage/index.html +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: LocalStorage -slug: Web/API/Storage/LocalStorage -translation_of: Web/API/Window/localStorage -translation_of_original: Web/API/Web_Storage_API/Local_storage ---- -

localStorage это аналог sessionStorage, с некоторыми same-origin правилами, но значения хранятся постоянно (в отличии от sessions). localStorage появился в Firefox 3.5.

- -
Примечание: Когда браузер переходит в режим приватного просмотра, создается новое временное хранилище. Изначально оно пустое. После выхода из режима приватного просмотра временное хранилище очищается.
- -
// Сохраняет данные в текущий local store
-localStorage.setItem("username", "John");
-
-// Извлекает ранее сохраненные данные
-alert( "username = " + localStorage.getItem("username"));
- -

localStorage's позволяет постоянно хранить некоторую полезную информацию, включая счетчики посещения страницы, как показано в примере this tutorial on Codepen.

- -

Совместимость

- -

Storage objects недавно добавлен в стандарт. Он может отсутствовать в некоторых браузерах. Вы можете работать с этой технологией добавив в страницу один из двух скриптов, которые представлены ниже. localStorage object реализуется програмно, если нет встроенной реализации.

- -

Этот алгоритм является точной имитацией localStorage object, но для хранения использует cookies.

- -
if (!window.localStorage) {
-  Object.defineProperty(window, "localStorage", new (function () {
-    var aKeys = [], oStorage = {};
-    Object.defineProperty(oStorage, "getItem", {
-      value: function (sKey) { return sKey ? this[sKey] : null; },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "key", {
-      value: function (nKeyId) { return aKeys[nKeyId]; },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "setItem", {
-      value: function (sKey, sValue) {
-        if(!sKey) { return; }
-        document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
-      },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "length", {
-      get: function () { return aKeys.length; },
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "removeItem", {
-      value: function (sKey) {
-        if(!sKey) { return; }
-        document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
-      },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "clear", {
-      value: function () {
-        if(!aKeys.length) { return; }
-        for (var sKey in aKeys) {
-          document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
-        }
-      },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    this.get = function () {
-      var iThisIndx;
-      for (var sKey in oStorage) {
-        iThisIndx = aKeys.indexOf(sKey);
-        if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
-        else { aKeys.splice(iThisIndx, 1); }
-        delete oStorage[sKey];
-      }
-      for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
-      for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx < aCouples.length; nIdx++) {
-        aCouple = aCouples[nIdx].split(/\s*=\s*/);
-        if (aCouple.length > 1) {
-          oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]);
-          aKeys.push(iKey);
-        }
-      }
-      return oStorage;
-    };
-    this.configurable = false;
-    this.enumerable = true;
-  })());
-}
-
- -
Примечание: Максимальныйe размер данных, которые могут быть сохранены, ограничен возможностями cookies. Используйте functions localStorage.setItem() и localStorage.removeItem() для добавления, изменения, или удаления ключа. Использование прямого присвоения localStorage.yourKey = yourValue; и delete localStorage.yourKey; для установки и удаления ключа не безопасно с этим кодом. Вы также можете изменить это имя (вместо window.localStorage прописать другое имя) и использовать объект для управления document's cookies, не обращая внимания на localStorage object.
- -
Примечание: Если изменить строку "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" на: "; path=/" (и изменить имя объекта), он превратится в sessionStorage polyfill больше, чем в localStorage polyfill. Однако эта реализация будет хранить общие значения для всех вкладок и окон браузера (and will only be cleared when all browser windows have been closed), в то время как полностью совместимая sessionStorage реализация хранит значения to the current browsing context only.
- -

Here is another, less exact, imitation of the localStorage object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8 (tested and working even in Internet Explorer 6). It also makes use of cookies.

- -
if (!window.localStorage) {
-  window.localStorage = {
-    getItem: function (sKey) {
-      if (!sKey || !this.hasOwnProperty(sKey)) { return null; }
-      return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
-    },
-    key: function (nKeyId) {
-      return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]);
-    },
-    setItem: function (sKey, sValue) {
-      if(!sKey) { return; }
-      document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
-      this.length = document.cookie.match(/\=/g).length;
-    },
-    length: 0,
-    removeItem: function (sKey) {
-      if (!sKey || !this.hasOwnProperty(sKey)) { return; }
-      document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
-      this.length--;
-    },
-    hasOwnProperty: function (sKey) {
-      return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
-    }
-  };
-  window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length;
-}
-
- -
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.getItem()localStorage.setItem(), and localStorage.removeItem() to get, add, change, or remove a key. The use of method localStorage.yourKey in order to get, set, or delete a key is not permitted with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
- -
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.
- -

Compatibility and relation with globalStorage

- -

localStorage is also the same as globalStorage[location.hostname], with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and localStorage being an instance of Storage as opposed to globalStorage[location.hostname] being an instance of StorageObsolete which is covered below. For example, http://example.com is not able to access the same localStorage object as https://example.com but they can access the same globalStorage item. localStorage is a standard interface while globalStorage is non-standard so you shouldn't rely on these.

- -

Please note that setting a property on globalStorage[location.hostname] does not set it on localStorage and extending Storage.prototype does not affect globalStorage items; only extending StorageObsolete.prototype does.

- -

Storage format

- -

Storage keys and values are both stored in the UTF-16 DOMString format, which uses 2 bytes per character.

- -

 

diff --git a/files/ru/web/api/svgaelement/svgalement.target/index.html b/files/ru/web/api/svgaelement/svgalement.target/index.html deleted file mode 100644 index dcd76310d4..0000000000 --- a/files/ru/web/api/svgaelement/svgalement.target/index.html +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: SVGAElement.target -slug: Web/API/SVGAElement/SVGAlement.target -translation_of: Web/API/SVGAElement/target -translation_of_original: Web/API/SVGAElement/SVGAlement.target ---- -

{{APIRef("SVGAElement")}}

- -

 

- -

Свойство SVGAElement.target для чтения только {{domxref ("SVGAElement")}} возвращает объект {{domxref ("SVGAnimatedString")}}, который указывает часть целевого окна, фрейма, панель, в которую открывается при активации ссылки.

- -

Это свойство используется, когда существует множество возможных целей для конечного ресурса, например, когда родительский документ является документом HTML или HTML-документом mlti-frame.

- -

 

- -

Синтаксис

- -
myLink.target = 'value';
- -

Стоимость

- -

{{Domxref ("SVGAnimatedString")}}, указывающий конечную цель ресурса, которая открывает документ при активации ссылки.

- -

Значения для {{domxref ("target")}} можно увидеть here

- -

Пример

- -

Код  взят из "SVGAElement example code"

- -
...
-var linkRef = document.querySelector('a');
-linkRef.target ='_blank';
-...
- -

Характеристики

- - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('SVG1.1', 'text.html#InterfaceSVGAElement', 'target')}}{{Spec2('SVG1.1')}} 
- -

Совместимость с браузером

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}9.0{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -

Смотрите также

- - diff --git a/files/ru/web/api/web_crypto_api/checking_authenticity_with_password/index.html b/files/ru/web/api/web_crypto_api/checking_authenticity_with_password/index.html deleted file mode 100644 index ea8ec86586..0000000000 --- a/files/ru/web/api/web_crypto_api/checking_authenticity_with_password/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Проверка подлинности данных с паролем -slug: Web/API/Web_Crypto_API/Checking_authenticity_with_password -tags: - - HMAC - - Web Crypto -translation_of: Web/API/Web_Crypto_API/Checking_authenticity_with_password ---- -

{{APIRef("Web Crypto API")}}{{draft}}

- -

Проверка подлинности данных может быть выполнена с помощью Web Crypto API. В этой статье мы покажем как создавать и управлять подписями, используя хэш-функцию и пароль.

- -

HMAC алгоритм генерирует хэш на основе передаваемых ключа и данных, которые нужно подписать. Позже, идентичный хэш может быть вычислен заного любым пользователем, у которого имеется ключ. Необходимость ключа позволяет хранить данные и хэш вместе: злоумышленник не сможет создать хэш для измененных данных, не имея ключа.

- -

Стоит заметить, что алгоритм никак не связан с какой-либо другой информацией о владельце: знание ключа – необходимое и достаточное условие для изменения данных.

- -

Предположим, данные хранятся на компьютере. Чтобы получить доступ к записи или чтению, мы будем использовать localforage.js – библиотека-обертка над хранилищами браузера. Эта библиотека необязательна и используется в качестве примера для удобства, чтобы сосредоточиться на криптографии.

- -

Данные, доступ к которым мы хотим получить, имеют следующую форму:

- -

 

- -

где data – данные для подписания и signature – подпись, информация для проверки подлинности.

- -

Криптографические ключи невозможно выучить наизусть, а обычные пароли недостаточно безопасны. Чтобы решить эту проблему, криптографы создали алгоритмы для создания криптографических ключей из паролей. Знание пароля позволяет воссоздать ключ и использовать его.

- -

Запрашиваем пароль у пользователя для генерации ключа:

- -
 
- -

С этим ключом мы можем вычислить хэш данных.

- -
 
diff --git a/files/ru/web/api/web_workers_api/using_web_workers/index.html b/files/ru/web/api/web_workers_api/using_web_workers/index.html new file mode 100644 index 0000000000..7503eccacb --- /dev/null +++ b/files/ru/web/api/web_workers_api/using_web_workers/index.html @@ -0,0 +1,871 @@ +--- +title: Использование Web Workers +slug: DOM/Using_web_workers +tags: + - воркер + - поток +translation_of: Web/API/Web_Workers_API/Using_web_workers +--- +
{{DefaultAPISidebar("Web Workers API")}}
+ +

Web Worker-ы предоставляют простое средство для запуска скриптов в фоновом потоке. Поток Worker'а может выполнять задачи без вмешательства в пользовательский интерфейс. К тому же, они могут осуществлять ввод/вывод, используя XMLHttpRequest (хотя атрибуты responseXML и channel всегда будут равны null). Существующий Worker может отсылать сообщения JavaScript коду-создателю через обработчик событий, указанный этим кодом (и наоборот). Эта статья дает детальную инструкцию по использованию Web Workers.

+ +

Web Workers API

+ +

Worker - это объект, создаваемый конструктором (например, {{domxref("Worker.Worker", "Worker()")}}) и запускающий именной JavaScript файл — этот файл содержит код, который будет выполнен в потоке Worker'а; объекты же Workers запускаются в другом глобальном контексте, отличающемся от текущего, - {{domxref("window")}}. Поэтому использование переменной {{domxref("window")}} для получения текущего глобального контекста (вместо {{domxref("window.self","self")}}) внутри {{domxref("Worker")}} вернет ошибку.

+ +

Контекст Worker'а представлен объектом {{domxref("DedicatedWorkerGlobalScope")}} в случае выделенных Workers (обычные Workers используются одним скриптом; совместные Workers используют объект {{domxref("SharedWorkerGlobalScope")}}). Выделенный Worker доступен только из скрипта-родителя, в то время как совместные Workers могут быть доступны из нескольких сценариев.

+ +
+

Заметка: Смотрите страницу Web Workers API для справки по Workers и прочие руководства.

+
+ +

Вы можете запускать любой код внутри потока worker-а, за некоторыми исключениями. Например, вы не можете прямо манипулировать DOM внутри worker-а, или использовать некоторые методы по умолчанию и свойства объекта {{domxref("window")}}. Но вы можете использовать большой набор опций, доступный под Window, включая WebSockets, и механизмы хранения данных, таких как IndexedDB и относящихся только к Firefox OS Data Store API. Для дополнительной информации смотрите Functions and classes available to workers.

+ +

Данные передаются между worker-ами и главным потоком через систему сообщений — обе стороны передают свои сообщения, используя метод postMessage() и отвечают на сообщения при помощи обработчика событий onmessage (сообщение хранится в аттрибуте data события {{event("Message")}}). Данные при этом копируются, а не делятся.

+ +

Объекты Workers могут, в свою очередь, создавать новые объекты workers, и так до тех пор, пока всё работает в рамках текущей страницы. Плюс к этому, объекты workers могут использовать XMLHttpRequest для сетевого ввода/вывода, но есть исключение - атрибуты responseXML и channel объекта XMLHttpRequest всегда возвращают null.

+ +

Выделенные Workers

+ +

Как уже упоминалось выше, выделенный Worker доступен только для скрипта, который его вызвал. В этом разделе речь пойдет о JavaScript, который можно найти в нашем основном примере выделенного Worker (запустить скрипт): этот пример позволяет ввести два числа для умножения. Эти числа отправляются в Worker, перемножаются, а результат возвращается на страницу и отображается.

+ +

Этот пример достаточно тривиален, но для ознакомления с базовыми концепциями worker-ов мы решили его упростить. Более продвинутые детали описаны далее в статье.

+ +

Определение поддержки Worker

+ +

Для большего контроля над ошибками и обратной совместимости, рекомендуется обернуть ваш код доступа к worker-у в следующий (main.js):

+ +
if (window.Worker) {
+
+  ...
+
+}
+ +

Создание выделенного worker

+ +

Создание нового worker-а — это легко. Всё что вам нужно это вызвать конструктор {{domxref("Worker.Worker", "Worker()")}}, указав URI скрипта для выполнения в потоке worker-а (main.js):

+ +
+
var myWorker = new Worker("worker.js");
+
+
+ +

Передача сообщений в и из выделенного worker

+ +

Магия worker-ов происходит через {{domxref("Worker.postMessage", "postMessage()")}} метод и обработчик событий {{domxref("Worker.onmessage", "onmessage")}}. Когда вы хотите отправить сообщение в worker, вы доставляете сообщение к нему вот так (main.js):

+ +
first.onchange = function() {
+  myWorker.postMessage([first.value,second.value]);
+  console.log('Message posted to worker');
+}
+
+second.onchange = function() {
+  myWorker.postMessage([first.value,second.value]);
+  console.log('Message posted to worker');
+}
+ +

В приведенном фрагменте кода мы имеем два {{htmlelement("input")}} элемента, представленных переменными first и second; когда значение любой из переменных изменяется, myWorker.postMessage([first.value,second.value]) используется для отправки обоих значений, представленных в виде массива, в worker. Посредством аргумента message возможна передача практически любых данных в worker.

+ +

Внутри worker-a мы можем обрабатывать сообщения и отвечать на них при помощи добавления обработчика события onmessage подобным образом (worker.js):

+ +
onmessage = function(e) {
+  console.log('Message received from main script');
+  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
+  console.log('Posting message back to main script');
+  postMessage(workerResult);
+}
+ +

Обработчик onmessage позволяет нам запустить некий код всякий раз, когда получен пакет с сообщением, доступным в атрибуте data события message. В примере выше мы просто перемножаем вместе две цифры, после чего используем postMessage() снова, чтобы отправить полученный результат назад в основной поток.

+ +

Возвращаясь в основной поток, мы используем onmessage снова, чтобы отреагировать на сообщение, отправленное нам назад из worker-а:

+ +
myWorker.onmessage = function(e) {
+  result.textContent = e.data;
+  console.log('Message received from worker');
+}
+ +

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

+ +

Заметка: Обратите внимание, что onmessage()​ и postmessage() должны вызываться из экземпляра Worker в главном потоке, но не в потоке worker-а. Это связано с тем, что внутри потока worker-а, worker выступает в качестве глобального объекта.

+ +

Заметка: При передаче сообщения между основным потоком и потоком worker-а, оно копируется или "передается" (перемещается), не делится между потоками. Читайте {{anch("Transferring data to and from workers: further details")}} для более подробного объяснения.

+ +

Завершение работы worker-а

+ +

Прекращение работы worker-а главного потока достигается методом {{domxref("Worker", "terminate")}}:

+ +
myWorker.terminate();
+ +

Поток worker-а немедленно уничтожается.

+ +

Обработка ошибок

+ +

При ошибке во время выполнения worker-а, вызывается его обработчик событий onerror. Он принимает событие error, которое реализует интерфейс ErrorEvent.

+ +

Событие не всплывает и его можно отменить. Для отмены действия по умолчанию, worker может вызвать метод preventDefault() в обработчике события ошибки.

+ +

У события ошибки есть три поля, которые представляют интерес:

+ +
+
message
+
Сообщение об ошибке в читаемом виде.
+
filename
+
Имя файла со скриптом, в котором ошибка произошла.
+
lineno
+
Номер строки в файле, в котором произошла ошибка.
+
+ +

Создание subworkers

+ +

Worker-ы могут запускать другие worker-ы. Так называемые sub-worker'ы должны быть того же происхождения (same-origin), что и родительский документ. Кроме того, URI для subworker-ов рассчитываются относительно родительского worker'а, а не родительского документа. Это позволяет worker-ам проще следить за тем, где находятся их зависимости.

+ +

Импорт скриптов и библиотек

+ +

Worker потоки имеют доступ к глобальной функции, importScripts(), которая позволяет импортировать скрипты с того же домена в их область видимости. Функция принимает ноль и более URI параметров, как список ссылок на ресурсы для импорта; все нижеприведенные примеры верны:

+ +
importScripts();                        /* imports nothing */
+importScripts('foo.js');                /* imports just "foo.js" */
+importScripts('foo.js', 'bar.js');      /* imports two scripts */
+
+ +

Браузер загружает каждый указанный скрипт и исполняет его. Любые глобальные объекты, создаваемые каждым скриптом могут быть использованы в worker'е. Если скрипт не удалось загрузить, будет брошена ошибка NETWORK_ERROR, и последующий код не будет исполнен. Тем не менее код, исполненный ранее (включая отложенный при помощи {{domxref("window.setTimeout()")}}) останется функционален. Объявления функций идущие после вызова метода importScripts() также будут доступны, т.к. объявления функций всегда обрабатываются перед остальным кодом.

+ +
Заметка: Скрипты могут быть загружены в произвольном порядке, но их исполнение будет в  том порядке, в котором имена файлов были переданы в importScripts(). Функция выполняется синхронно; importScripts() не вернет исполнение, пока все скрипты не будут загружены и исполнены.
+ +

Разделяемые worker-ы (Shared workers)

+ +

Разделяемый worker доступен нескольким разным скриптам — даже если они находятся в разных окнах, фреймах или даже worker-ах. В этом разделе мы обсудим JavaScript, который можно найти в нашем базовом примере разделяемых worker-ов (запустить разделяемый worker): Он очень похож на базовый пример выделенных worker-ов, за исключением двух функций, которые доступны из разных скриптовых файлов: умножение двух чисел или возведение числа в степень. Оба скрипта используют один и тот же worker для необходимых вычислений.

+ +

Здесь мы сосредоточимся на разнице между выделенными и раздялемыми worker-ами. Обратите внимание, что в данном примере есть две HTML страницы с JavaScript кодом, которые используют один и тот же файл worker-а.

+ +
+

Заметка: Если разделяемый worker может быть доступен из нескольких контекстов просмотра, то все они должны иметь одно и то же происхождение (одни и те же протокол, хост и порт).

+
+ +
+

Заметка: В Firefox разделяемый worker не может быть использован совместно документами в приватном и неприватном окне ({{bug(1177621)}}).

+
+ +

Создание разделяемого worker-а

+ +

Запуск разделяемого worker-а очень похож на запуск выделенного worker-а, но используется другой конструктор (см. index.html и index2.html) — в каждом документе необходимо поднять worker, для этого следует написать такой код:

+ +
var myWorker = new SharedWorker("worker.js");
+ +

Большая разница заключается в том, что с разделяемым worker-ом необходимо взаимодействовать через объект port — явно открыв порт, с помощью которого скрипты могут взаимодействовать с worker-ом (в случае выделенного worker-а это происходит неявно).

+ +

Соединение с портом должно быть осуществлено либо неявно, используя обработчик событие onmessage, либо явно, вызвав метод start() перед тем, как отправлять любые сообщения. Вызов метода start() необходим только тогда, когда подписка на событие реализована через метод addEventListener().

+ +
+

Заметка: Когда используется метод start() чтобы открыть соединение с портом, его необходимо вызывать и в родительском потоке и в потоке worker-а, если необходима двухсторонняя коммуникация.

+
+ +
myWorker.port.start();  // в родительском потоке
+ +
port.start();  // в потоке worker-а, где переменная port является ссылкой на порт
+ +

Передача сообщений в/из разделяемого worker-а

+ +

Теперь сообщения могут быть отправлены worker-у, как и прежде, но метод postMessage() должен вызываться из объекта port (еще раз, вы можете увидеть схожие кострукции в multiply.js и square.js):

+ +
squareNumber.onchange = function() {
+  myWorker.port.postMessage([squareNumber.value,squareNumber.value]);
+  console.log('Message posted to worker');
+}
+ +

Теперь на стороне worker-а. Здесь код немного сложнее (worker.js):

+ +
self.addEventListener('connect', function(e) { // требуется addEventListener()
+  var port = e.ports[0];
+  port.onmessage = function(e) {
+    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
+    port.postMessage(workerResult);
+  }
+  port.start();  // вызов необязательный, т.к. используется обработчик событий onmessage
+});
+ +

Первый этап состоит из события onconnect. Оно срабатывает, когда произошло подключение (т.е. когда в родительском потоке отработало событие onmessage или когда в нем был вызван метод start()).

+ +

Мы используем атрибут события ports, чтобы получить порт и сохранить его в переменной.

+ +

Второй этап — это обработчик события message на сохраненном порту. Он нужен для подсчета и вывода результата вычисления в основной поток. Установка обработчика message в потоке worker-а также открывает подключение к родительскому потоку, поэтому вызов на port.start() на самом деле не нужен (см. код обработчика onconnect).

+ +

Последний этап — возвращение в основной поток и обработка сообщения от worker‑а (еще раз, вы можете увидеть схожие конструкции в multiply.js и square.js):

+ +
myWorker.port.onmessage = function(e) {
+  result2.textContent = e.data[0];
+  console.log('Message received from worker');
+}
+ +

Когда сообщение приходит через порт от worker-а, мы проверяем тип результата вычислений и затем вставляем его в соответствующий абзац.

+ +

О потоковой безопасности

+ +

Интерфейс {{domxref("Worker")}} создаёт настоящие потоки на уровне операционной системы, что может смутить опытных программистов и навести их на мысли о проблемах, связанных с конфликтом доступа к общим объектам.

+ +

На самом деле создать такие проблемы достаточно сложно, так как worker-ы жёстко контролируются. У них нет доступа к непотокобезопасным объектам DOM, а все данные между потоками передаются в качестве сериализованных объектов. Придётся очень постараться, чтобы вызывать проблемы потокобезопасности в вашем коде.

+ +

Передача данных в и из worker-ов: другие детали

+ +

Передача данных между главной страницей и worker-ом происходит путем копирования, а не передачи по ссылке. Объекты сериализуются при передаче и затем десериализуются на другом конце. Страница и worker не используют совместно одни и те же экземпляры, для каждого создается свой. Большинство браузеров реализуют это структурированным клонированием (structured cloning).

+ +

Для иллюстрации этого мы создадим функцию emulateMessage(), которая будет имитировать поведение значения, которое клонируется, но не используется совместно при переходе от worker-а к главной странице или наоборот.

+ +
function emulateMessage (vVal) {
+    return eval("(" + JSON.stringify(vVal) + ")");
+}
+
+// Tests
+
+// test #1
+var example1 = new Number(3);
+console.log(typeof example1); // object
+console.log(typeof emulateMessage(example1)); // number
+
+// test #2
+var example2 = true;
+console.log(typeof example2); // boolean
+console.log(typeof emulateMessage(example2)); // boolean
+
+// test #3
+var example3 = new String("Hello World");
+console.log(typeof example3); // object
+console.log(typeof emulateMessage(example3)); // string
+
+// test #4
+var example4 = {
+    "name": "John Smith",
+    "age": 43
+};
+console.log(typeof example4); // object
+console.log(typeof emulateMessage(example4)); // object
+
+// test #5
+function Animal (sType, nAge) {
+    this.type = sType;
+    this.age = nAge;
+}
+var example5 = new Animal("Cat", 3);
+alert(example5.constructor); // Animal
+alert(emulateMessage(example5).constructor); // Object
+ +

Значения, которые клонируются и совместно не используются, называются сообщениями. Как вы, возможно, знаете, сообщения могут быть отправлены в главную страницу и из нее, используя postMessage(), и {{domxref("MessageEvent.data", "data")}}, содержа данные, передаваемые из worker-а.

+ +

example.html: (главная страница):

+ +
var myWorker = new Worker("my_task.js");
+
+myWorker.onmessage = function (oEvent) {
+  console.log("Worker said : " + oEvent.data);
+};
+
+myWorker.postMessage("ali");
+ +

my_task.js (worker):

+ +
postMessage("I\'m working before postMessage(\'ali\').");
+
+onmessage = function (oEvent) {
+  postMessage("Hi " + oEvent.data);
+};
+ +

Алгоритм структурированного клонирования может принять JSON и некоторые вещи, которые JSON не может принять, например, циклические ссылки.

+ +

Примеры передачи данных

+ +

Пример #1: Расширенная передача JSON данных и создание системы коммутации

+ +

Если вам нужно передать сложные данные и вызвать множество различных функций как на главной странице, так и в worker-е, вы можете создать следующую систему.

+ +

В первую очередь мы создаем класс QueryableWorker, который принимает url worker-а, стандартный обработчик событий (defaultListener) и обработчик ошибок. Этот класс будет отслеживать всех обработчиков и поможет нам общаться с воркером.

+ +
function QueryableWorker(url, defaultListener, onError) {
+    var instance = this,
+        worker = new Worker(url),
+        listeners = {};
+
+    this.defaultListener = defaultListener || function() {};
+
+    if (onError) {worker.onerror = onError;}
+
+    this.postMessage = function(message) {
+        worker.postMessage(message);
+    }
+
+    this.terminate = function() {
+        worker.terminate();
+    }
+}
+
+ +

Затем мы добавляем методы добавления/удаления обработчиков.

+ +
this.addListeners = function(name, listener) {
+    listeners[name] = listener;
+}
+
+this.removeListeners = function(name) {
+    delete listeners[name];
+}
+
+ +

Здесь мы создадим у worker-а два простых события для примера: получение разницы двух чисел и создание оповещения через три секунды. Но сначала нам нужно реализовать метод sendQuery, который проверит есть ли вообще у worker-а обработчик, который мы собираемся вызвать.

+ +
/*
+  Эта функция принимает по крайней мере один аргумент: имя метода, который мы хотим вызвать.
+  Далее мы можем передать методу необходимые ему аргументы.
+ */
+this.sendQuery = function() {
+    if (arguments.length < 1) {
+         throw new TypeError('QueryableWorker.sendQuery takes at least one argument');
+         return;
+    }
+    worker.postMessage({
+        'queryMethod': arguments[0],
+        'queryArguments': Array.prototype.slice.call(arguments, 1)
+    });
+}
+
+ +

Завершим QueryableWorker методом onmessage.  Если worker имеет соответствующий метод, который мы запросили, он также должен вернуть соответствующий обработчик и аргументы, которые нам нужны. Останется лишь найти его в listeners:

+ +
worker.onmessage = function(event) {
+    if (event.data instanceof Object &&
+        event.data.hasOwnProperty('queryMethodListener') &&
+        event.data.hasOwnProperty('queryMethodArguments')) {
+        listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
+    } else {
+        this.defaultListener.call(instance, event.data);
+    }
+}
+
+ +

Теперь к самому worker-у. Сначала следует определить эти два простых метода:

+ +
var queryableFunctions = {
+    getDifference: function(a, b) {
+        reply('printStuff', a - b);
+    },
+    waitSomeTime: function() {
+        setTimeout(function() {
+            reply('doAlert', 3, 'seconds');
+        }, 3000);
+    }
+}
+
+function reply() {
+    if (arguments.length < 1) {
+        throw new TypeError('reply - takes at least one argument');
+        return;
+    }
+    postMessage({
+        queryMethodListener: arguments[0],
+        queryMethodArguments: Array.prototype.slice.call(arguments, 1)
+    });
+}
+
+/* This method is called when main page calls QueryWorker's postMessage method directly*/
+function defaultReply(message) {
+    // do something
+}
+
+ +

И onmessage:

+ +
onmessage = function(event) {
+    if (event.data instanceof Object &&
+        event.data.hasOwnProperty('queryMethod') &&
+        event.data.hasOwnProperty('queryMethodArguments')) {
+        queryableFunctions[event.data.queryMethod]
+            .apply(self, event.data.queryMethodArguments);
+    } else {
+        defaultReply(event.data);
+    }
+}
+ +

Полный код примера:

+ +

example.html (основная страница):

+ +
<!doctype html>
+  <html>
+    <head>
+      <meta charset="UTF-8"  />
+      <title>MDN Example - Queryable worker</title>
+    <script type="text/javascript">
+    /*
+      QueryableWorker instances methods:
+        * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function
+        * postMessage(string or JSON Data): see Worker.prototype.postMessage()
+        * terminate(): terminates the Worker
+        * addListener(name, function): adds a listener
+        * removeListener(name): removes a listener
+      QueryableWorker instances properties:
+        * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
+     */
+    function QueryableWorker(url, defaultListener, onError) {
+      var instance = this,
+      worker = new Worker(url),
+      listeners = {};
+
+      this.defaultListener = defaultListener || function() {};
+
+      if (onError) {worker.onerror = onError;}
+
+      this.postMessage = function(message) {
+        worker.postMessage(message);
+      }
+
+      this.terminate = function() {
+        worker.terminate();
+      }
+
+      this.addListener = function(name, listener) {
+        listeners[name] = listener;
+      }
+
+      this.removeListener = function(name) {
+        delete listeners[name];
+      }
+
+      /*
+        This functions takes at least one argument, the method name we want to query.
+        Then we can pass in the arguments that the method needs.
+      */
+      this.sendQuery = function() {
+        if (arguments.length < 1) {
+          throw new TypeError('QueryableWorker.sendQuery takes at least one argument');
+          return;
+        }
+        worker.postMessage({
+          'queryMethod': arguments[0],
+          'queryMethodArguments': Array.prototype.slice.call(arguments, 1)
+        });
+      }
+
+      worker.onmessage = function(event) {
+        if (event.data instanceof Object &&
+          event.data.hasOwnProperty('queryMethodListener') &&
+          event.data.hasOwnProperty('queryMethodArguments')) {
+          listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
+        } else {
+          this.defaultListener.call(instance, event.data);
+        }
+      }
+    }
+
+    // your custom "queryable" worker
+    var myTask = new QueryableWorker('my_task.js');
+
+    // your custom "listeners"
+    myTask.addListener('printStuff', function (result) {
+      document.getElementById('firstLink').parentNode.appendChild(document.createTextNode('The difference is ' + result + '!'));
+    });
+
+    myTask.addListener('doAlert', function (time, unit) {
+      alert('Worker waited for ' + time + ' ' + unit + ' :-)');
+    });
+</script>
+</head>
+<body>
+  <ul>
+    <li><a id="firstLink" href="javascript:myTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li>
+    <li><a href="javascript:myTask.sendQuery('waitSomeTime');">Wait 3 seconds</a></li>
+    <li><a href="javascript:myTask.terminate();">terminate() the Worker</a></li>
+  </ul>
+</body>
+</html>
+ +

my_task.js (код worker-а):

+ +
var queryableFunctions = {
+  // пример #1: получить разницу между двумя числами
+  getDifference: function(nMinuend, nSubtrahend) {
+      reply('printStuff', nMinuend - nSubtrahend);
+  },
+  // пример #2: подождать три секунды
+  waitSomeTime: function() {
+      setTimeout(function() { reply('doAlert', 3, 'seconds'); }, 3000);
+  }
+};
+
+// системные функции
+
+function defaultReply(message) {
+  // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly
+  // do something
+}
+
+function reply() {
+  if (arguments.length < 1) { throw new TypeError('reply - not enough arguments'); return; }
+  postMessage({ 'queryMethodListener': arguments[0], 'queryMethodArguments': Array.prototype.slice.call(arguments, 1) });
+}
+
+onmessage = function(oEvent) {
+  if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty('queryMethod') && oEvent.data.hasOwnProperty('queryMethodArguments')) {
+    queryableFunctions[oEvent.data.queryMethod].apply(self, oEvent.data.queryMethodArguments);
+  } else {
+    defaultReply(oEvent.data);
+  }
+};
+
+ +

Можно переключать содержимое каждой главной страницы -> worker и worker -> сообщение главной страницы. И имена свойств "queryMethod", "queryMethodListeners", "queryMethodArguments" могут быть любыми пока они согласуются с QueryableWorker и worker.

+ +

Передача данных с помощью передачи владения (передаваемые объекты)

+ +

Google Chrome 17+ and Firefox 18+ имеют дополнительную возможность передачи определенных типов объектов (передаваемые объекты реализующие {{domxref("Transferable")}} интерфейс) к или из worker-а с высокой призводительностью. Эти объекты передаются из одного контекста в другой без операций копирования, что приводит к значительному повышению производительности при отправке больших наборов данных. Думайте об этом как о передаче по ссылке в мире C/C++. Однако в отличии от передачи по ссылке, "версия" из вызывающего контекста больше недоступна после передачи. Владельцем становится новый контекст.  Для примера, после передачи {{domxref("ArrayBuffer")}} из главной страницы к worker-у,  исходный {{domxref("ArrayBuffer")}} очищается и более недоступен для использования.  Его содержание (в буквальном смысле) переносится в рабочий контекст.

+ +
// Create a 32MB "file" and fill it.
+var uInt8Array = new Uint8Array(1024*1024*32); // 32MB
+for (var i = 0; i < uInt8Array.length; ++i) {
+  uInt8Array[i] = i;
+}
+
+worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
+
+ +
+

Заметка: Для дополнительной информации о передаваемых объектах, производительности и поддержки для этого метода, читайте  Transferable Objects: Lightning Fast! на HTML5 Rocks.

+
+ +

Встроенные worker-ы

+ +

Не существует утвержденного способа встроить код worker-а в рамках веб-страницы, как элемент {{HTMLElement("script")}} делает для обычных скриптов. Но элемент {{HTMLElement("script")}}, который не имеет аттрибута src и аттрибута  type, которому не назначен выполняемый MIME type, можно считать блоком данных для использования JavaScript. Блок данных "Data blocks" — это более общее свойство HTML5, может содержать любые текстовые данные. Так, worker может быть встроен следующим образом:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>MDN Example - Embedded worker</title>
+<script type="text/js-worker">
+  // Этот script НЕ БУДЕТ анализироваться JS движками, потому что  его MIME-тип text/js-worker.
+  var myVar = 'Hello World!';
+  // Остальная часть кода вашего воркера идет сюда.
+</script>
+<script type="text/javascript">
+  // Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.
+  function pageLog(sMsg) {
+    // Use a fragment: browser will only render/reflow once.
+    var oFragm = document.createDocumentFragment();
+    oFragm.appendChild(document.createTextNode(sMsg));
+    oFragm.appendChild(document.createElement('br'));
+    document.querySelector('#logDisplay').appendChild(oFragm);
+  }
+</script>
+<script type="text/js-worker">
+  // Этот script НЕ БУДЕТ анализироваться JS движками, потому что его MIME-тип text/js-worker.
+  onmessage = function(oEvent) {
+    postMessage(myVar);
+  };
+  // Остальная часть кода вашего воркера идет сюда.
+</script>
+<script type="text/javascript">
+  // Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.
+
+  // В прошлом...:
+  // blob builder существовал
+  // ... но теперь мы используем Blob...:
+  var blob = new Blob(Array.prototype.map.call(document.querySelectorAll('script[type=\'text\/js-worker\']'), function (oScript) { return oScript.textContent; }),{type: 'text/javascript'});
+
+  // Создание нового свойства document.worker, содержащего все наши "text/js-worker" скрипты.
+  document.worker = new Worker(window.URL.createObjectURL(blob));
+
+  document.worker.onmessage = function(oEvent) {
+    pageLog('Received: ' + oEvent.data);
+  };
+
+  // Запуск воркера.
+  window.onload = function() { document.worker.postMessage(''); };
+</script>
+</head>
+<body><div id="logDisplay"></div></body>
+</html>
+
+ +
Встраиваемый worker теперь внесен в новое custom свойство document.worker
+ +
+ +
Также стоит отметить, что вы также можете преобразовать функцию в BLOB-объект, а затем сгенерировать URL объекта из этого BLOB-объекта. Например:
+ +
function fn2workerURL(fn) {
+  var blob = new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'})
+  return URL.createObjectURL(blob)
+}
+
+ +

Другие примеры

+ +

В этой секции представлено еще несколько примеров как использовать worker-ы.

+ +

Выполнение вычислений в фоне

+ +

Worker-ы в основном полезны для того, чтобы позволить вашему коду выполнять ресурсоемкие вычисления, не блокируя поток пользовательского интерфейса. В этом примере, worker используется для вычисления числа Фибоначчи.

+ +

Код JavaScript

+ +

Следующий код JavaScript хранится в файле "fibonacci.js", на который ссылается HTML в следующем разделе.

+ +
var results = [];
+
+function resultReceiver(event) {
+  results.push(parseInt(event.data));
+  if (results.length == 2) {
+    postMessage(results[0] + results[1]);
+  }
+}
+
+function errorReceiver(event) {
+  throw event.data;
+}
+
+onmessage = function(event) {
+  var n = parseInt(event.data);
+
+  if (n == 0 || n == 1) {
+    postMessage(n);
+    return;
+  }
+
+  for (var i = 1; i <= 2; i++) {
+    var worker = new Worker("fibonacci.js");
+    worker.onmessage = resultReceiver;
+    worker.onerror = errorReceiver;
+    worker.postMessage(n - i);
+  }
+ };
+ +

Worker устанавливает свойство onmessage для функции,  которая будет получать сообщения, отправленные при вызове postMessage() рабочего объекта (обратите внимание, что это отличается от определения глобальной переменной с таким именем или определения функции с таким именем. var onmessage и function onmessage будет определять глобальные свойства с этими именами , но они не будут регистрировать функцию для получения сообщений, отправленных веб-страницей, которая создала worker). Это запускает рекурсию, порождая новые копии для обработки каждой итерации вычисления.

+ +

HTML код

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8"  />
+    <title>Test threads fibonacci</title>
+  </head>
+  <body>
+
+  <div id="result"></div>
+
+  <script language="javascript">
+
+    var worker = new Worker('fibonacci.js');
+
+    worker.onmessage = function(event) {
+      document.getElementById('result').textContent = event.data;
+      dump('Got: ' + event.data + '\n');
+    };
+
+    worker.onerror = function(error) {
+      dump('Worker error: ' + error.message + '\n');
+      throw error;
+    };
+
+    worker.postMessage('5');
+
+  </script>
+  </body>
+</html>
+ +

Веб-страница создает элемент div с ID result , который используется для отображения результата, а затем порождает worker. После порождения worker-а, обработчик onmessage настроен для отображения результатов путем установки содержимого элемента div, и обработчик onerror настроен на выброс сообщения об ошибке.

+ +

Наконец, сообщение отправляется worker-у, чтобы запустить его.

+ +

Попробуйте этот пример.

+ +

Выполнение веб I/O в фоне

+ +

Вы можете найти пример этого в статье Использование worker-ов в расширениях.

+ +

Разделение задач между множественными worker-ами

+ +

Поскольку многоядерные компьютеры становятся все более распространенными, часто бывает полезно разделить вычислительно сложные задачи между несколькими worker-ами, которые затем могут выполнить эти задачи на многопроцессорных ядрах.

+ +

Другие типы worker-ов

+ +

В дополнение к выделенным и совместно используемым web worker-ам доступны другие типы worker-ов:

+ + + +

Функции и интерфейсы доступные в worker-ах

+ +

Внутри web worker-а вы можете использовать большинство стандартных функций JavaScript, включая:

+ + + +

Главное, что вы не можете сделать в Worker это напрямую повлиять на родительскую страницу. Это включает в себя манипулирование DOM и использование объектов этой страницы. Вы должны сделать это косвенно, отправив сообщение обратно основному сценарию через {{domxref("DedicatedWorkerGlobalScope.postMessage")}}, а затем выполнив изменения оттуда.

+ +
+

Заметка: Для знакомства с  полным списком функций,  доступных для worker-ов, смотрите статью Функции и интерфейсы доступные worker-ам.

+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', '#toc-workers')}}{{Spec2('HTML WHATWG')}}Без изменений {{SpecName("Web Workers")}}.
{{SpecName('Web Workers')}}{{Spec2('Web Workers')}}Начальное определение.
+ +

Браузерная совместимость

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support4[1]{{CompatGeckoDesktop("1.9.1")}}10.010.6[1]4[2]
Shared workers4[1]{{CompatGeckoDesktop(29)}}{{CompatNo}}10.65
+ {{CompatNo}} 6.1[4]
Passing data using structured cloning13{{CompatGeckoDesktop(8)}}10.011.56
Passing data using transferable objects17 {{property_prefix("webkit")}}
+ 21
{{CompatGeckoDesktop(18)}}{{CompatNo}}156
Global {{domxref("window.URL", "URL")}}10[3]
+ 23
{{CompatGeckoDesktop(21)}}11156[3]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support4.44[1]3.51.0.110.011.5[1]5.1[2]
Shared workers{{CompatNo}}4[1]81.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using structured cloning{{CompatNo}}481.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using transferable objects{{CompatNo}}{{CompatNo}}181.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Chrome и Opera выдают ошибку "Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///Path/to/worker.js' cannot be accessed from origin 'null'." когда вы пытаетесь запустить worker локально. Нужно быть на надлежащем домене.

+ +

[2] Начиная с Safari 7.1.2, вы можете вызывать console.log изнутри worker-а, но он ничего не выведет в консоль. Более старые версии Safari не ползволяют вызывать console.log изнутри worker-а

+ +

[3] Эта функция реализована с префиксом как webkitURL.

+ +

[4] Safari удалил поддержку SharedWorker.

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html b/files/ru/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html new file mode 100644 index 0000000000..b5abccbe14 --- /dev/null +++ b/files/ru/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html @@ -0,0 +1,131 @@ +--- +title: Создание 3D объектов с помощью WebGL +slug: Web/API/WebGL_API/Tutorial/Создание_3D_объектов_с_помощью_WebGL +tags: + - WebGL + - Урок +translation_of: Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL +--- +

{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}

+ +

Давайте поместим наш квадрат в трехмерное пространство, добавив еще 5 граней, чтобы получить куб. Чтобы сделать это наиболее продуктивно, вместо рисования вершин непосредственным вызовом метода {{domxref("WebGLRenderingContext.drawArrays()", "gl.drawArrays()")}} , мы будем использовать массив вершин в виде таблицы и ссылаться на каждую вершину в этой таблице, чтобы определить положение каждой вершины грани, вызывая {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}.

+ +

Заметим: чтобы определить каждую грань необходимо четыре вершины, но каждая вершина принадлежит трем граням. Мы можем передавать намного меньше данных, построив список всех 24-х вершин, затем ссылаться на каждую из них в этом списке по её индексу, вместо того чтобы передавать все множество вершин. Если вы удивлены, почему нам нужны 24 вершины, а не только 8, так это потому, что каждое ребро принадлежит трем граням разных цветов, и каждая отдельная вершина должна иметь конкретный отдельный цвет - поэтому мы создадим 3 копии каждой вершины трех разных цветов, по одной для каждой грани.

+ +

Определение позиций вершин куба

+ +

Во первых, давайте построим буффер позиций вершин куба, обновив код в initBuffers(). Это в значительной степени то же самое как это было для квадрата, но несколько длиннее, так как здесь 24 вершины (4 с каждой стороны):

+ +
var vertices = [
+  // Передняя грань
+  -1.0, -1.0,  1.0,
+   1.0, -1.0,  1.0,
+   1.0,  1.0,  1.0,
+  -1.0,  1.0,  1.0,
+
+  // Задняя грань
+  -1.0, -1.0, -1.0,
+  -1.0,  1.0, -1.0,
+   1.0,  1.0, -1.0,
+   1.0, -1.0, -1.0,
+
+  // Верхняя грань
+  -1.0,  1.0, -1.0,
+  -1.0,  1.0,  1.0,
+   1.0,  1.0,  1.0,
+   1.0,  1.0, -1.0,
+
+  // Нижняя грань
+  -1.0, -1.0, -1.0,
+   1.0, -1.0, -1.0,
+   1.0, -1.0,  1.0,
+  -1.0, -1.0,  1.0,
+
+  // Правая грань
+   1.0, -1.0, -1.0,
+   1.0,  1.0, -1.0,
+   1.0,  1.0,  1.0,
+   1.0, -1.0,  1.0,
+
+  // Левая грань
+  -1.0, -1.0, -1.0,
+  -1.0, -1.0,  1.0,
+  -1.0,  1.0,  1.0,
+  -1.0,  1.0, -1.0
+];
+
+ +

Определение цветов вершин

+ +

Нам также нужно построить массив цветов для каждой из 24-х вершин. Этот код начинается с определения цветов для каждой грани, затем используется цикл для составления массива все всех цветов для каждой из вершин.

+ +
var colors = [
+  [1.0,  1.0,  1.0,  1.0],    // Front face: white
+  [1.0,  0.0,  0.0,  1.0],    // Back face: red
+  [0.0,  1.0,  0.0,  1.0],    // Top face: green
+  [0.0,  0.0,  1.0,  1.0],    // Bottom face: blue
+  [1.0,  1.0,  0.0,  1.0],    // Right face: yellow
+  [1.0,  0.0,  1.0,  1.0]     // Left face: purple
+];
+
+var generatedColors = [];
+
+for (j=0; j<6; j++) {
+  var c = colors[j];
+
+  for (var i=0; i<4; i++) {
+    generatedColors = generatedColors.concat(c);
+  }
+}
+
+cubeVerticesColorBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesColorBuffer);
+gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(generatedColors), gl.STATIC_DRAW);
+
+ +

Определение массива элементов

+ +

Как только массив вершин сгенерирован, нам нужно построить массив элементов.

+ +
cubeVerticesIndexBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
+
+// Этот массив определяет каждую грань как два треугольника,
+// используя индексы в массиве вершин, чтобы определить позицию
+// каждого треугольника.
+
+var cubeVertexIndices = [
+  0,  1,  2,      0,  2,  3,    // front
+  4,  5,  6,      4,  6,  7,    // back
+  8,  9,  10,     8,  10, 11,   // top
+  12, 13, 14,     12, 14, 15,   // bottom
+  16, 17, 18,     16, 18, 19,   // right
+  20, 21, 22,     20, 22, 23    // left
+];
+
+// Теперь отправим массив элементов в GL
+
+gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
+    new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
+
+ +

Массив cubeVertexIndices определяет каждую грань как пару треугольников, сопоставляя каждой вершине треугольника индекс в массиве вершин куба. Таким образом куб можно представить как набор из 12 треугольников.

+ +

Рисование куба

+ +

Далее нам нужно обновить код нашей функции drawScene() , чтобы рисовать, используя буффер индексов куба, добавив новые вызовы {{domxref("WebGLRenderingContext.bindBuffer()", "gl.bindBuffer()")}} и {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}:

+ +
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
+setMatrixUniforms();
+gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
+
+ +

Поскольку каждая грань нашего куба состоит из двух треугольников, где 6 вершин на каждой грани, или всего 36 вершин во всем кубе, даже если многие из них дублируются. Однако, поскольку наш массив индексов состоит из целых чисел, это не чрезмерное количество данных, посылаемых для каждого кадра анимации.

+ +

В данный момент у нас есть анимированный куб с гранями 6 разных цветов, который прыгает и вращается.

+ +

{{EmbedGHLiveSample('webgl-examples/tutorial/sample5/index.html', 670, 510) }}

+ +

View the complete code | Open this demo on a new page

+ +

{{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}

diff --git "a/files/ru/web/api/webgl_api/tutorial/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_3d_\320\276\320\261\321\212\320\265\320\272\321\202\320\276\320\262_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_webgl/index.html" "b/files/ru/web/api/webgl_api/tutorial/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_3d_\320\276\320\261\321\212\320\265\320\272\321\202\320\276\320\262_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_webgl/index.html" deleted file mode 100644 index b5abccbe14..0000000000 --- "a/files/ru/web/api/webgl_api/tutorial/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_3d_\320\276\320\261\321\212\320\265\320\272\321\202\320\276\320\262_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_webgl/index.html" +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: Создание 3D объектов с помощью WebGL -slug: Web/API/WebGL_API/Tutorial/Создание_3D_объектов_с_помощью_WebGL -tags: - - WebGL - - Урок -translation_of: Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL ---- -

{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}

- -

Давайте поместим наш квадрат в трехмерное пространство, добавив еще 5 граней, чтобы получить куб. Чтобы сделать это наиболее продуктивно, вместо рисования вершин непосредственным вызовом метода {{domxref("WebGLRenderingContext.drawArrays()", "gl.drawArrays()")}} , мы будем использовать массив вершин в виде таблицы и ссылаться на каждую вершину в этой таблице, чтобы определить положение каждой вершины грани, вызывая {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}.

- -

Заметим: чтобы определить каждую грань необходимо четыре вершины, но каждая вершина принадлежит трем граням. Мы можем передавать намного меньше данных, построив список всех 24-х вершин, затем ссылаться на каждую из них в этом списке по её индексу, вместо того чтобы передавать все множество вершин. Если вы удивлены, почему нам нужны 24 вершины, а не только 8, так это потому, что каждое ребро принадлежит трем граням разных цветов, и каждая отдельная вершина должна иметь конкретный отдельный цвет - поэтому мы создадим 3 копии каждой вершины трех разных цветов, по одной для каждой грани.

- -

Определение позиций вершин куба

- -

Во первых, давайте построим буффер позиций вершин куба, обновив код в initBuffers(). Это в значительной степени то же самое как это было для квадрата, но несколько длиннее, так как здесь 24 вершины (4 с каждой стороны):

- -
var vertices = [
-  // Передняя грань
-  -1.0, -1.0,  1.0,
-   1.0, -1.0,  1.0,
-   1.0,  1.0,  1.0,
-  -1.0,  1.0,  1.0,
-
-  // Задняя грань
-  -1.0, -1.0, -1.0,
-  -1.0,  1.0, -1.0,
-   1.0,  1.0, -1.0,
-   1.0, -1.0, -1.0,
-
-  // Верхняя грань
-  -1.0,  1.0, -1.0,
-  -1.0,  1.0,  1.0,
-   1.0,  1.0,  1.0,
-   1.0,  1.0, -1.0,
-
-  // Нижняя грань
-  -1.0, -1.0, -1.0,
-   1.0, -1.0, -1.0,
-   1.0, -1.0,  1.0,
-  -1.0, -1.0,  1.0,
-
-  // Правая грань
-   1.0, -1.0, -1.0,
-   1.0,  1.0, -1.0,
-   1.0,  1.0,  1.0,
-   1.0, -1.0,  1.0,
-
-  // Левая грань
-  -1.0, -1.0, -1.0,
-  -1.0, -1.0,  1.0,
-  -1.0,  1.0,  1.0,
-  -1.0,  1.0, -1.0
-];
-
- -

Определение цветов вершин

- -

Нам также нужно построить массив цветов для каждой из 24-х вершин. Этот код начинается с определения цветов для каждой грани, затем используется цикл для составления массива все всех цветов для каждой из вершин.

- -
var colors = [
-  [1.0,  1.0,  1.0,  1.0],    // Front face: white
-  [1.0,  0.0,  0.0,  1.0],    // Back face: red
-  [0.0,  1.0,  0.0,  1.0],    // Top face: green
-  [0.0,  0.0,  1.0,  1.0],    // Bottom face: blue
-  [1.0,  1.0,  0.0,  1.0],    // Right face: yellow
-  [1.0,  0.0,  1.0,  1.0]     // Left face: purple
-];
-
-var generatedColors = [];
-
-for (j=0; j<6; j++) {
-  var c = colors[j];
-
-  for (var i=0; i<4; i++) {
-    generatedColors = generatedColors.concat(c);
-  }
-}
-
-cubeVerticesColorBuffer = gl.createBuffer();
-gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesColorBuffer);
-gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(generatedColors), gl.STATIC_DRAW);
-
- -

Определение массива элементов

- -

Как только массив вершин сгенерирован, нам нужно построить массив элементов.

- -
cubeVerticesIndexBuffer = gl.createBuffer();
-gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
-
-// Этот массив определяет каждую грань как два треугольника,
-// используя индексы в массиве вершин, чтобы определить позицию
-// каждого треугольника.
-
-var cubeVertexIndices = [
-  0,  1,  2,      0,  2,  3,    // front
-  4,  5,  6,      4,  6,  7,    // back
-  8,  9,  10,     8,  10, 11,   // top
-  12, 13, 14,     12, 14, 15,   // bottom
-  16, 17, 18,     16, 18, 19,   // right
-  20, 21, 22,     20, 22, 23    // left
-];
-
-// Теперь отправим массив элементов в GL
-
-gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
-    new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
-
- -

Массив cubeVertexIndices определяет каждую грань как пару треугольников, сопоставляя каждой вершине треугольника индекс в массиве вершин куба. Таким образом куб можно представить как набор из 12 треугольников.

- -

Рисование куба

- -

Далее нам нужно обновить код нашей функции drawScene() , чтобы рисовать, используя буффер индексов куба, добавив новые вызовы {{domxref("WebGLRenderingContext.bindBuffer()", "gl.bindBuffer()")}} и {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}:

- -
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
-setMatrixUniforms();
-gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
-
- -

Поскольку каждая грань нашего куба состоит из двух треугольников, где 6 вершин на каждой грани, или всего 36 вершин во всем кубе, даже если многие из них дублируются. Однако, поскольку наш массив индексов состоит из целых чисел, это не чрезмерное количество данных, посылаемых для каждого кадра анимации.

- -

В данный момент у нас есть анимированный куб с гранями 6 разных цветов, который прыгает и вращается.

- -

{{EmbedGHLiveSample('webgl-examples/tutorial/sample5/index.html', 670, 510) }}

- -

View the complete code | Open this demo on a new page

- -

{{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}

diff --git a/files/ru/web/api/webrtc_api/connectivity/index.html b/files/ru/web/api/webrtc_api/connectivity/index.html new file mode 100644 index 0000000000..7c4f173c05 --- /dev/null +++ b/files/ru/web/api/webrtc_api/connectivity/index.html @@ -0,0 +1,70 @@ +--- +title: WebRTC подключение +slug: Web/API/WebRTC_API/связь +translation_of: Web/API/WebRTC_API/Connectivity +--- +

{{WebRTCSidebar}}{{draft}}

+ +

Теперь, когда мы рассмотрели протоколы по отдельности, мы можем сложить их вместе. Эта статья описывает, как различные связанные с WebRTC протоколы взаимодействуют друг с другом для того, чтобы создать соединение и передать данные и/или медиа между узлами.

+ +
+

Эта страница требует серьёзной переделки для структурной целостности и полноты содержания. Много информации здесь - это хорошо, но организация являет собой путаницу, поскольку сейчас являет собой вид "местности разгрузки"(dumping ground).

+
+ +

Что  такое Предложение/Ответ и Канал сигнализации?

+ +

К сожалению, WebRTC не может создавать соединения без какого-либо сервера посередине. Мы называем его "каналом сигнализации". Это любого рода канал связи для обмена информацией перед установкой соединения, будь то электронная почта, почтовая открытка или почтовый голубь... Зависит от вас.
+  

+ +

Информация, которой мы должны обменяться - это "предложение" и "ответ", которые содержат SDP, упомянутую ниже.

+ +

Узел A, тот кто будет инициатором соединения, создаст "предложение". Затем отправит это "предложение" узлу B, используя выбранный "сигнальный канал". Узел B получит "предложение" от "сигнального канала" и создаст "ответ". Затем отправит его обратно узлу A посредством "сигнального канала".

+ +

Описания сессии

+ +

Конфигурация конечной точки WebRTC-соединения называется "описание сессии"(session description). Описание включает информацию о типе посылаемого медиа, его формате, используемом протоколе передачи, IP-адресе и порте конечной точки, и  другую информацию, необходимую для описания конечной точки передачи медиа. Эта информация обменивается и хранится с помощью "протокола описания сессии". Session Description Protocol({{Glossary("SDP")}}). Если вы хотите подробную информацию о формате данных SDP, вы можете найти её в {{RFC(2327)}}.

+ +

Когда пользователь запускает WebRTC вызов другого пользователя, создаётся специальное описание, называемое "предложение"(offer). Это описание включает всю информацию для соединения, о предлагаемой конфигурации вызывающего абонента. Получатель затем откликается "ответом"(answer), являющимся описанием его конца соединения. Таким образом, оба устройства разделяют друг с другом информацию, необходимую для того, чтобы обмениваться медиа данными. Этот обмен обрабатывается с помощью "интерактивного создания подключения". Interactive Connectivity Establishment{{Glossary("ICE")}}. ICE - протокол, который позволяет двум устройствам использовать посредника для обмена "предложениями"(offers) и "ответами"(answers), даже если эти два устройства разделены механизмом "преобразования сетевых адресов". ({{Glossary("NAT")}}(Network Address Translation).

+ +

Каждый узел, тогда, держит два описания под рукой: локальное описание (local description), описывающее себя и удалённое описание(remote description), описывающее другой конец соединения.

+ +

Процесс "предложение/ответ"(offer/answer) выполняется как, когда соединение впервые устанавливается, так и в любой момент, когда формат соединения или другая конфигурация нуждается в изменении. Независимо от того, является ли это новым соединением, или реконфигурированием существующего, это основные шаги, которые должны произойти для обмена "предложением"(offer) и "ответом"(answer). Пропустим ICE-слой на данный момент:

+ +
    +
  1. Вызывающий вызывает {{domxref("RTCPeerConnection.createOffer()")}} для создания "предложения"(offer)
  2. +
  3. Вызывающий вызывает {{domxref("RTCPeerConnection.setLocalDescription()")}} для установки этого "предложения" как локального описания (то есть описания локального конца соединения).
  4. +
  5. Вызывающий использует сигнальный сервер для передачи "предложения" к требуемому получателю вызова.
  6. +
  7. Получатель получает "предложение" и вызывает {{domxref("RTCPeerConnection.setRemoteDescription()")}} для записи его, как удалённого описания(описания другого конца соединения).
  8. +
  9. Получатель делает всякую настройку, которую должен сделать для его конца соединения, включая добавления исходящих потоков для соединения.
  10. +
  11. Получатель затем создаёт "ответ"(answer) посредством вызова {{domxref("RTCPeerConnection.createAnswer()")}}.
  12. +
  13. Получатель вызывает {{domxref("RTCPeerConnection.setLocalDescription()")}}, чтобы установить "ответ"(answer) в качестве локального описания. Получатель теперь знает конфигурацию обоих концов соединения.
  14. +
  15. Получатель использует сигнальный сервер для отправки "ответа"(answer) вызывающему.
  16. +
  17. Вызывающий получает "ответ"(answer).
  18. +
  19. Вызывающий вызывает {{domxref("RTCPeerConnection.setRemoteDescription()")}} для установки "ответа"(answer) как удалённого описания для его конца соединения. Теперь известна конфигурация обоих узлов. Медиа начинает течь в соответствии с настройками.
  20. +
+ +

Рассматриваемые и текущие описания

+ +

Спускаясь на один шаг глубже в процесс, мы находим, что localDescription и remoteDescription, свойства, возвращаемые эти двумя описаниями, не так просты, как выглядят. Потому что во время повторных переговоров(перезаключения) (renegotiation), "предложение"(offer) может быть отклонено, поскольку оно предлагает несовместимый формат. Необходимо, чтобы каждая конечная точка имела возможность предложить новый формат, но не переключаться на него, пока он не принят другим узлом. По этой причине, WebRTC использует "рассматриваемые" и "текущие" "описания".

+ +

"Текущее описание"(current description) (которое возвращается свойствами {{domxref("RTCPeerConnection.currentLocalDescription")}} и {{domxref("RTCPeerConnection.currentRemoteDescription")}}) представляет собой описание, в данный момент, фактически используемое соединением. Это самое недавнее соединение, которое обе стороны полностью согласились использовать.

+ +

"Рассматриваемое описание"(pending description) (возвращаемое {{domxref("RTCPeerConnection.pendingLocalDescription")}} и {{domxref("RTCPeerConnection.pendingRemoteDescription")}}) указывает на то описание, которое в настоящий момент находится на рассмотрении после вызова setLocalDescription() или setRemoteDescription(), соответственно.

+ +

При чтении описания (возвращаемого {{domxref("RTCPeerConnection.localDescription")}} и {{domxref("RTCPeerConnection.remoteDescription")}}), возвращаемым значением является значение pendingLocalDescription/pendingRemoteDescription, если есть рассматриваемое описание (то есть, рассматриваемое описание не null). В противном случае, возвращается текущее описание (currentLocalDescription/currentRemoteDescription).

+ +

При изменении описания путём вызова setLocalDescription() или setRemoteDescription(), указанное описание устанавливается как "рассматриваемое описание"(pending description), и WebRTC-слой начинает оценивать, действительно ли это приемлемо. После того, как предложенное описание было согласовано, значение currentLocalDescription или currentRemoteDescription изменяется на "рассматриваемое описание"(pending description), и pending description устанавливается снова в null, указывая, что "отложенного описания"(pending description) не существует.

+ +
+

pendingLocalDescription содержит не только "предложение" или "ответ" на стадии рассмотрения, но и каких-либо ICE-кандидатов, которые уже были собраны с тех пор, как "предложение" или "ответ" были созданы. Подобным образом, pendingRemoteDescription включает любых удалённых ICE-кандидатов, которые были предоставлены вызовами {{domxref("RTCPeerConnection.addIceCandidate()")}}.

+
+ +

Смотрите отдельные статьи по этим свойствам и методам для большей конкретики.

+ +

Что такое ICE-кандидат?

+ +

В дополнение к обмену информацией о медиа(обсуждённой выше в offer/answer и SDP), узлы должны обменяться информацией о сетевом соединении. Об этом известно как о ICE-кандидате и деталях доступных методов, которыми узел может общаться (непосредственно или через TURN-сервер).

+ +

Весь обмен в сложной схеме

+ +

A complete architectural diagram showing the whole WebRTC process.

diff --git a/files/ru/web/api/webrtc_api/protocols/index.html b/files/ru/web/api/webrtc_api/protocols/index.html new file mode 100644 index 0000000000..df618ab083 --- /dev/null +++ b/files/ru/web/api/webrtc_api/protocols/index.html @@ -0,0 +1,38 @@ +--- +title: Введение в протоколы WebRTC +slug: Web/API/WebRTC_API/протоколы +translation_of: Web/API/WebRTC_API/Protocols +--- +

{{APIRef("WebRTC")}}{{draft}}

+ +

В этой статье представлены протоколы, поверх которых построен WebRTC API.

+ +

ICE

+ +

Interactive Connectivity Establishment (ICE) "Установка интерактивного подключения" представляет собой каркас, позволяющий вашему веб-браузеру соединяться с узлами. Есть много причин, почему прямое соединение от узла A к узлу B просто не будет работать. Оно должно обойти межсетевые экраны, которые будут препятствовать открытию соединений, дать вам уникальный адрес, если, как в большинстве ситуаций, ваше устройство не имеет публичного IP-адреса, и передавать данные через сервер, если ваш маршрутизатор не позволяет вам напрямую соединяться с узлами. ICE использует некоторые из следующих технических приёмов, описанных ниже, для достижения этой цели:

+ +

STUN

+ +

Session Traversal Utilities for NAT (STUN) (акроним в акрониме) это протокол для нахождения и определения вашего публичного адреса и любых ограничений в вашем маршрутизаторе, которые препятствуют прямому соединению с узлом.

+ +

Клиент отправит запрос к STUN серверу в интернете, который ответит публичным адресом клиента и, доступен ли, или нет, клиент за NAT маршрутизатором.

+ +

An interaction between two users of a WebRTC application involving a STUN server.

+ +

NAT

+ +

Network Address Translation (NAT) используется для того, чтобы дать вашему устройству публичный IP-адрес. Маршрутизатор имеет публичный IP-адрес, а каждое устройство, подключённое к маршрутизатору имеет частный IP-адрес. Запросы будут транслированы от частного IP-адреса устройства к публичному IP-адресу маршрутизатора (с уникальным портом). Таким образом вам не нужен уникальный IP-адрес для каждого устройства, тем не менее, оно может быть обнаружено в интернете.

+ +

Некоторые маршрутизаторы имеют ограничения на то, кто может подключаться к устройствам в сети. Это может означать, что даже если мы имеем публичный IP-адрес, найденный STUN сервером, никто не может создать соединение. В этой ситуации нам нужно обратиться к TURN.

+ +

TURN

+ +

Некоторые маршрутизаторы, использующие NAT применяют ограничение, называемое "Симметричный NAT" (Symmetric NAT). Это означает, что маршрутизатор будет принимать соединения только от узлов, к которым вы ранее подключились.

+ +

Traversal Using Relays around NAT (TURN) предназначен для обхода ограничения "Симметричный NAT" путём открытия соединения с TURN сервером и ретрансляции всей информации через этот сервер. Вы создадите соединение с TURN сервером и сообщите всем узлам слать пакеты этому серверу, которые затем будут переправлены вам. Очевидно, что они приходят с некоторыми накладными расходами, поэтому это используется, только если нет других альтернатив.

+ +

An interaction between two users of a WebRTC application involving STUN and TURN servers.

+ +

SDP

+ +

Session Description Protocol (SDP)  - это стандарт для описания мультимедийного контента соединения,  как например: разрешение, форматы, кодеки, шифрование и т.д. Так, чтобы оба узла могли понять друг друга, после того как данные начнут передаваться. Это, в сущности, метаданные, описывающие содержимое, а не медиа контент сам по себе.

diff --git a/files/ru/web/api/webrtc_api/webrtc_basics/index.html b/files/ru/web/api/webrtc_api/webrtc_basics/index.html deleted file mode 100644 index 863dde7e14..0000000000 --- a/files/ru/web/api/webrtc_api/webrtc_basics/index.html +++ /dev/null @@ -1,351 +0,0 @@ ---- -title: Основы WebRTC -slug: Web/API/WebRTC_API/WebRTC_basics -translation_of: Web/API/WebRTC_API/Signaling_and_video_calling -translation_of_original: Web/API/WebRTC_API/WebRTC_basics ---- -

{{WebRTCSidebar}}

- -

{{Draft}}

- -
-

После того, как вы понимаете WebRTC architecture, вы можете прочитать эту статью, которая сопроводит вас через создание кросс-браузерного RTC приложения. К концу этой документации, вы должны иметь рабочие каналы соединения равноправных узлов ЛВС и передачи данных средств массовой информации.

-
- -

Полу-старое содержание, из

- -

RTCPeerConnection

- -

Материал здесь происходит от RTCPeerConnection; она может остаться здесь, или же  может переместится в другое место.

- -

Основы использования
- Базовое использование RTCPeerConnection предполагает переговоры связь между локальной машиной и удаленной машиной один генерируя Session Description Protocol для обмена между ними. Вызывающая программа начинает процесс, отправив предложение на удаленное устройство, которое реагирует либо принять или отклонить запрос на соединение.

- -

Обе стороны (вызывающий и вызываемый абонент) необходимо настроить свои собственные экземпляры RTCPeerConnection, чтобы представить их конец соединения равноправных узлов ЛВС:

- -
var pc = new RTCPeerConnection();
-pc.onaddstream = function(obj) {
-  var vid = document.createElement("video");
-  document.appendChild(vid);
-  vid.srcObject = obj.stream;
-}
-
-// функция помощник
-function endCall() {
-  var videos = document.getElementsByTagName("video");
-  for (var i = 0; i < videos.length; i++) {
-    videos[i].pause();
-  }
-
-  pc.close();
-
-
-function error(err) {
-  endCall();
-}
-
- -

При инициализации вызова

- -

Если вы один инициирующий вызов, вы будете использовать navigator.getUserMedia(), чтобы получить видеопоток, а затем добавить поток в RTCPeerConnection. Как только это было сделано, вызов RTCPeerConnection, чтобы создать предложение, настроить предложение, а затем отправить его на сервер, через  соединение которое было создано.

- -
// Получить список людей с сервера
-// Пользователь выбирает список людей, чтобы установить соединение с нужным человеком
-navigator.getUserMedia({video: true}, function(stream) {
-  // Добавление локального потока не вызовет onaddstream обратного вызова,
-  // так называют его вручную.
-  pc.onaddstream = e => video.src = URL.createObjectURL(e.stream);
-  pc.addStream(stream);
-
-  pc.createOffer(function(offer) {
-    pc.setLocalDescription(offer, function() {
-      // send the offer to a server to be forwarded to the friend you're calling.
-    }, error);
-  }, error);
-});
-
- -

Ответ на вызов

- -

На противоположном конце, друг получит предложение от сервера, используя любой протокол используется для того чтобы сделать это. После того, как предложение прибывает, {{domxref ("navigator.getUserMedia ()")}} вновь используется для создания потока, который добавляется к RTCPeerConnection. {{Domxref ("RTCSessionDescription")}} объект создается и установить в качестве удаленного описания с помощью вызова {{domxref ("RTCPeerConnection.setRemoteDescription ()")}}.

- -

Тогда ответ создается с помощью RTCPeerConnection.createAnswer () и отправляется обратно на сервер, который направляет его к вызывающему абоненту.

- -
var offer = getOfferFromFriend();
-navigator.getUserMedia({video: true}, function(stream) {
-  pc.onaddstream = e => video.src = URL.createObjectURL(e.stream);
-  pc.addStream(stream);
-
-  pc.setRemoteDescription(new RTCSessionDescription(offer), function() {
-    pc.createAnswer(function(answer) {
-      pc.setLocalDescription(answer, function() {
-        // send the answer to a server to be forwarded back to the caller (you)
-      }, error);
-    }, error);
-  }, error);
-});
-
- -

Ответ на вызов

- -

На противоположном конце, человек получит предложение от сервера, используя любой протокол используется для того чтобы сделать это. После того, как предложение принято, navigator.getUserMedia () вновь используется для создания потока, который добавляется к RTCPeerConnection.  объект создается и установить в качестве удаленного описания с помощью вызова {{domxref ("RTCPeerConnection.setRemoteDescription ()")}}.

- -

Тогда ответ создается с помощью RTCPeerConnection.createAnswer () и отправляется обратно на сервер, который направляет его к вызывающему абоненту.

- -
// ПК был создан раньше, когда мы сделали первоначальное предложение
-var offer = getResponseFromFriend();
-pc.setRemoteDescription(new RTCSessionDescription(offer), function() { }, error);
- -

Old content follows!

- -

Все, что находится ниже этого пункта,  потенциально устарело. Это по-прежнему находится в стадии рассмотрения  и возможного включения в другие части документации, если они все еще актуальны.

- -
-

Не используйте примеры на этой странице. Смотрите статью Signaling and video calling для работы, актуальный пример с использованием WebRTC media.

-
- -

Note

- -

Due to recent changes in the API there are many old examples that require fixing:

- - - -

The currently working example is:

- - - -

Implementation may be inferred from the specification.

- -

This remainder of this page contains outdated information as noted on bugzilla.

- -

Shims

- -

As you can imagine, with such an early API, you must use the browser prefixes and shim it to a common variable.

- -
var RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
-var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
-var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
-navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
- -

RTCPeerConnection

- -

This is the starting point to creating a connection with a peer. It accepts configuration options about ICE servers to use to establish a connection.

- -
var pc = new RTCPeerConnection(configuration);
- -

RTCConfiguration

- -

The {{domxref("RTCConfiguration")}} object contains information about which TURN and/or STUN servers to use for ICE. This is required to ensure most users can actually create a connection by avoiding restrictions in NAT and firewalls.

- -
var configuration = {
-    iceServers: [
-        {urls: "stun:23.21.150.121"},
-        {urls: "stun:stun.l.google.com:19302"},
-        {urls: "turn:numb.viagenie.ca", credential: "webrtcdemo", username: "louis%40mozilla.com"}
-    ]
-}
- -

Google runs a public STUN server that we can use. I also created an account at http://numb.viagenie.ca/ for a free TURN server to access. You may want to do the same and replace with your own credentials.

- -

ICECandidate

- - - -

After creating the PeerConnection and passing in the available STUN and TURN servers, an event will be fired once the ICE framework has found some “candidates” that will allow you to connect with a peer. This is known as an ICE Candidate and will execute a callback function on PeerConnection#onicecandidate.

- -
pc.onicecandidate = function (e) {
-    // candidate exists in e.candidate
-    if (!e.candidate) return;
-    send("icecandidate", JSON.stringify(e.candidate));
-};
- -

When the callback is executed, we must use the signal channel to send the Candidate to the peer. On Chrome, multiple ICE candidates are usually found, we only need one so I typically send the first one then remove the handler. Firefox includes the Candidate in the Offer SDP.

- -

Signal Channel

- -

Now that we have an ICE candidate, we need to send that to our peer so they know how to connect with us. However this leaves us with a chicken and egg situation; we want PeerConnection to send data to a peer but before that we need to send them metadata…

- -

This is where the signal channel comes in. It’s any method of data transport that allows two peers to exchange information. In this article, we’re going to use FireBase because it’s incredibly easy to setup and doesn't require any hosting or server-code.

- -

For now just imagine two methods exist: send() will take a key and assign data to it and recv() will call a handler when a key has a value.

- -

The structure of the database will look like this:

- -
{
-    "": {
-        "candidate:": …
-        "offer": …
-        "answer": …
-    }
-}
- -

Connections are divided by a roomId and will store 4 pieces of information, the ICE candidate from the offerer, the ICE candidate from the answerer, the offer SDP and the answer SDP.

- -

Offer

- -

An Offer SDP (Session Description Protocol) is metadata that describes to the other peer the format to expect (video, formats, codecs, encryption, resolution, size, etc etc).

- -

An exchange requires an offer from a peer, then the other peer must receive the offer and provide back an answer.

- -
pc.createOffer(function (offer) {
-    pc.setLocalDescription(offer, function() {
-        send("offer", JSON.stringify(pc.localDescription);
-    }, errorHandler);
-}, errorHandler, options);
- -

errorHandler

- -

If there was an issue generating an offer, this method will be executed with error details as the first argument.

- -
var errorHandler = function (err) {
-    console.error(err);
-};
- -
options
- -

Options for the offer SDP.

- -
var options = {
-    offerToReceiveAudio: true,
-    offerToReceiveVideo: true
-};
- -

offerToReceiveAudio/Video tells the other peer that you would like to receive video or audio from them. This is not needed for DataChannels.

- -

Once the offer has been generated we must set the local SDP to the new offer and send it through the signal channel to the other peer and await their Answer SDP.

- -

Answer

- -

An Answer SDP is just like an offer but a response; sort of like answering the phone. We can only generate an answer once we have received an offer.

- -
recv("offer", function (offer) {
-    offer = new SessionDescription(JSON.parse(offer))
-    pc.setRemoteDescription(offer);
-
-    pc.createAnswer(function (answer) {
-        pc.setLocalDescription(answer, function() {
-            send("answer", JSON.stringify(pc.localDescription));
-        }, errorHandler);
-    }, errorHandler);
-});
- -

DataChannel

- -

I will first explain how to use PeerConnection for the DataChannels API and transferring arbitrary data between peers.

- -

Note: At the time of this article, interoperability between Chrome and Firefox is not possible with DataChannels. Chrome supports a similar but private protocol and will be supporting the standard protocol soon.

- -
var channel = pc.createDataChannel(channelName, channelOptions);
- -

The offerer should be the peer who creates the channel. The answerer will receive the channel in the callback ondatachannel on PeerConnection. You must call createDataChannel() once before creating the offer.

- -

channelName

- -

This is a string that acts as a label for your channel name. Warning: Make sure your channel name has no spaces or Chrome will fail on createAnswer().

- -

channelOptions

- -
var channelOptions = {};
- -

Currently these options are not well supported on Chrome so you can leave this empty for now. Check the RFC for more information about the options.

- -

Channel Events and Methods

- -
onopen
- -

Executed when the connection is established.

- -
onerror
- -

Executed if there is an error creating the connection. First argument is an error object.

- -
channel.onerror = function (err) {
-    console.error("Channel Error:", err);
-};
- -
onmessage
- -
channel.onmessage = function (e) {
-    console.log("Got message:", e.data);
-}
- -

The heart of the connection. When you receive a message, this method will execute. The first argument is an event object which contains the data, time received and other information.

- -
onclose
- -

Executed if the other peer closes the connection.

- -

Binding the Events

- -

If you were the creator of the channel (meaning the offerer), you can bind events directly to the DataChannel you created with createChannel. If you are the answerer, you must use the ondatachannel callback on PeerConnection to access the same channel.

- -
pc.ondatachannel = function (e) {
-    e.channel.onmessage = function () { … };
-};
- -

The channel is available in the event object passed into the handler as e.channel.

- -
send()
- -
channel.send("Hi Peer!");
- -

This method allows you to send data directly to the peer! Amazing. You must send either String, Blob, ArrayBuffer or ArrayBufferView, so be sure to stringify objects.

- -
close()
- -

Close the channel once the connection should end. It is recommended to do this on page unload.

- -

Media

- -

Now we will cover transmitting media such as audio and video. To display the video and audio you must include a <video> tag on the document with the attribute autoplay.

- -

Get User Media

- -
<video id="preview" autoplay></video>
-
-var video = document.getElementById("preview");
-navigator.getUserMedia(constraints, function (stream) {
-    video.src = URL.createObjectURL(stream);
-}, errorHandler);
- -

constraints

- -

Constraints on what media types you want to return from the user.

- -
var constraints = {
-    video: true,
-    audio: true
-};
- -

If you just want an audio chat, remove the video member.

- -
errorHandler
- -

Executed if there is an error returning the requested media.

- -

Media Events and Methods

- -
addStream
- -

Add the stream from getUserMedia to the PeerConnection.

- -
pc.addStream(stream);
- -
onaddstream
- -
<video id="otherPeer" autoplay></video>
-
-var otherPeer = document.getElementById("otherPeer");
-pc.onaddstream = function (e) {
-    otherPeer.src = URL.createObjectURL(e.stream);
-};
- -

Executed when the connection has been setup and the other peer has added the stream to the peer connection with addStream. You need another <video> tag to display the other peer's media.

- -

The first argument is an event object with the other peer's media stream.

diff --git "a/files/ru/web/api/webrtc_api/\320\277\321\200\320\276\321\202\320\276\320\272\320\276\320\273\321\213/index.html" "b/files/ru/web/api/webrtc_api/\320\277\321\200\320\276\321\202\320\276\320\272\320\276\320\273\321\213/index.html" deleted file mode 100644 index df618ab083..0000000000 --- "a/files/ru/web/api/webrtc_api/\320\277\321\200\320\276\321\202\320\276\320\272\320\276\320\273\321\213/index.html" +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Введение в протоколы WebRTC -slug: Web/API/WebRTC_API/протоколы -translation_of: Web/API/WebRTC_API/Protocols ---- -

{{APIRef("WebRTC")}}{{draft}}

- -

В этой статье представлены протоколы, поверх которых построен WebRTC API.

- -

ICE

- -

Interactive Connectivity Establishment (ICE) "Установка интерактивного подключения" представляет собой каркас, позволяющий вашему веб-браузеру соединяться с узлами. Есть много причин, почему прямое соединение от узла A к узлу B просто не будет работать. Оно должно обойти межсетевые экраны, которые будут препятствовать открытию соединений, дать вам уникальный адрес, если, как в большинстве ситуаций, ваше устройство не имеет публичного IP-адреса, и передавать данные через сервер, если ваш маршрутизатор не позволяет вам напрямую соединяться с узлами. ICE использует некоторые из следующих технических приёмов, описанных ниже, для достижения этой цели:

- -

STUN

- -

Session Traversal Utilities for NAT (STUN) (акроним в акрониме) это протокол для нахождения и определения вашего публичного адреса и любых ограничений в вашем маршрутизаторе, которые препятствуют прямому соединению с узлом.

- -

Клиент отправит запрос к STUN серверу в интернете, который ответит публичным адресом клиента и, доступен ли, или нет, клиент за NAT маршрутизатором.

- -

An interaction between two users of a WebRTC application involving a STUN server.

- -

NAT

- -

Network Address Translation (NAT) используется для того, чтобы дать вашему устройству публичный IP-адрес. Маршрутизатор имеет публичный IP-адрес, а каждое устройство, подключённое к маршрутизатору имеет частный IP-адрес. Запросы будут транслированы от частного IP-адреса устройства к публичному IP-адресу маршрутизатора (с уникальным портом). Таким образом вам не нужен уникальный IP-адрес для каждого устройства, тем не менее, оно может быть обнаружено в интернете.

- -

Некоторые маршрутизаторы имеют ограничения на то, кто может подключаться к устройствам в сети. Это может означать, что даже если мы имеем публичный IP-адрес, найденный STUN сервером, никто не может создать соединение. В этой ситуации нам нужно обратиться к TURN.

- -

TURN

- -

Некоторые маршрутизаторы, использующие NAT применяют ограничение, называемое "Симметричный NAT" (Symmetric NAT). Это означает, что маршрутизатор будет принимать соединения только от узлов, к которым вы ранее подключились.

- -

Traversal Using Relays around NAT (TURN) предназначен для обхода ограничения "Симметричный NAT" путём открытия соединения с TURN сервером и ретрансляции всей информации через этот сервер. Вы создадите соединение с TURN сервером и сообщите всем узлам слать пакеты этому серверу, которые затем будут переправлены вам. Очевидно, что они приходят с некоторыми накладными расходами, поэтому это используется, только если нет других альтернатив.

- -

An interaction between two users of a WebRTC application involving STUN and TURN servers.

- -

SDP

- -

Session Description Protocol (SDP)  - это стандарт для описания мультимедийного контента соединения,  как например: разрешение, форматы, кодеки, шифрование и т.д. Так, чтобы оба узла могли понять друг друга, после того как данные начнут передаваться. Это, в сущности, метаданные, описывающие содержимое, а не медиа контент сам по себе.

diff --git "a/files/ru/web/api/webrtc_api/\321\201\320\262\321\217\320\267\321\214/index.html" "b/files/ru/web/api/webrtc_api/\321\201\320\262\321\217\320\267\321\214/index.html" deleted file mode 100644 index 7c4f173c05..0000000000 --- "a/files/ru/web/api/webrtc_api/\321\201\320\262\321\217\320\267\321\214/index.html" +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: WebRTC подключение -slug: Web/API/WebRTC_API/связь -translation_of: Web/API/WebRTC_API/Connectivity ---- -

{{WebRTCSidebar}}{{draft}}

- -

Теперь, когда мы рассмотрели протоколы по отдельности, мы можем сложить их вместе. Эта статья описывает, как различные связанные с WebRTC протоколы взаимодействуют друг с другом для того, чтобы создать соединение и передать данные и/или медиа между узлами.

- -
-

Эта страница требует серьёзной переделки для структурной целостности и полноты содержания. Много информации здесь - это хорошо, но организация являет собой путаницу, поскольку сейчас являет собой вид "местности разгрузки"(dumping ground).

-
- -

Что  такое Предложение/Ответ и Канал сигнализации?

- -

К сожалению, WebRTC не может создавать соединения без какого-либо сервера посередине. Мы называем его "каналом сигнализации". Это любого рода канал связи для обмена информацией перед установкой соединения, будь то электронная почта, почтовая открытка или почтовый голубь... Зависит от вас.
-  

- -

Информация, которой мы должны обменяться - это "предложение" и "ответ", которые содержат SDP, упомянутую ниже.

- -

Узел A, тот кто будет инициатором соединения, создаст "предложение". Затем отправит это "предложение" узлу B, используя выбранный "сигнальный канал". Узел B получит "предложение" от "сигнального канала" и создаст "ответ". Затем отправит его обратно узлу A посредством "сигнального канала".

- -

Описания сессии

- -

Конфигурация конечной точки WebRTC-соединения называется "описание сессии"(session description). Описание включает информацию о типе посылаемого медиа, его формате, используемом протоколе передачи, IP-адресе и порте конечной точки, и  другую информацию, необходимую для описания конечной точки передачи медиа. Эта информация обменивается и хранится с помощью "протокола описания сессии". Session Description Protocol({{Glossary("SDP")}}). Если вы хотите подробную информацию о формате данных SDP, вы можете найти её в {{RFC(2327)}}.

- -

Когда пользователь запускает WebRTC вызов другого пользователя, создаётся специальное описание, называемое "предложение"(offer). Это описание включает всю информацию для соединения, о предлагаемой конфигурации вызывающего абонента. Получатель затем откликается "ответом"(answer), являющимся описанием его конца соединения. Таким образом, оба устройства разделяют друг с другом информацию, необходимую для того, чтобы обмениваться медиа данными. Этот обмен обрабатывается с помощью "интерактивного создания подключения". Interactive Connectivity Establishment{{Glossary("ICE")}}. ICE - протокол, который позволяет двум устройствам использовать посредника для обмена "предложениями"(offers) и "ответами"(answers), даже если эти два устройства разделены механизмом "преобразования сетевых адресов". ({{Glossary("NAT")}}(Network Address Translation).

- -

Каждый узел, тогда, держит два описания под рукой: локальное описание (local description), описывающее себя и удалённое описание(remote description), описывающее другой конец соединения.

- -

Процесс "предложение/ответ"(offer/answer) выполняется как, когда соединение впервые устанавливается, так и в любой момент, когда формат соединения или другая конфигурация нуждается в изменении. Независимо от того, является ли это новым соединением, или реконфигурированием существующего, это основные шаги, которые должны произойти для обмена "предложением"(offer) и "ответом"(answer). Пропустим ICE-слой на данный момент:

- -
    -
  1. Вызывающий вызывает {{domxref("RTCPeerConnection.createOffer()")}} для создания "предложения"(offer)
  2. -
  3. Вызывающий вызывает {{domxref("RTCPeerConnection.setLocalDescription()")}} для установки этого "предложения" как локального описания (то есть описания локального конца соединения).
  4. -
  5. Вызывающий использует сигнальный сервер для передачи "предложения" к требуемому получателю вызова.
  6. -
  7. Получатель получает "предложение" и вызывает {{domxref("RTCPeerConnection.setRemoteDescription()")}} для записи его, как удалённого описания(описания другого конца соединения).
  8. -
  9. Получатель делает всякую настройку, которую должен сделать для его конца соединения, включая добавления исходящих потоков для соединения.
  10. -
  11. Получатель затем создаёт "ответ"(answer) посредством вызова {{domxref("RTCPeerConnection.createAnswer()")}}.
  12. -
  13. Получатель вызывает {{domxref("RTCPeerConnection.setLocalDescription()")}}, чтобы установить "ответ"(answer) в качестве локального описания. Получатель теперь знает конфигурацию обоих концов соединения.
  14. -
  15. Получатель использует сигнальный сервер для отправки "ответа"(answer) вызывающему.
  16. -
  17. Вызывающий получает "ответ"(answer).
  18. -
  19. Вызывающий вызывает {{domxref("RTCPeerConnection.setRemoteDescription()")}} для установки "ответа"(answer) как удалённого описания для его конца соединения. Теперь известна конфигурация обоих узлов. Медиа начинает течь в соответствии с настройками.
  20. -
- -

Рассматриваемые и текущие описания

- -

Спускаясь на один шаг глубже в процесс, мы находим, что localDescription и remoteDescription, свойства, возвращаемые эти двумя описаниями, не так просты, как выглядят. Потому что во время повторных переговоров(перезаключения) (renegotiation), "предложение"(offer) может быть отклонено, поскольку оно предлагает несовместимый формат. Необходимо, чтобы каждая конечная точка имела возможность предложить новый формат, но не переключаться на него, пока он не принят другим узлом. По этой причине, WebRTC использует "рассматриваемые" и "текущие" "описания".

- -

"Текущее описание"(current description) (которое возвращается свойствами {{domxref("RTCPeerConnection.currentLocalDescription")}} и {{domxref("RTCPeerConnection.currentRemoteDescription")}}) представляет собой описание, в данный момент, фактически используемое соединением. Это самое недавнее соединение, которое обе стороны полностью согласились использовать.

- -

"Рассматриваемое описание"(pending description) (возвращаемое {{domxref("RTCPeerConnection.pendingLocalDescription")}} и {{domxref("RTCPeerConnection.pendingRemoteDescription")}}) указывает на то описание, которое в настоящий момент находится на рассмотрении после вызова setLocalDescription() или setRemoteDescription(), соответственно.

- -

При чтении описания (возвращаемого {{domxref("RTCPeerConnection.localDescription")}} и {{domxref("RTCPeerConnection.remoteDescription")}}), возвращаемым значением является значение pendingLocalDescription/pendingRemoteDescription, если есть рассматриваемое описание (то есть, рассматриваемое описание не null). В противном случае, возвращается текущее описание (currentLocalDescription/currentRemoteDescription).

- -

При изменении описания путём вызова setLocalDescription() или setRemoteDescription(), указанное описание устанавливается как "рассматриваемое описание"(pending description), и WebRTC-слой начинает оценивать, действительно ли это приемлемо. После того, как предложенное описание было согласовано, значение currentLocalDescription или currentRemoteDescription изменяется на "рассматриваемое описание"(pending description), и pending description устанавливается снова в null, указывая, что "отложенного описания"(pending description) не существует.

- -
-

pendingLocalDescription содержит не только "предложение" или "ответ" на стадии рассмотрения, но и каких-либо ICE-кандидатов, которые уже были собраны с тех пор, как "предложение" или "ответ" были созданы. Подобным образом, pendingRemoteDescription включает любых удалённых ICE-кандидатов, которые были предоставлены вызовами {{domxref("RTCPeerConnection.addIceCandidate()")}}.

-
- -

Смотрите отдельные статьи по этим свойствам и методам для большей конкретики.

- -

Что такое ICE-кандидат?

- -

В дополнение к обмену информацией о медиа(обсуждённой выше в offer/answer и SDP), узлы должны обменяться информацией о сетевом соединении. Об этом известно как о ICE-кандидате и деталях доступных методов, которыми узел может общаться (непосредственно или через TURN-сервер).

- -

Весь обмен в сложной схеме

- -

A complete architectural diagram showing the whole WebRTC process.

diff --git a/files/ru/web/api/websockets_api/index.html b/files/ru/web/api/websockets_api/index.html new file mode 100644 index 0000000000..8e6c614a0b --- /dev/null +++ b/files/ru/web/api/websockets_api/index.html @@ -0,0 +1,58 @@ +--- +title: WebSockets +slug: WebSockets +tags: + - NeedsBrowserCompatibility + - NeedsTranslation + - References + - TopicStub + - WebSockets +translation_of: Web/API/WebSockets_API +--- +

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

+ +
+
+

Документация

+ +
+
Writing WebSocket client applications
+
Учебник описывающий как написать WebSocket клиента работающего в браузере.
+
Справочник по WebSocket
+
A reference to the client-side WebSocket API.
+
(TBD) Writing WebSocket servers
+
A guide to writing server-side code to handle the WebSocket protocol.
+
+ +

View All...

+
+ +
+

Tools

+ + + + + + +
+
+ +

Совместимость с браузерами

+ +

{{Compat("api.WebSocket")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/websockets_api/writing_websocket_client_applications/index.html b/files/ru/web/api/websockets_api/writing_websocket_client_applications/index.html new file mode 100644 index 0000000000..5eaca515c2 --- /dev/null +++ b/files/ru/web/api/websockets_api/writing_websocket_client_applications/index.html @@ -0,0 +1,195 @@ +--- +title: Написание клиентских приложений с помощью вебсокетов +slug: WebSockets/Writing_WebSocket_client_applications +translation_of: Web/API/WebSockets_API/Writing_WebSocket_client_applications +--- +

{{ draft() }}

+ +

Вебсокеты - технология, которя позволяет открыть интерактивную сессию общения между браузером пользователя и сервером. Соединяясь через вебсокеты, веб-приложения могут осуществлять взаимодействие в реальном времени вместо того, чтобы делать запросы к клиенту о входящих/исходящих изменениях.

+ +
Замечание: У нас есть работающий пример чата, части кода из которого используются в статье. Пример будет доступен, когда инфраструктура сайта сможет должным образом поддерживать хостинг примеров с использованием вебсокетов.
+ +

Доступность вебсокетов

+ +

API вебсокетов доступно в Javascript коде, область видимости которого включает объект DOM {{ domxref("Window") }} или любой объект, реализующий {{ domxref("WorkerUtils") }}; это означает, что вы можете использовать Web Workers.

+ +
Замечание: API вебсокетов (как и протокол лежащий в его основе) всё ещё проходят этап активной разработки; в настоящее время существует много проблем совместимости с разными браузерами (и даже с разными релизами одного и того же браузера).
+ +

Создание объекта WebSocket

+ +

Чтобы общаться через протокол вебсокетов необходимо создать объект WebSocket; при его создании автоматически происходит попытка открыть соединение с сервером.

+ +

Конструктор WebSocket принимает один обязательный и один необязательный параметр:

+ +
WebSocket WebSocket(
+  in DOMString url,
+  in optional DOMString protocols
+);
+
+WebSocket WebSocket(
+  in DOMString url,
+  in optional DOMString[] protocols
+);
+
+ +
+
url
+
URL, с которым происходит соединение; это должен быть URL вебсокет-сервера.
+
protocols {{ optional_inline() }}
+
Может быть одной строкой протокола или массивом таких строк. Эти строки используют для индикации под-протоколов; таким образом, один сервер может реализовывать несколько под-протоколов вебсокетов (к примеру, вам может потребоваться, чтобы сервер мог обрабатывать разные типы взаимодействий в зависимости от определённого под-протокола). Если вы не укажете строку протокола, то будет передана пустая строка.
+
+ +

В конструкторе могут возникать следующие исключения:

+ +
+
SECURITY_ERR
+
Порт, к которому проводится подключение, заблокирован.
+
+ +
+
+ +

Ошибки подключения

+ +

Если ошибка случается во время попытки подключения, то в объект WebSocket сначала посылается простое событие с именем «error» (таким образом, задействуя обработчик onerror), потом - событие CloseEvent  (таким образом, задействуя обработчик onclose) чтобы обозначить причину закрытия соединения.

+ +

Однако, начиная с версии Firefox 11, типичным является получение в консоль от платформы Mozilla расширенного сообщения об обшибке и кода завершения, как то определено в RFC 6455, Section 7.4 посредством CloseEvent.

+ +

Примеры

+ +

Этот простой пример создает новый WebSocket, подключаемый к серверу ws://www.example.com/socketserver. В данном примере в конструктор сокета в качестве дополнительного параметра передается пользовательский протокол "protocolOne", хотя эта часть может быть опущена.

+ +
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", "protocolOne");
+
+ +

После выполнения функции, exampleSocket.readyState будет иметь значение CONNECTING. readyState изменится на OPEN как только соединение станет готовым к передаче данных.

+ +

Если нужно открыть соединение, поддерживающее несколько протоколов, можно передать массив протоколов:

+ +
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", ["protocolOne", "protocolTwo"]);
+
+ +

Когда соединение установлено (что соответствует, readyState OPEN), exampleSocket.protocol сообщит, какой протокол выбрал сервер.

+ +

In the above examples ws has replaced http, similarly wss replaces https. Establishing a WebSocket relies on the HTTP Upgrade mechanism, so the request for the protocol upgrade is implicit when we address the HTTP server as ws://www.example.com or wss://www.example.com.

+ +

Отправка данных на сервер

+ +

Однажды открыв соединение, вы можете передавать данные на сервер. Для осуществления этого, вызовите метод send() объекта WebSocket  для каждого сообщение, которое желаете отправить:

+ +
exampleSocket.send("Here's some text that the server is urgently awaiting!");
+
+ +

Вы можете пересылать данные в виде строки, {{ domxref("Blob") }}, так и ArrayBuffer.

+ +
Note: Prior to version 11, Firefox only supported sending data as a string.
+ +

As establishing a connection is asynchronous and prone to failure there is no guarantee that calling the send() method immediately after creating a WebSocket object will be successful. We can at least be sure that attempting to send data only takes place once a connection is established by defining an onopen handler to do the work:

+ +
exampleSocket.onopen = function (event) {
+  exampleSocket.send("Here's some text that the server is urgently awaiting!");
+};
+
+ +

Using JSON to transmit objects

+ +

One handy thing you can do is use JSON to send reasonably complex data to the server. For example, a chat program can interact with a server using a protocol implemented using packets of JSON-encapsulated data:

+ +
// Send text to all users through the server
+function sendText() {
+  // Construct a msg object containing the data the server needs to process the message from the chat client.
+  var msg = {
+    type: "message",
+    text: document.getElementById("text").value,
+    id:   clientID,
+    date: Date.now()
+  };
+
+  // Send the msg object as a JSON-formatted string.
+  exampleSocket.send(JSON.stringify(msg));
+
+  // Blank the text input element, ready to receive the next line of text from the user.
+  document.getElementById("text").value = "";
+}
+
+ +

Receiving messages from the server

+ +

WebSockets is an event-driven API; when messages are received, a "message" event is delivered to the onmessage function. To begin listening for incoming data, you can do something like this:

+ +
exampleSocket.onmessage = function (event) {
+  console.log(event.data);
+}
+
+ +

Receiving and interpreting JSON objects

+ +

Let's consider the chat client application first alluded to in {{ anch("Using JSON to transmit objects") }}. There are assorted types of data packets the client might receive, such as:

+ + + +

The code that interprets these incoming messages might look like this:

+ +
exampleSocket.onmessage = function(event) {
+  var f = document.getElementById("chatbox").contentDocument;
+  var text = "";
+  var msg = JSON.parse(event.data);
+  var time = new Date(msg.date);
+  var timeStr = time.toLocaleTimeString();
+
+  switch(msg.type) {
+    case "id":
+      clientID = msg.id;
+      setUsername();
+      break;
+    case "username":
+      text = "<b>User <em>" + msg.name + "</em> signed in at " + timeStr + "</b><br>";
+      break;
+    case "message":
+      text = "(" + timeStr + ") <b>" + msg.name + "</b>: " + msg.text + "<br>";
+      break;
+    case "rejectusername":
+      text = "<b>Your username has been set to <em>" + msg.name + "</em> because the name you chose is in use.</b><br>"
+      break;
+    case "userlist":
+      var ul = "";
+      for (i=0; i < msg.users.length; i++) {
+        ul += msg.users[i] + "<br>";
+      }
+      document.getElementById("userlistbox").innerHTML = ul;
+      break;
+  }
+
+  if (text.length) {
+    f.write(text);
+    document.getElementById("chatbox").contentWindow.scrollByPages(1);
+  }
+};
+
+ +

Here we use JSON.parse() to convert the JSON object back into the original object, then examine and act upon its contents.

+ +

Text data format

+ +

Text received over a WebSocket connection is in UTF-8 format.

+ +

Prior to Gecko 9.0 {{ geckoRelease("9.0") }}, certain non-characters in otherwise valid UTF-8 text would cause the connection to be terminated. Now Gecko permits these values.

+ +

Closing the connection

+ +

When you've finished using the WebSocket connection, call the WebSocket method close():

+ +
exampleSocket.close();
+
+ +

It may be helpful to examine the socket's bufferedAmount attribute before attempting to close the connection to determine if any data has yet to be transmitted on the network.

+ +

Security considerations

+ +

WebSockets should not be used in a mixed content environment; that is, you shouldn't open a non-secure WebSocket connection from a page loaded using HTTPS or vice-versa. In fact, some browsers explicitly forbid this, including Firefox 8 and later.

+ +

{{ languages ( {"zh-tw": "zh_tw/WebSockets/Writing_WebSocket_client_applications"} ) }}

diff --git a/files/ru/web/api/window/domcontentloaded_event/index.html b/files/ru/web/api/window/domcontentloaded_event/index.html new file mode 100644 index 0000000000..7702dcfd24 --- /dev/null +++ b/files/ru/web/api/window/domcontentloaded_event/index.html @@ -0,0 +1,146 @@ +--- +title: DOMContentLoaded +slug: Web/Events/DOMContentLoaded +tags: + - события +translation_of: Web/API/Window/DOMContentLoaded_event +--- +

Событие DOMContentLoaded происходит когда весь HTML был полностью загружен и пройден парсером, не дожидаясь окончания загрузки таблиц стилей, изображений и фреймов. Значительно отличающееся от него событие load используется для отслеживания только полностью загруженной страницы. Широко распространённой ошибкой является использование load в ситуации когда DOMContentLoaded является более подходящим, будьте внимательны.

+ +

{{Note("Синхронный JavaScript останавливает парсинг DOM.")}}

+ +

{{Note("Существуют различные библиотеки, как общего назначения так и специализированные, предлагающие кросс-браузерные методы, позволяющие определить, что DOM готов к использованию.")}}

+ +

Ускорение работы

+ +

Если вы хотите чтобы DOM был пройден парсером насколько возможно быстро, сразу после запроса пользователем страницы, вы можете попробовать выполнять JavaScript асинхронно и оптимизировать загрузку таблиц стилей которые обычно замедляют загрузку документа поскольку загружаясь одновременно "крадут" трафик у основного документа.

+ +

Основная информация

+ +
+
Спецификация
+
HTML5
+
Интерфейс 
+
Event
+
Всплывает
+
Да
+
Отменяемое
+
Да (несмотря на то, что в спецификации указано как простое событие, которое не является отменяемым)
+
Цель 
+
Document
+
Default Action
+
Нет.
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
+ +

Пример

+ +
<script>
+  document.addEventListener("DOMContentLoaded", function(event) {
+    console.log("DOM fully loaded and parsed");
+  });
+</script>
+
+ +
<script>
+  document.addEventListener("DOMContentLoaded", function(event) {
+    console.log("DOM fully loaded and parsed");
+  });
+
+for(var i=0; i<1000000000; i++)
+{} // this synchronous script is going to delay parsing of the DOM. So the DOMContentLoaded event is going to launch later.
+</script>
+
+ +

Поддержка браузерами

+ +

{{CompatibilityTable}}

+ + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка1.0[1]{{CompatGeckoDesktop("1")}}[1]9.0[2]9.03.1[1]
+ + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}[1]{{CompatGeckoMobile("1")}}[1]{{CompatUnknown}}[2]{{CompatVersionUnknown}}{{CompatVersionUnknown}}[1]
+ +

[1] Всплытие для этого события поддерживается как минимум с версий Gecko 1.9.2, Chrome 6, и Safari 4.

+ +

[2] Internet Explorer 8 поддерживает событие readystatechange, которое можно использовать для определения готовности DOM. В более ранних версиях Internet Explorer,это событие можно определить циклическим выполнением document.documentElement.doScroll("left");, это событие будет выбрасывать ошибку если DOM не готов.

+ +

Связанные события

+ + diff --git a/files/ru/web/api/window/load_event/index.html b/files/ru/web/api/window/load_event/index.html new file mode 100644 index 0000000000..a8d456806d --- /dev/null +++ b/files/ru/web/api/window/load_event/index.html @@ -0,0 +1,88 @@ +--- +title: load +slug: Web/Events/load +translation_of: Web/API/Window/load_event +--- +

Событие load происходит когда ресурс и его зависимые ресурсы закончили загружаться.

+ +

General info

+ +
+
Спецификация
+
DOM L3
+
Интерфейс
+
UIEvent
+
Всплывает
+
Да
+
Отменяемое
+
Нет
+
Цель
+
Window
+
Default Action
+
Нет.
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}EventTargetThe event target (the topmost target in the DOM tree).
type {{readonlyInline}}DOMStringThe type of event.
bubbles {{readonlyInline}}BooleanWhether the event normally bubbles or not.
cancelable {{readonlyInline}}BooleanWhether the event is cancellable or not.
view {{readonlyInline}}WindowProxydocument.defaultView (window of the document)
detail {{readonlyInline}}long (float)0.
+ +

Пример

+ +
<script>
+  window.addEventListener("load", function(event) {
+    console.log("All resources finished loading!");
+  });
+</script>
+
+ +

 

+ +

Связанные события

+ + diff --git a/files/ru/web/api/window/requestanimationframe/index.html b/files/ru/web/api/window/requestanimationframe/index.html new file mode 100644 index 0000000000..d451cae62f --- /dev/null +++ b/files/ru/web/api/window/requestanimationframe/index.html @@ -0,0 +1,92 @@ +--- +title: window.requestAnimationFrame() +slug: DOM/window.requestAnimationFrame +tags: + - Анимация +translation_of: Web/API/window/requestAnimationFrame +--- +
{{APIRef}}
+ +

window.requestAnimationFrame указывает браузеру на то, что вы хотите произвести анимацию, и просит его запланировать перерисовку на следующем кадре анимации. В качестве параметра метод получает функцию, которая будет вызвана перед перерисовкой.

+ +
Заметка: Ваш callback метод сам должен вызвать requestAnimationFrame() иначе анимация остановится.
+ +

Вы должны вызывать этот метод всякий раз, когда готовы обновить анимацию на экране, чтобы запросить планирование анимации. Обычно запросы происходят 60 раз в секунду, но чаще всего совпадают с частотой обновления экрана. В большинстве браузеров в фоновых вкладках или скрытых <iframe>, вызовы requestAnimationFrame() приостанавливаются, для того, чтобы повысить производительность и время работы батареи.

+ +

Callback методу передаётся один аргумент, {{domxref("DOMHighResTimeStamp")}}, который содержит текущее время (количество миллисекунд, прошедших с момента time origin). Когда callback-и, отправленные в очередь с помощью requestAnimationFrame() начинают вызывать несколько callback-ов в одном кадре, каждый получает одинаковый timestamp, хотя для вычисления каждого callback было затрачено время. Этот timestamp - десятичное число в миллисекундах, но с минимальной точностью в 1ms (1000 µs).

+ +

Синтаксис

+ +
window.requestAnimationFrame(callback);
+ +

Параметры

+ +
+
callback
+
Функция, которая будет вызвана, когда придёт время обновить вашу анимацию на следующей перерисовке.
+
element {{ optional_inline() }}
+
Необязательный параметр (не используется в Firefox или IE), определяющий элемент, который визуально содержит всю анимацию. Для canvas'а и WebGL'a им должен быть {{ HTMLElement("canvas") }}. Для других элементов вы можете опустить этот параметр для чуть лучшего пользовательского опыта.
+
+ +

Возвращаемое значение

+ +

requestID — длинное целое, являющееся уникальным идентификатором для записи, содержащей callback. Оно не равно нулю, но других предположений о его значении делать не следует. Вы можете передать его в {{ domxref("window.cancelAnimationFrame()") }} для отмены вызова.

+ +

Пример

+ +
var start = null;
+var element = document.getElementById('SomeElementYouWantToAnimate');
+
+function step(timestamp) {
+  if (!start) start = timestamp;
+  var progress = timestamp - start;
+  element.style.transform = 'translateX(' + Math.min(progress / 10, 200) + 'px)';
+  if (progress < 2000) {
+    window.requestAnimationFrame(step);
+  }
+}
+
+window.requestAnimationFrame(step);
+ +

Примечание

+ +

В Edge версиях младше 17 и в Internet Explorer не надежно запускать requestAnimationFrame перед циклом рисования.

+ +

Спецификация

+ + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', '#animation-frames', 'requestAnimationFrame')}}{{Spec2('HTML WHATWG')}}Без изменений, заменяет предыдущую.
{{SpecName('RequestAnimationFrame', '#dom-windowanimationtiming-requestanimationframe', 'requestAnimationFrame')}}{{Spec2('RequestAnimationFrame')}}Первоначальное описание.
+ +

Браузерная совместимость

+ +

{{Compat("api.Window.requestAnimationFrame")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/window/unhandledrejection_event/index.html b/files/ru/web/api/window/unhandledrejection_event/index.html new file mode 100644 index 0000000000..5248e75748 --- /dev/null +++ b/files/ru/web/api/window/unhandledrejection_event/index.html @@ -0,0 +1,49 @@ +--- +title: unhandledrejection +slug: Web/Events/unhandledrejection +translation_of: Web/API/Window/unhandledrejection_event +--- +

Событие unhandledrejection происходит, когда {{jsxref("Promise")}} завершен с ошибкой, но на данную ошибку не установлен обработчик.

+ + + + + + + + + + + + + + + + + + + + +
ВсплытиеНет
Возможность отменыНет
Target objectsdefaultView
Интерфейс{{domxref("PromiseRejectionEvent")}}
+ +

Пример

+ +
window.addEventListener("unhandledrejection", function (event) {
+  console.warn("Внимание: Необработанная ошибка Promise. Позор вам! Причина: "
+               + event.reason);
+});
+
+ +

Inheritance

+ +

Событие unhandledrejection реализует {{domxref("PromiseRejectionEvent")}} интерфейс, который наследуется от {{domxref("Event")}}. Вы можете использовать свойства и методы, определенные в данных интерфейсах.

+ +

{{InheritanceDiagram('','','', 'PromiseRejectionEvent')}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/windowbase64/base64_encoding_and_decoding/index.html b/files/ru/web/api/windowbase64/base64_encoding_and_decoding/index.html deleted file mode 100644 index b85f3671ef..0000000000 --- a/files/ru/web/api/windowbase64/base64_encoding_and_decoding/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: Кодирование и декодирование в формате Base64 -slug: Web/API/WindowBase64/Base64_encoding_and_decoding -translation_of: Glossary/Base64 ---- -

Base64 - это группа cхожих binary-to-text encoding схем, которые представляют двоичные данные в ASCII-формате методом перевода в radix-64 представление. Термин Base64 происходит от a specific MIME content transfer encoding.

- -

Кодирование Base64 широко используется в случаях, когда требуется перекодировать двоичные данные для передачи по каналу приспособленному для передачи текстовых данных. Это делается с целью защиты двоичных данных от любых возможных повреждений при передаче. Base64 широко используется во многих приложениях, включая электронную почту (MIME), и при сохранении больших объёмов данных в XML.

- -

В языке JavaScript существуют две функции, для кодирования и декодирования данных в/из формат Base64 соответственно:

- - - -

Функция atob() декодирует Base64-кодированную строку. В противоположность ей, функция btoa() создаёт Base64 кодированную ASCII строку из "строки" бинарных данных.

- -

Обе функции atob() и btoa() работают со строками. Если вам необходимо работать с ArrayBuffers, обратитесь к этому параграфу.

- - - - - - - - -
-

Документация

- -
-
data URIs
-
data URIs, описанные в RFC 2397, позволяют создателям контента встроить в документ маленькие файлы в виде строки (инлайном).
-
Base64
-
Wikipedia article about Base64 encoding.
-
{{domxref("WindowBase64.atob","atob()")}}
-
Decodes a string of data which has been encoded using base-64 encoding.
-
{{domxref("WindowBase64.btoa","btoa()")}}
-
Creates a base-64 encoded ASCII string from a "string" of binary data.
-
The "Unicode Problem"
-
In most browsers, calling btoa() on a Unicode string will cause a Character Out Of Range exception. This paragraph shows some solutions.
-
URIScheme
-
List of Mozilla supported URI schemes
-
StringView
-
In this article is published a library of ours whose aims are: -
    -
  • creating a C-like interface for strings (i.e. array of characters codes — ArrayBufferView in JavaScript) based upon the JavaScript ArrayBuffer interface,
  • -
  • creating a collection of methods for such string-like objects (since now: stringViews) which work strictly on array of numbers rather than on immutable JavaScript strings,
  • -
  • working with other Unicode encodings, different from default JavaScript's UTF-16 DOMStrings,
  • -
-
-
- -

View All...

-
-

Tools

- - - -

View All...

- - - - -
- -

The "Unicode Problem"

- -

Since DOMStrings are 16-bit-encoded strings, in most browsers calling window.btoa on a Unicode string will cause a Character Out Of Range exception if a character exceeds the range of a 8-bit byte (0x00~0xFF). There are two possible methods to solve this problem:

- - - -

Here are the two possible methods.

- -

Solution #1 – escaping the string before encoding it

- -
function b64EncodeUnicode(str) {
-    // first we use encodeURIComponent to get percent-encoded UTF-8,
-    // then we convert the percent encodings into raw bytes which
-    // can be fed into btoa.
-    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
-        function toSolidBytes(match, p1) {
-            return String.fromCharCode('0x' + p1);
-    }));
-}
-
-b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
-b64EncodeUnicode('\n'); // "Cg=="
-
- -

To decode the Base64-encoded value back into a String:

- -
function b64DecodeUnicode(str) {
-    // Going backwards: from bytestream, to percent-encoding, to original string.
-    return decodeURIComponent(atob(str).split('').map(function(c) {
-        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
-    }).join(''));
-}
-
-b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
-b64DecodeUnicode('Cg=='); // "\n"
-
- -

Unibabel implements common conversions using this strategy.

- -

Solution #2 – rewrite the DOMs atob() and btoa() using JavaScript's TypedArrays and UTF-8

- -

Use a TextEncoder polyfill such as TextEncoding (also includes legacy windows, mac, and ISO encodings), TextEncoderLite, combined with a Buffer and a Base64 implementation such as base64-js.

- -

When a native TextEncoder implementation is not available, the most light-weight solution would be to use TextEncoderLite with base64-js. Use the browser implementation when you can.

- -

The following function implements such a strategy. It assumes base64-js imported as <script type="text/javascript" src="base64js.min.js"/>. Note that TextEncoderLite only works with UTF-8.

- -
function Base64Encode(str, encoding = 'utf-8') {
-    var bytes = new (TextEncoder || TextEncoderLite)(encoding).encode(str);
-    return base64js.fromByteArray(bytes);
-}
-
-function Base64Decode(str, encoding = 'utf-8') {
-    var bytes = base64js.toByteArray(str);
-    return new (TextDecoder || TextDecoderLite)(encoding).decode(bytes);
-}
-
diff --git a/files/ru/web/api/windowbase64/btoa/index.html b/files/ru/web/api/windowbase64/btoa/index.html deleted file mode 100644 index 06b76a6304..0000000000 --- a/files/ru/web/api/windowbase64/btoa/index.html +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: WindowBase64.btoa() -slug: Web/API/WindowBase64/btoa -translation_of: Web/API/WindowOrWorkerGlobalScope/btoa ---- -
{{APIRef("HTML DOM")}}
- -

Создает ASCII строку закодированную в base-64 из "строки" бинарных данных.

- -

Будьте внимательней этот способ не подходит для Unicode строк! Описание работы с Unicode в секции ниже.

- -

Синтаксис

- -
var encodedData = window.btoa(stringToEncode);
- -

Пример

- -
var encodedData = window.btoa("Hello, world"); // encode a string
-var decodedData = window.atob(encodedData); // decode the string
-
- -

Замечания

- -

Вы можете воспользоваться этим способом, чтобы избежать проблем при передаче данных через сетевое соединение. Для этого нужно перекодировать данные в base64 и отправить их, и на другой стороне с помощью метода {{domxref("WindowBase64.atob","window.atob()")}} декодировать полученные данные в исходный вид. Например, вы можете перекодировать управляющие символы ASCII с 0 до 31.

- -

btoa() также доступна для XPCOM компонентов реализованных в JavaScript, даже если window не является глобальным объектом в компонентах.

- -

Строки Юникод

- -

В большинстве браузеров, вызов window.btoa() на Unicode строке выбросит исключение Character Out Of Range (Символ вне допустимого диапазона).

- -

Чтобы избежать этого, воспользуйтесь патерном, предложеным Johan Sundström:

- -
function utf8_to_b64(str) {
-    return window.btoa(unescape(encodeURIComponent(str)));
-}
-
-function b64_to_utf8(str) {
-    return decodeURIComponent(escape(window.atob(str)));
-}
-
-// Usage:
-utf8_to_b64('✓ à la mode'); // JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ==
-b64_to_utf8('JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ=='); // "✓ à la mode"
-
-utf8_to_b64('I \u2661 Unicode!'); // SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ==
-b64_to_utf8('SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ=='); // "I ♡ Unicode!"
-
-
- -

Более правильный и производительный способ - это конвертировать DOMString в UTF-8 строку передав typed arrays. Как это сделать узнать можно здесь в этом параграфе.

- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-windowbase64-btoa', 'WindowBase64.btoa()')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#dom-windowbase64-btoa', 'WindowBase64.btoa()')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#dom-windowbase64-btoa", "WindowBase64.btoa()")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
- -

Совместимость браузеров

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop(1)}}[1]10{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatGeckoMobile(1)}}{{CompatNo}}{{CompatUnknown}}{{CompatVersionUnknown}}
-
- -

[1] btoa() также доступна для XPCOM компонентов реализованных в JavaScript, даже если window не является глобальным объектом в компонентах.

- -

Смотрите также

- - diff --git a/files/ru/web/api/windowbase64/index.html b/files/ru/web/api/windowbase64/index.html deleted file mode 100644 index f51b72c102..0000000000 --- a/files/ru/web/api/windowbase64/index.html +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: WindowBase64 -slug: Web/API/WindowBase64 -tags: - - API - - HTML-DOM - - Helper - - NeedsTranslation - - TopicStub - - WindowBase64 -translation_of: Web/API/WindowOrWorkerGlobalScope -translation_of_original: Web/API/WindowBase64 ---- -

{{APIRef("HTML DOM")}}

- -

The WindowBase64 helper contains utility methods to convert data to and from base64, a binary-to-text encoding scheme. For example it is used in data URIs.

- -

There is no object of this type, though the context object, either the {{domxref("Window")}} for regular browsing scope, or the {{domxref("WorkerGlobalScope")}}  for workers, implements it.

- -

Properties

- -

This helper neither defines nor inherits any properties.

- -

Methods

- -

This helper does not inherit any methods.

- -
-
{{domxref("WindowBase64.atob()")}}
-
Decodes a string of data which has been encoded using base-64 encoding.
-
{{domxref("WindowBase64.btoa()")}}
-
Creates a base-64 encoded ASCII string from a string of binary data.
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#windowbase64', 'WindowBase64')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#windowbase64', 'WindowBase64')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#windowbase64", "WindowBase64")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{CompatGeckoDesktop(1)}} [1]{{CompatVersionUnknown}}10.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox Mobile (Gecko)AndroidIE MobileOpera MobileSafari Mobile
Basic support{{CompatGeckoMobile(1)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

[1]  atob() is also available to XPCOM components implemented in JavaScript, even though {{domxref("Window")}} is not the global object in components.

- -

See also

- - diff --git a/files/ru/web/api/windoworworkerglobalscope/btoa/index.html b/files/ru/web/api/windoworworkerglobalscope/btoa/index.html new file mode 100644 index 0000000000..06b76a6304 --- /dev/null +++ b/files/ru/web/api/windoworworkerglobalscope/btoa/index.html @@ -0,0 +1,141 @@ +--- +title: WindowBase64.btoa() +slug: Web/API/WindowBase64/btoa +translation_of: Web/API/WindowOrWorkerGlobalScope/btoa +--- +
{{APIRef("HTML DOM")}}
+ +

Создает ASCII строку закодированную в base-64 из "строки" бинарных данных.

+ +

Будьте внимательней этот способ не подходит для Unicode строк! Описание работы с Unicode в секции ниже.

+ +

Синтаксис

+ +
var encodedData = window.btoa(stringToEncode);
+ +

Пример

+ +
var encodedData = window.btoa("Hello, world"); // encode a string
+var decodedData = window.atob(encodedData); // decode the string
+
+ +

Замечания

+ +

Вы можете воспользоваться этим способом, чтобы избежать проблем при передаче данных через сетевое соединение. Для этого нужно перекодировать данные в base64 и отправить их, и на другой стороне с помощью метода {{domxref("WindowBase64.atob","window.atob()")}} декодировать полученные данные в исходный вид. Например, вы можете перекодировать управляющие символы ASCII с 0 до 31.

+ +

btoa() также доступна для XPCOM компонентов реализованных в JavaScript, даже если window не является глобальным объектом в компонентах.

+ +

Строки Юникод

+ +

В большинстве браузеров, вызов window.btoa() на Unicode строке выбросит исключение Character Out Of Range (Символ вне допустимого диапазона).

+ +

Чтобы избежать этого, воспользуйтесь патерном, предложеным Johan Sundström:

+ +
function utf8_to_b64(str) {
+    return window.btoa(unescape(encodeURIComponent(str)));
+}
+
+function b64_to_utf8(str) {
+    return decodeURIComponent(escape(window.atob(str)));
+}
+
+// Usage:
+utf8_to_b64('✓ à la mode'); // JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ==
+b64_to_utf8('JTI1dTI3MTMlMjUyMCUyNUUwJTI1MjBsYSUyNTIwbW9kZQ=='); // "✓ à la mode"
+
+utf8_to_b64('I \u2661 Unicode!'); // SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ==
+b64_to_utf8('SSUyNTIwJTI1dTI2NjElMjUyMFVuaWNvZGUlMjUyMQ=='); // "I ♡ Unicode!"
+
+
+ +

Более правильный и производительный способ - это конвертировать DOMString в UTF-8 строку передав typed arrays. Как это сделать узнать можно здесь в этом параграфе.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-windowbase64-btoa', 'WindowBase64.btoa()')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#dom-windowbase64-btoa', 'WindowBase64.btoa()')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#dom-windowbase64-btoa", "WindowBase64.btoa()")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
+ +

Совместимость браузеров

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatVersionUnknown}}{{CompatGeckoDesktop(1)}}[1]10{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatGeckoMobile(1)}}{{CompatNo}}{{CompatUnknown}}{{CompatVersionUnknown}}
+
+ +

[1] btoa() также доступна для XPCOM компонентов реализованных в JavaScript, даже если window не является глобальным объектом в компонентах.

+ +

Смотрите также

+ + diff --git a/files/ru/web/api/windoworworkerglobalscope/settimeout/index.html b/files/ru/web/api/windoworworkerglobalscope/settimeout/index.html new file mode 100644 index 0000000000..9e39020215 --- /dev/null +++ b/files/ru/web/api/windoworworkerglobalscope/settimeout/index.html @@ -0,0 +1,260 @@ +--- +title: WindowTimers.setTimeout() +slug: Web/API/WindowTimers/setTimeout +translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout +--- +
{{ APIRef() }}
+ +

Краткое изложение

+ +

Вызов функции или выполнение фрагмента кода после указанной задержки.

+ +

Синтаксис

+ +
var timeoutID = window.setTimeout(func, [, delay, param1, param2, ...]);
+var timeoutID = window.setTimeout(code [, delay]);
+
+ +

где

+ + + +

Необходимо принять во внимание, что передача дополнительных параметров функции в первом варианте не работает в Internet Explorer 9 и ниже. Для использования этого функционала в таких браузерах, необходимо использовать код для совместимости (см. раздел Аргументы функции обратного вызова).

+ +
Important: Prior to Gecko 13 {{ geckoRelease("13.0") }}, Gecko passed an extra parameter to the callback routine, indicating the "actual lateness" of the timeout in milliseconds. This non-standard parameter is no longer passed.
+ +

Пример

+ +

В следующем примере на веб странице создаются две простые кнопки, к которым привязываются действия setTimeout и clearTimeout. Нажатие на первую кнопку установит таймаут, который вызовет диалоговое окно через две секунды. Также будет сохранен id для clearTimeout. Таймаут также может быть отменен по нажатию на вторую кнопку.

+ +

HTML Content

+ +
<p>Live Example</p>
+<button onclick="delayedAlert();">Show an alert box after two seconds</button>
+<p></p>
+<button onclick="clearAlert();">Cancel alert before it happens</button>
+
+ +

JavaScript Content

+ +
var timeoutID;
+
+function delayedAlert() {
+  timeoutID = window.setTimeout(slowAlert, 2000);
+}
+
+function slowAlert() {
+  alert("That was really slow!");
+}
+
+function clearAlert() {
+  window.clearTimeout(timeoutID);
+}
+
+ +

{{ EmbedLiveSample('Example') }}

+ +

Смотрите также пример clearTimeout().

+ +

Аргументы функции обратного вызова

+ +

Если вам нужно передать аргумент в вашу callback функцию, но нужно, чтобы это работало в Internet Explorer 9 и ниже, который не поддерживает передачу дополнительных параметров (ни с setTimeout() или setInterval()), то вы можете прописать специальный код для совместимости с IE, вставив этот код в начало ваших скриптов, который включит функцию передачи стандартных параметров HTML5 в Internet Explorer для обоих таймеров.

+ +
/*\
+|*|
+|*|  IE-specific polyfill which enables the passage of arbitrary arguments to the
+|*|  callback functions of JavaScript timers (HTML5 standard syntax).
+|*|
+|*|  https://developer.mozilla.org/en-US/docs/DOM/window.setInterval
+|*|
+|*|  Syntax:
+|*|  var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
+|*|  var timeoutID = window.setTimeout(code, delay);
+|*|  var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
+|*|  var intervalID = window.setInterval(code, delay);
+|*|
+\*/
+
+if (document.all && !window.setTimeout.isPolyfill) {
+  var __nativeST__ = window.setTimeout;
+  window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
+    var aArgs = Array.prototype.slice.call(arguments, 2);
+    return __nativeST__(vCallback instanceof Function ? function () {
+      vCallback.apply(null, aArgs);
+    } : vCallback, nDelay);
+  };
+  window.setTimeout.isPolyfill = true;
+}
+
+if (document.all && !window.setInterval.isPolyfill) {
+  var __nativeSI__ = window.setInterval;
+  window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
+    var aArgs = Array.prototype.slice.call(arguments, 2);
+    return __nativeSI__(vCallback instanceof Function ? function () {
+      vCallback.apply(null, aArgs);
+    } : vCallback, nDelay);
+  };
+  window.setInterval.isPolyfill = true;
+}
+
+ +

Правка только для IE

+ +

If you want a completely unobtrusive hack for every other mobile or desktop browser, including IE 9 and below, you can either use JavaScript conditional comments:

+ +
/*@cc_on
+  // conditional IE < 9 only fix
+  @if (@_jscript_version <= 6)
+  (function(f){
+     window.setTimeout =f(window.setTimeout);
+     window.setInterval =f(window.setInterval);
+  })(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
+  @end
+@*/
+
+ +

Или используйте очень чистый подход, основанный на условном свойстве IE HTML:

+ +
<!--[if lte IE 9]><script>
+(function(f){
+window.setTimeout =f(window.setTimeout);
+window.setInterval =f(window.setInterval);
+})(function(f){return function(c,t){
+var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}
+});
+</script><![endif]-->
+
+ +

Another possibility is to use an anonymous function to call your callback, but this solution is a bit more expensive. Example:

+ +
var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);
+
+ +

Yet another possibility is to use function's bind. Example:

+ +
setTimeout(function(arg1){}.bind(undefined, 10));
+
+ +

Проблема с "this"

+ +

Когда вы передаете метод в setTimeout() (или в любую другую функцию, если на то пошло), то вызов будет осуществлен с неправильным значением this. Эта проблема разъясняется детально в JavaScript reference.

+ +

Объяснение

+ +

Code executed by setTimeout() is run in a separate execution context to the function from which it was called. As a consequence, the this keyword for the called function will be set to the window (or global) object; it will not be the same as the this value for the function that called setTimeout. See the following example:

+ +
myArray = ["zero", "one", "two"];
+myArray.myMethod = function (sProperty) {
+    alert(arguments.length > 0 ? this[sProperty] : this);
+};
+
+myArray.myMethod(); // prints "zero,one,two"
+myArray.myMethod(1); // prints "one"
+setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
+setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds
+// let's try to pass the 'this' object
+setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
+setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error
+ +

Как видите, нет способов передать объект this в функцию обратного вызова..

+ +

Возможное решение

+ +

A possible way to solve the "this" problem is to replace the two native setTimeout() or setInterval() global functions with two non-native ones which will enable their invocation through the Function.prototype.call method. The following example shows a possible replacement:

+ +
// Enable the passage of the 'this' object through the JavaScript timers
+
+var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval;
+
+window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
+  var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
+  return __nativeST__(vCallback instanceof Function ? function () {
+    vCallback.apply(oThis, aArgs);
+  } : vCallback, nDelay);
+};
+
+window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
+  var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
+  return __nativeSI__(vCallback instanceof Function ? function () {
+    vCallback.apply(oThis, aArgs);
+  } : vCallback, nDelay);
+};
+ +
Note: These two replacements will also enable the HTML5 standard passage of arbitrary arguments to the callback functions of timers in IE. So they can be used as polyfills also. See the Callback arguments paragraph.
+ +

Новая тестируемая особенность:

+ +
myArray = ["zero", "one", "two"];
+myArray.myMethod = function (sProperty) {
+    alert(arguments.length > 0 ? this[sProperty] : this);
+};
+
+setTimeout(alert, 1500, "Hello world!"); // the standard use of setTimeout and setInterval is preserved, but...
+setTimeout.call(myArray, myArray.myMethod, 2000); // prints "zero,one,two" after 2 seconds
+setTimeout.call(myArray, myArray.myMethod, 2500, 2); // prints "two" after 2.5 seconds
+
+ +

Это не нативные решения ad hoc для этой проблемы.

+ +
Note: JavaScript 1.8.5 introduces the Function.prototype.bind() method, which lets you specify the value that should be used as this for all calls to a given function. This lets you easily bypass problems where it's unclear what this will be, depending on the context from which your function was called.
+ +

Замечания

+ +

Отложенное выполнение кода можно отменить, используя window.clearTimeout(). Если функция должна вызываться неоднократно (например, каждые N миллисекунд), необходимо использовать window.setInterval().

+ +

Важно заметить, что функция или код не могут быть выполнены, пока не завершится поток, вызвавший setTimeout().

+ +

Passing string literals

+ +

Передача строки вместо функции в setTimeout() сопряжена с теми же опасностями, что и использование eval.

+ +
// Правильно
+window.setTimeout(function() {
+    alert("Hello World!");
+}, 500);
+
+// Неправильно
+window.setTimeout("alert(\"Hello World!\");", 500);
+
+
+ +

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

+ +

Минимальная/ максимальная задержка и вложенность таймаута

+ +

Historically browsers implement setTimeout() "clamping": successive setTimeout() calls with delay smaller than the "minimum delay" limit are forced to use at least the minimum delay. The minimum delay, DOM_MIN_TIMEOUT_VALUE, is 4 ms (stored in a preference in Firefox: dom.min_timeout_value), with a DOM_CLAMP_TIMEOUT_NESTING_LEVEL of 5ms.

+ +

In fact, 4ms is specified by the HTML5 spec and is consistent across browsers released in 2010 and onward. Prior to {{ geckoRelease("5.0") }}, the minimum timeout value for nested timeouts was 10 ms.

+ +

In addition to "clamping", the timeout can also fire later when the page (or the OS/browser itself) is busy with other tasks.

+ +

To implement a 0 ms timeout in a modern browser, you can use {{ domxref("window.postMessage()") }} as described here.

+ +

Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed Integer internally. This causes an Integer overflow when using delays larger than 2147483647, resulting in the timeout being executed immediately.

+ +

Неактивные вкладки

+ +

In {{ geckoRelease("5.0") }} and Chrome 11, timeouts are clamped to firing no more often than once per second (1000ms) in inactive tabs; see {{ bug(633421) }} for more information about this in Mozilla or crbug.com/66078 for details about this in Chrome.

+ +

Совместимость с браузерами

+ +

{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}

+ +

Спецификация

+ +

Part of DOM level 0, as specified in HTML5.

+ +

Также интересно

+ + diff --git a/files/ru/web/api/windowtimers/index.html b/files/ru/web/api/windowtimers/index.html deleted file mode 100644 index ac80f42b5f..0000000000 --- a/files/ru/web/api/windowtimers/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: WindowTimers -slug: Web/API/WindowTimers -tags: - - API - - HTML DOM -translation_of: Web/API/WindowOrWorkerGlobalScope -translation_of_original: Web/API/WindowTimers ---- -
{{APIRef("HTML DOM")}}
- -

WindowTimers contains utility methods to set and clear timers.

- -

There is no object of this type, though the context object, either the {{domxref("Window")}} for regular browsing scope, or the {{domxref("WorkerGlobalScope")}}  for workers, implements it.

- -

Properties

- -

This interface do not define any property, nor inherit any.

- -

Methods

- -

This interface do not inherit any method.

- -
-
{{domxref("WindowTimers.clearInterval()")}}
-
Cancels the repeated execution set using {{domxref("WindowTimers.setInterval()")}}.
-
{{domxref("WindowTimers.clearTimeout()")}}
-
Cancels the repeated execution set using {{domxref("WindowTimers.setTimeout()")}}.
-
{{domxref("WindowTimers.setInterval()")}}
-
Schedules the execution of a function each X milliseconds.
-
{{domxref("WindowTimers.setTimeout()")}}
-
Sets a delay for executing a function.
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#windowtimers', 'WindowTimers')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#windowtimers', 'WindowTimers')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#windowtimers", "WindowTimers")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties where on the target before it).
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{CompatGeckoDesktop(1)}}1.04.04.01.0
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox Mobile (Gecko)AndroidIE MobileOpera MobileSafari Mobile
Basic support{{CompatGeckoMobile(1)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

 

- -

See also

- - diff --git a/files/ru/web/api/windowtimers/settimeout/index.html b/files/ru/web/api/windowtimers/settimeout/index.html deleted file mode 100644 index 9e39020215..0000000000 --- a/files/ru/web/api/windowtimers/settimeout/index.html +++ /dev/null @@ -1,260 +0,0 @@ ---- -title: WindowTimers.setTimeout() -slug: Web/API/WindowTimers/setTimeout -translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout ---- -
{{ APIRef() }}
- -

Краткое изложение

- -

Вызов функции или выполнение фрагмента кода после указанной задержки.

- -

Синтаксис

- -
var timeoutID = window.setTimeout(func, [, delay, param1, param2, ...]);
-var timeoutID = window.setTimeout(code [, delay]);
-
- -

где

- - - -

Необходимо принять во внимание, что передача дополнительных параметров функции в первом варианте не работает в Internet Explorer 9 и ниже. Для использования этого функционала в таких браузерах, необходимо использовать код для совместимости (см. раздел Аргументы функции обратного вызова).

- -
Important: Prior to Gecko 13 {{ geckoRelease("13.0") }}, Gecko passed an extra parameter to the callback routine, indicating the "actual lateness" of the timeout in milliseconds. This non-standard parameter is no longer passed.
- -

Пример

- -

В следующем примере на веб странице создаются две простые кнопки, к которым привязываются действия setTimeout и clearTimeout. Нажатие на первую кнопку установит таймаут, который вызовет диалоговое окно через две секунды. Также будет сохранен id для clearTimeout. Таймаут также может быть отменен по нажатию на вторую кнопку.

- -

HTML Content

- -
<p>Live Example</p>
-<button onclick="delayedAlert();">Show an alert box after two seconds</button>
-<p></p>
-<button onclick="clearAlert();">Cancel alert before it happens</button>
-
- -

JavaScript Content

- -
var timeoutID;
-
-function delayedAlert() {
-  timeoutID = window.setTimeout(slowAlert, 2000);
-}
-
-function slowAlert() {
-  alert("That was really slow!");
-}
-
-function clearAlert() {
-  window.clearTimeout(timeoutID);
-}
-
- -

{{ EmbedLiveSample('Example') }}

- -

Смотрите также пример clearTimeout().

- -

Аргументы функции обратного вызова

- -

Если вам нужно передать аргумент в вашу callback функцию, но нужно, чтобы это работало в Internet Explorer 9 и ниже, который не поддерживает передачу дополнительных параметров (ни с setTimeout() или setInterval()), то вы можете прописать специальный код для совместимости с IE, вставив этот код в начало ваших скриптов, который включит функцию передачи стандартных параметров HTML5 в Internet Explorer для обоих таймеров.

- -
/*\
-|*|
-|*|  IE-specific polyfill which enables the passage of arbitrary arguments to the
-|*|  callback functions of JavaScript timers (HTML5 standard syntax).
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/DOM/window.setInterval
-|*|
-|*|  Syntax:
-|*|  var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
-|*|  var timeoutID = window.setTimeout(code, delay);
-|*|  var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
-|*|  var intervalID = window.setInterval(code, delay);
-|*|
-\*/
-
-if (document.all && !window.setTimeout.isPolyfill) {
-  var __nativeST__ = window.setTimeout;
-  window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
-    var aArgs = Array.prototype.slice.call(arguments, 2);
-    return __nativeST__(vCallback instanceof Function ? function () {
-      vCallback.apply(null, aArgs);
-    } : vCallback, nDelay);
-  };
-  window.setTimeout.isPolyfill = true;
-}
-
-if (document.all && !window.setInterval.isPolyfill) {
-  var __nativeSI__ = window.setInterval;
-  window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
-    var aArgs = Array.prototype.slice.call(arguments, 2);
-    return __nativeSI__(vCallback instanceof Function ? function () {
-      vCallback.apply(null, aArgs);
-    } : vCallback, nDelay);
-  };
-  window.setInterval.isPolyfill = true;
-}
-
- -

Правка только для IE

- -

If you want a completely unobtrusive hack for every other mobile or desktop browser, including IE 9 and below, you can either use JavaScript conditional comments:

- -
/*@cc_on
-  // conditional IE < 9 only fix
-  @if (@_jscript_version <= 6)
-  (function(f){
-     window.setTimeout =f(window.setTimeout);
-     window.setInterval =f(window.setInterval);
-  })(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
-  @end
-@*/
-
- -

Или используйте очень чистый подход, основанный на условном свойстве IE HTML:

- -
<!--[if lte IE 9]><script>
-(function(f){
-window.setTimeout =f(window.setTimeout);
-window.setInterval =f(window.setInterval);
-})(function(f){return function(c,t){
-var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}
-});
-</script><![endif]-->
-
- -

Another possibility is to use an anonymous function to call your callback, but this solution is a bit more expensive. Example:

- -
var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);
-
- -

Yet another possibility is to use function's bind. Example:

- -
setTimeout(function(arg1){}.bind(undefined, 10));
-
- -

Проблема с "this"

- -

Когда вы передаете метод в setTimeout() (или в любую другую функцию, если на то пошло), то вызов будет осуществлен с неправильным значением this. Эта проблема разъясняется детально в JavaScript reference.

- -

Объяснение

- -

Code executed by setTimeout() is run in a separate execution context to the function from which it was called. As a consequence, the this keyword for the called function will be set to the window (or global) object; it will not be the same as the this value for the function that called setTimeout. See the following example:

- -
myArray = ["zero", "one", "two"];
-myArray.myMethod = function (sProperty) {
-    alert(arguments.length > 0 ? this[sProperty] : this);
-};
-
-myArray.myMethod(); // prints "zero,one,two"
-myArray.myMethod(1); // prints "one"
-setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
-setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds
-// let's try to pass the 'this' object
-setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
-setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error
- -

Как видите, нет способов передать объект this в функцию обратного вызова..

- -

Возможное решение

- -

A possible way to solve the "this" problem is to replace the two native setTimeout() or setInterval() global functions with two non-native ones which will enable their invocation through the Function.prototype.call method. The following example shows a possible replacement:

- -
// Enable the passage of the 'this' object through the JavaScript timers
-
-var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval;
-
-window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
-  var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
-  return __nativeST__(vCallback instanceof Function ? function () {
-    vCallback.apply(oThis, aArgs);
-  } : vCallback, nDelay);
-};
-
-window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
-  var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
-  return __nativeSI__(vCallback instanceof Function ? function () {
-    vCallback.apply(oThis, aArgs);
-  } : vCallback, nDelay);
-};
- -
Note: These two replacements will also enable the HTML5 standard passage of arbitrary arguments to the callback functions of timers in IE. So they can be used as polyfills also. See the Callback arguments paragraph.
- -

Новая тестируемая особенность:

- -
myArray = ["zero", "one", "two"];
-myArray.myMethod = function (sProperty) {
-    alert(arguments.length > 0 ? this[sProperty] : this);
-};
-
-setTimeout(alert, 1500, "Hello world!"); // the standard use of setTimeout and setInterval is preserved, but...
-setTimeout.call(myArray, myArray.myMethod, 2000); // prints "zero,one,two" after 2 seconds
-setTimeout.call(myArray, myArray.myMethod, 2500, 2); // prints "two" after 2.5 seconds
-
- -

Это не нативные решения ad hoc для этой проблемы.

- -
Note: JavaScript 1.8.5 introduces the Function.prototype.bind() method, which lets you specify the value that should be used as this for all calls to a given function. This lets you easily bypass problems where it's unclear what this will be, depending on the context from which your function was called.
- -

Замечания

- -

Отложенное выполнение кода можно отменить, используя window.clearTimeout(). Если функция должна вызываться неоднократно (например, каждые N миллисекунд), необходимо использовать window.setInterval().

- -

Важно заметить, что функция или код не могут быть выполнены, пока не завершится поток, вызвавший setTimeout().

- -

Passing string literals

- -

Передача строки вместо функции в setTimeout() сопряжена с теми же опасностями, что и использование eval.

- -
// Правильно
-window.setTimeout(function() {
-    alert("Hello World!");
-}, 500);
-
-// Неправильно
-window.setTimeout("alert(\"Hello World!\");", 500);
-
-
- -

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

- -

Минимальная/ максимальная задержка и вложенность таймаута

- -

Historically browsers implement setTimeout() "clamping": successive setTimeout() calls with delay smaller than the "minimum delay" limit are forced to use at least the minimum delay. The minimum delay, DOM_MIN_TIMEOUT_VALUE, is 4 ms (stored in a preference in Firefox: dom.min_timeout_value), with a DOM_CLAMP_TIMEOUT_NESTING_LEVEL of 5ms.

- -

In fact, 4ms is specified by the HTML5 spec and is consistent across browsers released in 2010 and onward. Prior to {{ geckoRelease("5.0") }}, the minimum timeout value for nested timeouts was 10 ms.

- -

In addition to "clamping", the timeout can also fire later when the page (or the OS/browser itself) is busy with other tasks.

- -

To implement a 0 ms timeout in a modern browser, you can use {{ domxref("window.postMessage()") }} as described here.

- -

Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed Integer internally. This causes an Integer overflow when using delays larger than 2147483647, resulting in the timeout being executed immediately.

- -

Неактивные вкладки

- -

In {{ geckoRelease("5.0") }} and Chrome 11, timeouts are clamped to firing no more often than once per second (1000ms) in inactive tabs; see {{ bug(633421) }} for more information about this in Mozilla or crbug.com/66078 for details about this in Chrome.

- -

Совместимость с браузерами

- -

{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}

- -

Спецификация

- -

Part of DOM level 0, as specified in HTML5.

- -

Также интересно

- - diff --git a/files/ru/web/api/xmldocument/async/index.html b/files/ru/web/api/xmldocument/async/index.html new file mode 100644 index 0000000000..2ff21f28af --- /dev/null +++ b/files/ru/web/api/xmldocument/async/index.html @@ -0,0 +1,35 @@ +--- +title: Document.async +slug: Web/API/Document/async +translation_of: Web/API/XMLDocument/async +--- +

{{APIRef("DOM")}}{{Deprecated_header}} {{Non-standard_header}}

+ +

document.async может быть установлен, для того, чтобы определить, что вызов {{domxref("document.load")}} должен быть выполнен синхронно или не синхронно. true - стандартное значение, определяющее, асинхронно ли должны быть загружены документы.

+ +

(Загружать документы синхронно стало возможно с версии 1.4 alpha.)

+ +

Пример

+ +
function loadXMLData(e) {
+  alert(new XMLSerializer().serializeToString(e.target)); // Gives querydata.xml contents as string
+}
+
+var xmlDoc = document.implementation.createDocument("", "test", null);
+
+xmlDoc.async = false;
+xmlDoc.onload = loadXMLData;
+xmlDoc.load('querydata.xml');
+ +

Спецификация

+ + + +

Смотрите также

+ + diff --git a/files/ru/web/api/xmlhttprequest/loadstart_event/index.html b/files/ru/web/api/xmlhttprequest/loadstart_event/index.html new file mode 100644 index 0000000000..b725b05b30 --- /dev/null +++ b/files/ru/web/api/xmlhttprequest/loadstart_event/index.html @@ -0,0 +1,89 @@ +--- +title: loadstart +slug: Web/Events/loadstart +translation_of: Web/API/XMLHttpRequest/loadstart_event +--- +

Событие loadstart происходит, когда начинается загрузка.

+ +

Общая информация

+ +
+
Спецификация
+
Progress
+
Интерфейс
+
ProgressEvent
+
Распространяется
+
Нет
+
Отменяемое
+
Нет
+
Цель
+
Element
+
Действие по умолчанию
+
Нет
+
+ +

Свойства

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
lengthComputable {{readonlyInline}}{{jsxref("Boolean")}}Specifies whether or not the total size of the transfer is known. Read only.
loaded {{readonlyInline}}unsigned long (long)The number of bytes transferred since the beginning of the operation. This doesn't include headers and other overhead, but only the content itself. Read only.
total {{readonlyInline}}unsigned long (long)The total number of bytes of content that will be transferred during the operation. If the total size is unknown, this value is zero. Read only.
+ +

Связанные свойства

+ + + +

См. также

+ + diff --git "a/files/ru/web/api/\320\262\320\270\320\264\320\270\320\274\320\276\321\201\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213_api/index.html" "b/files/ru/web/api/\320\262\320\270\320\264\320\270\320\274\320\276\321\201\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213_api/index.html" deleted file mode 100644 index 9b181e92d1..0000000000 --- "a/files/ru/web/api/\320\262\320\270\320\264\320\270\320\274\320\276\321\201\321\202\321\214_\321\201\321\202\321\200\320\260\320\275\320\270\321\206\321\213_api/index.html" +++ /dev/null @@ -1,195 +0,0 @@ ---- -title: Видимость страницы API -slug: Web/API/Видимость_страницы_API -tags: - - API - - DOM - - Документ - - Показать страницу - - Скрыть страницу -translation_of: Web/API/Page_Visibility_API ---- -
{{DefaultAPISidebar("Page Visibility API")}}
- -

При переключении между вкладками, web страница переходит в фоновый режим и поэтому не видна пользователю. Page Visibility API предоставляет события, которые вы можете отслеживать, чтобы узнать, когда страница станет видимой или скрытой, а так же возможность наблюдать текущее состояние видимости страницы.

- -
-

Notes: The Page Visibility API особенно полезно для сбережения ресурсов и улучшения производительности, позволяя странице остановить выполнение не нужных задач, когда она не видна.

-
- -

Когда пользователь сворачивает окно или переключается на другую вкладку, API отправляет {{event("visibilitychange")}} событие обработчикам, что состояние страницы изменилось. Вы можете отследить это событие и выполнить какие-то действия. Например, если ваше app проигрывает видео, его можно поставить на паузу, когда пользователь переключил вкладку (страница ушла в фон), а затем возобновить видео, когда пользователь вернулся на вкладку. Пользователь не теряет место на котором остановил просмотр, звук от видео не конфликтует с аудио новой вкладки, пользователь комфортно просмотрить оба видео.

- -

Состояния видимости для {{HTMLElement("iframe")}} такие же как и для родительской страницы. Скрытие <iframe> используя CSS стили (такие как {{cssxref("display", "display: none;")}}) не вызывают события видимости и не изменяют состояние документа, содержащегося во фрейме.

- -

Использование

- -

Давайте рассмотрим несколько способов использования Page Visibility API.

- - - -

Раньше у разработчиков были не удобные способы. Например, обработка {{event("blur")}} и {{event("focus")}} событий на объекте window - помогала узнать когда страница становилась не активной, но это не давало возможность понять когда страница действительно скрыта от пользователя. Page Visibility API решает эту проблему.

- -
-

Note: Когда {{domxref("GlobalEventHandlers.onblur", "onblur")}} и {{domxref("GlobalEventHandlers.onfocus", "onfocus")}} уведомляют, что пользователь переключил окна, это не означает, что оно действительно скрыто. Страница действительно скрыта, когда пользователь переключил вкладки или свернул окно браузера с этой вкладкой.

-
- -

Policies in place to aid background page performance

- -

Separately from the Page Visibility API, user agents typically have a number of policies in place to mitigate the performance impact of background or hidden tabs. These may include:

- - - -

Some processes are exempt from this throttling behavior. In these cases, you can use the Page Visibility API to reduce the tabs' performance impact while they're hidden.

- - - -

Example

- -

View live example (video with sound).

- -

The example, which pauses the video when you switch to another tab and plays again when you return to its tab, was created with the following code:

- -
// Set the name of the hidden property and the change event for visibility
-var hidden, visibilityChange;
-if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
-  hidden = "hidden";
-  visibilityChange = "visibilitychange";
-} else if (typeof document.msHidden !== "undefined") {
-  hidden = "msHidden";
-  visibilityChange = "msvisibilitychange";
-} else if (typeof document.webkitHidden !== "undefined") {
-  hidden = "webkitHidden";
-  visibilityChange = "webkitvisibilitychange";
-}
-
-var videoElement = document.getElementById("videoElement");
-
-// If the page is hidden, pause the video;
-// if the page is shown, play the video
-function handleVisibilityChange() {
-  if (document[hidden]) {
-    videoElement.pause();
-  } else {
-    videoElement.play();
-  }
-}
-
-// Warn if the browser doesn't support addEventListener or the Page Visibility API
-if (typeof document.addEventListener === "undefined" || hidden === undefined) {
-  console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
-} else {
-  // Handle page visibility change
-  document.addEventListener(visibilityChange, handleVisibilityChange, false);
-
-  // When the video pauses, set the title.
-  // This shows the paused
-  videoElement.addEventListener("pause", function(){
-    document.title = 'Paused';
-  }, false);
-
-  // When the video plays, set the title.
-  videoElement.addEventListener("play", function(){
-    document.title = 'Playing';
-  }, false);
-
-}
-
- -

Properties added to the Document interface

- -

The Page Visibility API adds the following properties to the {{domxref("Document")}} interface:

- -
-
{{domxref("Document.hidden")}} {{ReadOnlyInline}}
-
Returns true if the page is in a state considered to be hidden to the user, and false otherwise.
-
{{domxref("Document.visibilityState")}} {{ReadOnlyInline}}
-
A {{domxref("DOMString")}} indicating the document's current visibility state. Possible values are: -
-
visible
-
The page content may be at least partially visible. In practice this means that the page is the foreground tab of a non-minimized window.
-
hidden
-
The page's content is not visible to the user, either due to the document's tab being in the background or part of a window that is minimized, or because the device's screen is off.
-
prerender
-
The page's content is being prerendered and is not visible to the user. A document may start in the prerender state, but will never switch to this state from any other state, since a document can only prerender once. -
Note: Not all browsers support prerendering.
-
-
unloaded
-
The page is in the process of being unloaded from memory. -
Note: Not all browsers support the unloaded value.
-
-
-
-
{{domxref("Document.onvisibilitychange")}}
-
An {{domxref("EventListener")}} providing the code to be called when the {{event("visibilitychange")}} event is fired.
-
- -
//startSimulation and pauseSimulation defined elsewhere
-function handleVisibilityChange() {
-  if (document.hidden) {
-    pauseSimulation();
-  } else  {
-    startSimulation();
-  }
-}
-
-document.addEventListener("visibilitychange", handleVisibilityChange, false);
-
- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Page Visibility API')}}{{Spec2('Page Visibility API')}}Initial definition.
- -

Browser compatibility

- -
-

Document.visibilityState

- -
- - -

{{Compat("api.Document.visibilityState")}}

-
-
- -

See also

- - diff --git "a/files/ru/web/api/\320\275\320\276\321\202\320\260\321\206\320\270\321\217/index.html" "b/files/ru/web/api/\320\275\320\276\321\202\320\260\321\206\320\270\321\217/index.html" deleted file mode 100644 index a1f468a55d..0000000000 --- "a/files/ru/web/api/\320\275\320\276\321\202\320\260\321\206\320\270\321\217/index.html" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Нотация -slug: Web/API/Нотация -tags: - - Нотация -translation_of: Web/API/Notation ---- -
{{APIRef("DOM")}}{{draft}}{{obsolete_header}}
- -

Представляет нотацию DTD (только для чтения). Может объявлять формат неразобранного объекта или формально объявлять цели инструкции по обработке документа. Наследует методы и свойства от Node. Его nodeName - это имя нотации. Не имеет родителя.

- -

Свойства

- -
-
{{domxref("Notation.publicId")}} {{ReadOnlyInline}}
-
Это {{domxref("DOMString")}}.
-
{{domxref("Notation.systemId")}} {{ReadOnlyInline}}
-
Это {{domxref("DOMString")}}.
-
- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарии
{{SpecName("DOM3 Core", "core.html#ID-5431D1B9", "Notation")}}{{Spec2("DOM3 Core")}}Без изменений
{{SpecName("DOM2 Core", "core.html#ID-5431D1B9", "Notation")}}{{Spec2("DOM2 Core")}}Без изменений
{{SpecName('DOM1', 'level-one-core.html#ID-5431D1B9', 'Notation')}}{{Spec2('DOM1')}}Первое определение
- -

Поддержка браузерами

- - - -

{{Compat("api.Notation")}}

diff --git a/files/ru/web/css/@viewport/user-zoom/index.html b/files/ru/web/css/@viewport/user-zoom/index.html deleted file mode 100644 index 3cb5768532..0000000000 --- a/files/ru/web/css/@viewport/user-zoom/index.html +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: user-zoom -slug: Web/CSS/@viewport/user-zoom -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/user-zoom ---- -
{{ CSSRef }}
- -

Введение

- -

The user-zoom CSS descriptor controls whether or not the user should be able to change the zoom factor of a document defined by {{cssxref("@viewport")}}.

- -

{{cssinfo}}

- -

Синтаксис

- -
/* Keyword values */
-user-zoom: zoom;
-user-zoom: fixed;
-
- -

Значения

- -
-
zoom
-
The user can zoom in or out.
-
fixed
-
The user cannot zoom in or out.
-
- -

Формальный синтаксис

- -
{{csssyntax}}
- -

Спецфикации

- - - - - - - - - - - - - - - - -
СпецфикацииСтатусКомментарий
{{SpecName('CSS3 Device', '#the-lsquouser-zoomrsquo-descriptor', '"user-zoom" descriptor')}}{{Spec2('CSS3 Device')}}Initial definition
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

 

diff --git a/files/ru/web/css/_colon_any/index.html b/files/ru/web/css/_colon_any/index.html deleted file mode 100644 index 6a9dab56ac..0000000000 --- a/files/ru/web/css/_colon_any/index.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: ':any' -slug: 'Web/CSS/:any' -tags: - - CSS - - Experimental - - Псевдоклассы - - Руководство - - Экспериментальное -translation_of: 'Web/CSS/:is' -translation_of_original: 'Web/CSS/:any' ---- -
{{CSSRef}}{{SeeCompatTable}}
- -

Описание

- -

Псевдокласс :any() дает возможность быстрого конструирования наборов похожих селекторов путем составления групп, в которых каждый из входящих элементов будет комбинироваться с элементами из других групп. Это альтернатива для прописывания комбинаций селекторов для одного элемента, который может находится в разных родителях.

- -
Замечание: Этот псевдо-класс все еще находится в процессе стандартизации в CSS селекторах уровня 4 под именем :matches(). Вполне вероятно, что синтаксис и имя :-vendor-any() будут изменены в ближайшем будущем, чтобы соответствовать спецификации.
- -

Синтаксис

- -
:-moz-any( selector[, selector]* ) :-webkit-any( selector[, selector]* )
- -

Параметры

- -
-
selector
-
Селектор. Это может быть просто селектор или несколько селекторов, состоящих из CSS 3 простых селекторов и может включать комбинацию потомков.
-
- -
Замечание: Селекторы не могут содержать псевдо-элементы, допускается только комбинирование потомков.
- -

Примеры

- -

Например, следующий CSS:

- -
/* на глубине 3 (или больше) неупорядоченные списки используют square */
-ol ol ul,     ol ul ul,     ol menu ul,     ol dir ul,
-ol ol menu,   ol ul menu,   ol menu menu,   ol dir menu,
-ol ol dir,    ol ul dir,    ol menu dir,    ol dir dir,
-ul ol ul,     ul ul ul,     ul menu ul,     ul dir ul,
-ul ol menu,   ul ul menu,   ul menu menu,   ul dir menu,
-ul ol dir,    ul ul dir,    ul menu dir,    ul dir dir,
-menu ol ul,   menu ul ul,   menu menu ul,   menu dir ul,
-menu ol menu, menu ul menu, menu menu menu, menu dir menu,
-menu ol dir,  menu ul dir,  menu menu dir,  menu dir dir,
-dir ol ul,    dir ul ul,    dir menu ul,    dir dir ul,
-dir ol menu,  dir ul menu,  dir menu menu,  dir dir menu,
-dir ol dir,   dir ul dir,   dir menu dir,   dir dir dir {
-  list-style-type: square;
-}
-
- -

Может быть записано, как:

- -
/* на глубине 3 (или больше) неупорядоченные списки используют square */
-:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) ul,
-:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) menu,
-:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) dir {
-  list-style-type: square;
-}
- -

Однако, не нужно использовать это так: (Смотрите раздел о производительности ниже.)

- -
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) :-moz-any(ul, menu, dir) {
-  list-style-type: square;
-}
- -

Примечания

- -

Особенно полезен при работе с разделами и заголовками в HTML5 . Теги {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, и {{HTMLElement("nav")}} могут быть вложенными, без :any() стилизация их соответствия друг другу может быть сложной.

- -

Например, без :any(), стилизация всех элементов {{HTMLElement("h1")}} на разной глубине будет очень сложна:

- -
/* Уровень 0 */
-h1 {
-  font-size: 30px;
-}
-/* Уровень 1 */
-section h1, article h1, aside h1, nav h1 {
-  font-size: 25px;
-}
-/* Уровень 2 */
-section section h1, section article h1, section aside h1, section nav h1,
-article section h1, article article h1, article aside h1, article nav h1,
-aside section h1, aside article h1, aside aside h1, aside nav h1,
-nav section h1, nav article h1, nav aside h1, nav nav h1, {
-  font-size: 20px;
-}
-/* Уровень 3 */
-/* ... даже не думайте о нём*/
-
- -

При использовании :-any(), это становится намного проще:

- -
/* Уровень 0 */
-h1 {
-  font-size: 30px;
-}
-/* Уровень 1 */
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 25px;
-}
-/* Уровень 2 */
-:-moz-any(section, article, aside, nav)
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 20px;
-}
-/* Уровень 3 */
-:-moz-any(section, article, aside, nav)
-:-moz-any(section, article, aside, nav)
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 15px;
-}
- -

Проблемы с производительностью и особенности

- -

{{ bug("561154") }} в Gecko, где специфика :-moz-any() не корректна. Текущая реализация (как в Firefox 12) ставит :-moz-any() в категорию универсальных правил, что означает, что использование его в качестве селектора справа будет медленнее, чем использование селекторов по ID, классу, или тегу.

- -

Например:

- -
.a > :-moz-any(.b, .c)
-
- -

медленнее, чем:

- -
.a > .b, .a > .c
-
- -

а следующее быстрее:

- -
:-moz-any(.a, .d) > .b, :-moz-any(.a, .d) > .c
-
- -

Поддержка браузерами

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
ВозможностьFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Базовая поддержка{{CompatGeckoDesktop("2")}}{{property_prefix("-moz")}}12.0 (534.30){{property_prefix("-webkit")}}   -

5
- {{property_prefix("-webkit")}}

-
-
- -
- - - - - - - - - - - - - - - - - - - - - -
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка{{CompatUnknown}}{{CompatVersionUnknown}}{{property_prefix("-webkit")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}5
- {{property_prefix("-webkit")}}
-
diff --git a/files/ru/web/css/actual_value/index.html b/files/ru/web/css/actual_value/index.html new file mode 100644 index 0000000000..da6231da1f --- /dev/null +++ b/files/ru/web/css/actual_value/index.html @@ -0,0 +1,40 @@ +--- +title: Действительное значение +slug: Web/CSS/Действительное_значение +tags: + - CSS + - Guide + - Web +translation_of: Web/CSS/actual_value +--- +

{{CSSRef}}

+ +

Описание

+ +

Действительное значение CSS свойства - используемое после всех приближений значение. Например, браузер может отображать рамки только с целым значением пикселей и будет прининудительно округлять ширину.

+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('CSS2.1', 'cascade.html#actual-value', 'actual value')}}{{Spec2('CSS2.1')}}Изначальное определение
+ +

Смотрите также

+ + diff --git a/files/ru/web/css/box_model/index.html b/files/ru/web/css/box_model/index.html deleted file mode 100644 index 6868871c5a..0000000000 --- a/files/ru/web/css/box_model/index.html +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: 'Блоковая модель (боксовая модель, box model)' -slug: Web/CSS/box_model -tags: - - CSS - - Guide - - Веб -translation_of: Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model ---- -

Описание

- -

В HTML-документе каждому элементу на странице соответствует прямоугольная область (бокс или блок). Движок рендеринга в браузере определяет размеры и положение боксов на странице, а также их свойства вроде цвета, фоновой картинки для того, чтобы отобразить их на экране.

- -

В языке CSS есть специальная боксовая модель (также блоковая модель или блочная модель, англ. box model), которая описывает, из чего состоит бокс и какие свойства влияют на его размеры. В ней у каждого бокса есть 4 области: margin (внешние отступы), border (рамка), padding (внутренние поля), и content (контент или содержимое).

- -

CSS Box model

- -

Внутренняя область элемента (content area) содержит текст и другие элементы, расположенные внутри (контент или содержимое). У неё часто бывает фон, цвет или изображение (в таком порядке: фоновый цвет скрывается под непрозрачным изображением), и она находится внутри content edge; её размеры называются ширина контента (content width или content-box width), и высота контента (content height или content-box height). Иногда еще говорят «внутренняя ширина/высота элемента»

- -

По умолчанию, если CSS-свойство {{ cssxref("box-sizing") }} не задано, размер внутренней области с содержимым задается свойствами {{ cssxref("width") }}, {{ cssxref("min-width") }}, {{ cssxref("max-width") }}, {{ cssxref("height") }}, {{ cssxref("min-height") }} and {{ cssxref("max-height") }}. Если же свойство  {{ cssxref("box-sizing") }} задано, то оно определяет, для какой области указаны размеры.

- -

Поля элемента (padding area) — это пустая область, окружающая контент. Она может быть залита каким-то цветом, покрыта фоновый картинкой, а её границы называются края полей (padding edge).

- -

Размеры полей задаются по отдельности с разных сторон свойствами {{ cssxref("padding-top") }}, {{ cssxref("padding-right") }}, {{ cssxref("padding-bottom") }}, {{ cssxref("padding-left") }} или общим свойством {{ cssxref("padding") }}.

- -

Область рамки (border area) окружает поля элемента, а ее граница называется края рамки (border edge). Ширина рамки задается отдельным свойством  {{ cssxref("border-width") }} или в составе свойства {{ cssxref("border") }}. Размеры элемента с учетом полей и рамки иногда называют внешней шириной/высотой элемента.

- -

Отступы (margin area) добавляют пустое пространство вокруг элемента и определяют расстояние до соседних элементов.

- -

Величина отступов задается по отдельности в разных направлениях свойствами {{ cssxref("margin-top") }}, {{ cssxref("margin-right") }}, {{ cssxref("margin-bottom") }}, {{ cssxref("margin-left") }} или общим свойством {{ cssxref("margin") }}.

- -

Отступы двух соседних элементов, расположенных друг над другом или вложенных друг в друга, могут накладываться. Это называется схлопывание границ (margin collapsing). Схлопываются только вертикальные отступы.

- -

Для элементов с {{ cssxref("display") }}: inline (или inline-block, inline-table) на занимаемое по высоте место также влияет значение свойства {{ cssxref('line-height') }}.

- -

Стандарты

- - - - - - - - - - - - - - - - - - - - - -
СтандартСтатусПримечание
CSS Level 2 (revision 1){{ Spec2('CSS2.1') }}Though more precisely worded, there is no practical change
CSS Level 1{{ Spec2('CSS1') }} 
- -

Смотрите также

- - diff --git a/files/ru/web/css/comments/index.html b/files/ru/web/css/comments/index.html new file mode 100644 index 0000000000..1db7dd50b5 --- /dev/null +++ b/files/ru/web/css/comments/index.html @@ -0,0 +1,50 @@ +--- +title: Комментарии +slug: Web/CSS/Тихий +tags: + - Beginner + - CSS + - CSS Reference + - Комментарии + - Новичку + - Руководство +translation_of: Web/CSS/Comments +--- +
{{CSSRef}}
+ +

Описание

+ +

Комментарии используются для добавления поясняющих заметок или для того, чтобы предотвратить интеграцию части кода в браузер.

+ +

Синтаксис

+ +
/* Комментарий */
+ +

Примеры

+ +
/* Однострочный комментарий */
+
+/*
+Комментарий
+который содержит
+несколько
+строк
+*/
+
+ +

Замечания

+ +

Данный /* */ синтаксис комментария используется для обоих вариантов, и однострочного и многострочного комментария. Нет других способов добавить комментарий во внешнюю таблицу стилей. Также, когда используется элемент <style>, вы можете использовать <!-- -->, чтобы спрятать CSS от старых браузеров, но это не рекомендуется. Как и в большинстве языков программирования, которые используют синтаксис комментариев /* */ , комментарии нельзя вкладывать друг в друга. Другими словами, данная часть синтаксиса */, которая следует за /* закрывает комментарий.

+ +

Спецификации

+ + + +

Смотрите также

+ + diff --git a/files/ru/web/css/common_css_questions/index.html b/files/ru/web/css/common_css_questions/index.html deleted file mode 100644 index cecfb92b82..0000000000 --- a/files/ru/web/css/common_css_questions/index.html +++ /dev/null @@ -1,182 +0,0 @@ ---- -title: Common CSS questions -slug: Web/CSS/Common_CSS_Questions -translation_of: Learn/CSS/Howto/CSS_FAQ ---- -

Why doesn't my CSS, which is valid, render correctly?

- -

Браузер использует декларацию DOCTYPE чтобы выбрать, как именно отображать документ - в форме, более совместимой с современными стандартами или в форме,  которую будут поддерживать старые браузеры. Правильное использование декларациии DOCTYPE в начале вашего HTML кода повлияет на совместимость с современными стандартами веб браузеров.

- -

У современных браузеров есть два режима отображения веб-страниц:

- - - -

Gecko-based browsers, have a third Almost Standards Mode that has only a few minor quirks.

- -

This is a list of the most commonly used DOCTYPE declarations that will trigger Standards or Almost Standards mode:

- -
<!DOCTYPE html> /* This is the HTML5 doctype. Given that each modern browser uses an HTML5
-                   parser, this is the recommended doctype */
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-"http://www.w3.org/TR/html4/strict.dtd">
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
- -

Why doesn't my CSS, which is valid, render at all?

- -

To be applied, a CSS stylesheet must be served with a text/css MIME type. If the Web server doesn't serve it with this type, it won't be applied.

- -

What is the difference between id and class?

- -

HTML elements can have an id and/or class attribute. The id attribute assigns a name to the element it is applied to, and for valid markup, there can be only one element with that name. The class attribute assigns a class name to the element, and that name can be used on many elements within the page. CSS allows you to apply styles to particular id and/or class names.
-
- Use an id-specific style when you want to restrict the applied styling rules to one specific block or element. This style will only be used by the element with that particular id.
-
- Use a class-specific style when you want to apply the styling rules to many blocks and elements within the page.

- -

Stylesheets with fewer rules are usually more performant. It is therefore recommended to use classes as much as possible, and to reserve the use of id for specific uses (like to connect label and form elements or for styling elements that must be semantically unique).

- -

See CSS selectors

- -

How do I restore the default value of a property?

- -

Initially CSS didn't provide a "default" keyword and the only way to restore the default value of a property is to explicitly re-declare that property.

- -

This has changed with CSS 2; the keyword initial is now a valid value for a CSS property. It resets it to its default value, which is defined in the CSS specification of the given property.

- -

How do I derive one style from another?

- -

CSS does not allow one style to be defined in terms of another. (See Eric Meyer's note about the Working Group's stance). However, assigning multiple classes to a single element can provide the same effect.

- -

How do I assign multiple classes to an element?

- -

HTML elements can be assigned multiple classes by listing the classes in the class attribute, with a blank space to separate them.

- -
<style type="text/css">
-.news { background: black; color: white; }
-.today { font-weight: bold; }
-</style>
-
-<div class="news today">
-... content of today's news ...
-</div>
-
- -

If the same property is declared in both rules, the conflict is resolved first through specificity, then according to the order of the CSS declarations. The order of classes in the class attribute is not relevant.

- -

Why don't my style rules work properly?

- -

Style rules that are syntactically correct may not apply in certain situations. You can use DOM Inspector's CSS Style Rules view to debug problems of this kind, but the most frequent instances of ignored style rules are listed below.

- -

HTML elements hierarchy

- -

The way CSS styles are applied to HTML elements depends also on the elements hierarchy. It is important to remember that a rule applied to a descendent overrides the style of the parent, in spite of any specificity or priority of CSS rules.

- -
.news { color: black; }
-.corpName { font-weight: bold; color: red; }
-
-<!-- news item text is black, but corporate name is red and in bold -->
-<div class="news">
-   (Reuters) <span class="corpName">General Electric</span> (GE.NYS) announced on Thursday...
-</div>
-
- -

In case of complex HTML hierarchies, if a rule seems to be ignored, check if the element is inside another element with a different style.

- -

Explicitly re-defined style rule

- -

In CSS stylesheets, order is important. If you define a rule and then you re-define the same rule, the last definition is used.

- -
#stockTicker { font-weight: bold; }
-.stockSymbol { color: red; }
-/*  other rules             */
-/*  other rules             */
-/*  other rules             */
-.stockSymbol { font-weight: normal; }
-
-<!-- most text is in bold, except "GE", which is red and not bold -->
-<div id="stockTicker">
-   NYS: <span class="stockSymbol">GE</span> +1.0 ...
-</div>
-
- -

To avoid this kind of error, try to define rules only once for a certain selector, and group all rules belonging to that selector.

- -

Use of a shorthand property

- -

Using shorthand properties for defining style rules is good because it uses a very compact syntax. Using shorthand with only some attributes is possible and correct, but it must be remembered that undeclared attributes are automatically reset to default. This means that a previous rule for a single attribute could be implicitly overridden.

- -
#stockTicker { font-size: 12px; font-family: Verdana; font-weight: bold; }
-.stockSymbol { font: 14px Arial; color: red; }
-
-<div id="stockTicker">
-   NYS: <span class="stockSymbol">GE</span> +1.0 ...
-</div>
-
- -

In the previous example the problem occurred on rules belonging to different elements, but it could happen also for the same element, because rule order is important.

- -
#stockTicker {
-   font-weight: bold;
-   font: 12px Verdana;  /* font-weight is now normal */
-}
-
- -

Use of the * selector

- -

The * wildcard selector refers to any element, and it has to be used with particular care.

- -
body * { font-weight: normal; }
-#stockTicker { font: 12px Verdana; }
-.corpName { font-weight: bold; }
-.stockUp { color: red; }
-
-<div id="section">
-   NYS: <span class="corpName"><span class="stockUp">GE</span></span> +1.0 ...
-</div>
-
- -

In this example the body * selector applies the rule to all elements inside body, at any hierarchy level, including the .stockUp class. So font-weight: bold; applied to the .corpName class is overridden by font-weight: normal; applied to all elements in the body.

- -

The use of the * selector should be minimized as it is a slow selector, especially when not used as the first element of a selector. Its use should be avoided as much as possible.

- -

Specificity in CSS

- -

When multiples rules apply to a certain element, the rule chosen depends on its style specificity. Inline style (in HTML style attributes) comes first, followed by ID selectors, then class selectors and eventually element-name selectors.

- -
div { color: black; }
-#orange { color: orange; }
-.green { color: green; }
-
-<div id="orange" class="green" style="color: red;">This is red</div>
-
- -

The rules are more complicated when the selector has multiple parts. More detailed information about how selector specificity is calculated can be found in the CSS 2.1 Specification chapter 6.4.3.

- -

What do the -moz-*, -ms-*, -webkit-*, -o-* and -khtml-* properties do?

- -

These properties, called prefixed properties, are extensions to the CSS standard. They are used to use experimental and non-standard features without polluting the regular namespace, preventing future incompatibilities to arise when the standard is extended.

- -

The use of such properties on production websites is not recommended. If nevertheless needed, you are hinted to make a plan for the website evolution: these prefixed properties can be modified or even suppressed when the standard evolves.

- -

Please see the Mozilla CSS Extensions page for more information on the Mozilla-prefixed CSS properties.

- -

How does z-index relate to positioning?

- -

The z-index property specifies the stack order of elements.

- -

An element with a higher z-index/stack order is always in front of an element with a lower z-index/stack order.

- -

Z-index will only work on elements that have a specified position (position:absolute, position:relative, or position:fixed).

diff --git a/files/ru/web/css/css_animations/ispolzovanie_css_animatciy/index.html b/files/ru/web/css/css_animations/ispolzovanie_css_animatciy/index.html deleted file mode 100644 index 05f6cb5cec..0000000000 --- a/files/ru/web/css/css_animations/ispolzovanie_css_animatciy/index.html +++ /dev/null @@ -1,388 +0,0 @@ ---- -title: Использование CSS-анимации -slug: Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy -tags: - - Advanced - - CSS - - CSS Animations - - Example - - Experimental - - Guide -translation_of: Web/CSS/CSS_Animations/Using_CSS_animations ---- -

{{SeeCompatTable}}{{CSSRef}}

- -

CSS анимации позволяют анимировать переходы от одной конфигурации CSS стилей к другой. CSS-анимации состоят из двух компонентов: стилевое описание анимации и набор ключевых кадров, определяющих начальное, конечное и, возможно, промежуточное состояние анимируемых стилей.

- -

Есть три преимущества CSS-анимации перед традиционными способами:

- -
    -
  1. Простота использования для простых анимаций; Вы можете создать анимацию, не зная JavaScript.
  2. -
  3. Анимации будут хорошо работать даже при умеренных нагрузках системы. Простые анимации на JavaScript, если они плохо написаны, часто выполняются плохо. Движок может использовать frame-skipping и другие техники, чтобы сохранить производительность на таком высоком уровне .
  4. -
  5. Позволяет браузеру контролировать последовательность анимации, тем самым оптимизируя производительность и эффективность браузера. Например, уменьшая частоту обновления кадров анимации в непросматриваемых в данный момент вкладках.
  6. -
- -

Конфигурирование анимации

- -

Чтобы создать CSS-анимацию Вы должны добавить в стиль элемента, который хотите анимировать, свойство {{ cssxref("animation") }} или его подсвойства. Это позволит Вам настроить ускорение и продолжительность анимации, а также другие детали того, как анимация должна протекать. Это не поможет Вам настроить внешний вид анимации, который настраивается с помощью {{ cssxref("@keyframes") }}, рассматриваемой далее в {{ anch("Определение последовательности анимации с помощью ключевых кадров") }}.

- -

Свойство {{ cssxref("animation") }} имеет следующие подсвойства:

- -
-
{{ cssxref("animation-name") }}
-
Определяет имя {{ cssxref("@keyframes") }}, настраивающего кадры анимации.
-
{{ cssxref("animation-duration") }}
-
Определяет время, в течение которого должен пройти один цикл анимации.
-
{{ cssxref("animation-timing-function") }}
-
Настраивает ускорение анимации.
-
{{ cssxref("animation-delay") }}
-
Настраивает задержку между временем загрузки элемента и временем начала анимации.
-
{{ cssxref("animation-iteration-count") }}
-
Определяет количество повторений анимации; Вы можете использовать значение infinite для бесконечного повторения анимации.
-
{{ cssxref("animation-direction") }}
-
Дает возможность при каждом повторе анимации идти по альтернативному пути, либо сбросить все значения и повторить анимацию.
-
{{ cssxref("animation-fill-mode") }}
-
Настраивает значения, используемые анимацией, до и после исполнения.
-
{{ cssxref("animation-play-state") }}
-
Позволяет приостановить и возобновить анимацию.
-
- -

Определение последовательности анимации с помощью ключевых кадров

- -

После того, как вы настроили временные свойства (продолжительность, ускорение) анимации, вы должны определить внешний вид анимации. Это делается с помощью двух и более ключевых кадров после {{ cssxref("@keyframes") }}. Каждый кадр описывает, как должен выглядеть анимированный элемент в текущий момент.

- -

В то время, как временные характеристики (продолжительность анимации) указываются в стилях для анимируемого элемента, ключевые кадры используют {{ cssxref("percentage") }}, чтобы определить стадию протекания анимации. 0% означает начало анимации, а 100% ее конец. Так как эти значения очень важны, то для них придумали специальные слова: from и to.

- -

Вы также можете добавить ключевые кадры, характеризующие промежуточное состояние анимации.

- -

Примеры

- -
Внимание: Примеры ниже не используют префиксов для CSS стилей . Webkit-браузеры и старые версии других браузеров нуждаются в указании префиксов в CSS стилях. Примеры, на которые Вы можете кликнуть в своем браузере, также содержат префиксы -webkit-.
- -

Скольжение текста

- -

Этот простой пример анимирует скольжение текста в элементе {{ HTMLElement("p") }} от правого края окна браузера.

- -

Обратите внимание на то, что анимация может сделать страницу шире, чем окно браузера. Этого можно избежать, поместив элемент, который будет анимироваться, в контейнер и установив ему свойство {{cssxref("overflow")}}: hidden.

- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-}
-
-@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%;
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-}
-
- -

В стиле для элемента {{ HTMLElement("p") }} с помощью свойства {{ cssxref("animation-duration") }} указано, что исполнение анимации от начала до конца должно занять 3 с , и что имя для  {{ cssxref("@keyframes") }}, описывающей саму анимацию, определено как "slidein".

- -

В элемент {{ HTMLElement("p") }} можно добавлять и другие пользовательские стили, чтобы как-то украсить его, однако здесь мы хотели продемонстрировать только эффект анимации.

- -

Kлючевые кадры определяются с помощью правила {{ cssxref("@keyframes") }}. В данном случае мы имеем только два ключевых кадра. Первый при 0% анимации (from). Здесь мы придаем элементу левый отступ в 100% и ширину в 300% (в три раза больше ширины родительского элемента). Это становится причиной того, что при первом кадре анимации заголовок {{ HTMLElement("p") }} находится за пределами правого края окна браузера .

- -

Второй ключевой кадр (to) определяет конец анимации, т.е (100%). Левый отступ устанавливается равным 0, а ширина 100%. Все выглядит так, будто заголовок {{ HTMLElement("p") }} приплывает к левому краю окна браузера.

- -
<p>The Caterpillar and Alice looked at each other for some time in silence:
-at last the Caterpillar took the hookah out of its mouth, and addressed
-her in a languid, sleepy voice.</p>
-
- -

(Обновите страницу, чтобы увидеть анимацию, или щелкните по кнопке CodePen, чтобы воспроизвести ее в окне CodePen)

- -

{{EmbedLiveSample("Скольжение_текста","100%","250")}}

- -

Добавление других ключевыч кадров

- -

Давайте добавим другие ключевые кадры в предыдущий пример. Скажем, мы хотим чтобы размер шрифта заголовка временно увеличивался по мере продвижения влево, а потом возращался к первоначальному значению . Это легко реализовать с помощью следующего ключевого кадра:

- -
75% {
-  font-size: 300%;
-  margin-left: 25%;
-  width: 150%;
-}
-
- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-}
-
-@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%;
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-
-  75% {
-    font-size: 300%;
-    margin-left: 25%;
-    width: 150%;
-  }
-}
-
- -
<p>The Caterpillar and Alice looked at each other for some time in silence:
-at last the Caterpillar took the hookah out of its mouth, and addressed
-her in a languid, sleepy voice.</p>
-
- -

Это говорит браузеру о том, что при 75% выполнения анимации, шрифт должен быть 300%, а ширина 150%.

- -

(Обновите страницу, чтобы увидеть анимацию, или щелкните по кнопке CodePen, чтобы воспроизвести ее в окне CodePen)

- -

{{ EmbedLiveSample('Добавление_других_ключевыч_кадров', '100%', '250', '', 'Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy') }}

- -

Настройка повторения

- -

Чтобы настроить повторение, нужно добавить свойство {{ cssxref("animation-iteration-count") }} и задать ему значение, равное нужному количеству повторений анимаций . В данном случае давайте установим значение infinite для бесконечного повторения:

- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-  animation-iteration-count: infinite;
-}
-
- -
@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%;
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-}
-
- -
<p>The Caterpillar and Alice looked at each other for some time in silence:
-at last the Caterpillar took the hookah out of its mouth, and addressed
-her in a languid, sleepy voice.</p>
-
- -

{{EmbedLiveSample("Настройка_повторения","100%","250")}}

- -

Движение текста вправо и влево

- -

Итак, мы настроили повторение, но получили нечто странное: текст при каждом повторении снова "запрыгивает" за край окна браузера. То, чего мы хотим, так это чтобы текст двигался влево и вправо. Этого легко достичь с помощью установки свойству {{ cssxref("animation-direction") }} значения alternate:

- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-  animation-iteration-count: infinite;
-  animation-direction: alternate;
-}
-
- -
@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%;
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-}
-
- -
<p>The Caterpillar and Alice looked at each other for some time in silence:
-at last the Caterpillar took the hookah out of its mouth, and addressed
-her in a languid, sleepy voice.</p>
-
- -

{{ EmbedLiveSample('Движение_текста_вправо_и_влево', '100%', '250', '', 'Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy') }}

- -

Использование шорткодов

- -

Шорткод {{cssxref("animation")}} полезен для экономии места в коде. Например, правило, которое мы используем в этой статье:

- -
p {
-  animation-duration: 3s;
-  animation-name: slidein;
-  animation-iteration-count: infinite;
-  animation-direction: alternate;
-}
- -

можно заменить на:

- -
p {
-  animation: 3s infinite alternate slidein;
-}
- -
-

Внимание: подробнее об этом на странице раздела {{cssxref("animation")}} 

-
- -

Установка нескольких значений свойствам анимации  

- -

CSS cвойство анимации может иметь несколько значений, разделенных запятыми. Это используется, чтобы указать несколько значений анимации в одном правиле и установить разную продолжительность, число повторений и т.д., для различных анимаций. Рассмотрим несколько примеров, чтобы увидеть разницу.

- -

В первом примере у свойства имени анимации установлены три значения, у свойств продолжительности и количества повторений  — по одному. В этом случае у всех трех анимаций одинаковая продолжительность и число повторений:

- -
animation-name: fadeInOut, moveLeft300px, bounce;
-animation-duration: 3s;
-animation-iteration-count: 1;
- -

Во втором примере установлены три значения для каждого из свойств. В этом случае каждая анимация выполняется с соответствующими по порядку значениями в каждом свойстве, так, например, fadeInOut имеет продолжительность 2.5 с и количество повторений 2, и т.д.

- -
animation-name: fadeInOut, moveLeft300px, bounce;
-animation-duration: 2.5s, 5s, 1s;
-animation-iteration-count: 2, 1, 5;
- -

В третьем примере определены три значения имени анимации, но два значения продолжительности и количества повторений. В случае, когда количества значений недостаточно для каждой анимации, значения берутся циклически от начала до конца. Например, у fadeInOut длительность будет 2.5s,  а moveLeft300px — 5s. Значения продолжительности закончились, теперь они берутся сначала — bounce получит продолжительность 2.5s. Значение количества повторений (а также другие указанные свойства) будет определено таким же образом.

- -
animation-name: fadeInOut, moveLeft300px, bounce;
-animation-duration: 2.5s, 5s;
-animation-iteration-count: 2, 1;
- -

Использование событий анимации

- -

Вы можете получить дополнительный контроль над анимацией, а также полезную информацию о ней, с помощью событий анимации. Эти события, представленные объектом {{ domxref("event/AnimationEvent", "AnimationEvent") }}, можно использовать, чтобы определить, когда начинается и заканчивается анимация или начинается новая итерация. Каждое событие содержит момент времени, когда оно произошло, а также имя анимации, которая вызвала событие.

- -

Мы будем модифицировать текст, чтобы выводить некоторую информацию  о каждом событии анимации. Так мы сможем увидеть, как она работает.

- -

Добавление CSS

- -

Начнем с добавления CSS. Анимация будет длиться 3 секунды, будет называться "slidein", будет повторяться 3 раза, а также значение animation-direction установлено alternate. В ключевых кадрах {{ cssxref("@keyframes") }} установлены такие значения ширины и левого отступа, что элемент будет скользить по экрану.

- -
.slidein {
-  -moz-animation-duration: 3s;
-  -webkit-animation-duration: 3s;
-  animation-duration: 3s;
-  -moz-animation-name: slidein;
-  -webkit-animation-name: slidein;
-  animation-name: slidein;
-  -moz-animation-iteration-count: 3;
-  -webkit-animation-iteration-count: 3;
-  animation-iteration-count: 3;
-  -moz-animation-direction: alternate;
-  -webkit-animation-direction: alternate;
-  animation-direction: alternate;
-}
-
-@-moz-keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%
-  }
-
-  to {
-    margin-left: 0%;
-    width: 100%;
-  }
-}
-
-@-webkit-keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%
-  }
-
-  to {
-   margin-left: 0%;
-   width: 100%;
- }
-}
-
-@keyframes slidein {
-  from {
-    margin-left: 100%;
-    width: 300%
-  }
-
-  to {
-   margin-left: 0%;
-   width: 100%;
- }
-}
- -

Добавление обработчика события анимации

- -

Будем использовать JavaScript для отслеживания всех трех возможных событий анимации. Следующий код конфигурирует обработчик; мы вызываем его при первой загрузке документа.

- -
var e = document.getElementById("watchme");
-e.addEventListener("animationstart", listener, false);
-e.addEventListener("animationend", listener, false);
-e.addEventListener("animationiteration", listener, false);
-
-e.className = "slidein";
-
- -

Это довольно стандартный код; Вы можете получить дополнительную информацию в документации {{ domxref("element.addEventListener()") }}. Последнее, что делает этот код - это установка класса "slidein" для анимируемого элемента; мы делаем это, чтобы запустить анимацию.

- -

Почему? Потому что в нашем случае событие animationstart происходит как только анимация стартует, и это происходит раньше, чем исполняется наш сценарий. Так мы сможем контролировать начало анимации самостоятельно посредством вставки класса "slidein" для анимируемого элемента.

- -

Регистрация событий

- -

События будут передаваться функции listener(), показанной ниже.

- -
function listener(e) {
-  var l = document.createElement("li");
-  switch(e.type) {
-    case "animationstart":
-      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
-      break;
-    case "animationend":
-      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
-      break;
-    case "animationiteration":
-      l.innerHTML = "New loop started at time " + e.elapsedTime;
-      break;
-  }
-  document.getElementById("output").appendChild(l);
-}
-
- -

Этот код также очень прост. Этот код следит за {{ domxref("event.type") }}, чтобы определить тип события, и добавляет элемент {{ HTMLElement("ul") }}, чтобы залогировать произошедшее событие.

- -

Вывод, когда анимация закончится, будет выглядеть примерно следующим образом:

- - - -

Обратите внимание, что время, указанное в выводе, и время, которое мы указали в стилях, не совпадают. Также обратите внимание, что после окончания итерации не посылается событие animationiteration ; вместо него посылается событие animationend.

- -

HTML

- -

Ради полноты картины приведем код разметки HTML. В разметке имеется тег ul, в который и выводится вся информация:

- -
<body>
-  <h1 id="watchme">Watch me move</h1>
-  <p>This example shows how to use CSS animations to make <code>p</code> elements
-  move across the page.</p>
-  <p>In addition, we output some text each time an animation event fires, so you can see them in action.</p>
-  <ul id="output">
-  </ul>
-</body>
-
- -

{{ EmbedLiveSample('Использование_событий_анимации', '600', '300')}}

- -

Смотрите также

- - diff --git a/files/ru/web/css/css_animations/using_css_animations/index.html b/files/ru/web/css/css_animations/using_css_animations/index.html new file mode 100644 index 0000000000..05f6cb5cec --- /dev/null +++ b/files/ru/web/css/css_animations/using_css_animations/index.html @@ -0,0 +1,388 @@ +--- +title: Использование CSS-анимации +slug: Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy +tags: + - Advanced + - CSS + - CSS Animations + - Example + - Experimental + - Guide +translation_of: Web/CSS/CSS_Animations/Using_CSS_animations +--- +

{{SeeCompatTable}}{{CSSRef}}

+ +

CSS анимации позволяют анимировать переходы от одной конфигурации CSS стилей к другой. CSS-анимации состоят из двух компонентов: стилевое описание анимации и набор ключевых кадров, определяющих начальное, конечное и, возможно, промежуточное состояние анимируемых стилей.

+ +

Есть три преимущества CSS-анимации перед традиционными способами:

+ +
    +
  1. Простота использования для простых анимаций; Вы можете создать анимацию, не зная JavaScript.
  2. +
  3. Анимации будут хорошо работать даже при умеренных нагрузках системы. Простые анимации на JavaScript, если они плохо написаны, часто выполняются плохо. Движок может использовать frame-skipping и другие техники, чтобы сохранить производительность на таком высоком уровне .
  4. +
  5. Позволяет браузеру контролировать последовательность анимации, тем самым оптимизируя производительность и эффективность браузера. Например, уменьшая частоту обновления кадров анимации в непросматриваемых в данный момент вкладках.
  6. +
+ +

Конфигурирование анимации

+ +

Чтобы создать CSS-анимацию Вы должны добавить в стиль элемента, который хотите анимировать, свойство {{ cssxref("animation") }} или его подсвойства. Это позволит Вам настроить ускорение и продолжительность анимации, а также другие детали того, как анимация должна протекать. Это не поможет Вам настроить внешний вид анимации, который настраивается с помощью {{ cssxref("@keyframes") }}, рассматриваемой далее в {{ anch("Определение последовательности анимации с помощью ключевых кадров") }}.

+ +

Свойство {{ cssxref("animation") }} имеет следующие подсвойства:

+ +
+
{{ cssxref("animation-name") }}
+
Определяет имя {{ cssxref("@keyframes") }}, настраивающего кадры анимации.
+
{{ cssxref("animation-duration") }}
+
Определяет время, в течение которого должен пройти один цикл анимации.
+
{{ cssxref("animation-timing-function") }}
+
Настраивает ускорение анимации.
+
{{ cssxref("animation-delay") }}
+
Настраивает задержку между временем загрузки элемента и временем начала анимации.
+
{{ cssxref("animation-iteration-count") }}
+
Определяет количество повторений анимации; Вы можете использовать значение infinite для бесконечного повторения анимации.
+
{{ cssxref("animation-direction") }}
+
Дает возможность при каждом повторе анимации идти по альтернативному пути, либо сбросить все значения и повторить анимацию.
+
{{ cssxref("animation-fill-mode") }}
+
Настраивает значения, используемые анимацией, до и после исполнения.
+
{{ cssxref("animation-play-state") }}
+
Позволяет приостановить и возобновить анимацию.
+
+ +

Определение последовательности анимации с помощью ключевых кадров

+ +

После того, как вы настроили временные свойства (продолжительность, ускорение) анимации, вы должны определить внешний вид анимации. Это делается с помощью двух и более ключевых кадров после {{ cssxref("@keyframes") }}. Каждый кадр описывает, как должен выглядеть анимированный элемент в текущий момент.

+ +

В то время, как временные характеристики (продолжительность анимации) указываются в стилях для анимируемого элемента, ключевые кадры используют {{ cssxref("percentage") }}, чтобы определить стадию протекания анимации. 0% означает начало анимации, а 100% ее конец. Так как эти значения очень важны, то для них придумали специальные слова: from и to.

+ +

Вы также можете добавить ключевые кадры, характеризующие промежуточное состояние анимации.

+ +

Примеры

+ +
Внимание: Примеры ниже не используют префиксов для CSS стилей . Webkit-браузеры и старые версии других браузеров нуждаются в указании префиксов в CSS стилях. Примеры, на которые Вы можете кликнуть в своем браузере, также содержат префиксы -webkit-.
+ +

Скольжение текста

+ +

Этот простой пример анимирует скольжение текста в элементе {{ HTMLElement("p") }} от правого края окна браузера.

+ +

Обратите внимание на то, что анимация может сделать страницу шире, чем окно браузера. Этого можно избежать, поместив элемент, который будет анимироваться, в контейнер и установив ему свойство {{cssxref("overflow")}}: hidden.

+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+}
+
+@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%;
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+}
+
+ +

В стиле для элемента {{ HTMLElement("p") }} с помощью свойства {{ cssxref("animation-duration") }} указано, что исполнение анимации от начала до конца должно занять 3 с , и что имя для  {{ cssxref("@keyframes") }}, описывающей саму анимацию, определено как "slidein".

+ +

В элемент {{ HTMLElement("p") }} можно добавлять и другие пользовательские стили, чтобы как-то украсить его, однако здесь мы хотели продемонстрировать только эффект анимации.

+ +

Kлючевые кадры определяются с помощью правила {{ cssxref("@keyframes") }}. В данном случае мы имеем только два ключевых кадра. Первый при 0% анимации (from). Здесь мы придаем элементу левый отступ в 100% и ширину в 300% (в три раза больше ширины родительского элемента). Это становится причиной того, что при первом кадре анимации заголовок {{ HTMLElement("p") }} находится за пределами правого края окна браузера .

+ +

Второй ключевой кадр (to) определяет конец анимации, т.е (100%). Левый отступ устанавливается равным 0, а ширина 100%. Все выглядит так, будто заголовок {{ HTMLElement("p") }} приплывает к левому краю окна браузера.

+ +
<p>The Caterpillar and Alice looked at each other for some time in silence:
+at last the Caterpillar took the hookah out of its mouth, and addressed
+her in a languid, sleepy voice.</p>
+
+ +

(Обновите страницу, чтобы увидеть анимацию, или щелкните по кнопке CodePen, чтобы воспроизвести ее в окне CodePen)

+ +

{{EmbedLiveSample("Скольжение_текста","100%","250")}}

+ +

Добавление других ключевыч кадров

+ +

Давайте добавим другие ключевые кадры в предыдущий пример. Скажем, мы хотим чтобы размер шрифта заголовка временно увеличивался по мере продвижения влево, а потом возращался к первоначальному значению . Это легко реализовать с помощью следующего ключевого кадра:

+ +
75% {
+  font-size: 300%;
+  margin-left: 25%;
+  width: 150%;
+}
+
+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+}
+
+@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%;
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+
+  75% {
+    font-size: 300%;
+    margin-left: 25%;
+    width: 150%;
+  }
+}
+
+ +
<p>The Caterpillar and Alice looked at each other for some time in silence:
+at last the Caterpillar took the hookah out of its mouth, and addressed
+her in a languid, sleepy voice.</p>
+
+ +

Это говорит браузеру о том, что при 75% выполнения анимации, шрифт должен быть 300%, а ширина 150%.

+ +

(Обновите страницу, чтобы увидеть анимацию, или щелкните по кнопке CodePen, чтобы воспроизвести ее в окне CodePen)

+ +

{{ EmbedLiveSample('Добавление_других_ключевыч_кадров', '100%', '250', '', 'Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy') }}

+ +

Настройка повторения

+ +

Чтобы настроить повторение, нужно добавить свойство {{ cssxref("animation-iteration-count") }} и задать ему значение, равное нужному количеству повторений анимаций . В данном случае давайте установим значение infinite для бесконечного повторения:

+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+  animation-iteration-count: infinite;
+}
+
+ +
@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%;
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+}
+
+ +
<p>The Caterpillar and Alice looked at each other for some time in silence:
+at last the Caterpillar took the hookah out of its mouth, and addressed
+her in a languid, sleepy voice.</p>
+
+ +

{{EmbedLiveSample("Настройка_повторения","100%","250")}}

+ +

Движение текста вправо и влево

+ +

Итак, мы настроили повторение, но получили нечто странное: текст при каждом повторении снова "запрыгивает" за край окна браузера. То, чего мы хотим, так это чтобы текст двигался влево и вправо. Этого легко достичь с помощью установки свойству {{ cssxref("animation-direction") }} значения alternate:

+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+  animation-iteration-count: infinite;
+  animation-direction: alternate;
+}
+
+ +
@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%;
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+}
+
+ +
<p>The Caterpillar and Alice looked at each other for some time in silence:
+at last the Caterpillar took the hookah out of its mouth, and addressed
+her in a languid, sleepy voice.</p>
+
+ +

{{ EmbedLiveSample('Движение_текста_вправо_и_влево', '100%', '250', '', 'Web/CSS/CSS_Animations/Ispolzovanie_CSS_animatciy') }}

+ +

Использование шорткодов

+ +

Шорткод {{cssxref("animation")}} полезен для экономии места в коде. Например, правило, которое мы используем в этой статье:

+ +
p {
+  animation-duration: 3s;
+  animation-name: slidein;
+  animation-iteration-count: infinite;
+  animation-direction: alternate;
+}
+ +

можно заменить на:

+ +
p {
+  animation: 3s infinite alternate slidein;
+}
+ +
+

Внимание: подробнее об этом на странице раздела {{cssxref("animation")}} 

+
+ +

Установка нескольких значений свойствам анимации  

+ +

CSS cвойство анимации может иметь несколько значений, разделенных запятыми. Это используется, чтобы указать несколько значений анимации в одном правиле и установить разную продолжительность, число повторений и т.д., для различных анимаций. Рассмотрим несколько примеров, чтобы увидеть разницу.

+ +

В первом примере у свойства имени анимации установлены три значения, у свойств продолжительности и количества повторений  — по одному. В этом случае у всех трех анимаций одинаковая продолжительность и число повторений:

+ +
animation-name: fadeInOut, moveLeft300px, bounce;
+animation-duration: 3s;
+animation-iteration-count: 1;
+ +

Во втором примере установлены три значения для каждого из свойств. В этом случае каждая анимация выполняется с соответствующими по порядку значениями в каждом свойстве, так, например, fadeInOut имеет продолжительность 2.5 с и количество повторений 2, и т.д.

+ +
animation-name: fadeInOut, moveLeft300px, bounce;
+animation-duration: 2.5s, 5s, 1s;
+animation-iteration-count: 2, 1, 5;
+ +

В третьем примере определены три значения имени анимации, но два значения продолжительности и количества повторений. В случае, когда количества значений недостаточно для каждой анимации, значения берутся циклически от начала до конца. Например, у fadeInOut длительность будет 2.5s,  а moveLeft300px — 5s. Значения продолжительности закончились, теперь они берутся сначала — bounce получит продолжительность 2.5s. Значение количества повторений (а также другие указанные свойства) будет определено таким же образом.

+ +
animation-name: fadeInOut, moveLeft300px, bounce;
+animation-duration: 2.5s, 5s;
+animation-iteration-count: 2, 1;
+ +

Использование событий анимации

+ +

Вы можете получить дополнительный контроль над анимацией, а также полезную информацию о ней, с помощью событий анимации. Эти события, представленные объектом {{ domxref("event/AnimationEvent", "AnimationEvent") }}, можно использовать, чтобы определить, когда начинается и заканчивается анимация или начинается новая итерация. Каждое событие содержит момент времени, когда оно произошло, а также имя анимации, которая вызвала событие.

+ +

Мы будем модифицировать текст, чтобы выводить некоторую информацию  о каждом событии анимации. Так мы сможем увидеть, как она работает.

+ +

Добавление CSS

+ +

Начнем с добавления CSS. Анимация будет длиться 3 секунды, будет называться "slidein", будет повторяться 3 раза, а также значение animation-direction установлено alternate. В ключевых кадрах {{ cssxref("@keyframes") }} установлены такие значения ширины и левого отступа, что элемент будет скользить по экрану.

+ +
.slidein {
+  -moz-animation-duration: 3s;
+  -webkit-animation-duration: 3s;
+  animation-duration: 3s;
+  -moz-animation-name: slidein;
+  -webkit-animation-name: slidein;
+  animation-name: slidein;
+  -moz-animation-iteration-count: 3;
+  -webkit-animation-iteration-count: 3;
+  animation-iteration-count: 3;
+  -moz-animation-direction: alternate;
+  -webkit-animation-direction: alternate;
+  animation-direction: alternate;
+}
+
+@-moz-keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%
+  }
+
+  to {
+    margin-left: 0%;
+    width: 100%;
+  }
+}
+
+@-webkit-keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%
+  }
+
+  to {
+   margin-left: 0%;
+   width: 100%;
+ }
+}
+
+@keyframes slidein {
+  from {
+    margin-left: 100%;
+    width: 300%
+  }
+
+  to {
+   margin-left: 0%;
+   width: 100%;
+ }
+}
+ +

Добавление обработчика события анимации

+ +

Будем использовать JavaScript для отслеживания всех трех возможных событий анимации. Следующий код конфигурирует обработчик; мы вызываем его при первой загрузке документа.

+ +
var e = document.getElementById("watchme");
+e.addEventListener("animationstart", listener, false);
+e.addEventListener("animationend", listener, false);
+e.addEventListener("animationiteration", listener, false);
+
+e.className = "slidein";
+
+ +

Это довольно стандартный код; Вы можете получить дополнительную информацию в документации {{ domxref("element.addEventListener()") }}. Последнее, что делает этот код - это установка класса "slidein" для анимируемого элемента; мы делаем это, чтобы запустить анимацию.

+ +

Почему? Потому что в нашем случае событие animationstart происходит как только анимация стартует, и это происходит раньше, чем исполняется наш сценарий. Так мы сможем контролировать начало анимации самостоятельно посредством вставки класса "slidein" для анимируемого элемента.

+ +

Регистрация событий

+ +

События будут передаваться функции listener(), показанной ниже.

+ +
function listener(e) {
+  var l = document.createElement("li");
+  switch(e.type) {
+    case "animationstart":
+      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
+      break;
+    case "animationend":
+      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
+      break;
+    case "animationiteration":
+      l.innerHTML = "New loop started at time " + e.elapsedTime;
+      break;
+  }
+  document.getElementById("output").appendChild(l);
+}
+
+ +

Этот код также очень прост. Этот код следит за {{ domxref("event.type") }}, чтобы определить тип события, и добавляет элемент {{ HTMLElement("ul") }}, чтобы залогировать произошедшее событие.

+ +

Вывод, когда анимация закончится, будет выглядеть примерно следующим образом:

+ + + +

Обратите внимание, что время, указанное в выводе, и время, которое мы указали в стилях, не совпадают. Также обратите внимание, что после окончания итерации не посылается событие animationiteration ; вместо него посылается событие animationend.

+ +

HTML

+ +

Ради полноты картины приведем код разметки HTML. В разметке имеется тег ul, в который и выводится вся информация:

+ +
<body>
+  <h1 id="watchme">Watch me move</h1>
+  <p>This example shows how to use CSS animations to make <code>p</code> elements
+  move across the page.</p>
+  <p>In addition, we output some text each time an animation event fires, so you can see them in action.</p>
+  <ul id="output">
+  </ul>
+</body>
+
+ +

{{ EmbedLiveSample('Использование_событий_анимации', '600', '300')}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/css/css_background_and_borders/border-radius_generator/index.html b/files/ru/web/css/css_background_and_borders/border-radius_generator/index.html new file mode 100644 index 0000000000..71f94831f0 --- /dev/null +++ b/files/ru/web/css/css_background_and_borders/border-radius_generator/index.html @@ -0,0 +1,1599 @@ +--- +title: Border-radius генератор +slug: Web/CSS/CSS_Background_and_Borders/Border-radius_генератор +translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator +--- +

С помощью этого инструмента вы можете создать CSS3 {{cssxref("border-radius")}} эффекты.

+ +
+

border-radius

+ +

HTML Content

+ +
<div id="container">
+    <div class="group section">
+        <div id="preview" class="col span_12">
+            <div id="subject">
+                <div id="top-left" class="radius-container"
+                    data-X="left" data-Y="top">
+                </div>
+                <div id="top-right" class="radius-container"
+                    data-X="right" data-Y="top">
+                </div>
+                <div id="bottom-right" class="radius-container"
+                    data-X="right" data-Y="bottom">
+                </div>
+                <div id="bottom-left" class="radius-container"
+                    data-X="left" data-Y="bottom">
+                </div>
+
+                <div id="radius-ui-sliders">
+                    <div id="tlr" class="ui-input-slider" data-topic="top-left"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="tlw" class="ui-input-slider" data-topic="top-left-w"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="tlh" class="ui-input-slider" data-topic="top-left-h"
+                        data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="trr" class="ui-input-slider" data-topic="top-right"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="trw" class="ui-input-slider" data-topic="top-right-w"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="trh" class="ui-input-slider" data-topic="top-right-h"
+                        data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="brr" class="ui-input-slider" data-topic="bottom-right"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="brw" class="ui-input-slider" data-topic="bottom-right-w"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="brh" class="ui-input-slider" data-topic="bottom-right-h"
+                        data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="blr" class="ui-input-slider" data-topic="bottom-left"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="blw" class="ui-input-slider" data-topic="bottom-left-w"
+                         data-unit=" px" data-sensivity="2"></div>
+
+                    <div id="blh" class="ui-input-slider" data-topic="bottom-left-h"
+                        data-unit=" px" data-sensivity="2"></div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div id="controls" class="group section">
+
+        <div class="group section">
+            <div id="dimensions">
+                <div class="ui-input-slider" data-topic="width" data-info="width"
+                     data-unit=" px" data-min="150" data-max="700" data-sensivity="1"></div>
+
+                <div class="ui-input-slider" data-topic="height" data-info="height"
+                    data-unit=" px" data-min="75" data-max="350" data-sensivity="1"></div>
+            </div>
+
+            <div id="output"></div>
+        </div>
+
+        <div class="group section">
+            <div id="radius-lock">
+                <div class="info"> rounded corner </div>
+                <div class="ui-checkbox" data-topic='top-left'></div>
+                <div class="ui-checkbox" data-topic='top-right'></div>
+                <div class="ui-checkbox" data-topic='bottom-right'></div>
+                <div class="ui-checkbox" data-topic='bottom-left'></div>
+            </div>
+
+            <div id="unit-selection">
+                <div class="info"> select border units </div>
+            </div>
+        </div>
+
+    </div>
+</div>
+
+ +

CSS Content

+ +
/*  GRID OF TEN
+ * ========================================================================== */
+
+.span_12 {
+	width: 100%;
+}
+
+.span_11 {
+	width: 91.46%;
+}
+
+.span_10 {
+	width: 83%;
+}
+
+.span_9 {
+	width: 74.54%;
+}
+
+.span_8 {
+	width: 66.08%;
+}
+
+.span_7 {
+	width: 57.62%;
+}
+
+.span_6 {
+	width: 49.16%;
+}
+
+.span_5 {
+	width: 40.7%;
+}
+
+.span_4 {
+	width: 32.24%;
+}
+
+.span_3 {
+	width: 23.78%;
+}
+
+.span_2 {
+	width: 15.32%;
+}
+
+.span_1 {
+	width: 6.86%;
+}
+
+
+
+
+/*  SECTIONS
+ * ========================================================================== */
+
+.section {
+	clear: both;
+	padding: 0px;
+	margin: 0px;
+}
+
+/*  GROUPING
+ * ========================================================================== */
+
+
+.group:before, .group:after {
+    content: "";
+    display: table;
+}
+
+.group:after {
+    clear:both;
+}
+
+.group {
+    zoom: 1; /* For IE 6/7 (trigger hasLayout) */
+}
+
+/*  GRID COLUMN SETUP
+ * ========================================================================== */
+
+.col {
+	display: block;
+	float:left;
+	margin: 1% 0 1% 1.6%;
+}
+
+.col:first-child {
+	margin-left: 0;
+} /* all browsers except IE6 and lower */
+
+
+/*
+ * UI Component
+ */
+
+.ui-input-slider-container {
+	height: 20px;
+	margin: 10px 0;
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+	-moz-user-select: none;
+	user-select: none;
+}
+
+.ui-input-slider-container * {
+	float: left;
+	height: 100%;
+	line-height: 100%;
+}
+
+/* Input Slider */
+
+.ui-input-slider > input {
+	margin: 0;
+	padding: 0;
+	width: 50px;
+	text-align: center;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.ui-input-slider-info {
+	width: 90px;
+	padding: 0px 10px 0px 0px;
+	text-align: right;
+	text-transform: lowercase;
+}
+
+.ui-input-slider-left, .ui-input-slider-right {
+	width: 16px;
+	cursor: pointer;
+	background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center left no-repeat;
+}
+
+.ui-input-slider-right {
+	background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center right no-repeat;
+}
+
+.ui-input-slider-name {
+	width: 90px;
+	padding: 0 10px 0 0;
+	text-align: right;
+	text-transform: lowercase;
+}
+
+.ui-input-slider-btn-set {
+	width: 25px;
+	background-color: #2C9FC9;
+	border-radius: 5px;
+	color: #FFF;
+	font-weight: bold;
+	line-height: 14px;
+	text-align: center;
+}
+
+.ui-input-slider-btn-set:hover {
+	background-color: #379B4A;
+	cursor: pointer;
+}
+
+/*
+ * UI Component
+ */
+
+/* Checkbox */
+
+.ui-checkbox {
+	text-align: center;
+	font-size: 16px;
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+	line-height: 1.5em;
+	color: #FFF;
+
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.ui-checkbox > input {
+ 	display: none;
+}
+
+.ui-checkbox > label {
+	font-size: 12px;
+	padding: 0.333em 1.666em 0.5em;
+	height: 1em;
+	line-height: 1em;
+
+	background-color: #888;
+	background-image: url("https://mdn.mozillademos.org/files/5683/disabled.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+
+	color: #FFF;
+	border-radius: 3px;
+	font-weight: bold;
+	float: left;
+}
+
+.ui-checkbox .text {
+	padding-left: 34px;
+	background-position: center left 10px;
+}
+
+.ui-checkbox .left {
+	padding-right: 34px;
+	padding-left: 1.666em;
+	background-position: center right 10px;
+}
+
+.ui-checkbox > label:hover {
+	cursor: pointer;
+}
+
+.ui-checkbox > input:checked + label {
+	background-image: url("https://mdn.mozillademos.org/files/5681/checked.png");
+	background-color: #379B4A;
+}
+
+body {
+	max-width: 1000px;
+	margin: 0 auto;
+
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+#container {
+	width: 100%;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+/*
+ * Preview Area
+ */
+
+#preview {
+	height: 500px;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+	text-align: center;
+	overflow: hidden;
+	position: relative;
+}
+
+#preview .content {
+	width: 100%;
+	height: 100%;
+	display: block;
+}
+
+#preview input {
+	color: #333;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+}
+
+#subject {
+	width: 400px;
+	height: 150px;
+	margin: 0 auto;
+	border: 3px solid #C60;
+	background: #FFF;
+	position: relative;
+}
+
+.radius {
+	width: 50%;
+	height: 50%;
+	border: 1px solid #CCC;
+	display: none;
+	position: absolute;
+	z-index: 1;
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.handle {
+	width: 16px;
+	height: 16px;
+	position: absolute;
+	z-index: 2;
+}
+
+.handle-top-left {
+	top: -12px;
+	left: -12px;
+	cursor: se-resize;
+	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top left no-repeat;
+}
+
+.handle-top-right {
+	top: -12px;
+	right: -12px;
+	cursor: sw-resize;
+	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top right no-repeat;
+}
+
+.handle-bottom-right {
+	bottom: -12px;
+	right: -12px;
+	cursor: nw-resize;
+	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom right no-repeat;
+}
+
+.handle-bottom-left {
+	bottom: -12px;
+	left: -12px;
+	cursor: ne-resize;
+	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom left no-repeat;
+}
+
+
+.radius-container {
+	position: absolute;
+	display : block;
+	z-index: 1;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+
+/* TOP LEFT */
+#top-left {
+	top: 0;
+	left: 0;
+}
+
+#top-left .radius {
+	border-top-left-radius: 100%;
+	top: 0;
+	left: 0;
+}
+
+/* TOP RIGHT */
+#top-right {
+	top: 0;
+	right: 0;
+}
+
+#top-right .radius {
+	border-top-right-radius: 100%;
+	top: 0;
+	right: 0;
+}
+
+/* BOTTOM RIGHT */
+#bottom-right {
+	bottom: 0;
+	right: 0;
+}
+
+#bottom-right .radius {
+	border-bottom-right-radius: 100%;
+	bottom: 0;
+	right: 0;
+}
+
+/* BOTTOM lEFT */
+#bottom-left {
+	bottom: 0;
+	left: 0;
+}
+
+#bottom-left .radius {
+	border-bottom-left-radius: 100%;
+	bottom: 0;
+}
+
+/* INPUT SLIDERS */
+
+#preview .ui-input-slider {
+	margin: 10px;
+	position: absolute;
+	z-index: 10;
+}
+
+#radius-ui-sliders {
+	width: 100%;
+	height: 100%;
+	min-height: 75px;
+	min-width: 150px;
+	padding: 20px 50px;
+	top: -20px;
+	left: -50px;
+	position: relative;
+}
+
+#tlr {
+	top: -30px;
+	left: -50px;
+	display: none;
+}
+
+#tlw {
+	top: -30px;
+	left: 30px;
+}
+
+#tlh {
+	top: 20px;
+	left: -50px;
+}
+
+#trr {
+	top: -30px;
+	right: -50px;
+	display: none;
+}
+
+#trw {
+	top: -30px;
+	right: 30px;
+}
+
+#trh {
+	top: 20px;
+	right: -50px;
+}
+
+#brr {
+	bottom: -30px;
+	right: -50px;
+	display: none;
+}
+
+#brw {
+	bottom: -30px;
+	right: 30px;
+}
+
+#brh {
+	bottom: 20px;
+	right: -50px;
+}
+
+#blr {
+	bottom: -30px;
+	left: -50px;
+	display: none;
+}
+
+#blw {
+	bottom: -30px;
+	left: 30px;
+}
+
+#blh {
+	bottom: 20px;
+	left: -50px;
+}
+
+#preview .ui-input-slider-left, #preview .ui-input-slider-right {
+	visibility: hidden;
+}
+
+#preview .ui-input-slider-container:hover .ui-input-slider-left {
+	visibility: visible;
+}
+
+#preview .ui-input-slider-container:hover .ui-input-slider-right {
+	visibility: visible;
+}
+
+/*
+ *
+ */
+
+#unit-selection {
+	width: 200px;
+	height: 75px;
+	margin: 30px 30px 0 0;
+	padding: 30px;
+	border: 3px solid #555;
+	border-radius: 10px;
+	position: relative;
+	float: right;
+}
+
+#unit-selection .info {
+	height: 20%;
+	width: 100%;
+	line-height: 20%;
+	font-size: 20px;
+	text-align: center;
+	position: relative;
+	top: 40%;
+}
+
+#unit-selection .dropdown {
+	width: 50px;
+	height: 20px;
+	margin: 10px;
+	padding: 0;
+	border-radius: 3px;
+	position: absolute;
+	overflow: hidden;
+}
+
+#unit-selection select {
+	width: 50px;
+	height: 20px;
+	marign: 0;
+	padding: 0 0 0 10px;
+	background: #555;
+	border: 1px solid #555;
+	border: none;
+	color: #FFF;
+	float: left;
+}
+
+#unit-selection select option {
+	background: #FFF;
+	color: #333;
+}
+
+#unit-selection select:hover {
+	cursor: pointer;
+}
+
+#unit-selection .dropdown:before {
+	content: "";
+	width: 18px;
+	height: 20px;
+	display: block;
+	background-color: #555;
+	background-image: url("https://mdn.mozillademos.org/files/5675/dropdown.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+	top: 0px;
+	right: 0px;
+	position: absolute;
+	z-index: 1;
+	pointer-events: none;
+}
+
+#unit-selection .unit-top-left {
+	top: 0;
+	left: 0;
+	display: none;
+}
+
+#unit-selection .unit-top-left-w {
+	top: -22px;
+	left: 30px;
+}
+
+#unit-selection .unit-top-left-h {
+	top: 20px;
+	left: -37px;
+}
+
+#unit-selection .unit-top-right {
+	top: 0;
+	right: 0;
+	display: none;
+}
+
+#unit-selection .unit-top-right-w {
+	top: -22px;
+	right: 30px;
+}
+
+#unit-selection .unit-top-right-h {
+	top: 20px;
+	right: -37px;
+}
+
+#unit-selection .unit-bottom-right {
+	bottom: 0;
+	right: 0;
+	display: none;
+}
+
+#unit-selection .unit-bottom-right-w {
+	bottom: -22px;
+	right: 30px;
+}
+
+#unit-selection .unit-bottom-right-h {
+	bottom: 20px;
+	right: -37px;
+}
+
+#unit-selection .unit-bottom-left {
+	bottom: 0;
+	left: 0;
+	display: none;
+}
+
+#unit-selection .unit-bottom-left-w {
+	bottom: -22px;
+	left: 30px;
+}
+
+#unit-selection .unit-bottom-left-h {
+	bottom: 20px;
+	left: -37px;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+
+
+#radius-lock {
+	width: 200px;
+	height: 75px;
+	margin: 30px 0 0 30px;
+	padding: 30px;
+	border: 3px solid #555;
+	border-radius: 10px;
+	position: relative;
+	float: left;
+}
+
+#radius-lock .ui-checkbox {
+	color: #FFF;
+	position: absolute;
+}
+
+#radius-lock .ui-checkbox > label {
+	height: 20px;
+	width: 34px;
+	padding: 0;
+}
+
+#radius-lock .info {
+	height: 20%;
+	width: 100%;
+	line-height: 20%;
+	font-size: 20px;
+	text-align: center;
+	position: relative;
+	top: 40%;
+}
+
+#radius-lock [data-topic="top-left"] {
+	top: 10px;
+	left: 10px;
+}
+
+#radius-lock [data-topic="top-right"] {
+	top: 10px;
+	right: 10px;
+}
+
+#radius-lock [data-topic="bottom-right"] {
+	bottom: 10px;
+	right: 10px;
+}
+
+#radius-lock [data-topic="bottom-left"] {
+	bottom: 10px;
+	left: 10px;
+}
+
+/**
+ * Controls
+ */
+
+#dimensions {
+	width: 200px;
+	color: #444;
+	float:left;
+}
+
+#dimensions input {
+	background: #555;
+	color: #FFF;
+	border: none;
+	border-radius: 3px;
+}
+
+#output {
+	width: 500px;
+	padding: 10px 0;
+	margin: 10px 0;
+	color: #555;
+	text-align: center;
+	border: 1px dashed #999;
+	border-radius: 3px;
+	-moz-user-select: text;
+	-webkit-user-select: text;
+	-ms-user-select: text;
+	user-select: text;
+
+	float: right;
+}
+
+
+
+ +

JavaScript Content

+ +
'use strict';
+
+
+/**
+ * UI-InputSliderManager
+ */
+
+var InputSliderManager = (function InputSliderManager() {
+
+	var subscribers = {};
+	var sliders = [];
+
+	var InputComponent = function InputComponent(obj) {
+		var input = document.createElement('input');
+		input.setAttribute('type', 'text');
+
+		input.addEventListener('click', function(e) {
+			this.select();
+		});
+
+		input.addEventListener('change', function(e) {
+			var value = parseInt(e.target.value);
+
+			if (isNaN(value) === true)
+				setValue(obj.topic, obj.value);
+			else
+				setValue(obj.topic, value);
+		});
+
+		subscribe(obj.topic, function(value) {
+			input.value = value + obj.unit;
+		});
+
+		return input;
+	}
+
+	var SliderComponent = function SliderComponent(obj, sign) {
+		var slider = document.createElement('div');
+		var startX = null;
+		var start_value = 0;
+
+		slider.addEventListener("click", function(e) {
+			setValue(obj.topic, obj.value + obj.step * sign);
+		});
+
+		slider.addEventListener("mousedown", function(e) {
+			startX = e.clientX;
+			start_value = obj.value;
+			document.body.style.cursor = "e-resize";
+			document.addEventListener("mousemove", sliderMotion);
+		});
+
+		document.addEventListener("mouseup", function(e) {
+			document.removeEventListener("mousemove", sliderMotion);
+			document.body.style.cursor = "auto";
+			slider.style.cursor = "pointer";
+		});
+
+		var sliderMotion = function sliderMotion(e) {
+			slider.style.cursor = "e-resize";
+			var delta = (e.clientX - startX) / obj.sensivity | 0;
+			var value = delta * obj.step + start_value;
+			setValue(obj.topic, value);
+		}
+
+		return slider;
+	}
+
+	var InputSlider = function(node) {
+		var min		= node.getAttribute('data-min') | 0;
+		var max		= node.getAttribute('data-max') | 0;
+		var step	= node.getAttribute('data-step') | 0;
+		var value	= node.getAttribute('data-value') | 0;
+		var topic	= node.getAttribute('data-topic');
+		var unit	= node.getAttribute('data-unit');
+		var name 	= node.getAttribute('data-info');
+		var sensivity = node.getAttribute('data-sensivity') | 0;
+
+		this.min = min;
+		this.max = max > 0 ? max : 100;
+		this.step = step === 0 ? 1 : step;
+		this.topic = topic;
+		this.node = node;
+		this.unit = unit;
+		this.sensivity = sensivity > 0 ? sensivity : 5;
+
+		var input = new InputComponent(this);
+		var slider_left  = new SliderComponent(this, -1);
+		var slider_right = new SliderComponent(this,  1);
+
+		slider_left.className = 'ui-input-slider-left';
+		slider_right.className = 'ui-input-slider-right';
+
+		if (name) {
+			var info = document.createElement('span');
+			info.className = 'ui-input-slider-info';
+			info.textContent = name;
+			node.appendChild(info);
+		}
+
+		node.appendChild(slider_left);
+		node.appendChild(input);
+		node.appendChild(slider_right);
+		node.className = 'ui-input-slider ui-input-slider-container';
+
+		this.input = input;
+		sliders[topic] = this;
+		setValue(topic, value);
+	}
+
+	var setValue = function setValue(topic, value, send_notify) {
+		var slider = sliders[topic];
+		if (slider === undefined)
+			return;
+
+		if (value > slider.max) value = slider.max;
+		if (value < slider.min)	value = slider.min;
+
+		slider.value = value;
+		slider.node.setAttribute('data-value', value);
+
+		if (send_notify !== undefined && send_notify === false) {
+			slider.input.value = value + slider.unit;
+			return;
+		}
+
+		notify.call(slider);
+	}
+
+	var setMax = function setMax(topic, value) {
+		var slider = sliders[topic];
+		if (slider === undefined)
+			return;
+
+		slider.max = value;
+		setValue(topic, slider.value);
+	}
+
+	var setMin = function setMin(topic, value) {
+		var slider = sliders[topic];
+		if (slider === undefined)
+			return;
+
+		slider.min = value;
+		setValue(topic, slider.value);
+	}
+
+	var setUnit = function setUnit(topic, unit) {
+		var slider = sliders[topic];
+		if (slider === undefined)
+			return;
+
+		slider.unit = unit;
+		setValue(topic, slider.value);
+	}
+
+	var getNode =  function getNode(topic) {
+		return sliders[topic].node;
+	}
+
+	var subscribe = function subscribe(topic, callback) {
+		if (subscribers[topic] === undefined)
+			subscribers[topic] = [];
+		subscribers[topic].push(callback);
+	}
+
+	var unsubscribe = function unsubscribe(topic, callback) {
+		subscribers[topic].indexOf(callback);
+		subscribers[topic].splice(index, 1);
+	}
+
+	var notify = function notify() {
+		for (var i in subscribers[this.topic]) {
+			subscribers[this.topic][i](this.value);
+		}
+	}
+
+	var init = function init() {
+		var elem = document.querySelectorAll('.ui-input-slider');
+		var size = elem.length;
+		for (var i = 0; i < size; i++)
+			new InputSlider(elem[i]);
+	}
+
+	return {
+		init : init,
+		setMax : setMax,
+		setMin : setMin,
+		setUnit : setUnit,
+		getNode : getNode,
+		setValue : setValue,
+		subscribe : subscribe,
+		unsubscribe : unsubscribe
+	}
+
+})();
+
+/**
+ * UI-ButtonManager
+ */
+
+var ButtonManager = (function CheckBoxManager() {
+
+	var subscribers = [];
+	var buttons = [];
+
+	var CheckBox = function CheckBox(node) {
+		var topic = node.getAttribute('data-topic');
+		var state = node.getAttribute('data-state');
+		var name = node.getAttribute('data-label');
+		var align = node.getAttribute('data-text-on');
+
+		state = (state === "true");
+
+		var checkbox = document.createElement("input");
+		var label = document.createElement("label");
+
+		var id = 'checkbox-' + topic;
+		checkbox.id = id;
+		checkbox.setAttribute('type', 'checkbox');
+		checkbox.checked = state;
+
+		label.setAttribute('for', id);
+		if (name) {
+			label.className = 'text';
+			if (align)
+				label.className += ' ' + align;
+			label.textContent = name;
+		}
+
+		node.appendChild(checkbox);
+		node.appendChild(label);
+
+		this.node = node;
+		this.topic = topic;
+		this.checkbox = checkbox;
+
+		checkbox.addEventListener('change', function(e) {
+			notify.call(this);
+		}.bind(this));
+
+		buttons[topic] = this;
+	}
+
+	var getNode =  function getNode(topic) {
+		return buttons[topic].node;
+	}
+
+	var setValue = function setValue(topic, value) {
+		try {
+			buttons[topic].checkbox.checked = value;
+		}
+		catch(error) {
+			console.log(error);
+		}
+	}
+
+	var subscribe = function subscribe(topic, callback) {
+		if (subscribers[topic] === undefined)
+			subscribers[topic] = [];
+
+		subscribers[topic].push(callback);
+	}
+
+	var unsubscribe = function unsubscribe(topic, callback) {
+		subscribers[topic].indexOf(callback);
+		subscribers[topic].splice(index, 1);
+	}
+
+	var notify = function notify() {
+		for (var i = 0; i < subscribers[this.topic].length; i++)
+			subscribers[this.topic][i](this.checkbox.checked);
+	}
+
+	var init = function init() {
+		var elem = document.querySelectorAll('.ui-checkbox');
+		var size = elem.length;
+		for (var i = 0; i < size; i++)
+			new CheckBox(elem[i]);
+	}
+
+	return {
+		init : init,
+		setValue : setValue,
+		subscribe : subscribe,
+		unsubscribe : unsubscribe
+	}
+
+})();
+
+
+window.addEventListener("load", function() {
+	BorderRadius.init();
+});
+
+var BorderRadius = (function BorderRadius() {
+
+	function getElemById(id) {
+		return document.getElementById(id);
+	}
+
+	/**
+	 * Shadow dragging
+	 */
+	var PreviewMouseTracking = (function Drag() {
+		var active = false;
+		var lastX = 0;
+		var lastY = 0;
+		var subscribers = [];
+
+		var init = function init(id) {
+			var elem = getElemById(id);
+			elem.addEventListener('mousedown', dragStart, false);
+			document.addEventListener('mouseup', dragEnd, false);
+		}
+
+		var dragStart = function dragStart(e) {
+			if (e.button !== 0)
+				return;
+
+			active = true;
+			lastX = e.clientX;
+			lastY = e.clientY;
+			document.addEventListener('mousemove', mouseDrag, false);
+		}
+
+		var dragEnd = function dragEnd(e) {
+			if (e.button !== 0)
+				return;
+
+			if (active === true) {
+				active = false;
+				document.removeEventListener('mousemove', mouseDrag, false);
+			}
+		}
+
+		var mouseDrag = function mouseDrag(e) {
+			notify(e.clientX - lastX, e.clientY - lastY);
+			lastX = e.clientX;
+			lastY = e.clientY;
+		}
+
+		var subscribe = function subscribe(callback) {
+			subscribers.push(callback);
+		}
+
+		var unsubscribe = function unsubscribe(callback) {
+			var index = subscribers.indexOf(callback);
+			subscribers.splice(index, 1);
+		}
+
+		var notify = function notify(deltaX, deltaY) {
+			for (var i in subscribers)
+				subscribers[i](deltaX, deltaY);
+		}
+
+		return {
+			init : init,
+			subscribe : subscribe,
+			unsubscribe : unsubscribe
+		}
+
+	})();
+
+	var subject;
+	var units = ['px', '%'];
+	var output = null;
+
+	var UnitSelector = function UnitSelector(topic) {
+
+		this.container = document.createElement("div");
+		this.select = document.createElement("select");
+		for (var i in units) {
+			var option = document.createElement("option");
+			option.value = i;
+			option.textContent = units[i];
+			this.select.appendChild(option);
+		}
+
+		this.container.className = 'dropdown ' + 'unit-' + topic;
+		this.container.appendChild(this.select);
+	}
+
+	UnitSelector.prototype.setValue = function setValue(value) {
+		this.salect.value = value;
+	}
+
+
+	var RadiusContainer = function RadiusContainer(node) {
+		var radius = document.createElement('div');
+		var handle = document.createElement('div');
+		var x = node.getAttribute('data-x');
+		var y = node.getAttribute('data-y');
+		var active = false;
+
+		this.id = node.id;
+		this.node = node;
+		this.radius = radius;
+		this.handle = handle;
+		this.width = 100;
+		this.height = 50;
+		this.size = 0;
+		this.rounded = false;
+
+		this.unitX = 0;
+		this.unitY = 0;
+		this.unitR = 0;
+
+		this.maxW = 100;
+		this.maxH = 100;
+		this.maxR = 100;
+
+		this.topic = y + '-' + x;
+
+		var sliderW = InputSliderManager.getNode(this.topic + '-w');
+		var sliderH = InputSliderManager.getNode(this.topic + '-h');
+		var sliderR = InputSliderManager.getNode(this.topic);
+
+		this.setUnitX(this.unitX);
+		this.setUnitY(this.unitY);
+		this.setUnitR(this.unitR);
+
+		this.updateWidth();
+		this.updateHeight();
+		this.updateRadius();
+
+		if (x === 'left')	this.resizeX =  1;
+		if (x === 'right')	this.resizeX = -1;
+		if (y === 'top')	this.resizeY =  1;
+		if (y === 'bottom')	this.resizeY = -1;
+
+		radius.className = 'radius';
+
+		var unit_selector = document.getElementById("unit-selection");
+		var unitW = new UnitSelector(this.topic + '-w');
+		var unitH = new UnitSelector(this.topic + '-h');
+		var unitR = new UnitSelector(this.topic);
+
+		unit_selector.appendChild(unitW.container);
+		unit_selector.appendChild(unitH.container);
+		unit_selector.appendChild(unitR.container);
+		node.appendChild(radius);
+		subject.appendChild(handle);
+
+		unitW.select.addEventListener('change', function(e) {
+			this.setUnitX(e.target.value | 0);
+		}.bind(this));
+
+		unitH.select.addEventListener('change', function(e) {
+			this.setUnitY(e.target.value | 0);
+		}.bind(this));
+
+		unitR.select.addEventListener('change', function(e) {
+			this.setUnitR(e.target.value | 0);
+		}.bind(this));
+
+		if (x === 'left' && y == 'top') handle.className = 'handle handle-top-left'
+		if (x === 'right' && y == 'top') handle.className = 'handle handle-top-right';
+		if (x === 'right' && y == 'bottom') handle.className = 'handle handle-bottom-right';
+		if (x === 'left' && y == 'bottom') 	handle.className = 'handle handle-bottom-left';
+
+		handle.addEventListener("mousedown", function(e) {
+			active = true;
+			this.radius.style.display = 'block';
+			PreviewMouseTracking.subscribe(this.updateContainer.bind(this));
+		}.bind(this));
+
+		document.addEventListener("mouseup", function(e) {
+			this.radius.style.display = 'none';
+			if (active === true)
+				PreviewMouseTracking.unsubscribe(this.updateContainer.bind(this));
+		}.bind(this));
+
+		InputSliderManager.subscribe(this.topic + '-w', this.setWidth.bind(this));
+		InputSliderManager.subscribe(this.topic + '-h', this.setHeight.bind(this));
+		InputSliderManager.subscribe(this.topic, this.setRadius.bind(this));
+
+		ButtonManager.subscribe(this.topic, function(value) {
+			this.rounded = value;
+			if (value === true) {
+				unitW.container.style.display = 'none';
+				unitH.container.style.display = 'none';
+				unitR.container.style.display = 'block';
+				sliderW.style.display = 'none';
+				sliderH.style.display = 'none';
+				sliderR.style.display = 'block';
+				this.setUnitR(this.unitR);
+				this.updateRadius();
+			}
+
+			if (value === false) {
+				unitW.container.style.display = 'block';
+				unitH.container.style.display = 'block';
+				unitR.container.style.display = 'none';
+				sliderW.style.display = 'block';
+				sliderH.style.display = 'block';
+				sliderR.style.display = 'none';
+				this.setUnitX(this.unitX);
+				this.setUnitY(this.unitY);
+				this.updateWidth();
+				this.updateHeight();
+			}
+
+			this.updateBorderRadius();
+
+		}.bind(this));
+
+		this.updateBorderRadius();
+	}
+
+	RadiusContainer.prototype.updateWidth = function updateWidth() {
+		this.node.style.width = this.width + units[this.unitX];
+		var value = Math.round(this.width / 2);
+		InputSliderManager.setValue(this.topic + '-w', value, false);
+	}
+
+	RadiusContainer.prototype.updateHeight = function updateHeight() {
+		this.node.style.height = this.height + units[this.unitY];
+		var value = Math.round(this.height / 2);
+		InputSliderManager.setValue(this.topic + '-h', value, false);
+	}
+
+	RadiusContainer.prototype.updateRadius = function updateRadius() {
+		var value = Math.round(this.size / 2);
+		this.node.style.width = this.size + units[this.unitR];
+		this.node.style.height = this.size + units[this.unitR];
+		InputSliderManager.setValue(this.topic, value, false);
+	}
+
+	RadiusContainer.prototype.setWidth = function setWidth(value) {
+		this.radius.style.display = 'block';
+		this.width = 2 * value;
+		this.node.style.width = this.width + units[this.unitX];
+		this.updateBorderRadius();
+	}
+
+	RadiusContainer.prototype.setHeight = function setHeight(value) {
+		this.radius.style.display = 'block';
+		this.height = 2 * value;
+		this.node.style.height = this.height + units[this.unitY];
+		this.updateBorderRadius();
+	}
+
+	RadiusContainer.prototype.setRadius = function setRadius(value) {
+		this.radius.style.display = 'block';
+		this.size = 2 * value;
+		this.node.style.width = this.size + units[this.unitR];
+		this.node.style.height = this.size + units[this.unitR];
+		this.updateBorderRadius();
+	}
+
+	RadiusContainer.prototype.setUnitX = function setUnitX(value) {
+		this.unitX = value;
+		if (this.unitX === 0) this.maxW = 2 * subject.clientWidth;
+		if (this.unitX === 1) this.maxW = 200;
+		InputSliderManager.setUnit(this.topic + '-w', units[this.unitX]);
+		InputSliderManager.setMax(this.topic + '-w', this.maxW / 2);
+	}
+
+	RadiusContainer.prototype.setUnitY = function setUnitY(value) {
+		this.unitY = value;
+		if (this.unitY === 0) this.maxH = 2 * subject.clientHeight;
+		if (this.unitY === 1) this.maxH = 200;
+		InputSliderManager.setUnit(this.topic + '-h', units[this.unitY]);
+		InputSliderManager.setMax(this.topic + '-h', this.maxH / 2);
+	}
+
+	RadiusContainer.prototype.setUnitR = function setUnitR(value) {
+		this.unitR = value;
+
+		if (this.unitR === 0)
+			this.maxR = 2 * Math.min(subject.clientHeight , subject.clientWidth);
+
+		if (this.unitR === 1)
+			this.maxR = 200;
+
+		InputSliderManager.setUnit(this.topic, units[this.unitR]);
+		InputSliderManager.setMax(this.topic, this.maxR / 2);
+	}
+
+	RadiusContainer.prototype.updateUnits = function updateUnits(unit) {
+		if (this.rounded) {
+			this.setUnitR(this.unitR);
+			return;
+		}
+
+		if (unit === 0)
+			this.setUnitX(this.unitX);
+
+		if (unit === 1)
+			this.setUnitY(this.unitY);
+	}
+
+	RadiusContainer.prototype.composeBorderRadius = function composeBorderRadius () {
+
+		if (this.rounded === true) {
+			var unit = units[this.unitR];
+			var value = Math.round(this.size / 2);
+			return value + unit;
+		}
+
+		var unitX = units[this.unitX];
+		var unitY = units[this.unitY];
+		var valueX = Math.round(this.width / 2);
+		var valueY = Math.round(this.height / 2);
+
+		if (valueX === valueY && this.unitX === this.unitY)
+			return valueX + unitX;
+
+		return valueX + unitX + ' ' + valueY + unitY;
+	}
+
+	RadiusContainer.prototype.updateBorderRadius = function updateBorderRadius () {
+		var radius = this.composeBorderRadius();
+		var corner = 0;
+
+		if (this.topic === 'top-left') {
+			subject.style.borderTopLeftRadius = radius;
+			corner = 0;
+		}
+
+		if (this.topic === 'top-right') {
+			subject.style.borderTopRightRadius = radius;
+			corner = 1;
+		}
+
+		if (this.topic === 'bottom-right') {
+			subject.style.borderBottomRightRadius = radius;
+			corner = 2;
+		}
+
+		if (this.topic === 'bottom-left') {
+			subject.style.borderBottomLeftRadius = radius;
+			corner = 3;
+		}
+
+		Tool.updateOutput(corner, radius);
+	}
+
+	RadiusContainer.prototype.updateContainer = function updateContainer(deltaX, deltaY) {
+
+		if (this.rounded === true) {
+			this.size += this.resizeX * deltaX + this.resizeY * deltaY;
+			if (this.size < 0)	this.size = 0;
+			if (this.size > this.maxR)	this.size = this.maxR;
+			this.updateRadius();
+			this.updateBorderRadius();
+			return;
+		}
+
+		if (deltaX) {
+			this.width += this.resizeX * deltaX;
+			if (this.width < 0)	this.width = 0;
+			if (this.width > this.maxW)	this.width = this.maxW;
+			this.updateWidth();
+		}
+
+		if (deltaY) {
+			this.height += this.resizeY * deltaY;
+			if (this.height < 0) this.height = 0;
+			if (this.height > this.maxH)	this.height = this.maxH;
+			this.updateHeight();
+		}
+
+		if (deltaX || deltaY)
+			this.updateBorderRadius();
+	}
+
+
+	/**
+	 * Tool Manager
+	 */
+	var Tool = (function Tool() {
+		var preview;
+		var preview_ui;
+		var radius_containers = [];
+		var border_width = 3;
+		var borders1 = [null, null, null, null];
+		var borders2 = [0, 0, 0, 0];
+
+		var updateUIWidth = function updateUIWidth(value) {
+			var pwidth = subject.parentElement.clientWidth;
+			var left = (pwidth - value) / 2;
+			subject.style.width = value + "px";
+
+			for (var i = 0; i < 4; i++)
+				radius_containers[i].updateUnits(0);
+		}
+
+		var updateUIHeight = function updateUIHeight(value) {
+			var pheight = subject.parentElement.clientHeight;
+			var top = (pheight - value) / 2;
+			subject.style.height = value + "px";
+			subject.style.top = top - border_width + "px";
+
+			for (var i = 0; i < 4; i++)
+				radius_containers[i].updateUnits(1);
+		}
+
+		var updatePreviewUIWidth = function updatePreviewUIWidth() {
+			var p = subject.parentElement.clientWidth;
+			var v = preview_ui.clientWidth;
+			console.log(p, v, (p - v ) / 2);
+			preview_ui.style.left = (p - v) / 2 + "px" ;
+		}
+
+		var updatePreviewUIHeight = function updatePreviewUIHeight() {
+			var p = subject.parentElement.clientHeight;
+			var v = preview_ui.clientHeight;
+			console.log(p, v, (p - v ) / 2);
+			preview_ui.style.top = (p - v) / 2 + "px" ;
+		}
+
+		var updateOutput = function updateOutput(corner, radius) {
+			var values = radius.split(" ");
+
+			borders1[corner] = values[0];
+			borders2[corner] = values[0];
+
+			if (values.length === 2)
+				borders2[corner] = values[1];
+
+			var border_1_value = borders1.join(" ");
+			var border_2_value = borders2.join(" ");
+			var border_radius = 'border-radius: ' + border_1_value;
+
+			if (border_2_value !== border_1_value)
+				border_radius += ' / ' + border_2_value;
+
+			border_radius += ';';
+			output.textContent = border_radius;
+		}
+
+		var init = function init() {
+			preview = getElemById("preview");
+			subject = getElemById("subject");
+			output = getElemById("output");
+			preview_ui = getElemById("radius-ui-sliders");
+
+			var elem = document.querySelectorAll('.radius-container');
+			var size = elem.length;
+			for (var i = 0; i < size; i++)
+				radius_containers[i] = new RadiusContainer(elem[i]);
+
+			InputSliderManager.subscribe("width", updateUIWidth);
+			InputSliderManager.subscribe("height", updateUIHeight);
+
+			InputSliderManager.setValue("width", subject.clientWidth);
+			InputSliderManager.setValue("height", subject.clientHeight);
+		}
+
+		return {
+			init : init,
+			updateOutput : updateOutput
+		}
+
+	})();
+
+	/**
+	 * Init Tool
+	 */
+	var init = function init() {
+		ButtonManager.init();
+		InputSliderManager.init();
+		PreviewMouseTracking.init("preview");
+		Tool.init();
+	}
+
+	return {
+		init : init
+	}
+
+})();
+
+
+
+
+ +

{{ EmbedLiveSample('border-radius-generator', '100%', '800px', '') }}

+ +

 

diff --git "a/files/ru/web/css/css_background_and_borders/border-radius_\320\263\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200/index.html" "b/files/ru/web/css/css_background_and_borders/border-radius_\320\263\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200/index.html" deleted file mode 100644 index 71f94831f0..0000000000 --- "a/files/ru/web/css/css_background_and_borders/border-radius_\320\263\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200/index.html" +++ /dev/null @@ -1,1599 +0,0 @@ ---- -title: Border-radius генератор -slug: Web/CSS/CSS_Background_and_Borders/Border-radius_генератор -translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator ---- -

С помощью этого инструмента вы можете создать CSS3 {{cssxref("border-radius")}} эффекты.

- -
-

border-radius

- -

HTML Content

- -
<div id="container">
-    <div class="group section">
-        <div id="preview" class="col span_12">
-            <div id="subject">
-                <div id="top-left" class="radius-container"
-                    data-X="left" data-Y="top">
-                </div>
-                <div id="top-right" class="radius-container"
-                    data-X="right" data-Y="top">
-                </div>
-                <div id="bottom-right" class="radius-container"
-                    data-X="right" data-Y="bottom">
-                </div>
-                <div id="bottom-left" class="radius-container"
-                    data-X="left" data-Y="bottom">
-                </div>
-
-                <div id="radius-ui-sliders">
-                    <div id="tlr" class="ui-input-slider" data-topic="top-left"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="tlw" class="ui-input-slider" data-topic="top-left-w"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="tlh" class="ui-input-slider" data-topic="top-left-h"
-                        data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="trr" class="ui-input-slider" data-topic="top-right"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="trw" class="ui-input-slider" data-topic="top-right-w"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="trh" class="ui-input-slider" data-topic="top-right-h"
-                        data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="brr" class="ui-input-slider" data-topic="bottom-right"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="brw" class="ui-input-slider" data-topic="bottom-right-w"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="brh" class="ui-input-slider" data-topic="bottom-right-h"
-                        data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="blr" class="ui-input-slider" data-topic="bottom-left"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="blw" class="ui-input-slider" data-topic="bottom-left-w"
-                         data-unit=" px" data-sensivity="2"></div>
-
-                    <div id="blh" class="ui-input-slider" data-topic="bottom-left-h"
-                        data-unit=" px" data-sensivity="2"></div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div id="controls" class="group section">
-
-        <div class="group section">
-            <div id="dimensions">
-                <div class="ui-input-slider" data-topic="width" data-info="width"
-                     data-unit=" px" data-min="150" data-max="700" data-sensivity="1"></div>
-
-                <div class="ui-input-slider" data-topic="height" data-info="height"
-                    data-unit=" px" data-min="75" data-max="350" data-sensivity="1"></div>
-            </div>
-
-            <div id="output"></div>
-        </div>
-
-        <div class="group section">
-            <div id="radius-lock">
-                <div class="info"> rounded corner </div>
-                <div class="ui-checkbox" data-topic='top-left'></div>
-                <div class="ui-checkbox" data-topic='top-right'></div>
-                <div class="ui-checkbox" data-topic='bottom-right'></div>
-                <div class="ui-checkbox" data-topic='bottom-left'></div>
-            </div>
-
-            <div id="unit-selection">
-                <div class="info"> select border units </div>
-            </div>
-        </div>
-
-    </div>
-</div>
-
- -

CSS Content

- -
/*  GRID OF TEN
- * ========================================================================== */
-
-.span_12 {
-	width: 100%;
-}
-
-.span_11 {
-	width: 91.46%;
-}
-
-.span_10 {
-	width: 83%;
-}
-
-.span_9 {
-	width: 74.54%;
-}
-
-.span_8 {
-	width: 66.08%;
-}
-
-.span_7 {
-	width: 57.62%;
-}
-
-.span_6 {
-	width: 49.16%;
-}
-
-.span_5 {
-	width: 40.7%;
-}
-
-.span_4 {
-	width: 32.24%;
-}
-
-.span_3 {
-	width: 23.78%;
-}
-
-.span_2 {
-	width: 15.32%;
-}
-
-.span_1 {
-	width: 6.86%;
-}
-
-
-
-
-/*  SECTIONS
- * ========================================================================== */
-
-.section {
-	clear: both;
-	padding: 0px;
-	margin: 0px;
-}
-
-/*  GROUPING
- * ========================================================================== */
-
-
-.group:before, .group:after {
-    content: "";
-    display: table;
-}
-
-.group:after {
-    clear:both;
-}
-
-.group {
-    zoom: 1; /* For IE 6/7 (trigger hasLayout) */
-}
-
-/*  GRID COLUMN SETUP
- * ========================================================================== */
-
-.col {
-	display: block;
-	float:left;
-	margin: 1% 0 1% 1.6%;
-}
-
-.col:first-child {
-	margin-left: 0;
-} /* all browsers except IE6 and lower */
-
-
-/*
- * UI Component
- */
-
-.ui-input-slider-container {
-	height: 20px;
-	margin: 10px 0;
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-	-moz-user-select: none;
-	user-select: none;
-}
-
-.ui-input-slider-container * {
-	float: left;
-	height: 100%;
-	line-height: 100%;
-}
-
-/* Input Slider */
-
-.ui-input-slider > input {
-	margin: 0;
-	padding: 0;
-	width: 50px;
-	text-align: center;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-.ui-input-slider-info {
-	width: 90px;
-	padding: 0px 10px 0px 0px;
-	text-align: right;
-	text-transform: lowercase;
-}
-
-.ui-input-slider-left, .ui-input-slider-right {
-	width: 16px;
-	cursor: pointer;
-	background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center left no-repeat;
-}
-
-.ui-input-slider-right {
-	background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center right no-repeat;
-}
-
-.ui-input-slider-name {
-	width: 90px;
-	padding: 0 10px 0 0;
-	text-align: right;
-	text-transform: lowercase;
-}
-
-.ui-input-slider-btn-set {
-	width: 25px;
-	background-color: #2C9FC9;
-	border-radius: 5px;
-	color: #FFF;
-	font-weight: bold;
-	line-height: 14px;
-	text-align: center;
-}
-
-.ui-input-slider-btn-set:hover {
-	background-color: #379B4A;
-	cursor: pointer;
-}
-
-/*
- * UI Component
- */
-
-/* Checkbox */
-
-.ui-checkbox {
-	text-align: center;
-	font-size: 16px;
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-	line-height: 1.5em;
-	color: #FFF;
-
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-}
-
-.ui-checkbox > input {
- 	display: none;
-}
-
-.ui-checkbox > label {
-	font-size: 12px;
-	padding: 0.333em 1.666em 0.5em;
-	height: 1em;
-	line-height: 1em;
-
-	background-color: #888;
-	background-image: url("https://mdn.mozillademos.org/files/5683/disabled.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-
-	color: #FFF;
-	border-radius: 3px;
-	font-weight: bold;
-	float: left;
-}
-
-.ui-checkbox .text {
-	padding-left: 34px;
-	background-position: center left 10px;
-}
-
-.ui-checkbox .left {
-	padding-right: 34px;
-	padding-left: 1.666em;
-	background-position: center right 10px;
-}
-
-.ui-checkbox > label:hover {
-	cursor: pointer;
-}
-
-.ui-checkbox > input:checked + label {
-	background-image: url("https://mdn.mozillademos.org/files/5681/checked.png");
-	background-color: #379B4A;
-}
-
-body {
-	max-width: 1000px;
-	margin: 0 auto;
-
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-}
-
-#container {
-	width: 100%;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/*
- * Preview Area
- */
-
-#preview {
-	height: 500px;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-	text-align: center;
-	overflow: hidden;
-	position: relative;
-}
-
-#preview .content {
-	width: 100%;
-	height: 100%;
-	display: block;
-}
-
-#preview input {
-	color: #333;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-}
-
-#subject {
-	width: 400px;
-	height: 150px;
-	margin: 0 auto;
-	border: 3px solid #C60;
-	background: #FFF;
-	position: relative;
-}
-
-.radius {
-	width: 50%;
-	height: 50%;
-	border: 1px solid #CCC;
-	display: none;
-	position: absolute;
-	z-index: 1;
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-.handle {
-	width: 16px;
-	height: 16px;
-	position: absolute;
-	z-index: 2;
-}
-
-.handle-top-left {
-	top: -12px;
-	left: -12px;
-	cursor: se-resize;
-	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top left no-repeat;
-}
-
-.handle-top-right {
-	top: -12px;
-	right: -12px;
-	cursor: sw-resize;
-	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top right no-repeat;
-}
-
-.handle-bottom-right {
-	bottom: -12px;
-	right: -12px;
-	cursor: nw-resize;
-	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom right no-repeat;
-}
-
-.handle-bottom-left {
-	bottom: -12px;
-	left: -12px;
-	cursor: ne-resize;
-	background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom left no-repeat;
-}
-
-
-.radius-container {
-	position: absolute;
-	display : block;
-	z-index: 1;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-
-/* TOP LEFT */
-#top-left {
-	top: 0;
-	left: 0;
-}
-
-#top-left .radius {
-	border-top-left-radius: 100%;
-	top: 0;
-	left: 0;
-}
-
-/* TOP RIGHT */
-#top-right {
-	top: 0;
-	right: 0;
-}
-
-#top-right .radius {
-	border-top-right-radius: 100%;
-	top: 0;
-	right: 0;
-}
-
-/* BOTTOM RIGHT */
-#bottom-right {
-	bottom: 0;
-	right: 0;
-}
-
-#bottom-right .radius {
-	border-bottom-right-radius: 100%;
-	bottom: 0;
-	right: 0;
-}
-
-/* BOTTOM lEFT */
-#bottom-left {
-	bottom: 0;
-	left: 0;
-}
-
-#bottom-left .radius {
-	border-bottom-left-radius: 100%;
-	bottom: 0;
-}
-
-/* INPUT SLIDERS */
-
-#preview .ui-input-slider {
-	margin: 10px;
-	position: absolute;
-	z-index: 10;
-}
-
-#radius-ui-sliders {
-	width: 100%;
-	height: 100%;
-	min-height: 75px;
-	min-width: 150px;
-	padding: 20px 50px;
-	top: -20px;
-	left: -50px;
-	position: relative;
-}
-
-#tlr {
-	top: -30px;
-	left: -50px;
-	display: none;
-}
-
-#tlw {
-	top: -30px;
-	left: 30px;
-}
-
-#tlh {
-	top: 20px;
-	left: -50px;
-}
-
-#trr {
-	top: -30px;
-	right: -50px;
-	display: none;
-}
-
-#trw {
-	top: -30px;
-	right: 30px;
-}
-
-#trh {
-	top: 20px;
-	right: -50px;
-}
-
-#brr {
-	bottom: -30px;
-	right: -50px;
-	display: none;
-}
-
-#brw {
-	bottom: -30px;
-	right: 30px;
-}
-
-#brh {
-	bottom: 20px;
-	right: -50px;
-}
-
-#blr {
-	bottom: -30px;
-	left: -50px;
-	display: none;
-}
-
-#blw {
-	bottom: -30px;
-	left: 30px;
-}
-
-#blh {
-	bottom: 20px;
-	left: -50px;
-}
-
-#preview .ui-input-slider-left, #preview .ui-input-slider-right {
-	visibility: hidden;
-}
-
-#preview .ui-input-slider-container:hover .ui-input-slider-left {
-	visibility: visible;
-}
-
-#preview .ui-input-slider-container:hover .ui-input-slider-right {
-	visibility: visible;
-}
-
-/*
- *
- */
-
-#unit-selection {
-	width: 200px;
-	height: 75px;
-	margin: 30px 30px 0 0;
-	padding: 30px;
-	border: 3px solid #555;
-	border-radius: 10px;
-	position: relative;
-	float: right;
-}
-
-#unit-selection .info {
-	height: 20%;
-	width: 100%;
-	line-height: 20%;
-	font-size: 20px;
-	text-align: center;
-	position: relative;
-	top: 40%;
-}
-
-#unit-selection .dropdown {
-	width: 50px;
-	height: 20px;
-	margin: 10px;
-	padding: 0;
-	border-radius: 3px;
-	position: absolute;
-	overflow: hidden;
-}
-
-#unit-selection select {
-	width: 50px;
-	height: 20px;
-	marign: 0;
-	padding: 0 0 0 10px;
-	background: #555;
-	border: 1px solid #555;
-	border: none;
-	color: #FFF;
-	float: left;
-}
-
-#unit-selection select option {
-	background: #FFF;
-	color: #333;
-}
-
-#unit-selection select:hover {
-	cursor: pointer;
-}
-
-#unit-selection .dropdown:before {
-	content: "";
-	width: 18px;
-	height: 20px;
-	display: block;
-	background-color: #555;
-	background-image: url("https://mdn.mozillademos.org/files/5675/dropdown.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-	top: 0px;
-	right: 0px;
-	position: absolute;
-	z-index: 1;
-	pointer-events: none;
-}
-
-#unit-selection .unit-top-left {
-	top: 0;
-	left: 0;
-	display: none;
-}
-
-#unit-selection .unit-top-left-w {
-	top: -22px;
-	left: 30px;
-}
-
-#unit-selection .unit-top-left-h {
-	top: 20px;
-	left: -37px;
-}
-
-#unit-selection .unit-top-right {
-	top: 0;
-	right: 0;
-	display: none;
-}
-
-#unit-selection .unit-top-right-w {
-	top: -22px;
-	right: 30px;
-}
-
-#unit-selection .unit-top-right-h {
-	top: 20px;
-	right: -37px;
-}
-
-#unit-selection .unit-bottom-right {
-	bottom: 0;
-	right: 0;
-	display: none;
-}
-
-#unit-selection .unit-bottom-right-w {
-	bottom: -22px;
-	right: 30px;
-}
-
-#unit-selection .unit-bottom-right-h {
-	bottom: 20px;
-	right: -37px;
-}
-
-#unit-selection .unit-bottom-left {
-	bottom: 0;
-	left: 0;
-	display: none;
-}
-
-#unit-selection .unit-bottom-left-w {
-	bottom: -22px;
-	left: 30px;
-}
-
-#unit-selection .unit-bottom-left-h {
-	bottom: 20px;
-	left: -37px;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-
-
-#radius-lock {
-	width: 200px;
-	height: 75px;
-	margin: 30px 0 0 30px;
-	padding: 30px;
-	border: 3px solid #555;
-	border-radius: 10px;
-	position: relative;
-	float: left;
-}
-
-#radius-lock .ui-checkbox {
-	color: #FFF;
-	position: absolute;
-}
-
-#radius-lock .ui-checkbox > label {
-	height: 20px;
-	width: 34px;
-	padding: 0;
-}
-
-#radius-lock .info {
-	height: 20%;
-	width: 100%;
-	line-height: 20%;
-	font-size: 20px;
-	text-align: center;
-	position: relative;
-	top: 40%;
-}
-
-#radius-lock [data-topic="top-left"] {
-	top: 10px;
-	left: 10px;
-}
-
-#radius-lock [data-topic="top-right"] {
-	top: 10px;
-	right: 10px;
-}
-
-#radius-lock [data-topic="bottom-right"] {
-	bottom: 10px;
-	right: 10px;
-}
-
-#radius-lock [data-topic="bottom-left"] {
-	bottom: 10px;
-	left: 10px;
-}
-
-/**
- * Controls
- */
-
-#dimensions {
-	width: 200px;
-	color: #444;
-	float:left;
-}
-
-#dimensions input {
-	background: #555;
-	color: #FFF;
-	border: none;
-	border-radius: 3px;
-}
-
-#output {
-	width: 500px;
-	padding: 10px 0;
-	margin: 10px 0;
-	color: #555;
-	text-align: center;
-	border: 1px dashed #999;
-	border-radius: 3px;
-	-moz-user-select: text;
-	-webkit-user-select: text;
-	-ms-user-select: text;
-	user-select: text;
-
-	float: right;
-}
-
-
-
- -

JavaScript Content

- -
'use strict';
-
-
-/**
- * UI-InputSliderManager
- */
-
-var InputSliderManager = (function InputSliderManager() {
-
-	var subscribers = {};
-	var sliders = [];
-
-	var InputComponent = function InputComponent(obj) {
-		var input = document.createElement('input');
-		input.setAttribute('type', 'text');
-
-		input.addEventListener('click', function(e) {
-			this.select();
-		});
-
-		input.addEventListener('change', function(e) {
-			var value = parseInt(e.target.value);
-
-			if (isNaN(value) === true)
-				setValue(obj.topic, obj.value);
-			else
-				setValue(obj.topic, value);
-		});
-
-		subscribe(obj.topic, function(value) {
-			input.value = value + obj.unit;
-		});
-
-		return input;
-	}
-
-	var SliderComponent = function SliderComponent(obj, sign) {
-		var slider = document.createElement('div');
-		var startX = null;
-		var start_value = 0;
-
-		slider.addEventListener("click", function(e) {
-			setValue(obj.topic, obj.value + obj.step * sign);
-		});
-
-		slider.addEventListener("mousedown", function(e) {
-			startX = e.clientX;
-			start_value = obj.value;
-			document.body.style.cursor = "e-resize";
-			document.addEventListener("mousemove", sliderMotion);
-		});
-
-		document.addEventListener("mouseup", function(e) {
-			document.removeEventListener("mousemove", sliderMotion);
-			document.body.style.cursor = "auto";
-			slider.style.cursor = "pointer";
-		});
-
-		var sliderMotion = function sliderMotion(e) {
-			slider.style.cursor = "e-resize";
-			var delta = (e.clientX - startX) / obj.sensivity | 0;
-			var value = delta * obj.step + start_value;
-			setValue(obj.topic, value);
-		}
-
-		return slider;
-	}
-
-	var InputSlider = function(node) {
-		var min		= node.getAttribute('data-min') | 0;
-		var max		= node.getAttribute('data-max') | 0;
-		var step	= node.getAttribute('data-step') | 0;
-		var value	= node.getAttribute('data-value') | 0;
-		var topic	= node.getAttribute('data-topic');
-		var unit	= node.getAttribute('data-unit');
-		var name 	= node.getAttribute('data-info');
-		var sensivity = node.getAttribute('data-sensivity') | 0;
-
-		this.min = min;
-		this.max = max > 0 ? max : 100;
-		this.step = step === 0 ? 1 : step;
-		this.topic = topic;
-		this.node = node;
-		this.unit = unit;
-		this.sensivity = sensivity > 0 ? sensivity : 5;
-
-		var input = new InputComponent(this);
-		var slider_left  = new SliderComponent(this, -1);
-		var slider_right = new SliderComponent(this,  1);
-
-		slider_left.className = 'ui-input-slider-left';
-		slider_right.className = 'ui-input-slider-right';
-
-		if (name) {
-			var info = document.createElement('span');
-			info.className = 'ui-input-slider-info';
-			info.textContent = name;
-			node.appendChild(info);
-		}
-
-		node.appendChild(slider_left);
-		node.appendChild(input);
-		node.appendChild(slider_right);
-		node.className = 'ui-input-slider ui-input-slider-container';
-
-		this.input = input;
-		sliders[topic] = this;
-		setValue(topic, value);
-	}
-
-	var setValue = function setValue(topic, value, send_notify) {
-		var slider = sliders[topic];
-		if (slider === undefined)
-			return;
-
-		if (value > slider.max) value = slider.max;
-		if (value < slider.min)	value = slider.min;
-
-		slider.value = value;
-		slider.node.setAttribute('data-value', value);
-
-		if (send_notify !== undefined && send_notify === false) {
-			slider.input.value = value + slider.unit;
-			return;
-		}
-
-		notify.call(slider);
-	}
-
-	var setMax = function setMax(topic, value) {
-		var slider = sliders[topic];
-		if (slider === undefined)
-			return;
-
-		slider.max = value;
-		setValue(topic, slider.value);
-	}
-
-	var setMin = function setMin(topic, value) {
-		var slider = sliders[topic];
-		if (slider === undefined)
-			return;
-
-		slider.min = value;
-		setValue(topic, slider.value);
-	}
-
-	var setUnit = function setUnit(topic, unit) {
-		var slider = sliders[topic];
-		if (slider === undefined)
-			return;
-
-		slider.unit = unit;
-		setValue(topic, slider.value);
-	}
-
-	var getNode =  function getNode(topic) {
-		return sliders[topic].node;
-	}
-
-	var subscribe = function subscribe(topic, callback) {
-		if (subscribers[topic] === undefined)
-			subscribers[topic] = [];
-		subscribers[topic].push(callback);
-	}
-
-	var unsubscribe = function unsubscribe(topic, callback) {
-		subscribers[topic].indexOf(callback);
-		subscribers[topic].splice(index, 1);
-	}
-
-	var notify = function notify() {
-		for (var i in subscribers[this.topic]) {
-			subscribers[this.topic][i](this.value);
-		}
-	}
-
-	var init = function init() {
-		var elem = document.querySelectorAll('.ui-input-slider');
-		var size = elem.length;
-		for (var i = 0; i < size; i++)
-			new InputSlider(elem[i]);
-	}
-
-	return {
-		init : init,
-		setMax : setMax,
-		setMin : setMin,
-		setUnit : setUnit,
-		getNode : getNode,
-		setValue : setValue,
-		subscribe : subscribe,
-		unsubscribe : unsubscribe
-	}
-
-})();
-
-/**
- * UI-ButtonManager
- */
-
-var ButtonManager = (function CheckBoxManager() {
-
-	var subscribers = [];
-	var buttons = [];
-
-	var CheckBox = function CheckBox(node) {
-		var topic = node.getAttribute('data-topic');
-		var state = node.getAttribute('data-state');
-		var name = node.getAttribute('data-label');
-		var align = node.getAttribute('data-text-on');
-
-		state = (state === "true");
-
-		var checkbox = document.createElement("input");
-		var label = document.createElement("label");
-
-		var id = 'checkbox-' + topic;
-		checkbox.id = id;
-		checkbox.setAttribute('type', 'checkbox');
-		checkbox.checked = state;
-
-		label.setAttribute('for', id);
-		if (name) {
-			label.className = 'text';
-			if (align)
-				label.className += ' ' + align;
-			label.textContent = name;
-		}
-
-		node.appendChild(checkbox);
-		node.appendChild(label);
-
-		this.node = node;
-		this.topic = topic;
-		this.checkbox = checkbox;
-
-		checkbox.addEventListener('change', function(e) {
-			notify.call(this);
-		}.bind(this));
-
-		buttons[topic] = this;
-	}
-
-	var getNode =  function getNode(topic) {
-		return buttons[topic].node;
-	}
-
-	var setValue = function setValue(topic, value) {
-		try {
-			buttons[topic].checkbox.checked = value;
-		}
-		catch(error) {
-			console.log(error);
-		}
-	}
-
-	var subscribe = function subscribe(topic, callback) {
-		if (subscribers[topic] === undefined)
-			subscribers[topic] = [];
-
-		subscribers[topic].push(callback);
-	}
-
-	var unsubscribe = function unsubscribe(topic, callback) {
-		subscribers[topic].indexOf(callback);
-		subscribers[topic].splice(index, 1);
-	}
-
-	var notify = function notify() {
-		for (var i = 0; i < subscribers[this.topic].length; i++)
-			subscribers[this.topic][i](this.checkbox.checked);
-	}
-
-	var init = function init() {
-		var elem = document.querySelectorAll('.ui-checkbox');
-		var size = elem.length;
-		for (var i = 0; i < size; i++)
-			new CheckBox(elem[i]);
-	}
-
-	return {
-		init : init,
-		setValue : setValue,
-		subscribe : subscribe,
-		unsubscribe : unsubscribe
-	}
-
-})();
-
-
-window.addEventListener("load", function() {
-	BorderRadius.init();
-});
-
-var BorderRadius = (function BorderRadius() {
-
-	function getElemById(id) {
-		return document.getElementById(id);
-	}
-
-	/**
-	 * Shadow dragging
-	 */
-	var PreviewMouseTracking = (function Drag() {
-		var active = false;
-		var lastX = 0;
-		var lastY = 0;
-		var subscribers = [];
-
-		var init = function init(id) {
-			var elem = getElemById(id);
-			elem.addEventListener('mousedown', dragStart, false);
-			document.addEventListener('mouseup', dragEnd, false);
-		}
-
-		var dragStart = function dragStart(e) {
-			if (e.button !== 0)
-				return;
-
-			active = true;
-			lastX = e.clientX;
-			lastY = e.clientY;
-			document.addEventListener('mousemove', mouseDrag, false);
-		}
-
-		var dragEnd = function dragEnd(e) {
-			if (e.button !== 0)
-				return;
-
-			if (active === true) {
-				active = false;
-				document.removeEventListener('mousemove', mouseDrag, false);
-			}
-		}
-
-		var mouseDrag = function mouseDrag(e) {
-			notify(e.clientX - lastX, e.clientY - lastY);
-			lastX = e.clientX;
-			lastY = e.clientY;
-		}
-
-		var subscribe = function subscribe(callback) {
-			subscribers.push(callback);
-		}
-
-		var unsubscribe = function unsubscribe(callback) {
-			var index = subscribers.indexOf(callback);
-			subscribers.splice(index, 1);
-		}
-
-		var notify = function notify(deltaX, deltaY) {
-			for (var i in subscribers)
-				subscribers[i](deltaX, deltaY);
-		}
-
-		return {
-			init : init,
-			subscribe : subscribe,
-			unsubscribe : unsubscribe
-		}
-
-	})();
-
-	var subject;
-	var units = ['px', '%'];
-	var output = null;
-
-	var UnitSelector = function UnitSelector(topic) {
-
-		this.container = document.createElement("div");
-		this.select = document.createElement("select");
-		for (var i in units) {
-			var option = document.createElement("option");
-			option.value = i;
-			option.textContent = units[i];
-			this.select.appendChild(option);
-		}
-
-		this.container.className = 'dropdown ' + 'unit-' + topic;
-		this.container.appendChild(this.select);
-	}
-
-	UnitSelector.prototype.setValue = function setValue(value) {
-		this.salect.value = value;
-	}
-
-
-	var RadiusContainer = function RadiusContainer(node) {
-		var radius = document.createElement('div');
-		var handle = document.createElement('div');
-		var x = node.getAttribute('data-x');
-		var y = node.getAttribute('data-y');
-		var active = false;
-
-		this.id = node.id;
-		this.node = node;
-		this.radius = radius;
-		this.handle = handle;
-		this.width = 100;
-		this.height = 50;
-		this.size = 0;
-		this.rounded = false;
-
-		this.unitX = 0;
-		this.unitY = 0;
-		this.unitR = 0;
-
-		this.maxW = 100;
-		this.maxH = 100;
-		this.maxR = 100;
-
-		this.topic = y + '-' + x;
-
-		var sliderW = InputSliderManager.getNode(this.topic + '-w');
-		var sliderH = InputSliderManager.getNode(this.topic + '-h');
-		var sliderR = InputSliderManager.getNode(this.topic);
-
-		this.setUnitX(this.unitX);
-		this.setUnitY(this.unitY);
-		this.setUnitR(this.unitR);
-
-		this.updateWidth();
-		this.updateHeight();
-		this.updateRadius();
-
-		if (x === 'left')	this.resizeX =  1;
-		if (x === 'right')	this.resizeX = -1;
-		if (y === 'top')	this.resizeY =  1;
-		if (y === 'bottom')	this.resizeY = -1;
-
-		radius.className = 'radius';
-
-		var unit_selector = document.getElementById("unit-selection");
-		var unitW = new UnitSelector(this.topic + '-w');
-		var unitH = new UnitSelector(this.topic + '-h');
-		var unitR = new UnitSelector(this.topic);
-
-		unit_selector.appendChild(unitW.container);
-		unit_selector.appendChild(unitH.container);
-		unit_selector.appendChild(unitR.container);
-		node.appendChild(radius);
-		subject.appendChild(handle);
-
-		unitW.select.addEventListener('change', function(e) {
-			this.setUnitX(e.target.value | 0);
-		}.bind(this));
-
-		unitH.select.addEventListener('change', function(e) {
-			this.setUnitY(e.target.value | 0);
-		}.bind(this));
-
-		unitR.select.addEventListener('change', function(e) {
-			this.setUnitR(e.target.value | 0);
-		}.bind(this));
-
-		if (x === 'left' && y == 'top') handle.className = 'handle handle-top-left'
-		if (x === 'right' && y == 'top') handle.className = 'handle handle-top-right';
-		if (x === 'right' && y == 'bottom') handle.className = 'handle handle-bottom-right';
-		if (x === 'left' && y == 'bottom') 	handle.className = 'handle handle-bottom-left';
-
-		handle.addEventListener("mousedown", function(e) {
-			active = true;
-			this.radius.style.display = 'block';
-			PreviewMouseTracking.subscribe(this.updateContainer.bind(this));
-		}.bind(this));
-
-		document.addEventListener("mouseup", function(e) {
-			this.radius.style.display = 'none';
-			if (active === true)
-				PreviewMouseTracking.unsubscribe(this.updateContainer.bind(this));
-		}.bind(this));
-
-		InputSliderManager.subscribe(this.topic + '-w', this.setWidth.bind(this));
-		InputSliderManager.subscribe(this.topic + '-h', this.setHeight.bind(this));
-		InputSliderManager.subscribe(this.topic, this.setRadius.bind(this));
-
-		ButtonManager.subscribe(this.topic, function(value) {
-			this.rounded = value;
-			if (value === true) {
-				unitW.container.style.display = 'none';
-				unitH.container.style.display = 'none';
-				unitR.container.style.display = 'block';
-				sliderW.style.display = 'none';
-				sliderH.style.display = 'none';
-				sliderR.style.display = 'block';
-				this.setUnitR(this.unitR);
-				this.updateRadius();
-			}
-
-			if (value === false) {
-				unitW.container.style.display = 'block';
-				unitH.container.style.display = 'block';
-				unitR.container.style.display = 'none';
-				sliderW.style.display = 'block';
-				sliderH.style.display = 'block';
-				sliderR.style.display = 'none';
-				this.setUnitX(this.unitX);
-				this.setUnitY(this.unitY);
-				this.updateWidth();
-				this.updateHeight();
-			}
-
-			this.updateBorderRadius();
-
-		}.bind(this));
-
-		this.updateBorderRadius();
-	}
-
-	RadiusContainer.prototype.updateWidth = function updateWidth() {
-		this.node.style.width = this.width + units[this.unitX];
-		var value = Math.round(this.width / 2);
-		InputSliderManager.setValue(this.topic + '-w', value, false);
-	}
-
-	RadiusContainer.prototype.updateHeight = function updateHeight() {
-		this.node.style.height = this.height + units[this.unitY];
-		var value = Math.round(this.height / 2);
-		InputSliderManager.setValue(this.topic + '-h', value, false);
-	}
-
-	RadiusContainer.prototype.updateRadius = function updateRadius() {
-		var value = Math.round(this.size / 2);
-		this.node.style.width = this.size + units[this.unitR];
-		this.node.style.height = this.size + units[this.unitR];
-		InputSliderManager.setValue(this.topic, value, false);
-	}
-
-	RadiusContainer.prototype.setWidth = function setWidth(value) {
-		this.radius.style.display = 'block';
-		this.width = 2 * value;
-		this.node.style.width = this.width + units[this.unitX];
-		this.updateBorderRadius();
-	}
-
-	RadiusContainer.prototype.setHeight = function setHeight(value) {
-		this.radius.style.display = 'block';
-		this.height = 2 * value;
-		this.node.style.height = this.height + units[this.unitY];
-		this.updateBorderRadius();
-	}
-
-	RadiusContainer.prototype.setRadius = function setRadius(value) {
-		this.radius.style.display = 'block';
-		this.size = 2 * value;
-		this.node.style.width = this.size + units[this.unitR];
-		this.node.style.height = this.size + units[this.unitR];
-		this.updateBorderRadius();
-	}
-
-	RadiusContainer.prototype.setUnitX = function setUnitX(value) {
-		this.unitX = value;
-		if (this.unitX === 0) this.maxW = 2 * subject.clientWidth;
-		if (this.unitX === 1) this.maxW = 200;
-		InputSliderManager.setUnit(this.topic + '-w', units[this.unitX]);
-		InputSliderManager.setMax(this.topic + '-w', this.maxW / 2);
-	}
-
-	RadiusContainer.prototype.setUnitY = function setUnitY(value) {
-		this.unitY = value;
-		if (this.unitY === 0) this.maxH = 2 * subject.clientHeight;
-		if (this.unitY === 1) this.maxH = 200;
-		InputSliderManager.setUnit(this.topic + '-h', units[this.unitY]);
-		InputSliderManager.setMax(this.topic + '-h', this.maxH / 2);
-	}
-
-	RadiusContainer.prototype.setUnitR = function setUnitR(value) {
-		this.unitR = value;
-
-		if (this.unitR === 0)
-			this.maxR = 2 * Math.min(subject.clientHeight , subject.clientWidth);
-
-		if (this.unitR === 1)
-			this.maxR = 200;
-
-		InputSliderManager.setUnit(this.topic, units[this.unitR]);
-		InputSliderManager.setMax(this.topic, this.maxR / 2);
-	}
-
-	RadiusContainer.prototype.updateUnits = function updateUnits(unit) {
-		if (this.rounded) {
-			this.setUnitR(this.unitR);
-			return;
-		}
-
-		if (unit === 0)
-			this.setUnitX(this.unitX);
-
-		if (unit === 1)
-			this.setUnitY(this.unitY);
-	}
-
-	RadiusContainer.prototype.composeBorderRadius = function composeBorderRadius () {
-
-		if (this.rounded === true) {
-			var unit = units[this.unitR];
-			var value = Math.round(this.size / 2);
-			return value + unit;
-		}
-
-		var unitX = units[this.unitX];
-		var unitY = units[this.unitY];
-		var valueX = Math.round(this.width / 2);
-		var valueY = Math.round(this.height / 2);
-
-		if (valueX === valueY && this.unitX === this.unitY)
-			return valueX + unitX;
-
-		return valueX + unitX + ' ' + valueY + unitY;
-	}
-
-	RadiusContainer.prototype.updateBorderRadius = function updateBorderRadius () {
-		var radius = this.composeBorderRadius();
-		var corner = 0;
-
-		if (this.topic === 'top-left') {
-			subject.style.borderTopLeftRadius = radius;
-			corner = 0;
-		}
-
-		if (this.topic === 'top-right') {
-			subject.style.borderTopRightRadius = radius;
-			corner = 1;
-		}
-
-		if (this.topic === 'bottom-right') {
-			subject.style.borderBottomRightRadius = radius;
-			corner = 2;
-		}
-
-		if (this.topic === 'bottom-left') {
-			subject.style.borderBottomLeftRadius = radius;
-			corner = 3;
-		}
-
-		Tool.updateOutput(corner, radius);
-	}
-
-	RadiusContainer.prototype.updateContainer = function updateContainer(deltaX, deltaY) {
-
-		if (this.rounded === true) {
-			this.size += this.resizeX * deltaX + this.resizeY * deltaY;
-			if (this.size < 0)	this.size = 0;
-			if (this.size > this.maxR)	this.size = this.maxR;
-			this.updateRadius();
-			this.updateBorderRadius();
-			return;
-		}
-
-		if (deltaX) {
-			this.width += this.resizeX * deltaX;
-			if (this.width < 0)	this.width = 0;
-			if (this.width > this.maxW)	this.width = this.maxW;
-			this.updateWidth();
-		}
-
-		if (deltaY) {
-			this.height += this.resizeY * deltaY;
-			if (this.height < 0) this.height = 0;
-			if (this.height > this.maxH)	this.height = this.maxH;
-			this.updateHeight();
-		}
-
-		if (deltaX || deltaY)
-			this.updateBorderRadius();
-	}
-
-
-	/**
-	 * Tool Manager
-	 */
-	var Tool = (function Tool() {
-		var preview;
-		var preview_ui;
-		var radius_containers = [];
-		var border_width = 3;
-		var borders1 = [null, null, null, null];
-		var borders2 = [0, 0, 0, 0];
-
-		var updateUIWidth = function updateUIWidth(value) {
-			var pwidth = subject.parentElement.clientWidth;
-			var left = (pwidth - value) / 2;
-			subject.style.width = value + "px";
-
-			for (var i = 0; i < 4; i++)
-				radius_containers[i].updateUnits(0);
-		}
-
-		var updateUIHeight = function updateUIHeight(value) {
-			var pheight = subject.parentElement.clientHeight;
-			var top = (pheight - value) / 2;
-			subject.style.height = value + "px";
-			subject.style.top = top - border_width + "px";
-
-			for (var i = 0; i < 4; i++)
-				radius_containers[i].updateUnits(1);
-		}
-
-		var updatePreviewUIWidth = function updatePreviewUIWidth() {
-			var p = subject.parentElement.clientWidth;
-			var v = preview_ui.clientWidth;
-			console.log(p, v, (p - v ) / 2);
-			preview_ui.style.left = (p - v) / 2 + "px" ;
-		}
-
-		var updatePreviewUIHeight = function updatePreviewUIHeight() {
-			var p = subject.parentElement.clientHeight;
-			var v = preview_ui.clientHeight;
-			console.log(p, v, (p - v ) / 2);
-			preview_ui.style.top = (p - v) / 2 + "px" ;
-		}
-
-		var updateOutput = function updateOutput(corner, radius) {
-			var values = radius.split(" ");
-
-			borders1[corner] = values[0];
-			borders2[corner] = values[0];
-
-			if (values.length === 2)
-				borders2[corner] = values[1];
-
-			var border_1_value = borders1.join(" ");
-			var border_2_value = borders2.join(" ");
-			var border_radius = 'border-radius: ' + border_1_value;
-
-			if (border_2_value !== border_1_value)
-				border_radius += ' / ' + border_2_value;
-
-			border_radius += ';';
-			output.textContent = border_radius;
-		}
-
-		var init = function init() {
-			preview = getElemById("preview");
-			subject = getElemById("subject");
-			output = getElemById("output");
-			preview_ui = getElemById("radius-ui-sliders");
-
-			var elem = document.querySelectorAll('.radius-container');
-			var size = elem.length;
-			for (var i = 0; i < size; i++)
-				radius_containers[i] = new RadiusContainer(elem[i]);
-
-			InputSliderManager.subscribe("width", updateUIWidth);
-			InputSliderManager.subscribe("height", updateUIHeight);
-
-			InputSliderManager.setValue("width", subject.clientWidth);
-			InputSliderManager.setValue("height", subject.clientHeight);
-		}
-
-		return {
-			init : init,
-			updateOutput : updateOutput
-		}
-
-	})();
-
-	/**
-	 * Init Tool
-	 */
-	var init = function init() {
-		ButtonManager.init();
-		InputSliderManager.init();
-		PreviewMouseTracking.init("preview");
-		Tool.init();
-	}
-
-	return {
-		init : init
-	}
-
-})();
-
-
-
-
- -

{{ EmbedLiveSample('border-radius-generator', '100%', '800px', '') }}

- -

 

diff --git a/files/ru/web/css/css_background_and_borders/box-shadow_generator/index.html b/files/ru/web/css/css_background_and_borders/box-shadow_generator/index.html new file mode 100644 index 0000000000..3f46cf53ba --- /dev/null +++ b/files/ru/web/css/css_background_and_borders/box-shadow_generator/index.html @@ -0,0 +1,2884 @@ +--- +title: Генератор теней +slug: Web/CSS/CSS_Box_Model/Box-shadow_generator +tags: + - CSS3 + - Тень + - инструменты +translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator +--- +

Этот инструмент позволяет вам создавать CSS {{cssxref("box-shadow")}} эффекты, добавлять тени вашим элементам.

+ +
+

Генератор box-shadow generator

+ +

HTML Content

+ +
<div id="container">
+    <div class="group section">
+        <div id="layer_manager">
+            <div class="group section">
+                <div class="button" data-type="add"> </div>
+                <div class="button" data-type="move-up"> </div>
+                <div class="button" data-type="move-down"> </div>
+            </div>
+            <div id="stack_container"></div>
+        </div>
+
+        <div id="preview_zone">
+            <div id="layer_menu" class="col span_12">
+                <div class="button" id="element" data-type="subject" data-title="element"> элементы </div>
+                <div class="button" id="before" data-type="subject" data-title=":before">
+                    :before
+                    <span class="delete" data-type="disable"></span>
+                </div>
+                <div class="button" id="after" data-type="subject" data-title=":after">
+                    :after
+                    <span class="delete" data-type="disable"></span>
+                </div>
+                <div class="ui-checkbox" data-topic='before' data-label=":before"></div>
+                <div class="ui-checkbox" data-topic='after' data-label=":after"></div>
+            </div>
+
+            <div id="preview">
+                <div id="obj-element">
+                    <div class="content"> </div>
+                    <div id="obj-before"> </div>
+                    <div id="obj-after"> </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div id="controls" class="group section">
+        <div class="wrap-left">
+            <div class="colorpicker category">
+                <div class="title"> </div>
+                <div id="colorpicker" class="group">
+                    <div id="gradient" class="gradient">
+                        <div id="gradient_picker"> </div>
+                    </div>
+                    <div id="hue" data-topic="hue" class="hue">
+                        <div id="hue_selector"> </div>
+                    </div>
+                    <div class="info">
+                        <div class="input" data-topic="hue" data-title='H:' data-action="HSV"></div>
+                        <div class="input" data-topic="saturation" data-title='S:' data-action="HSV"></div>
+                        <div class="input" data-topic="value" data-title='V:' data-action="HSV"></div>
+                    </div>
+                    <div class="alpha">
+                        <div id="alpha" data-topic="alpha">
+                            <div id="alpha_selector"> </div>
+                        </div>
+                    </div>
+                    <div class="info">
+                        <div class="input" data-topic="r" data-title='R:' data-action="RGB"></div>
+                        <div class="input" data-topic="g" data-title='G:' data-action="RGB"></div>
+                        <div class="input" data-topic="b" data-title='B:' data-action="RGB"></div>
+                    </div>
+                    <div class="preview block">
+                        <div id="output_color"> </div>
+                    </div>
+                    <div class="block info">
+                        <div class="input" data-topic="a" data-title='alpha:' data-action="alpha"></div>
+                        <div class="input" data-topic="hexa" data-title='' data-action="hexa"></div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div class="wrap-right">
+
+            <div id="shadow_properties" class="category">
+                <div class="title"> Shadow properties </div>
+                <div class="group">
+                    <div class="group property">
+                        <div class="ui-slider-name"> inset </div>
+                        <div class="ui-checkbox" data-topic='inset'></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Position x </div>
+                        <div class="ui-slider-btn-set" data-topic="posX" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="posX"
+                            data-min="-500" data-max="500" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="posX" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="posX" data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Position y </div>
+                        <div class="ui-slider-btn-set" data-topic="posY" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="posY"
+                            data-min="-500" data-max="500" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="posY" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="posY" data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Blur </div>
+                        <div class="ui-slider-btn-set" data-topic="blur" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="blur"
+                            data-min="0" data-max="200" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="blur" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="blur" data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Spread </div>
+                        <div class="ui-slider-btn-set" data-topic="spread" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="spread"
+                            data-min="-100"    data-max="100" data-step="1" data-value="50">
+                        </div>
+                        <div class="ui-slider-btn-set" data-topic="spread" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="spread" data-unit="px"></div>
+                    </div>
+                </div>
+            </div>
+
+            <div id="element_properties" class="category">
+                <div class="title"> Параметры элемента</div>
+                <div class="group">
+                    <div class="group property">
+                        <div class="ui-slider-name"> border </div>
+                        <div class="ui-checkbox" data-topic='border-state' data-state="true"></div>
+                    </div>
+                    <div id="z-index" class="slidergroup">
+                        <div class="ui-slider-name"> z-index </div>
+                        <div class="ui-slider-btn-set" data-topic="z-index" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="z-index"
+                            data-min="-10" data-max="10" data-step="1"></div>
+                        <div class="ui-slider-btn-set" data-topic="z-index" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="z-index"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> top </div>
+                        <div class="ui-slider-btn-set" data-topic="top" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="top"
+                            data-min="-500" data-max="500" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="top" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="top" data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> left </div>
+                        <div class="ui-slider-btn-set" data-topic="left" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="left"
+                            data-min="-300" data-max="700" data-step="1"> </div>
+                        <div class="ui-slider-btn-set" data-topic="left" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="left" data-unit="px"></div>
+                    </div>
+                    <div id="transform_rotate" class="slidergroup">
+                        <div class="ui-slider-name"> Rotate </div>
+                        <div class="ui-slider-btn-set" data-topic="rotate" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="rotate"
+                            data-min="-360" data-max="360" data-step="1" data-value="0">
+                        </div>
+                        <div class="ui-slider-btn-set" data-topic="rotate" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="rotate" data-unit="deg"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Width </div>
+                        <div class="ui-slider-btn-set" data-topic="width" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="width"
+                            data-min="0" data-max="1000" data-step="1" data-value="200">
+                        </div>
+                        <div class="ui-slider-btn-set" data-topic="width" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="width"  data-unit="px"></div>
+                    </div>
+                    <div class="slidergroup">
+                        <div class="ui-slider-name"> Height </div>
+                        <div class="ui-slider-btn-set" data-topic="height" data-type="sub"></div>
+                        <div class="ui-slider" data-topic="height"
+                            data-min="0" data-max="400" data-step="1" data-value="200">
+                        </div>
+                        <div class="ui-slider-btn-set" data-topic="height" data-type="add"></div>
+                        <div class="ui-slider-input" data-topic="height" data-unit="px"></div>
+                    </div>
+                </div>
+            </div>
+
+            <div id="output" class="category">
+                <div id="menu" class="menu"></div>
+                <div class="title">    CSS-код </div>
+                <div class="group" style="border-top-left-radius: 0;">
+                    <div class="output" data-topic="element" data-name="element"
+                        data-prop="width height background-color position=[relative] box-shadow">
+                    </div>
+                    <div class="output" data-topic="before" data-name="element:before"
+                        data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
+                    </div>
+                    <div class="output" data-topic="after" data-name="element:after"
+                        data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+ +

CSS Content

+ +
/*  GRID OF TWELVE
+ * ========================================================================== */
+
+.span_12 {
+	width: 100%;
+}
+
+.span_11 {
+	width: 91.46%;
+}
+
+.span_10 {
+	width: 83%;
+}
+
+.span_9 {
+	width: 74.54%;
+}
+
+.span_8 {
+	width: 66.08%;
+}
+
+.span_7 {
+	width: 57.62%;
+}
+
+.span_6 {
+	width: 49.16%;
+}
+
+.span_5 {
+	width: 40.7%;
+}
+
+.span_4 {
+	width: 32.24%;
+}
+
+.span_3 {
+	width: 23.78%;
+}
+
+.span_2 {
+	width: 15.32%;
+}
+
+.span_1 {
+	width: 6.86%;
+}
+
+
+/*  SECTIONS
+ * ========================================================================== */
+
+.section {
+	clear: both;
+	padding: 0px;
+	margin: 0px;
+}
+
+/*  GROUPING
+ * ========================================================================== */
+
+
+.group:before, .group:after {
+    content: "";
+    display: table;
+}
+
+.group:after {
+    clear:both;
+}
+
+.group {
+    zoom: 1; /* For IE 6/7 (trigger hasLayout) */
+}
+
+/*  GRID COLUMN SETUP
+ * ========================================================================== */
+
+.col {
+	display: block;
+	float:left;
+	margin: 1% 0 1% 1.6%;
+}
+
+.col:first-child {
+	margin-left: 0;
+} /* all browsers except IE6 and lower */
+
+/*
+ * UI Slider
+ */
+
+.slidergroup {
+	height: 20px;
+	margin: 10px 0;
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+	-moz-user-select: none;
+	user-select: none;
+}
+
+.slidergroup * {
+	float: left;
+	height: 100%;
+	line-height: 100%;
+}
+
+/* Slider */
+
+.ui-slider {
+	height: 10px;
+	width: 200px;
+	margin: 4px 10px;
+	display: block;
+	border: 1px solid #999;
+	border-radius: 3px;
+	background: #EEE;
+}
+
+.ui-slider:hover {
+	cursor: pointer;
+}
+
+.ui-slider-name {
+	width: 90px;
+	padding: 0 10px 0 0;
+	text-align: right;
+	text-transform: lowercase;
+}
+
+.ui-slider-pointer {
+	width: 13px;
+	height: 13px;
+	background-color: #EEE;
+	border: 1px solid #2C9FC9;
+	border-radius: 3px;
+	position: relative;
+	top: -3px;
+	left: 0%;
+}
+
+.ui-slider-btn-set {
+	width: 25px;
+	background-color: #2C9FC9;
+	border-radius: 3px;
+	color: #FFF;
+	font-weight: bold;
+	text-align: center;
+}
+
+.ui-slider-btn-set:hover {
+	background-color: #379B4A;
+	cursor: pointer;
+}
+
+.ui-slider-input > input {
+	margin: 0 10px;
+	padding: 0;
+	width: 50px;
+	text-align: center;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+/*
+ * UI Button
+ */
+
+/* Checkbox */
+
+.ui-checkbox {
+	text-align: center;
+	font-size: 16px;
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+	line-height: 1.5em;
+	color: #FFF;
+
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.ui-checkbox > input {
+ 	display: none;
+}
+
+.ui-checkbox > label {
+	font-size: 12px;
+	padding: 0.333em 1.666em 0.5em;
+	height: 1em;
+	line-height: 1em;
+
+	background-color: #888;
+	background-image: url("https://mdn.mozillademos.org/files/5683/disabled.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+
+	color: #FFF;
+	border-radius: 3px;
+	font-weight: bold;
+	float: left;
+}
+
+.ui-checkbox .text {
+	padding-left: 34px;
+	background-position: center left 10px;
+}
+
+.ui-checkbox .left {
+	padding-right: 34px;
+	padding-left: 1.666em;
+	background-position: center right 10px;
+}
+
+.ui-checkbox > label:hover {
+	cursor: pointer;
+}
+
+.ui-checkbox > input:checked + label {
+	background-image: url("https://mdn.mozillademos.org/files/5681/checked.png");
+	background-color: #379B4A;
+}
+
+/*
+ * BOX SHADOW GENERATOR TOOL
+ */
+
+body {
+	max-width: 1000px;
+	height: 800px;
+	margin: 20px auto 0;
+
+	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+}
+
+#container {
+	width: 100%;
+	padding: 2px;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+
+/* container with shadows stacks */
+#stack_container {
+	height: 400px;
+	overflow: hidden;
+	position: relative;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#stack_container .container {
+	height: 100%;
+	width: 100%;
+	position: absolute;
+	left: 100%;
+	transition-property: left;
+	transition-duration: 0.5s;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+
+#stack_container .title {
+	text-align: center;
+	font-weight: bold;
+	line-height: 2em;
+	border-bottom: 1px solid #43A6E1;
+	color: #666;
+}
+
+
+/*
+ * Stack of Layers for shadow
+ */
+
+#layer_manager {
+	width: 17%;
+	background-color: #FEFEFE;
+	margin: 0 1% 0 0;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	float: left;
+}
+
+
+#layer_manager .button {
+	width: 30%;
+	height: 25px;
+	margin:0 0 10px;
+	color: #333;
+	background-color: #EEE;
+	text-align: center;
+	font-size: 0.75em;
+	line-height: 1.5em;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+
+	display: block;
+	background-position: center center;
+	background-repeat: no-repeat;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	float: left;
+}
+
+#layer_manager .button:hover {
+	background-color: #3380C4;
+	border: 1px solid #3380C4;
+	cursor: pointer;
+}
+
+#layer_manager [data-type='add'] {
+	background-image: url("https://mdn.mozillademos.org/files/5685/add-black.png");
+}
+
+#layer_manager [data-type='add']:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5687/add-white.png");
+}
+
+#layer_manager [data-type='move-up'] {
+	background-image: url("https://mdn.mozillademos.org/files/5697/up-black.png");
+	margin-left: 5%;
+	margin-right: 5%;
+}
+
+#layer_manager [data-type='move-up']:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5709/up-white.png");
+}
+
+#layer_manager [data-type='move-down'] {
+	background-image: url("https://mdn.mozillademos.org/files/5693/down-black.png");
+}
+
+#layer_manager [data-type='move-down']:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5695/down-white.png");
+}
+
+/* shadows classes */
+
+#layer_manager .node {
+	width: 100%;
+	margin: 5px 0;
+	padding: 5px;
+	text-align: center;
+	background-color: #EEE;
+	border: 1px solid #DDD;
+	font-size: 0.75em;
+	line-height: 1.5em;
+	color: #333;
+	border-radius: 3px;
+
+	position: relative;
+	display: block;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#layer_manager .node:hover {
+	color: #FFF;
+	background-color: #3380C4;
+	cursor: pointer;
+}
+
+/* active element styling */
+
+#layer_manager [data-active='layer'] {
+	color: #FFF;
+	border: none;
+	background-color: #379B4A;
+}
+
+#layer_manager [data-active='subject'] {
+	color: #FFF;
+	background-color: #467FC9;
+}
+
+/* delete button */
+
+#layer_manager .delete {
+	width: 1.5em;
+	height: 100%;
+	float: right;
+	border-radius: 3px;
+	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+	position: absolute;
+	top: 0;
+	right: 10px;
+	display: none;
+}
+
+#layer_manager .delete:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
+}
+
+#layer_manager .node:hover .delete {
+	display: block;
+}
+
+
+#layer_manager .stack {
+	padding: 0 5px;
+	max-height: 90%;
+	overflow: auto;
+	overflow-x: hidden;
+}
+
+
+/*
+ * Layer Menu
+ */
+
+#layer_menu {
+	margin: 0 0 10px 0;
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#layer_menu .button {
+	width: 100px;
+	margin: 0 5px 0 0;
+	padding: 2.5px;
+	color: #333;
+	background-color: #EEE;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+	text-align: center;
+	font-size: 0.75em;
+	line-height: 1.5em;
+
+	position: relative;
+	display: block;
+	float: left;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#layer_menu .button:hover {
+	color: #FFF;
+	background-color: #3380C4;
+	border: 1px solid #3380C4;
+	cursor: pointer;
+}
+
+#layer_menu .delete {
+	width: 1.5em;
+	height: 100%;
+	float: right;
+	border-radius: 3px;
+	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
+	background-position: center center;
+	background-repeat: no-repeat;
+	position: absolute;
+	top: 0;
+	right: 5px;
+	display: none;
+}
+
+#layer_menu .delete:hover {
+	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
+}
+
+#layer_menu .button:hover .delete {
+	display: block;
+}
+
+
+/*
+ * active element styling
+ */
+
+#layer_menu [data-active='subject'] {
+	color: #FFF;
+	background-color: #379B4A;
+	border: 1px solid #379B4A;
+}
+
+
+/* Checkbox */
+
+#layer_menu .ui-checkbox > label {
+	height: 15px;
+	line-height: 17px;
+	font-weight: normal;
+	width: 46px;
+	margin: 0 5px 0 0;
+}
+
+#layer_menu .ui-checkbox > input:checked + label {
+	display: none;
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+/*
+ * Preview Area
+ */
+
+#preview_zone {
+	width: 82%;
+	float: left;
+
+}
+
+
+#preview {
+	width: 100%;
+	height: 400px;
+	border: 1px solid #CCC;
+	border-radius: 3px;
+	text-align: center;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	cursor: move;
+	float: left;
+}
+
+#preview .content {
+	width: 100%;
+	height: 100%;
+	display: block;
+}
+
+#obj-element {
+	width: 300px;
+	height: 100px;
+	border: 1px solid #CCC;
+	background: #FFF;
+	position: relative;
+}
+
+
+#obj-before {
+	height: 100%;
+	width: 100%;
+	background: #999;
+	border: 1px solid #CCC;
+	text-align: left;
+	display : block;
+	position: absolute;
+	z-index: -1;
+}
+
+#obj-after {
+	height: 100%;
+	width: 100%;
+	background: #DDD;
+	border: 1px solid #CCC;
+	text-align: right;
+	display : block;
+	position: absolute;
+	z-index: -1;
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+
+/**
+ * Controls
+ */
+
+.wrap-left {
+	float: left;
+	overflow: hidden;
+}
+
+.wrap-right {
+	float: right;
+	overflow: hidden;
+}
+
+.wrap-left > * {
+	float: left;
+}
+
+.wrap-right > * {
+	float: right;
+}
+
+@media (min-width: 960px) {
+
+	.wrap-left {
+		width: 45%;
+	}
+
+	.wrap-right {
+		width: 55%;
+	}
+}
+
+
+@media (max-width: 959px) {
+
+	.wrap-left {
+		width: 30%;
+	}
+
+	.wrap-right {
+		width: 70%;
+	}
+}
+
+
+#controls {
+	color: #444;
+	margin: 10px 0 0 0;
+}
+
+
+#controls .category {
+	width: 500px;
+	margin: 0 auto 20px;
+	padding: 0;
+
+}
+
+#controls .category .title {
+	width: 100%;
+	height: 1.5em;
+	line-height: 1.5em;
+	color: #AAA;
+	text-align: right;
+}
+
+#controls .category > .group {
+	border: 1px solid #CCC;
+	border-radius: 3px;
+}
+
+
+/**
+ * 	Color Picker
+ */
+
+@media (min-width: 960px) {
+	#controls .colorpicker {
+		width: 420px;
+	}
+}
+
+@media (max-width: 959px) {
+	#controls .colorpicker {
+		width: 210px;
+	}
+}
+
+#colorpicker {
+	width: 100%;
+	margin: 0 auto;
+}
+
+#colorpicker .gradient {
+	width: 200px;
+	height: 200px;
+	margin: 5px;
+	background: url("https://mdn.mozillademos.org/files/5707/picker_mask_200.png");
+	background: -moz-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
+				-moz-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
+	background: -webkit-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
+				-webkit-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
+	background-color: #F00;
+	float: left;
+}
+
+#colorpicker .hue {
+	width: 200px;
+	height: 30px;
+	margin: 5px;
+	background: url("https://mdn.mozillademos.org/files/5701/hue.png");
+	background: -moz-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
+				#00F 66.66%, #F0F 83.33%, #F00 100%);
+	background: -webkit-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
+				#00F 66.66%, #F0F 83.33%, #F00 100%);
+	float: left;
+}
+
+#colorpicker .alpha {
+	width: 200px;
+	height: 30px;
+	margin: 5px;
+	border: 1px solid #CCC;
+	float: left;
+	background: url("https://mdn.mozillademos.org/files/5705/alpha.png");
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#colorpicker #alpha {
+	width: 100%;
+	height: 100%;
+	background: url("https://mdn.mozillademos.org/files/5703/alpha_mask.png");
+	background: -moz-linear-gradient(left, rgba(255, 0, 0, 0) 0%, rgba(255, 0, 0, 1) 100%);
+}
+
+#colorpicker #gradient_picker {
+	width: 0.5em;
+	height: 0.5em;
+	border-radius: 0.4em;
+	border: 2px solid #CCC;
+	position: relative;
+	top: 20%;
+	left: 20%;
+}
+
+#colorpicker #hue_selector,
+#colorpicker #alpha_selector {
+	width: 3px;
+	height: 100%;
+	border: 1px solid #777;
+	background-color: #FFF;
+	position: relative;
+	top: -1px;
+	left: 0%;
+}
+
+/* input HSV and RGB */
+#colorpicker .info {
+	width: 200px;
+	margin: 5px;
+	float: left;
+}
+
+#colorpicker .info * {
+	float: left;
+}
+
+#colorpicker .info input {
+	margin: 0;
+	text-align: center;
+	width: 30px;
+	-moz-user-select: text;
+	-webkit-user-select: text;
+	-ms-user-select: text;
+}
+
+#colorpicker .info span {
+	height: 20px;
+	width: 30px;
+	text-align: center;
+	line-height: 20px;
+	display: block;
+}
+
+/* Preview color */
+#colorpicker .block {
+	width: 95px;
+	height: 54px;
+	float: left;
+	position: relative;
+}
+
+#colorpicker .preview {
+	margin: 5px;
+	border: 1px solid #CCC;
+	background-image: url("https://mdn.mozillademos.org/files/5705/alpha.png");
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+#colorpicker .preview:before {
+	height: 100%;
+	width: 50%;
+	left: 50%;
+	content: "";
+	background: #FFF;
+	position: absolute;
+	z-index: 1;
+}
+
+#colorpicker .preview > * {
+	width: 50%;
+	height: 100%;
+}
+
+#colorpicker #output_color {
+	width: 100%;
+	height: 100%;
+	position: absolute;
+	z-index: 2;
+}
+
+#colorpicker .block .input {
+	float: right;
+}
+
+#colorpicker [data-topic="a"] > span {
+	width: 50px;
+}
+
+#colorpicker [data-topic="hexa"] {
+	float: right;
+	margin: 10px 0 0 0;
+}
+
+#colorpicker [data-topic="hexa"] > span {
+	display: none;
+}
+
+#colorpicker [data-topic="hexa"] > input {
+	width: 85px;
+	padding: 2px 0;
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+
+/*
+ * UI Components
+ */
+
+/* Property */
+
+.property {
+	height: 20px;
+	margin: 10px 0;
+}
+
+.property * {
+	float: left;
+	height: 100%;
+	line-height: 100%;
+}
+
+/* Slider */
+
+#controls .ui-slider-name {
+	margin: 0 10px 0 0;
+}
+
+/*
+ * Output code styling
+ */
+
+#output {
+	position: relative;
+}
+
+#output .menu {
+	max-width: 70%;
+	height: 20px;
+	position: absolute;
+	top: 2px;
+}
+
+#output .button {
+	width: 90px;
+	height: 22px;
+	margin: 0 5px 0 0;
+	text-align: center;
+	line-height: 20px;
+	font-size: 14px;
+	color: #FFF;
+	background-color: #999;
+	border-top-left-radius: 3px;
+	border-top-right-radius: 3px;
+	bottom: -5px;
+	float:left;
+}
+
+#output .button:hover {
+	color: #FFF;
+	background-color: #666;
+	cursor: pointer;
+}
+
+#output .menu [data-active="true"] {
+	color: #777;
+	background-color: #FFF;
+	border: 1px solid #CCC;
+	border-bottom: none;
+}
+
+#output .menu [data-topic="before"] {
+	left: 100px;
+}
+
+#output .menu [data-topic="after"] {
+	left: 200px;
+}
+
+#output .output {
+	width: 480px;
+	margin: 10px;
+	padding: 10px;
+	overflow: hidden;
+	color: #555;
+	font-size: 14px;
+	border: 1px dashed #CCC;
+	border-radius: 3px;
+	display: none;
+
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+
+	-moz-user-select: text;
+	-webkit-user-select: text;
+	-ms-user-select: text;
+}
+
+#output .css-property {
+	width: 100%;
+	float: left;
+	white-space: pre;
+}
+
+#output .name {
+	width: 35%;
+	float: left;
+}
+
+#output .value {
+	width: 65%;
+	float: left;
+}
+
+
+ +

JavaScript Content

+ +

+
+'use strict';
+
+/**
+ * UI-SlidersManager
+ */
+
+var SliderManager = (function SliderManager() {
+
+	var subscribers = {};
+	var sliders = [];
+
+	var Slider = function(node) {
+		var min = node.getAttribute('data-min') | 0;
+		var max = node.getAttribute('data-max') | 0;
+		var step = node.getAttribute('data-step') | 0;
+		var value = node.getAttribute('data-value') | 0;
+		var snap = node.getAttribute('data-snap');
+		var topic = node.getAttribute('data-topic');
+
+		this.min = min;
+		this.max = max > 0 ? max : 100;
+		this.step = step === 0 ? 1 : step;
+		this.value = value <= max && value >= min ? value : (min + max) / 2 | 0;
+		this.snap = snap === "true" ? true : false;
+		this.topic = topic;
+		this.node = node;
+
+		var pointer = document.createElement('div');
+		pointer.className = 'ui-slider-pointer';
+		node.appendChild(pointer);
+		this.pointer = pointer;
+
+		setMouseTracking(node, updateSlider.bind(this));
+
+		sliders[topic] = this;
+		setValue(topic, this.value);
+	}
+
+	var setButtonComponent = function setButtonComponent(node) {
+		var type = node.getAttribute('data-type');
+		var topic = node.getAttribute('data-topic');
+		if (type === "sub") {
+			node.textContent = '-';
+			node.addEventListener("click", function() {
+				decrement(topic);
+			});
+		}
+		if (type === "add") {
+			node.textContent = '+';
+			node.addEventListener("click", function() {
+				increment(topic);
+			});
+		}
+	}
+
+	var setInputComponent = function setInputComponent(node) {
+		var topic		= node.getAttribute('data-topic');
+		var unit_type	= node.getAttribute('data-unit');
+
+		var input = document.createElement('input');
+		var unit = document.createElement('span');
+		unit.textContent = unit_type;
+
+		input.setAttribute('type', 'text');
+		node.appendChild(input);
+		node.appendChild(unit);
+
+		input.addEventListener('click', function(e) {
+			this.select();
+		});
+
+		input.addEventListener('change', function(e) {
+			setValue(topic, e.target.value | 0);
+		});
+
+		subscribe(topic, function(value) {
+			node.children[0].value = value;
+		});
+	}
+
+	var increment = function increment(topic) {
+		var slider = sliders[topic];
+		if (slider === null || slider === undefined)
+			return;
+
+		if (slider.value + slider.step <= slider.max) {
+			slider.value += slider.step;
+			setValue(slider.topic, slider.value)
+			notify.call(slider);
+		}
+	};
+
+	var decrement = function decrement(topic) {
+		var slider = sliders[topic];
+		if (slider === null || slider === undefined)
+			return;
+
+		if (slider.value - slider.step >= slider.min) {
+			slider.value -= slider.step;
+			setValue(topic, slider.value)
+			notify.call(slider);
+		}
+	}
+
+	// this = Slider object
+	var updateSlider = function updateSlider(e) {
+		var node = this.node;
+		var pos = e.pageX - node.offsetLeft;
+		var width = node.clientWidth;
+		var delta = this.max - this.min;
+		var offset = this.pointer.clientWidth + 4; // border width * 2
+
+		if (pos < 0) pos = 0;
+		if (pos > width) pos = width;
+
+		var value = pos * delta / width | 0;
+		var precision = value % this.step;
+		value = value - precision + this.min;
+		if (precision > this.step / 2)
+			value = value + this.step;
+
+		if (this.snap)
+			pos =  (value - this.min) * width / delta;
+
+		this.pointer.style.left = pos - offset/2 + "px";
+		this.value = value;
+		node.setAttribute('data-value', value);
+		notify.call(this);
+	}
+
+	var setValue = function setValue(topic, value) {
+		var slider = sliders[topic];
+
+		if (value > slider.max || value < slider.min)
+			return;
+
+		var delta = slider.max - slider.min;
+		var width = slider.node.clientWidth;
+		var offset = slider.pointer.clientWidth;
+		var pos =  (value - slider.min) * width / delta;
+		slider.value = value;
+		slider.pointer.style.left = pos - offset / 2 + "px";
+		slider.node.setAttribute('data-value', value);
+		notify.call(slider);
+	}
+
+	var setMouseTracking = function setMouseTracking(elem, callback) {
+		elem.addEventListener("mousedown", function(e) {
+			callback(e);
+			document.addEventListener("mousemove", callback);
+		});
+
+		document.addEventListener("mouseup", function(e) {
+			document.removeEventListener("mousemove", callback);
+		});
+	}
+
+	var subscribe = function subscribe(topic, callback) {
+		if (subscribers[topic] === undefined)
+			subscribers[topic] = [];
+		subscribers[topic].push(callback);
+	}
+
+	var unsubscribe = function unsubscribe(topic, callback) {
+		subscribers[topic].indexOf(callback);
+		subscribers[topic].splice(index, 1);
+	}
+
+	var notify = function notify() {
+		if (subscribers[this.topic] === undefined)
+			return;
+
+		for (var i in subscribers[this.topic]) {
+			subscribers[this.topic][i](this.value);
+		}
+	}
+
+	var init = function init() {
+		var elem, size;
+
+		elem = document.querySelectorAll('.ui-slider-btn-set');
+		size = elem.length;
+		for (var i = 0; i < size; i++)
+			setButtonComponent(elem[i]);
+
+		elem = document.querySelectorAll('.ui-slider-input');
+		size = elem.length;
+		for (var i = 0; i < size; i++)
+			setInputComponent(elem[i]);
+
+		elem = document.querySelectorAll('.ui-slider');
+		size = elem.length;
+		for (var i = 0; i < size; i++)
+			new Slider(elem[i]);
+	}
+
+	return {
+		init : init,
+		setValue : setValue,
+		subscribe : subscribe,
+		unsubscribe : unsubscribe
+	}
+
+})();
+
+/**
+ * UI-ButtonManager
+ */
+
+var ButtonManager = (function CheckBoxManager() {
+
+	var subscribers = [];
+	var buttons = [];
+
+	var CheckBox = function CheckBox(node) {
+		var topic = node.getAttribute('data-topic');
+		var state = node.getAttribute('data-state');
+		var name = node.getAttribute('data-label');
+		var align = node.getAttribute('data-text-on');
+
+		state = (state === "true");
+
+		var checkbox = document.createElement("input");
+		var label = document.createElement("label");
+
+		var id = 'checkbox-' + topic;
+		checkbox.id = id;
+		checkbox.setAttribute('type', 'checkbox');
+		checkbox.checked = state;
+
+		label.setAttribute('for', id);
+		if (name) {
+			label.className = 'text';
+			if (align)
+				label.className += ' ' + align;
+			label.textContent = name;
+		}
+
+		node.appendChild(checkbox);
+		node.appendChild(label);
+
+		this.node = node;
+		this.topic = topic;
+		this.checkbox = checkbox;
+
+		checkbox.addEventListener('change', function(e) {
+			notify.call(this);
+		}.bind(this));
+
+		buttons[topic] = this;
+	}
+
+	var getNode =  function getNode(topic) {
+		return buttons[topic].node;
+	}
+
+	var setValue = function setValue(topic, value) {
+		try {
+			buttons[topic].checkbox.checked = value;
+			notify.call(buttons[topic]);
+		}
+		catch(error) {
+			console.log(error, topic, value);
+		}
+	}
+
+	var subscribe = function subscribe(topic, callback) {
+		if (subscribers[topic] === undefined)
+			subscribers[topic] = [];
+
+		subscribers[topic].push(callback);
+	}
+
+	var unsubscribe = function unsubscribe(topic, callback) {
+		subscribers[topic].indexOf(callback);
+		subscribers[topic].splice(index, 1);
+	}
+
+	var notify = function notify() {
+		if (subscribers[this.topic] === undefined)
+			return;
+		for (var i = 0; i < subscribers[this.topic].length; i++)
+			subscribers[this.topic][i](this.checkbox.checked);
+	}
+
+	var init = function init() {
+		var elem = document.querySelectorAll('.ui-checkbox');
+		var size = elem.length;
+		for (var i = 0; i < size; i++)
+			new CheckBox(elem[i]);
+	}
+
+	return {
+		init : init,
+		setValue : setValue,
+		subscribe : subscribe,
+		unsubscribe : unsubscribe
+	}
+
+})();
+
+
+window.addEventListener("load", function(){
+	BoxShadow.init();
+});
+
+var BoxShadow = (function BoxShadow() {
+
+	function getElemById(id) {
+		return document.getElementById(id);
+	}
+
+	/**
+	 * RGBA Color class
+	 */
+
+	function Color() {
+		this.r = 0;
+		this.g = 0;
+		this.b = 0;
+		this.a = 1;
+		this.hue = 0;
+		this.saturation = 0;
+		this.value = 0;
+	}
+
+	Color.prototype.copy = function copy(obj) {
+		if(obj instanceof Color !== true) {
+			console.log("Typeof instance not Color");
+			return;
+		}
+
+		this.r = obj.r;
+		this.g = obj.g;
+		this.b = obj.b;
+		this.a = obj.a;
+		this.hue = obj.hue;
+		this.saturation = obj.saturation;
+		this.value = obj.value;
+	}
+
+	Color.prototype.setRGBA = function setRGBA(red, green, blue, alpha) {
+		if (red != undefined)
+			this.r = red | 0;
+		if (green != undefined)
+			this.g = green | 0;
+		if (blue != undefined)
+			this.b = blue | 0;
+		if (alpha != undefined)
+			this.a = alpha | 0;
+	}
+
+	/**
+	 * HSV/HSB (hue, saturation, value / brightness)
+	 * @param hue			0-360
+	 * @param saturation	0-100
+	 * @param value 		0-100
+	 */
+	Color.prototype.setHSV = function setHSV(hue, saturation, value) {
+		this.hue = hue;
+		this.saturation = saturation;
+		this.value = value;
+		this.updateRGB();
+	}
+
+	Color.prototype.updateRGB = function updateRGB() {
+		var sat = this.saturation / 100;
+		var value = this.value / 100;
+		var C = sat * value;
+		var H = this.hue / 60;
+		var X = C * (1 - Math.abs(H % 2 - 1));
+		var m = value - C;
+		var precision = 255;
+
+		C = (C + m) * precision;
+		X = (X + m) * precision;
+		m = m * precision;
+
+		if (H >= 0 && H < 1) {	this.setRGBA(C, X, m);	return; }
+		if (H >= 1 && H < 2) {	this.setRGBA(X, C, m);	return; }
+		if (H >= 2 && H < 3) {	this.setRGBA(m, C, X);	return; }
+		if (H >= 3 && H < 4) {	this.setRGBA(m, X, C);	return; }
+		if (H >= 4 && H < 5) {	this.setRGBA(X, m, C);	return; }
+		if (H >= 5 && H < 6) {	this.setRGBA(C, m, X);	return; }
+	}
+
+	Color.prototype.updateHSV = function updateHSV() {
+		var red		= this.r / 255;
+		var green	= this.g / 255;
+		var blue	= this.b / 255;
+
+		var cmax = Math.max(red, green, blue);
+		var cmin = Math.min(red, green, blue);
+		var delta = cmax - cmin;
+		var hue = 0;
+		var saturation = 0;
+
+		if (delta) {
+			if (cmax === red ) { hue = ((green - blue) / delta); }
+			if (cmax === green ) { hue = 2 + (blue - red) / delta; }
+			if (cmax === blue ) { hue = 4 + (red - green) / delta; }
+			if (cmax) saturation = delta / cmax;
+		}
+
+		this.hue = 60 * hue | 0;
+		if (this.hue < 0) this.hue += 360;
+		this.saturation = (saturation * 100) | 0;
+		this.value = (cmax * 100) | 0;
+	}
+
+	Color.prototype.setHexa = function setHexa(value) {
+		var valid  = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)/i.test(value)
+		if (valid !== true)
+			return;
+
+		if (value[0] === '#')
+			value = value.slice(1, value.length);
+
+		if (value.length === 3)
+			value = value.replace(/([0-9A-F])([0-9A-F])([0-9A-F])/i,"$1$1$2$2$3$3");
+
+		this.r = parseInt(value.substr(0, 2), 16);
+		this.g = parseInt(value.substr(2, 2), 16);
+		this.b = parseInt(value.substr(4, 2), 16);
+
+		this.alpha	= 1;
+	}
+
+	Color.prototype.getHexa = function getHexa() {
+		var r = this.r.toString(16);
+		var g = this.g.toString(16);
+		var b = this.b.toString(16);
+		if (this.r < 16) r = '0' + r;
+		if (this.g < 16) g = '0' + g;
+		if (this.b < 16) b = '0' + b;
+		var value = '#' + r + g + b;
+		return value.toUpperCase();
+	}
+
+	Color.prototype.getRGBA = function getRGBA() {
+
+		var rgb = "(" + this.r + ", " + this.g + ", " + this.b;
+		var a = '';
+		var v = '';
+		if (this.a !== 1) {
+			a = 'a';
+			v = ', ' + this.a;
+		}
+
+		var value = "rgb" + a + rgb + v + ")";
+		return value;
+	}
+
+	Color.prototype.getColor = function getColor() {
+		if (this.a | 0 === 1)
+			return this.getHexa();
+		return this.getRGBA();
+	}
+
+	/**
+	 * Shadow Object
+	 */
+	function Shadow() {
+		this.inset  = false;
+		this.posX   = 5;
+		this.posY   = -5;
+		this.blur   = 5;
+		this.spread = 0;
+		this.color  = new Color();
+
+		var hue			= (Math.random() * 360) | 0;
+		var saturation	= (Math.random() * 75) | 0;
+		var value 		= (Math.random() * 50 + 50) | 0;
+		this.color.setHSV(hue, saturation, value, 1);
+	}
+
+	Shadow.prototype.computeCSS = function computeCSS() {
+		var value = "";
+		if (this.inset === true)
+			value += "inset ";
+		value += this.posX + "px ";
+		value += this.posY + "px ";
+		value += this.blur + "px ";
+		value += this.spread + "px ";
+		value += this.color.getColor();
+
+		return value;
+	}
+
+	Shadow.prototype.toggleInset = function toggleInset(value) {
+		if (value !== undefined || typeof value === "boolean")
+			this.inset = value;
+		else
+			this.inset = this.inset === true ? false : true;
+	}
+
+	Shadow.prototype.copy = function copy(obj) {
+		if(obj instanceof Shadow !== true) {
+			console.log("Typeof instance not Shadow");
+			return;
+		}
+
+		this.inset  = obj.inset;
+		this.posX   = obj.posX;
+		this.posY   = obj.posY;
+		this.blur   = obj.blur;
+		this.spread = obj.spread;
+		this.color.copy(obj.color);
+	}
+
+	/**
+	 * Color Picker
+	 */
+	var ColoPicker = (function ColoPicker() {
+
+		var colorpicker;
+		var hue_area;
+		var gradient_area;
+		var alpha_area;
+		var gradient_picker;
+		var hue_selector;
+		var alpha_selector;
+		var pick_object;
+		var info_rgb;
+		var info_hsv;
+		var info_hexa;
+		var output_color;
+		var color = new Color();
+		var subscribers = [];
+
+		var updateColor = function updateColor(e) {
+			var x = e.pageX - gradient_area.offsetLeft;
+			var y = e.pageY - gradient_area.offsetTop;
+
+			// width and height should be the same
+			var size = gradient_area.clientWidth;
+
+			if (x > size)
+				x = size;
+			if (y > size)
+				y = size;
+
+			if (x < 0) x = 0;
+			if (y < 0) y = 0;
+
+			var value = 100 - (y * 100 / size) | 0;
+			var saturation = x * 100 / size | 0;
+
+			color.setHSV(color.hue, saturation, value);
+			// should update just
+			// color pointer location
+			updateUI();
+			notify("color", color);
+		}
+
+		var updateHue = function updateHue(e) {
+			var x = e.pageX - hue_area.offsetLeft;
+			var width = hue_area.clientWidth;
+
+			if (x < 0) x = 0;
+			if (x > width) x = width;
+
+			var hue = ((360 * x) / width) | 0;
+			if (hue === 360) hue = 359;
+
+			color.setHSV(hue, color.saturation, color.value);
+
+			// should update just
+			// hue pointer location
+			// picker area background
+			// alpha area background
+			updateUI();
+			notify("color", color);
+		}
+
+		var updateAlpha = function updateAlpha(e) {
+			var x = e.pageX - alpha_area.offsetLeft;
+			var width = alpha_area.clientWidth;
+
+			if (x < 0) x = 0;
+			if (x > width) x = width;
+
+			color.a = (x / width).toFixed(2);
+
+			// should update just
+			// alpha pointer location
+			updateUI();
+			notify("color", color);
+		}
+
+		var setHueGfx = function setHueGfx(hue) {
+			var sat = color.saturation;
+			var val = color.value;
+			var alpha = color.a;
+
+			color.setHSV(hue, 100, 100);
+			gradient_area.style.backgroundColor = color.getHexa();
+
+			color.a = 0;
+			var start = color.getRGBA();
+			color.a = 1;
+			var end = color.getRGBA();
+			color.a = alpha;
+
+			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
+			alpha_area.style.background = gradient;
+		}
+
+		var updateUI = function updateUI() {
+			var x, y;		// coordinates
+			var size;		// size of the area
+			var offset;		// pointer graphic selector offset
+
+			// Set color pointer location
+			size = gradient_area.clientWidth;
+			offset = gradient_picker.clientWidth / 2 + 2;
+
+			x = (color.saturation * size / 100) | 0;
+			y = size - (color.value * size / 100) | 0;
+
+			gradient_picker.style.left = x - offset + "px";
+			gradient_picker.style.top = y - offset + "px";
+
+			// Set hue pointer location
+			size = hue_area.clientWidth;
+			offset = hue_selector.clientWidth/2;
+			x = (color.hue * size / 360 ) | 0;
+			hue_selector.style.left = x - offset + "px";
+
+			// Set alpha pointer location
+			size = alpha_area.clientWidth;
+			offset = alpha_selector.clientWidth/2;
+			x = (color.a * size) | 0;
+			alpha_selector.style.left = x - offset + "px";
+
+			// Set picker area background
+			var nc = new Color();
+			nc.copy(color);
+			if (nc.hue === 360) nc.hue = 0;
+			nc.setHSV(nc.hue, 100, 100);
+			gradient_area.style.backgroundColor = nc.getHexa();
+
+			// Set alpha area background
+			nc.copy(color);
+			nc.a = 0;
+			var start = nc.getRGBA();
+			nc.a = 1;
+			var end = nc.getRGBA();
+			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
+			alpha_area.style.background = gradient;
+
+			// Update color info
+			notify("color", color);
+			notify("hue", color.hue);
+			notify("saturation", color.saturation);
+			notify("value", color.value);
+			notify("r", color.r);
+			notify("g", color.g);
+			notify("b", color.b);
+			notify("a", color.a);
+			notify("hexa", color.getHexa());
+			output_color.style.backgroundColor = color.getRGBA();
+		}
+
+		var setInputComponent = function setInputComponent(node) {
+			var topic = node.getAttribute('data-topic');
+			var title = node.getAttribute('data-title');
+			var action = node.getAttribute('data-action');
+			title = title === null ? '' : title;
+
+			var input = document.createElement('input');
+			var info = document.createElement('span');
+			info.textContent = title;
+
+			input.setAttribute('type', 'text');
+			input.setAttribute('data-action', 'set-' + action + '-' + topic);
+			node.appendChild(info);
+			node.appendChild(input);
+
+			input.addEventListener('click', function(e) {
+				this.select();
+			});
+
+			input.addEventListener('change', function(e) {
+				if (action === 'HSV')
+					inputChangeHSV(topic);
+				if (action === 'RGB')
+					inputChangeRGB(topic);
+				if (action === 'alpha')
+					inputChangeAlpha(topic);
+				if (action === 'hexa')
+					inputChangeHexa(topic);
+			});
+
+			subscribe(topic, function(value) {
+				node.children[1].value = value;
+			});
+		}
+
+		var inputChangeHSV = function actionHSV(topic) {
+			var selector = "[data-action='set-HSV-" + topic + "']";
+			var node = document.querySelector("#colorpicker " + selector);
+			var value = parseInt(node.value);
+
+			if (typeof value === 'number' && isNaN(value) === false &&
+				value >= 0 && value < 360)
+				color[topic] = value;
+
+			color.updateRGB();
+			updateUI();
+		}
+
+		var inputChangeRGB = function inputChangeRGB(topic) {
+			var selector = "[data-action='set-RGB-" + topic + "']";
+			var node = document.querySelector("#colorpicker " + selector);
+			var value = parseInt(node.value);
+
+			if (typeof value === 'number' && isNaN(value) === false &&
+				value >= 0 && value <= 255)
+				color[topic] = value;
+
+			color.updateHSV();
+			updateUI();
+		}
+
+		var inputChangeAlpha = function inputChangeAlpha(topic) {
+			var selector = "[data-action='set-alpha-" + topic + "']";
+			var node = document.querySelector("#colorpicker " + selector);
+			var value = parseFloat(node.value);
+
+			if (typeof value === 'number' && isNaN(value) === false &&
+				value >= 0 && value <= 1)
+				color.a = value.toFixed(2);
+
+			updateUI();
+		}
+
+		var inputChangeHexa = function inputChangeHexa(topic) {
+			var selector = "[data-action='set-hexa-" + topic + "']";
+			var node = document.querySelector("#colorpicker " + selector);
+			var value = node.value;
+			color.setHexa(value);
+			color.updateHSV();
+			updateUI();
+		}
+
+		var setMouseTracking = function setMouseTracking(elem, callback) {
+
+			elem.addEventListener("mousedown", function(e) {
+				callback(e);
+				document.addEventListener("mousemove", callback);
+			});
+
+			document.addEventListener("mouseup", function(e) {
+				document.removeEventListener("mousemove", callback);
+			});
+		}
+
+		/*
+		 * Observer
+		 */
+		var setColor = function setColor(obj) {
+			if(obj instanceof Color !== true) {
+				console.log("Typeof instance not Color");
+				return;
+			}
+			color.copy(obj);
+			updateUI();
+		}
+
+		var subscribe = function subscribe(topic, callback) {
+			if (subscribers[topic] === undefined)
+				subscribers[topic] = [];
+
+			subscribers[topic].push(callback);
+		}
+
+		var unsubscribe = function unsubscribe(callback) {
+			subscribers.indexOf(callback);
+			subscribers.splice(index, 1);
+		}
+
+		var notify = function notify(topic, value) {
+			for (var i in subscribers[topic])
+				subscribers[topic][i](value);
+		}
+
+		var init = function init() {
+			colorpicker		= getElemById("colorpicker");
+			hue_area		= getElemById("hue");
+			gradient_area	= getElemById("gradient");
+			alpha_area		= getElemById("alpha");
+			gradient_picker	= getElemById("gradient_picker");
+			hue_selector	= getElemById("hue_selector");
+			alpha_selector	= getElemById("alpha_selector");
+			output_color	= getElemById("output_color");
+
+			var elem = document.querySelectorAll('#colorpicker .input');
+			var size = elem.length;
+			for (var i = 0; i < size; i++)
+				setInputComponent(elem[i]);
+
+			setMouseTracking(gradient_area, updateColor);
+			setMouseTracking(hue_area, updateHue);
+			setMouseTracking(alpha_area, updateAlpha);
+
+		}
+
+		return {
+			init : init,
+			setColor : setColor,
+			subscribe : subscribe,
+			unsubscribe : unsubscribe
+		}
+
+	})();
+
+	/**
+	 * Shadow dragging
+	 */
+	var PreviewMouseTracking = (function Drag() {
+		var active = false;
+		var lastX = 0;
+		var lastY = 0;
+		var subscribers = [];
+
+		var init = function init(id) {
+			var elem = getElemById(id);
+			elem.addEventListener('mousedown', dragStart, false);
+			document.addEventListener('mouseup', dragEnd, false);
+		}
+
+		var dragStart = function dragStart(e) {
+			if (e.button !== 0)
+				return;
+
+			active = true;
+			lastX = e.clientX;
+			lastY = e.clientY;
+			document.addEventListener('mousemove', mouseDrag, false);
+		}
+
+		var dragEnd = function dragEnd(e) {
+			if (e.button !== 0)
+				return;
+
+			if (active === true) {
+				active = false;
+				document.removeEventListener('mousemove', mouseDrag, false);
+			}
+		}
+
+		var mouseDrag = function mouseDrag(e) {
+			notify(e.clientX - lastX, e.clientY - lastY);
+			lastX = e.clientX;
+			lastY = e.clientY;
+		}
+
+		var subscribe = function subscribe(callback) {
+			subscribers.push(callback);
+		}
+
+		var unsubscribe = function unsubscribe(callback) {
+			var index = subscribers.indexOf(callback);
+			subscribers.splice(index, 1);
+		}
+
+		var notify = function notify(deltaX, deltaY) {
+			for (var i in subscribers)
+				subscribers[i](deltaX, deltaY);
+		}
+
+		return {
+			init : init,
+			subscribe : subscribe,
+			unsubscribe : unsubscribe
+		}
+
+	})();
+
+	/*
+	 * Element Class
+	 */
+	var CssClass = function CssClass(id) {
+		this.left = 0;
+		this.top = 0;
+		this.rotate = 0;
+		this.width = 300;
+		this.height = 100;
+		this.display = true;
+		this.border = true;
+		this.zIndex = -1;
+		this.bgcolor = new Color();
+		this.id = id;
+		this.node = getElemById('obj-' + id);
+		this.object = getElemById(id);
+		this.shadowID = null;
+		this.shadows = []
+		this.render = [];
+		this.init();
+	}
+
+	CssClass.prototype.init = function init() {
+		this.left = ((this.node.parentNode.clientWidth - this.node.clientWidth) / 2) | 0;
+		this.top = ((this.node.parentNode.clientHeight - this.node.clientHeight) / 2) | 0;
+
+		this.setTop(this.top);
+		this.setLeft(this.left);
+		this.setHeight(this.height);
+		this.setWidth(this.width);
+		this.bgcolor.setHSV(0, 0, 100);
+		this.updateBgColor(this.bgcolor);
+	}
+
+	CssClass.prototype.updatePos = function updatePos(deltaX, deltaY) {
+		this.left += deltaX;
+		this.top += deltaY;
+		this.node.style.top = this.top + "px";
+		this.node.style.left = this.left + "px";
+		SliderManager.setValue("left", this.left);
+		SliderManager.setValue("top", this.top);
+	}
+
+	CssClass.prototype.setLeft = function setLeft(value) {
+		this.left = value;
+		this.node.style.left = this.left + "px";
+		OutputManager.updateProperty(this.id, 'left', this.left + 'px');
+	}
+
+	CssClass.prototype.setTop = function setTop(value) {
+		this.top = value;
+		this.node.style.top = this.top + 'px';
+		OutputManager.updateProperty(this.id, 'top', this.top + 'px');
+	}
+
+	CssClass.prototype.setWidth = function setWidth(value) {
+		this.width = value;
+		this.node.style.width = this.width + 'px';
+		OutputManager.updateProperty(this.id, 'width', this.width + 'px');
+	}
+
+	CssClass.prototype.setHeight = function setHeight(value) {
+		this.height = value;
+		this.node.style.height = this.height + 'px';
+		OutputManager.updateProperty(this.id, 'height', this.height + 'px');
+	}
+
+	// Browser support
+	CssClass.prototype.setRotate = function setRotate(value) {
+		var cssvalue = 'rotate(' + value +'deg)';
+
+		this.node.style.transform = cssvalue;
+		this.node.style.webkitTransform = cssvalue;
+		this.node.style.msTransform = cssvalue;
+
+		if (value !== 0) {
+			if (this.rotate === 0) {
+				OutputManager.toggleProperty(this.id, 'transform', true);
+				OutputManager.toggleProperty(this.id, '-webkit-transform', true);
+				OutputManager.toggleProperty(this.id, '-ms-transform', true);
+			}
+		}
+		else {
+			OutputManager.toggleProperty(this.id, 'transform', false);
+			OutputManager.toggleProperty(this.id, '-webkit-transform', false);
+			OutputManager.toggleProperty(this.id, '-ms-transform', false);
+		}
+
+		OutputManager.updateProperty(this.id, 'transform', cssvalue);
+		OutputManager.updateProperty(this.id, '-webkit-transform', cssvalue);
+		OutputManager.updateProperty(this.id, '-ms-transform', cssvalue);
+		this.rotate = value;
+	}
+
+	CssClass.prototype.setzIndex = function setzIndex(value) {
+		this.node.style.zIndex = value;
+		OutputManager.updateProperty(this.id, 'z-index', value);
+		this.zIndex = value;
+	}
+
+	CssClass.prototype.toggleDisplay = function toggleDisplay(value) {
+		if (typeof value !== "boolean" || this.display === value)
+			return;
+
+		this.display = value;
+		var display = this.display === true ? "block" : "none";
+		this.node.style.display = display;
+		this.object.style.display = display;
+	}
+
+	CssClass.prototype.toggleBorder = function toggleBorder(value) {
+		if (typeof value !== "boolean" || this.border === value)
+			return;
+
+		this.border = value;
+		var border = this.border === true ? "1px solid #CCC" : "none";
+		this.node.style.border = border;
+	}
+
+	CssClass.prototype.updateBgColor = function updateBgColor(color) {
+		this.bgcolor.copy(color);
+		this.node.style.backgroundColor = color.getColor();
+		OutputManager.updateProperty(this.id, 'background-color', color.getColor());
+	}
+
+	CssClass.prototype.updateShadows = function updateShadows() {
+		if (this.render.length === 0)
+			OutputManager.toggleProperty(this.id, 'box-shadow', false);
+		if (this.render.length === 1)
+			OutputManager.toggleProperty(this.id, 'box-shadow', true);
+
+		this.node.style.boxShadow = this.render.join(", ");
+		OutputManager.updateProperty(this.id, 'box-shadow', this.render.join(", \n"));
+
+	}
+
+
+	/**
+	 * Tool Manager
+	 */
+	var Tool = (function Tool() {
+
+		var preview;
+		var classes = [];
+		var active = null;
+		var animate = false;
+
+		/*
+		 * Toll actions
+		 */
+		var addCssClass = function addCssClass(id) {
+			classes[id] = new CssClass(id);
+		}
+
+		var setActiveClass = function setActiveClass(id) {
+			active = classes[id];
+			active.shadowID = null;
+			ColoPicker.setColor(classes[id].bgcolor);
+			SliderManager.setValue("top", active.top);
+			SliderManager.setValue("left", active.left);
+			SliderManager.setValue("rotate", active.rotate);
+			SliderManager.setValue("z-index", active.zIndex);
+			SliderManager.setValue("width", active.width);
+			SliderManager.setValue("height", active.height);
+			ButtonManager.setValue("border-state", active.border);
+			active.updateShadows();
+		}
+
+		var disableClass = function disableClass(topic) {
+			classes[topic].toggleDisplay(false);
+			ButtonManager.setValue(topic, false);
+		}
+
+		var addShadow = function addShadow(position) {
+			if (animate === true)
+				return -1;
+
+			active.shadows.splice(position, 0, new Shadow());
+			active.render.splice(position, 0, null);
+		}
+
+		var swapShadow = function swapShadow(id1, id2) {
+			var x = active.shadows[id1];
+			active.shadows[id1] = active.shadows[id2];
+			active.shadows[id2] = x;
+			updateShadowCSS(id1);
+			updateShadowCSS(id2);
+		}
+
+		var deleteShadow = function deleteShadow(position) {
+			active.shadows.splice(position, 1);
+			active.render.splice(position, 1);
+			active.updateShadows();
+		}
+
+		var setActiveShadow = function setActiveShadow(id, glow) {
+			active.shadowID = id;
+			ColoPicker.setColor(active.shadows[id].color);
+			ButtonManager.setValue("inset", active.shadows[id].inset);
+			SliderManager.setValue("blur", active.shadows[id].blur);
+			SliderManager.setValue("spread", active.shadows[id].spread);
+			SliderManager.setValue("posX", active.shadows[id].posX);
+			SliderManager.setValue("posY", active.shadows[id].posY);
+			if (glow === true)
+				addGlowEffect(id);
+		}
+
+		var addGlowEffect = function addGlowEffect(id) {
+			if (animate === true)
+				return;
+
+			animate = true;
+			var store = new Shadow();
+			var shadow = active.shadows[id];
+
+			store.copy(shadow);
+			shadow.color.setRGBA(40, 125, 200, 1);
+			shadow.blur = 10;
+			shadow.spread = 10;
+
+			active.node.style.transition = "box-shadow 0.2s";
+			updateShadowCSS(id);
+
+			setTimeout(function() {
+				shadow.copy(store);
+				updateShadowCSS(id);
+				setTimeout(function() {
+					active.node.style.removeProperty("transition");
+					animate = false;
+				}, 100);
+			}, 200);
+		}
+
+		var updateActivePos = function updateActivePos(deltaX, deltaY) {
+			if (active.shadowID === null)
+				active.updatePos(deltaX, deltaY);
+			else
+				updateShadowPos(deltaX, deltaY);
+		}
+
+		/*
+		 * Shadow properties
+		 */
+		var updateShadowCSS = function updateShadowCSS(id) {
+			active.render[id] = active.shadows[id].computeCSS();
+			active.updateShadows();
+		}
+
+		var toggleShadowInset = function toggleShadowInset(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].toggleInset(value);
+			updateShadowCSS(active.shadowID);
+		}
+
+		var updateShadowPos = function updateShadowPos(deltaX, deltaY) {
+			var shadow = active.shadows[active.shadowID];
+			shadow.posX += deltaX;
+			shadow.posY += deltaY;
+			SliderManager.setValue("posX", shadow.posX);
+			SliderManager.setValue("posY", shadow.posY);
+			updateShadowCSS(active.shadowID);
+		}
+
+		var setShadowPosX = function setShadowPosX(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].posX = value;
+			updateShadowCSS(active.shadowID);
+		}
+
+		var setShadowPosY = function setShadowPosY(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].posY = value;
+			updateShadowCSS(active.shadowID);
+		}
+
+		var setShadowBlur = function setShadowBlur(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].blur = value;
+			updateShadowCSS(active.shadowID);
+		}
+
+		var setShadowSpread = function setShadowSpread(value) {
+			if (active.shadowID === null)
+				return;
+			active.shadows[active.shadowID].spread = value;
+			updateShadowCSS(active.shadowID);
+		}
+
+		var updateShadowColor = function updateShadowColor(color) {
+			active.shadows[active.shadowID].color.copy(color);
+			updateShadowCSS(active.shadowID);
+		}
+
+		/*
+		 * Element Properties
+		 */
+		var updateColor = function updateColor(color) {
+			if (active.shadowID === null)
+				active.updateBgColor(color);
+			else
+				updateShadowColor(color);
+		}
+
+		var init = function init() {
+			preview = getElemById("preview");
+
+			ColoPicker.subscribe("color", updateColor);
+			PreviewMouseTracking.subscribe(updateActivePos);
+
+			// Affects shadows
+			ButtonManager.subscribe("inset", toggleShadowInset);
+			SliderManager.subscribe("posX", setShadowPosX);
+			SliderManager.subscribe("posY", setShadowPosY);
+			SliderManager.subscribe("blur", setShadowBlur);
+			SliderManager.subscribe("spread", setShadowSpread);
+
+			// Affects element
+			SliderManager.subscribe("top", function(value){
+				active.setTop(value);
+			});
+			SliderManager.subscribe("left", function(value){
+				active.setLeft(value);
+			});
+			SliderManager.subscribe("rotate", function(value) {
+				if (active == classes["element"])
+					return;
+				active.setRotate(value);
+			});
+
+			SliderManager.subscribe("z-index", function(value) {
+				if (active == classes["element"])
+					return;
+				active.setzIndex(value);
+			});
+
+			SliderManager.subscribe("width", function(value) {
+				active.setWidth(value)
+			});
+
+			SliderManager.subscribe("height", function(value) {
+				active.setHeight(value)
+			});
+
+			// Actions
+			classes['before'].top = -30;
+			classes['before'].left = -30;
+			classes['after'].top = 30;
+			classes['after'].left = 30;
+			classes['before'].toggleDisplay(false);
+			classes['after'].toggleDisplay(false);
+			ButtonManager.setValue('before', false);
+			ButtonManager.setValue('after', false);
+
+			ButtonManager.subscribe("before", classes['before'].toggleDisplay.bind(classes['before']));
+			ButtonManager.subscribe("after", classes['after'].toggleDisplay.bind(classes['after']));
+
+			ButtonManager.subscribe("border-state", function(value) {
+				active.toggleBorder(value);
+			});
+
+		}
+
+		return {
+			init 			: init,
+			addShadow		: addShadow,
+			swapShadow		: swapShadow,
+			addCssClass		: addCssClass,
+			disableClass	: disableClass,
+			deleteShadow	: deleteShadow,
+			setActiveClass	: setActiveClass,
+			setActiveShadow : setActiveShadow
+		}
+
+	})();
+
+	/**
+	 * Layer Manager
+	 */
+	var LayerManager = (function LayerManager() {
+		var stacks = [];
+		var active = {
+			node : null,
+			stack : null
+		}
+		var elements = {};
+
+		var mouseEvents = function mouseEvents(e) {
+			var node = e.target;
+			var type = node.getAttribute('data-type');
+
+			if (type === 'subject')
+				setActiveStack(stacks[node.id]);
+
+			if (type === 'disable') {
+				Tool.disableClass(node.parentNode.id);
+				setActiveStack(stacks['element']);
+			}
+
+			if (type === 'add')
+				active.stack.addLayer();
+
+			if (type === 'layer')
+				active.stack.setActiveLayer(node);
+
+			if (type === 'delete')
+				active.stack.deleteLayer(node.parentNode);
+
+			if (type === 'move-up')
+				active.stack.moveLayer(1);
+
+			if (type === 'move-down')
+				active.stack.moveLayer(-1);
+		}
+
+		var setActiveStack = function setActiveStack(stackObj) {
+			active.stack.hide();
+			active.stack = stackObj;
+			active.stack.show();
+		}
+
+		/*
+		 * Stack object
+		 */
+		var Stack = function Stack(subject) {
+			var S = document.createElement('div');
+			var title = document.createElement('div');
+			var stack = document.createElement('div');
+
+			S.className = 'container';
+			stack.className = 'stack';
+			title.className = 'title';
+			title.textContent = subject.getAttribute('data-title');
+			S.appendChild(title);
+			S.appendChild(stack);
+
+			this.id = subject.id;
+			this.container = S;
+			this.stack = stack;
+			this.subject = subject;
+			this.order = [];
+			this.uid = 0;
+			this.count = 0;
+			this.layer = null;
+			this.layerID = 0;
+		}
+
+		Stack.prototype.addLayer = function addLayer() {
+			if (Tool.addShadow(this.layerID) == -1)
+				return;
+
+			var uid = this.getUID();
+			var layer = this.createLayer(uid);
+
+			if (this.layer === null && this.stack.children.length >= 1)
+				this.layer = this.stack.children[0];
+
+			this.stack.insertBefore(layer, this.layer);
+			this.order.splice(this.layerID, 0, uid);
+			this.count++;
+			this.setActiveLayer(layer);
+		}
+
+		Stack.prototype.createLayer = function createLayer(uid) {
+			var layer = document.createElement('div');
+			var del = document.createElement('span');
+
+			layer.className = 'node';
+			layer.setAttribute('data-shid', uid);
+			layer.setAttribute('data-type', 'layer');
+			layer.textContent = 'тень ' + uid;
+
+			del.className = 'delete';
+			del.setAttribute('data-type', 'delete');
+
+			layer.appendChild(del);
+			return layer;
+		}
+
+		Stack.prototype.getUID = function getUID() {
+			return this.uid++;
+		}
+
+		// SOLVE IE BUG
+		Stack.prototype.moveLayer = function moveLayer(direction) {
+			if (this.count <= 1 || this.layer === null)
+				return;
+			if (direction === -1 && this.layerID === (this.count - 1) )
+				return;
+			if (direction === 1 && this.layerID === 0 )
+				return;
+
+			if (direction === -1) {
+				var before = null;
+				Tool.swapShadow(this.layerID, this.layerID + 1);
+				this.swapOrder(this.layerID, this.layerID + 1);
+				this.layerID += 1;
+
+				if (this.layerID + 1 !== this.count)
+					before = this.stack.children[this.layerID + 1];
+
+				this.stack.insertBefore(this.layer, before);
+				Tool.setActiveShadow(this.layerID, false);
+			}
+
+			if (direction === 1) {
+				Tool.swapShadow(this.layerID, this.layerID - 1);
+				this.swapOrder(this.layerID, this.layerID - 1);
+				this.layerID -= 1;
+				this.stack.insertBefore(this.layer, this.stack.children[this.layerID]);
+				Tool.setActiveShadow(this.layerID, false);
+			}
+		}
+
+		Stack.prototype.swapOrder = function swapOrder(pos1, pos2) {
+			var x = this.order[pos1];
+			this.order[pos1] = this.order[pos2];
+			this.order[pos2] = x;
+		}
+
+		Stack.prototype.deleteLayer = function deleteLayer(node) {
+			var shadowID =  node.getAttribute('data-shid') | 0;
+			var index = this.order.indexOf(shadowID);
+			this.stack.removeChild(this.stack.children[index]);
+			this.order.splice(index, 1);
+			this.count--;
+
+			Tool.deleteShadow(index);
+
+			if (index > this.layerID)
+				return;
+
+			if (index == this.layerID) {
+				if (this.count >= 1) {
+					this.layerID = 0;
+					this.setActiveLayer(this.stack.children[0], true);
+				}
+				else {
+					this.layer = null;
+					this.show();
+				}
+			}
+
+			if (index < this.layerID) {
+				this.layerID--;
+				Tool.setActiveShadow(this.layerID, true);
+			}
+
+		}
+
+		Stack.prototype.setActiveLayer = function setActiveLayer(node) {
+			elements.shadow_properties.style.display = 'block';
+			elements.element_properties.style.display = 'none';
+
+			if (this.layer)
+				this.layer.removeAttribute('data-active');
+
+			this.layer = node;
+			this.layer.setAttribute('data-active', 'layer');
+
+			var shadowID =  node.getAttribute('data-shid') | 0;
+			this.layerID = this.order.indexOf(shadowID);
+			Tool.setActiveShadow(this.layerID, true);
+		}
+
+		Stack.prototype.unsetActiveLayer = function unsetActiveLayer() {
+			if (this.layer)
+				this.layer.removeAttribute('data-active');
+
+			this.layer = null;
+			this.layerID = 0;
+		}
+
+		Stack.prototype.hide = function hide() {
+			this.unsetActiveLayer();
+			this.subject.removeAttribute('data-active');
+			var style = this.container.style;
+			style.left = '100%';
+			style.zIndex = '0';
+		}
+
+		Stack.prototype.show = function show() {
+			elements.shadow_properties.style.display = 'none';
+			elements.element_properties.style.display = 'block';
+
+			if (this.id === 'element') {
+				elements.zIndex.style.display = 'none';
+				elements.transform_rotate.style.display = 'none';
+			}
+			else {
+				elements.zIndex.style.display = 'block';
+				elements.transform_rotate.style.display = 'block';
+			}
+
+			this.subject.setAttribute('data-active', 'subject');
+			var style = this.container.style;
+			style.left = '0';
+			style.zIndex = '10';
+			Tool.setActiveClass(this.id);
+		}
+
+		function init() {
+
+			var elem, size;
+			var layerManager = getElemById("layer_manager");
+			var layerMenu = getElemById("layer_menu");
+			var container = getElemById("stack_container");
+
+			elements.shadow_properties = getElemById('shadow_properties');
+			elements.element_properties = getElemById('element_properties');
+			elements.transform_rotate = getElemById('transform_rotate');
+			elements.zIndex = getElemById('z-index');
+
+			elem = document.querySelectorAll('#layer_menu [data-type="subject"]');
+			size = elem.length;
+
+			for (var i = 0; i < size; i++) {
+				var S = new Stack(elem[i]);
+				stacks[elem[i].id] = S;
+				container.appendChild(S.container);
+				Tool.addCssClass(elem[i].id);
+			}
+
+			active.stack = stacks['element'];
+			stacks['element'].show();
+
+			layerManager.addEventListener("click", mouseEvents);
+			layerMenu.addEventListener("click", mouseEvents);
+
+			ButtonManager.subscribe("before", function(value) {
+				if (value === false && active.stack === stacks['before'])
+					setActiveStack(stacks['element'])
+				if (value === true && active.stack !== stacks['before'])
+					setActiveStack(stacks['before'])
+			});
+
+			ButtonManager.subscribe("after", function(value) {
+				if (value === false && active.stack === stacks['after'])
+					setActiveStack(stacks['element'])
+				if (value === true && active.stack !== stacks['after'])
+					setActiveStack(stacks['after'])
+			});
+		}
+
+		return {
+			init : init
+		}
+	})();
+
+	/*
+	 * OutputManager
+	 */
+	var OutputManager = (function OutputManager() {
+		var classes = [];
+		var buttons = [];
+		var active = null;
+		var menu = null;
+		var button_offset = 0;
+
+		var crateOutputNode = function(topic, property) {
+
+			var prop = document.createElement('div');
+			var name = document.createElement('span');
+			var value = document.createElement('span');
+
+			var pmatch = property.match(/(^([a-z0-9\-]*)=\[([a-z0-9\-\"]*)\])|^([a-z0-9\-]*)/i);
+
+			name.textContent = '\t' + pmatch[4];
+
+			if (pmatch[3] !== undefined) {
+				name.textContent = '\t' + pmatch[2];
+				value.textContent = pmatch[3] + ';';
+			}
+
+			name.textContent += ': ';
+			prop.className = 'css-property';
+			name.className = 'name';
+			value.className = 'value';
+			prop.appendChild(name);
+			prop.appendChild(value);
+
+			classes[topic].node.appendChild(prop);
+			classes[topic].line[property] = prop;
+			classes[topic].prop[property] = value;
+		}
+
+		var OutputClass = function OutputClass(node) {
+			var topic = node.getAttribute('data-topic');
+			var prop = node.getAttribute('data-prop');
+			var name = node.getAttribute('data-name');
+			var properties = prop.split(' ');
+
+			classes[topic] = {};
+			classes[topic].node = node;
+			classes[topic].prop = [];
+			classes[topic].line = [];
+			classes[topic].button = new Button(topic);
+
+			var open_decl = document.createElement('div');
+			var end_decl = document.createElement('div');
+
+			open_decl.textContent = name + ' {';
+			end_decl.textContent = '}';
+			node.appendChild(open_decl);
+
+			for (var i in properties)
+				crateOutputNode(topic, properties[i]);
+
+			node.appendChild(end_decl);
+		}
+
+		var Button = function Button(topic) {
+			var button = document.createElement('div');
+
+			button.className = 'button';
+			button.textContent = topic;
+			button.style.left = button_offset + 'px';
+			button_offset += 100;
+
+			button.addEventListener("click", function() {
+				toggleDisplay(topic);
+			})
+
+			menu.appendChild(button);
+			return button;
+		}
+
+		var toggleDisplay = function toggleDisplay(topic) {
+			active.button.removeAttribute('data-active');
+			active.node.style.display = 'none';
+			active = classes[topic];
+			active.node.style.display = 'block';
+			active.button.setAttribute('data-active', 'true');
+		}
+
+		var toggleButton = function toggleButton(topic, value) {
+			var display = (value === true) ? 'block' : 'none';
+			classes[topic].button.style.display = display;
+
+			if (value === true)
+				toggleDisplay(topic);
+			else
+				toggleDisplay('element');
+		}
+
+		var updateProperty = function updateProperty(topic, property, data) {
+			try {
+				classes[topic].prop[property].textContent = data + ';';
+			}
+			catch(error) {
+				// console.log("ERROR undefined : ", topic, property, data);
+			}
+		}
+
+		var toggleProperty = function toggleProperty(topic, property, value) {
+			var display = (value === true) ? 'block' : 'none';
+			try {
+				classes[topic].line[property].style.display = display;
+			}
+			catch(error) {
+				// console.log("ERROR undefined : ",classes, topic, property, value);
+			}
+		}
+
+		var init = function init() {
+
+			menu = getElemById('menu');
+
+			var elem = document.querySelectorAll('#output .output');
+			var size = elem.length;
+			for (var i = 0; i < size; i++)
+				OutputClass(elem[i]);
+
+			active = classes['element'];
+			toggleDisplay('element');
+
+			ButtonManager.subscribe("before", function(value) {
+				toggleButton('before', value);
+			});
+
+			ButtonManager.subscribe("after", function(value) {
+				toggleButton('after', value);
+			});
+		}
+
+		return {
+			init : init,
+			updateProperty : updateProperty,
+			toggleProperty : toggleProperty
+		}
+
+	})();
+
+
+	/**
+	 * Init Tool
+	 */
+	var init = function init() {
+		ButtonManager.init();
+		OutputManager.init();
+		ColoPicker.init();
+		SliderManager.init();
+		LayerManager.init();
+		PreviewMouseTracking.init("preview");
+		Tool.init();
+	}
+
+	return {
+		init : init
+	}
+
+})();
+
+
+
+
+ +
{{ EmbedLiveSample('box-shadow_generator', '100%', '1100px', '') }}
+ +

Похожий инструмент: Генератор CSS Box Shadow

diff --git a/files/ru/web/css/css_background_and_borders/index.html b/files/ru/web/css/css_background_and_borders/index.html deleted file mode 100644 index 59c2117194..0000000000 --- a/files/ru/web/css/css_background_and_borders/index.html +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: CSS Background and Borders -slug: Web/CSS/CSS_Background_and_Borders -tags: - - CSS - - CSS Backgrounds and Borders - - CSS Reference - - NeedsTranslation - - Overview - - TopicStub -translation_of: Web/CSS/CSS_Backgrounds_and_Borders -translation_of_original: Web/CSS/CSS_Background_and_Borders ---- -

{{CSSRef}}

- -

CSS Background and Borders is a module of CSS that defines how background and borders of elements are described. Borders can be lines or images, boxes can have one or multiple backgrounds, have rounded corners, and shadows.

- -

Reference

- -

CSS Properties

- -
- -
- -

Guides

- -
-
Using CSS multiple backgrounds
-
Explains how to set backgrounds on elements and how they will interact with it.
-
Scaling background images
-
Describes how to change the appearance of the background images, by stretching them or repeating them, to cover the whole background of the element, or not.
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('CSS3 Backgrounds') }}{{ Spec2('CSS3 Backgrounds') }} 
{{SpecName('CSS2.1', 'box.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1', '#border')}}{{Spec2('CSS1')}} 
- -

Browser compatibility

- -

{{CompatibilityTable()}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatGeckoDesktop("1.0")}}4.03.51.0 (85)
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown()}}{{CompatGeckoMobile("1.9.2")}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}1.0
-
diff --git "a/files/ru/web/css/css_background_and_borders/\320\274\320\275\320\276\320\266\320\265\321\201\321\202\320\262\320\265\320\275\320\275\321\213\320\265_\321\204\320\276\320\275\321\213/index.html" "b/files/ru/web/css/css_background_and_borders/\320\274\320\275\320\276\320\266\320\265\321\201\321\202\320\262\320\265\320\275\320\275\321\213\320\265_\321\204\320\276\320\275\321\213/index.html" deleted file mode 100644 index 231c794702..0000000000 --- "a/files/ru/web/css/css_background_and_borders/\320\274\320\275\320\276\320\266\320\265\321\201\321\202\320\262\320\265\320\275\320\275\321\213\320\265_\321\204\320\276\320\275\321\213/index.html" +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Множественные фоны -slug: Web/CSS/CSS_Background_and_Borders/Множественные_фоны -translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds -translation_of_original: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds ---- -

{{CSSRef}}

- -

Краткое описание

- -

С помощью CSS3 вы можете применить несколько фонов к элементам. Они будут располагаться поверх друг друга: фон, заданный первым - в самом верху, последний фон - в самом низу.

- -

Задать множественные фоны легко:

- -
.myclass {
-  background: background1, background 2, ..., backgroundN;
-}
-
- -

Вы можете сделать это сокращенным {{ cssxref("background") }} свойством и отдельными свойствами кроме {{ cssxref("background-color") }}. Таким образом следующие свойства могут быть определены в виде списка по одному на фон: {{ cssxref("background") }}, {{ cssxref("background-attachment") }}, {{ cssxref("background-clip") }}, {{ cssxref("background-image") }}, {{ cssxref("background-origin") }}, {{ cssxref("background-position") }}, {{ cssxref("background-repeat") }}, {{ cssxref("background-size") }}.

- -

Пример

- -

В этом примере три фона: логотип Firefox, линейный градиент и изображение пузырей:

- -

HTML

- -
<div class="multi_bg_example"></div>
- -

CSS

- -
.multi_bg_example {
-  width: 100%;
-  height: 400px;
-  background-image: url(https://mdn.mozillademos.org/files/11305/firefox.png), url(https://mdn.mozillademos.org/files/11307/bubbles.png), linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0));
-  background-repeat: no-repeat, no-repeat, no-repeat;
-  background-position: bottom right, left, right;
-  background: -moz-linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), -webkit-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), -ms-linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0));
-}
- -

Результат

- -

(If image does not appear in CodePen, click the TIdy button in the CSS section)

- -

{{EmbedLiveSample('Example','100%','400')}}

- -

Как вы можете видеть, логотип Firefox (первый в списке) расположен сверху, далее идет градиент и в самом низу фон с пузырями. Каждое последующее под-свойство ({{ cssxref("background-repeat") }} и {{ cssxref("background-position") }}) применяется к соответствующим фонам. Например первое значение свойства {{ cssxref("background-repeat") }} применяется к первому фону, и т.д.

- -

Смотрите также

- - diff --git a/files/ru/web/css/css_backgrounds_and_borders/index.html b/files/ru/web/css/css_backgrounds_and_borders/index.html new file mode 100644 index 0000000000..59c2117194 --- /dev/null +++ b/files/ru/web/css/css_backgrounds_and_borders/index.html @@ -0,0 +1,155 @@ +--- +title: CSS Background and Borders +slug: Web/CSS/CSS_Background_and_Borders +tags: + - CSS + - CSS Backgrounds and Borders + - CSS Reference + - NeedsTranslation + - Overview + - TopicStub +translation_of: Web/CSS/CSS_Backgrounds_and_Borders +translation_of_original: Web/CSS/CSS_Background_and_Borders +--- +

{{CSSRef}}

+ +

CSS Background and Borders is a module of CSS that defines how background and borders of elements are described. Borders can be lines or images, boxes can have one or multiple backgrounds, have rounded corners, and shadows.

+ +

Reference

+ +

CSS Properties

+ +
+ +
+ +

Guides

+ +
+
Using CSS multiple backgrounds
+
Explains how to set backgrounds on elements and how they will interact with it.
+
Scaling background images
+
Describes how to change the appearance of the background images, by stretching them or repeating them, to cover the whole background of the element, or not.
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('CSS3 Backgrounds') }}{{ Spec2('CSS3 Backgrounds') }} 
{{SpecName('CSS2.1', 'box.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1', '#border')}}{{Spec2('CSS1')}} 
+ +

Browser compatibility

+ +

{{CompatibilityTable()}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatGeckoDesktop("1.0")}}4.03.51.0 (85)
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown()}}{{CompatGeckoMobile("1.9.2")}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}1.0
+
diff --git a/files/ru/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html b/files/ru/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html new file mode 100644 index 0000000000..231c794702 --- /dev/null +++ b/files/ru/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html @@ -0,0 +1,53 @@ +--- +title: Множественные фоны +slug: Web/CSS/CSS_Background_and_Borders/Множественные_фоны +translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds +translation_of_original: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds +--- +

{{CSSRef}}

+ +

Краткое описание

+ +

С помощью CSS3 вы можете применить несколько фонов к элементам. Они будут располагаться поверх друг друга: фон, заданный первым - в самом верху, последний фон - в самом низу.

+ +

Задать множественные фоны легко:

+ +
.myclass {
+  background: background1, background 2, ..., backgroundN;
+}
+
+ +

Вы можете сделать это сокращенным {{ cssxref("background") }} свойством и отдельными свойствами кроме {{ cssxref("background-color") }}. Таким образом следующие свойства могут быть определены в виде списка по одному на фон: {{ cssxref("background") }}, {{ cssxref("background-attachment") }}, {{ cssxref("background-clip") }}, {{ cssxref("background-image") }}, {{ cssxref("background-origin") }}, {{ cssxref("background-position") }}, {{ cssxref("background-repeat") }}, {{ cssxref("background-size") }}.

+ +

Пример

+ +

В этом примере три фона: логотип Firefox, линейный градиент и изображение пузырей:

+ +

HTML

+ +
<div class="multi_bg_example"></div>
+ +

CSS

+ +
.multi_bg_example {
+  width: 100%;
+  height: 400px;
+  background-image: url(https://mdn.mozillademos.org/files/11305/firefox.png), url(https://mdn.mozillademos.org/files/11307/bubbles.png), linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0));
+  background-repeat: no-repeat, no-repeat, no-repeat;
+  background-position: bottom right, left, right;
+  background: -moz-linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), -webkit-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), -ms-linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0)), linear-gradient(to right, rgba(30, 75, 115, 1), rgba(255, 255, 255, 0));
+}
+ +

Результат

+ +

(If image does not appear in CodePen, click the TIdy button in the CSS section)

+ +

{{EmbedLiveSample('Example','100%','400')}}

+ +

Как вы можете видеть, логотип Firefox (первый в списке) расположен сверху, далее идет градиент и в самом низу фон с пузырями. Каждое последующее под-свойство ({{ cssxref("background-repeat") }} и {{ cssxref("background-position") }}) применяется к соответствующим фонам. Например первое значение свойства {{ cssxref("background-repeat") }} применяется к первому фону, и т.д.

+ +

Смотрите также

+ + diff --git a/files/ru/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html b/files/ru/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html new file mode 100644 index 0000000000..c629b7bffd --- /dev/null +++ b/files/ru/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html @@ -0,0 +1,120 @@ +--- +title: Использование URL значений для свойства cursor +slug: >- + Web/CSS/CSS_Basic_User_Interface/Использование_URL_значений_для_свойства_cursor +tags: + - CSS + - Gecko + - Справка + - справочник +translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property +--- +
{{cssref}}
+ +

Gecko 1.8 (Firefox 1.5, SeaMonkey 1.0) поддерживает URL-значения для CSS свойства {{cssxref("cursor")}} в Windows и Linux. Поддержка Mac была добавлена в Gecko 2 (Firefox 4). Это позволяет устанавливать произвольные изображения в качестве курсора мыши — может быть использовать любой формат изображений, поддерживаемый Gecko.

+ +

Синтаксис

+ +

Базовый (CSS 2.1) синтаксис для этого свойства:

+ +
cursor:  [<url>,]* ключевое_слово
+ +

Это означает, что устанавливать можно любое количество URL'ов (отделенных запятой), которые должны сопровождаться одним из ключевых слов, определеннымы спецификацией CSS, таких как auto или pointer.

+ +

Например, такая последовательность значений допустима:

+ +
cursor:  url(foo.cur), url(http://www.example.com/bar.gif), auto;
+ +

В первую очередь браузер пытается загрузить foo.cur. Если такой файл отсутствует или его форма не допустим по каким-то другим причинам, то дальше загружается bar.gif. И если он также не может быть использован, будет использовано значение auto.

+ +

Поддержка CSS 3 синтаксиса для указания курсора была добавлена в Gecko 1.8 (Firefox 1.5):

+ +
cursor:  [<uri> [<x> <y>]?,]* ключевое_слово
+ +

Это позволяет устанавливать координаты смещения курсора, которые буду зафиксированы на границах курсора. Если координаты не указаны, то они считываются непосредственно из файла (для CUR и XBM файлов) или же устанавливаются в левый верхний угол изображения.

+ +

Пример CSS 3 синтаксиса:

+ +
.foo  {
+  cursor:  auto;
+  cursor:  url(cursor1.png) 4 12, auto;
+}
+
+.bar  {
+  cursor:  pointer;
+  cursor:  url(cursor2.png) 2 2, pointer;
+}
+
+/* откатываются на 'auto' и 'pointer' в IE, но должны быть установлены отдельны */
+
+ +

Первое число определяет координату по оси x, а вторая - по оси y. Данный пример сместит изображение на точку (4,12) относительно левого верхнего угла (0,0).

+ +

Ограничения

+ +

Могут быть использованы любые форматы, поддерживаемые Gecko. Это означает, что вы можете использовать PNG, GIF, JPG, BMP, CUR и т.д. ANI не поддерживается. Анимированные PNG и GIF не добавят анимацию курсору.

+ +
+

Примечание: Начиная с Gecko 2.0 {{geckoRelease("2.0")}}, Gecko также поддерживает формат SVG в качестве изображения курсора. Тем не менее, SVG изображение должно содержать значения (кроме процентных значений) высоты и ширины на корневом SVG узле. JavaScript, CSS анимация и декларативный SMIL внутри SVG изображения игнорируются; например, вы не можете использовать SVG, чтобы создать анимированный курсор.

+
+ +

В Gecko (Firefox) максимальный размер курсора - 128×128 пикселей. Изображения большего размера игнорируются. Однако, вам следую ограничиться рамером курсора в 32×32 пикселя для максимальной совместимости с операционными системами и платформами.

+ +

(В следствие бага Gecko 1.9.2-1.9.2.6, Firefox 3.6-3.6.6 в Windows ограничивает размер в 32x32 пикселя. Это исправляется в более новых версиях.)

+ +

Прозрачные курсоры не поддерживаются в версиях Windows ниже XP. Это ограничение для операционной системы. Прозрачность работает на любых платформах.

+ +

URL в качестве курсора поддерживаются в Windows, OS/2, и Linux (с использованием GTK+ 2.4 или выше) версиях Mozilla. Поддержка Mac OS X была добавлена в Gecko 2 (Firefox 4).

+ +

Совместимость с другими браузерами

+ +

Microsoft Internet Explorer 6.0 также поддерживает URI значения для свойства cursor. Тем не менее:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
БраузерРанняя версияФорматыx-y-координаты
Internet Explorer6.0.cur | .ani---
Firefox (Gecko), Windows и Linux1.5 (1.8).cur | .png | .gif | .jpg1.5 (1.8)
Firefox (Gecko)4.0 (2.0).cur | .png | .gif | .jpg | .svg(Gecko 2.0)
Opera---------
Safari (Webkit)3.0 (522-523).cur | .png | .gif | .jpg3.0 (522-523)
Начиная с OS X 10.5, Safari (Mac) поддерживает  .cur файлы
diff --git "a/files/ru/web/css/css_basic_user_interface/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_url_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\271_\320\264\320\273\321\217_\321\201\320\262\320\276\320\271\321\201\321\202\320\262\320\260_cursor/index.html" "b/files/ru/web/css/css_basic_user_interface/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_url_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\271_\320\264\320\273\321\217_\321\201\320\262\320\276\320\271\321\201\321\202\320\262\320\260_cursor/index.html" deleted file mode 100644 index c629b7bffd..0000000000 --- "a/files/ru/web/css/css_basic_user_interface/\320\270\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_url_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\271_\320\264\320\273\321\217_\321\201\320\262\320\276\320\271\321\201\321\202\320\262\320\260_cursor/index.html" +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: Использование URL значений для свойства cursor -slug: >- - Web/CSS/CSS_Basic_User_Interface/Использование_URL_значений_для_свойства_cursor -tags: - - CSS - - Gecko - - Справка - - справочник -translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property ---- -
{{cssref}}
- -

Gecko 1.8 (Firefox 1.5, SeaMonkey 1.0) поддерживает URL-значения для CSS свойства {{cssxref("cursor")}} в Windows и Linux. Поддержка Mac была добавлена в Gecko 2 (Firefox 4). Это позволяет устанавливать произвольные изображения в качестве курсора мыши — может быть использовать любой формат изображений, поддерживаемый Gecko.

- -

Синтаксис

- -

Базовый (CSS 2.1) синтаксис для этого свойства:

- -
cursor:  [<url>,]* ключевое_слово
- -

Это означает, что устанавливать можно любое количество URL'ов (отделенных запятой), которые должны сопровождаться одним из ключевых слов, определеннымы спецификацией CSS, таких как auto или pointer.

- -

Например, такая последовательность значений допустима:

- -
cursor:  url(foo.cur), url(http://www.example.com/bar.gif), auto;
- -

В первую очередь браузер пытается загрузить foo.cur. Если такой файл отсутствует или его форма не допустим по каким-то другим причинам, то дальше загружается bar.gif. И если он также не может быть использован, будет использовано значение auto.

- -

Поддержка CSS 3 синтаксиса для указания курсора была добавлена в Gecko 1.8 (Firefox 1.5):

- -
cursor:  [<uri> [<x> <y>]?,]* ключевое_слово
- -

Это позволяет устанавливать координаты смещения курсора, которые буду зафиксированы на границах курсора. Если координаты не указаны, то они считываются непосредственно из файла (для CUR и XBM файлов) или же устанавливаются в левый верхний угол изображения.

- -

Пример CSS 3 синтаксиса:

- -
.foo  {
-  cursor:  auto;
-  cursor:  url(cursor1.png) 4 12, auto;
-}
-
-.bar  {
-  cursor:  pointer;
-  cursor:  url(cursor2.png) 2 2, pointer;
-}
-
-/* откатываются на 'auto' и 'pointer' в IE, но должны быть установлены отдельны */
-
- -

Первое число определяет координату по оси x, а вторая - по оси y. Данный пример сместит изображение на точку (4,12) относительно левого верхнего угла (0,0).

- -

Ограничения

- -

Могут быть использованы любые форматы, поддерживаемые Gecko. Это означает, что вы можете использовать PNG, GIF, JPG, BMP, CUR и т.д. ANI не поддерживается. Анимированные PNG и GIF не добавят анимацию курсору.

- -
-

Примечание: Начиная с Gecko 2.0 {{geckoRelease("2.0")}}, Gecko также поддерживает формат SVG в качестве изображения курсора. Тем не менее, SVG изображение должно содержать значения (кроме процентных значений) высоты и ширины на корневом SVG узле. JavaScript, CSS анимация и декларативный SMIL внутри SVG изображения игнорируются; например, вы не можете использовать SVG, чтобы создать анимированный курсор.

-
- -

В Gecko (Firefox) максимальный размер курсора - 128×128 пикселей. Изображения большего размера игнорируются. Однако, вам следую ограничиться рамером курсора в 32×32 пикселя для максимальной совместимости с операционными системами и платформами.

- -

(В следствие бага Gecko 1.9.2-1.9.2.6, Firefox 3.6-3.6.6 в Windows ограничивает размер в 32x32 пикселя. Это исправляется в более новых версиях.)

- -

Прозрачные курсоры не поддерживаются в версиях Windows ниже XP. Это ограничение для операционной системы. Прозрачность работает на любых платформах.

- -

URL в качестве курсора поддерживаются в Windows, OS/2, и Linux (с использованием GTK+ 2.4 или выше) версиях Mozilla. Поддержка Mac OS X была добавлена в Gecko 2 (Firefox 4).

- -

Совместимость с другими браузерами

- -

Microsoft Internet Explorer 6.0 также поддерживает URI значения для свойства cursor. Тем не менее:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
БраузерРанняя версияФорматыx-y-координаты
Internet Explorer6.0.cur | .ani---
Firefox (Gecko), Windows и Linux1.5 (1.8).cur | .png | .gif | .jpg1.5 (1.8)
Firefox (Gecko)4.0 (2.0).cur | .png | .gif | .jpg | .svg(Gecko 2.0)
Opera---------
Safari (Webkit)3.0 (522-523).cur | .png | .gif | .jpg3.0 (522-523)
Начиная с OS X 10.5, Safari (Mac) поддерживает  .cur файлы
diff --git a/files/ru/web/css/css_box_model/box-shadow_generator/index.html b/files/ru/web/css/css_box_model/box-shadow_generator/index.html deleted file mode 100644 index 3f46cf53ba..0000000000 --- a/files/ru/web/css/css_box_model/box-shadow_generator/index.html +++ /dev/null @@ -1,2884 +0,0 @@ ---- -title: Генератор теней -slug: Web/CSS/CSS_Box_Model/Box-shadow_generator -tags: - - CSS3 - - Тень - - инструменты -translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator ---- -

Этот инструмент позволяет вам создавать CSS {{cssxref("box-shadow")}} эффекты, добавлять тени вашим элементам.

- -
-

Генератор box-shadow generator

- -

HTML Content

- -
<div id="container">
-    <div class="group section">
-        <div id="layer_manager">
-            <div class="group section">
-                <div class="button" data-type="add"> </div>
-                <div class="button" data-type="move-up"> </div>
-                <div class="button" data-type="move-down"> </div>
-            </div>
-            <div id="stack_container"></div>
-        </div>
-
-        <div id="preview_zone">
-            <div id="layer_menu" class="col span_12">
-                <div class="button" id="element" data-type="subject" data-title="element"> элементы </div>
-                <div class="button" id="before" data-type="subject" data-title=":before">
-                    :before
-                    <span class="delete" data-type="disable"></span>
-                </div>
-                <div class="button" id="after" data-type="subject" data-title=":after">
-                    :after
-                    <span class="delete" data-type="disable"></span>
-                </div>
-                <div class="ui-checkbox" data-topic='before' data-label=":before"></div>
-                <div class="ui-checkbox" data-topic='after' data-label=":after"></div>
-            </div>
-
-            <div id="preview">
-                <div id="obj-element">
-                    <div class="content"> </div>
-                    <div id="obj-before"> </div>
-                    <div id="obj-after"> </div>
-                </div>
-            </div>
-        </div>
-    </div>
-
-    <div id="controls" class="group section">
-        <div class="wrap-left">
-            <div class="colorpicker category">
-                <div class="title"> </div>
-                <div id="colorpicker" class="group">
-                    <div id="gradient" class="gradient">
-                        <div id="gradient_picker"> </div>
-                    </div>
-                    <div id="hue" data-topic="hue" class="hue">
-                        <div id="hue_selector"> </div>
-                    </div>
-                    <div class="info">
-                        <div class="input" data-topic="hue" data-title='H:' data-action="HSV"></div>
-                        <div class="input" data-topic="saturation" data-title='S:' data-action="HSV"></div>
-                        <div class="input" data-topic="value" data-title='V:' data-action="HSV"></div>
-                    </div>
-                    <div class="alpha">
-                        <div id="alpha" data-topic="alpha">
-                            <div id="alpha_selector"> </div>
-                        </div>
-                    </div>
-                    <div class="info">
-                        <div class="input" data-topic="r" data-title='R:' data-action="RGB"></div>
-                        <div class="input" data-topic="g" data-title='G:' data-action="RGB"></div>
-                        <div class="input" data-topic="b" data-title='B:' data-action="RGB"></div>
-                    </div>
-                    <div class="preview block">
-                        <div id="output_color"> </div>
-                    </div>
-                    <div class="block info">
-                        <div class="input" data-topic="a" data-title='alpha:' data-action="alpha"></div>
-                        <div class="input" data-topic="hexa" data-title='' data-action="hexa"></div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="wrap-right">
-
-            <div id="shadow_properties" class="category">
-                <div class="title"> Shadow properties </div>
-                <div class="group">
-                    <div class="group property">
-                        <div class="ui-slider-name"> inset </div>
-                        <div class="ui-checkbox" data-topic='inset'></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Position x </div>
-                        <div class="ui-slider-btn-set" data-topic="posX" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="posX"
-                            data-min="-500" data-max="500" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="posX" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="posX" data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Position y </div>
-                        <div class="ui-slider-btn-set" data-topic="posY" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="posY"
-                            data-min="-500" data-max="500" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="posY" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="posY" data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Blur </div>
-                        <div class="ui-slider-btn-set" data-topic="blur" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="blur"
-                            data-min="0" data-max="200" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="blur" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="blur" data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Spread </div>
-                        <div class="ui-slider-btn-set" data-topic="spread" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="spread"
-                            data-min="-100"    data-max="100" data-step="1" data-value="50">
-                        </div>
-                        <div class="ui-slider-btn-set" data-topic="spread" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="spread" data-unit="px"></div>
-                    </div>
-                </div>
-            </div>
-
-            <div id="element_properties" class="category">
-                <div class="title"> Параметры элемента</div>
-                <div class="group">
-                    <div class="group property">
-                        <div class="ui-slider-name"> border </div>
-                        <div class="ui-checkbox" data-topic='border-state' data-state="true"></div>
-                    </div>
-                    <div id="z-index" class="slidergroup">
-                        <div class="ui-slider-name"> z-index </div>
-                        <div class="ui-slider-btn-set" data-topic="z-index" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="z-index"
-                            data-min="-10" data-max="10" data-step="1"></div>
-                        <div class="ui-slider-btn-set" data-topic="z-index" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="z-index"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> top </div>
-                        <div class="ui-slider-btn-set" data-topic="top" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="top"
-                            data-min="-500" data-max="500" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="top" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="top" data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> left </div>
-                        <div class="ui-slider-btn-set" data-topic="left" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="left"
-                            data-min="-300" data-max="700" data-step="1"> </div>
-                        <div class="ui-slider-btn-set" data-topic="left" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="left" data-unit="px"></div>
-                    </div>
-                    <div id="transform_rotate" class="slidergroup">
-                        <div class="ui-slider-name"> Rotate </div>
-                        <div class="ui-slider-btn-set" data-topic="rotate" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="rotate"
-                            data-min="-360" data-max="360" data-step="1" data-value="0">
-                        </div>
-                        <div class="ui-slider-btn-set" data-topic="rotate" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="rotate" data-unit="deg"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Width </div>
-                        <div class="ui-slider-btn-set" data-topic="width" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="width"
-                            data-min="0" data-max="1000" data-step="1" data-value="200">
-                        </div>
-                        <div class="ui-slider-btn-set" data-topic="width" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="width"  data-unit="px"></div>
-                    </div>
-                    <div class="slidergroup">
-                        <div class="ui-slider-name"> Height </div>
-                        <div class="ui-slider-btn-set" data-topic="height" data-type="sub"></div>
-                        <div class="ui-slider" data-topic="height"
-                            data-min="0" data-max="400" data-step="1" data-value="200">
-                        </div>
-                        <div class="ui-slider-btn-set" data-topic="height" data-type="add"></div>
-                        <div class="ui-slider-input" data-topic="height" data-unit="px"></div>
-                    </div>
-                </div>
-            </div>
-
-            <div id="output" class="category">
-                <div id="menu" class="menu"></div>
-                <div class="title">    CSS-код </div>
-                <div class="group" style="border-top-left-radius: 0;">
-                    <div class="output" data-topic="element" data-name="element"
-                        data-prop="width height background-color position=[relative] box-shadow">
-                    </div>
-                    <div class="output" data-topic="before" data-name="element:before"
-                        data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
-                    </div>
-                    <div class="output" data-topic="after" data-name="element:after"
-                        data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
-
- -

CSS Content

- -
/*  GRID OF TWELVE
- * ========================================================================== */
-
-.span_12 {
-	width: 100%;
-}
-
-.span_11 {
-	width: 91.46%;
-}
-
-.span_10 {
-	width: 83%;
-}
-
-.span_9 {
-	width: 74.54%;
-}
-
-.span_8 {
-	width: 66.08%;
-}
-
-.span_7 {
-	width: 57.62%;
-}
-
-.span_6 {
-	width: 49.16%;
-}
-
-.span_5 {
-	width: 40.7%;
-}
-
-.span_4 {
-	width: 32.24%;
-}
-
-.span_3 {
-	width: 23.78%;
-}
-
-.span_2 {
-	width: 15.32%;
-}
-
-.span_1 {
-	width: 6.86%;
-}
-
-
-/*  SECTIONS
- * ========================================================================== */
-
-.section {
-	clear: both;
-	padding: 0px;
-	margin: 0px;
-}
-
-/*  GROUPING
- * ========================================================================== */
-
-
-.group:before, .group:after {
-    content: "";
-    display: table;
-}
-
-.group:after {
-    clear:both;
-}
-
-.group {
-    zoom: 1; /* For IE 6/7 (trigger hasLayout) */
-}
-
-/*  GRID COLUMN SETUP
- * ========================================================================== */
-
-.col {
-	display: block;
-	float:left;
-	margin: 1% 0 1% 1.6%;
-}
-
-.col:first-child {
-	margin-left: 0;
-} /* all browsers except IE6 and lower */
-
-/*
- * UI Slider
- */
-
-.slidergroup {
-	height: 20px;
-	margin: 10px 0;
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-	-moz-user-select: none;
-	user-select: none;
-}
-
-.slidergroup * {
-	float: left;
-	height: 100%;
-	line-height: 100%;
-}
-
-/* Slider */
-
-.ui-slider {
-	height: 10px;
-	width: 200px;
-	margin: 4px 10px;
-	display: block;
-	border: 1px solid #999;
-	border-radius: 3px;
-	background: #EEE;
-}
-
-.ui-slider:hover {
-	cursor: pointer;
-}
-
-.ui-slider-name {
-	width: 90px;
-	padding: 0 10px 0 0;
-	text-align: right;
-	text-transform: lowercase;
-}
-
-.ui-slider-pointer {
-	width: 13px;
-	height: 13px;
-	background-color: #EEE;
-	border: 1px solid #2C9FC9;
-	border-radius: 3px;
-	position: relative;
-	top: -3px;
-	left: 0%;
-}
-
-.ui-slider-btn-set {
-	width: 25px;
-	background-color: #2C9FC9;
-	border-radius: 3px;
-	color: #FFF;
-	font-weight: bold;
-	text-align: center;
-}
-
-.ui-slider-btn-set:hover {
-	background-color: #379B4A;
-	cursor: pointer;
-}
-
-.ui-slider-input > input {
-	margin: 0 10px;
-	padding: 0;
-	width: 50px;
-	text-align: center;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-/*
- * UI Button
- */
-
-/* Checkbox */
-
-.ui-checkbox {
-	text-align: center;
-	font-size: 16px;
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-	line-height: 1.5em;
-	color: #FFF;
-
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-}
-
-.ui-checkbox > input {
- 	display: none;
-}
-
-.ui-checkbox > label {
-	font-size: 12px;
-	padding: 0.333em 1.666em 0.5em;
-	height: 1em;
-	line-height: 1em;
-
-	background-color: #888;
-	background-image: url("https://mdn.mozillademos.org/files/5683/disabled.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-
-	color: #FFF;
-	border-radius: 3px;
-	font-weight: bold;
-	float: left;
-}
-
-.ui-checkbox .text {
-	padding-left: 34px;
-	background-position: center left 10px;
-}
-
-.ui-checkbox .left {
-	padding-right: 34px;
-	padding-left: 1.666em;
-	background-position: center right 10px;
-}
-
-.ui-checkbox > label:hover {
-	cursor: pointer;
-}
-
-.ui-checkbox > input:checked + label {
-	background-image: url("https://mdn.mozillademos.org/files/5681/checked.png");
-	background-color: #379B4A;
-}
-
-/*
- * BOX SHADOW GENERATOR TOOL
- */
-
-body {
-	max-width: 1000px;
-	height: 800px;
-	margin: 20px auto 0;
-
-	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	-ms-user-select: none;
-}
-
-#container {
-	width: 100%;
-	padding: 2px;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-
-/* container with shadows stacks */
-#stack_container {
-	height: 400px;
-	overflow: hidden;
-	position: relative;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#stack_container .container {
-	height: 100%;
-	width: 100%;
-	position: absolute;
-	left: 100%;
-	transition-property: left;
-	transition-duration: 0.5s;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-
-#stack_container .title {
-	text-align: center;
-	font-weight: bold;
-	line-height: 2em;
-	border-bottom: 1px solid #43A6E1;
-	color: #666;
-}
-
-
-/*
- * Stack of Layers for shadow
- */
-
-#layer_manager {
-	width: 17%;
-	background-color: #FEFEFE;
-	margin: 0 1% 0 0;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-	float: left;
-}
-
-
-#layer_manager .button {
-	width: 30%;
-	height: 25px;
-	margin:0 0 10px;
-	color: #333;
-	background-color: #EEE;
-	text-align: center;
-	font-size: 0.75em;
-	line-height: 1.5em;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-
-	display: block;
-	background-position: center center;
-	background-repeat: no-repeat;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-	float: left;
-}
-
-#layer_manager .button:hover {
-	background-color: #3380C4;
-	border: 1px solid #3380C4;
-	cursor: pointer;
-}
-
-#layer_manager [data-type='add'] {
-	background-image: url("https://mdn.mozillademos.org/files/5685/add-black.png");
-}
-
-#layer_manager [data-type='add']:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5687/add-white.png");
-}
-
-#layer_manager [data-type='move-up'] {
-	background-image: url("https://mdn.mozillademos.org/files/5697/up-black.png");
-	margin-left: 5%;
-	margin-right: 5%;
-}
-
-#layer_manager [data-type='move-up']:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5709/up-white.png");
-}
-
-#layer_manager [data-type='move-down'] {
-	background-image: url("https://mdn.mozillademos.org/files/5693/down-black.png");
-}
-
-#layer_manager [data-type='move-down']:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5695/down-white.png");
-}
-
-/* shadows classes */
-
-#layer_manager .node {
-	width: 100%;
-	margin: 5px 0;
-	padding: 5px;
-	text-align: center;
-	background-color: #EEE;
-	border: 1px solid #DDD;
-	font-size: 0.75em;
-	line-height: 1.5em;
-	color: #333;
-	border-radius: 3px;
-
-	position: relative;
-	display: block;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#layer_manager .node:hover {
-	color: #FFF;
-	background-color: #3380C4;
-	cursor: pointer;
-}
-
-/* active element styling */
-
-#layer_manager [data-active='layer'] {
-	color: #FFF;
-	border: none;
-	background-color: #379B4A;
-}
-
-#layer_manager [data-active='subject'] {
-	color: #FFF;
-	background-color: #467FC9;
-}
-
-/* delete button */
-
-#layer_manager .delete {
-	width: 1.5em;
-	height: 100%;
-	float: right;
-	border-radius: 3px;
-	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-	position: absolute;
-	top: 0;
-	right: 10px;
-	display: none;
-}
-
-#layer_manager .delete:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
-}
-
-#layer_manager .node:hover .delete {
-	display: block;
-}
-
-
-#layer_manager .stack {
-	padding: 0 5px;
-	max-height: 90%;
-	overflow: auto;
-	overflow-x: hidden;
-}
-
-
-/*
- * Layer Menu
- */
-
-#layer_menu {
-	margin: 0 0 10px 0;
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#layer_menu .button {
-	width: 100px;
-	margin: 0 5px 0 0;
-	padding: 2.5px;
-	color: #333;
-	background-color: #EEE;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-	text-align: center;
-	font-size: 0.75em;
-	line-height: 1.5em;
-
-	position: relative;
-	display: block;
-	float: left;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#layer_menu .button:hover {
-	color: #FFF;
-	background-color: #3380C4;
-	border: 1px solid #3380C4;
-	cursor: pointer;
-}
-
-#layer_menu .delete {
-	width: 1.5em;
-	height: 100%;
-	float: right;
-	border-radius: 3px;
-	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
-	background-position: center center;
-	background-repeat: no-repeat;
-	position: absolute;
-	top: 0;
-	right: 5px;
-	display: none;
-}
-
-#layer_menu .delete:hover {
-	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
-}
-
-#layer_menu .button:hover .delete {
-	display: block;
-}
-
-
-/*
- * active element styling
- */
-
-#layer_menu [data-active='subject'] {
-	color: #FFF;
-	background-color: #379B4A;
-	border: 1px solid #379B4A;
-}
-
-
-/* Checkbox */
-
-#layer_menu .ui-checkbox > label {
-	height: 15px;
-	line-height: 17px;
-	font-weight: normal;
-	width: 46px;
-	margin: 0 5px 0 0;
-}
-
-#layer_menu .ui-checkbox > input:checked + label {
-	display: none;
-}
-
-
-/******************************************************************************/
-/******************************************************************************/
-/*
- * Preview Area
- */
-
-#preview_zone {
-	width: 82%;
-	float: left;
-
-}
-
-
-#preview {
-	width: 100%;
-	height: 400px;
-	border: 1px solid #CCC;
-	border-radius: 3px;
-	text-align: center;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-	cursor: move;
-	float: left;
-}
-
-#preview .content {
-	width: 100%;
-	height: 100%;
-	display: block;
-}
-
-#obj-element {
-	width: 300px;
-	height: 100px;
-	border: 1px solid #CCC;
-	background: #FFF;
-	position: relative;
-}
-
-
-#obj-before {
-	height: 100%;
-	width: 100%;
-	background: #999;
-	border: 1px solid #CCC;
-	text-align: left;
-	display : block;
-	position: absolute;
-	z-index: -1;
-}
-
-#obj-after {
-	height: 100%;
-	width: 100%;
-	background: #DDD;
-	border: 1px solid #CCC;
-	text-align: right;
-	display : block;
-	position: absolute;
-	z-index: -1;
-}
-
-
-/******************************************************************************/
-/******************************************************************************/
-
-/**
- * Controls
- */
-
-.wrap-left {
-	float: left;
-	overflow: hidden;
-}
-
-.wrap-right {
-	float: right;
-	overflow: hidden;
-}
-
-.wrap-left > * {
-	float: left;
-}
-
-.wrap-right > * {
-	float: right;
-}
-
-@media (min-width: 960px) {
-
-	.wrap-left {
-		width: 45%;
-	}
-
-	.wrap-right {
-		width: 55%;
-	}
-}
-
-
-@media (max-width: 959px) {
-
-	.wrap-left {
-		width: 30%;
-	}
-
-	.wrap-right {
-		width: 70%;
-	}
-}
-
-
-#controls {
-	color: #444;
-	margin: 10px 0 0 0;
-}
-
-
-#controls .category {
-	width: 500px;
-	margin: 0 auto 20px;
-	padding: 0;
-
-}
-
-#controls .category .title {
-	width: 100%;
-	height: 1.5em;
-	line-height: 1.5em;
-	color: #AAA;
-	text-align: right;
-}
-
-#controls .category > .group {
-	border: 1px solid #CCC;
-	border-radius: 3px;
-}
-
-
-/**
- * 	Color Picker
- */
-
-@media (min-width: 960px) {
-	#controls .colorpicker {
-		width: 420px;
-	}
-}
-
-@media (max-width: 959px) {
-	#controls .colorpicker {
-		width: 210px;
-	}
-}
-
-#colorpicker {
-	width: 100%;
-	margin: 0 auto;
-}
-
-#colorpicker .gradient {
-	width: 200px;
-	height: 200px;
-	margin: 5px;
-	background: url("https://mdn.mozillademos.org/files/5707/picker_mask_200.png");
-	background: -moz-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
-				-moz-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
-	background: -webkit-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
-				-webkit-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
-	background-color: #F00;
-	float: left;
-}
-
-#colorpicker .hue {
-	width: 200px;
-	height: 30px;
-	margin: 5px;
-	background: url("https://mdn.mozillademos.org/files/5701/hue.png");
-	background: -moz-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
-				#00F 66.66%, #F0F 83.33%, #F00 100%);
-	background: -webkit-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
-				#00F 66.66%, #F0F 83.33%, #F00 100%);
-	float: left;
-}
-
-#colorpicker .alpha {
-	width: 200px;
-	height: 30px;
-	margin: 5px;
-	border: 1px solid #CCC;
-	float: left;
-	background: url("https://mdn.mozillademos.org/files/5705/alpha.png");
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#colorpicker #alpha {
-	width: 100%;
-	height: 100%;
-	background: url("https://mdn.mozillademos.org/files/5703/alpha_mask.png");
-	background: -moz-linear-gradient(left, rgba(255, 0, 0, 0) 0%, rgba(255, 0, 0, 1) 100%);
-}
-
-#colorpicker #gradient_picker {
-	width: 0.5em;
-	height: 0.5em;
-	border-radius: 0.4em;
-	border: 2px solid #CCC;
-	position: relative;
-	top: 20%;
-	left: 20%;
-}
-
-#colorpicker #hue_selector,
-#colorpicker #alpha_selector {
-	width: 3px;
-	height: 100%;
-	border: 1px solid #777;
-	background-color: #FFF;
-	position: relative;
-	top: -1px;
-	left: 0%;
-}
-
-/* input HSV and RGB */
-#colorpicker .info {
-	width: 200px;
-	margin: 5px;
-	float: left;
-}
-
-#colorpicker .info * {
-	float: left;
-}
-
-#colorpicker .info input {
-	margin: 0;
-	text-align: center;
-	width: 30px;
-	-moz-user-select: text;
-	-webkit-user-select: text;
-	-ms-user-select: text;
-}
-
-#colorpicker .info span {
-	height: 20px;
-	width: 30px;
-	text-align: center;
-	line-height: 20px;
-	display: block;
-}
-
-/* Preview color */
-#colorpicker .block {
-	width: 95px;
-	height: 54px;
-	float: left;
-	position: relative;
-}
-
-#colorpicker .preview {
-	margin: 5px;
-	border: 1px solid #CCC;
-	background-image: url("https://mdn.mozillademos.org/files/5705/alpha.png");
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-#colorpicker .preview:before {
-	height: 100%;
-	width: 50%;
-	left: 50%;
-	content: "";
-	background: #FFF;
-	position: absolute;
-	z-index: 1;
-}
-
-#colorpicker .preview > * {
-	width: 50%;
-	height: 100%;
-}
-
-#colorpicker #output_color {
-	width: 100%;
-	height: 100%;
-	position: absolute;
-	z-index: 2;
-}
-
-#colorpicker .block .input {
-	float: right;
-}
-
-#colorpicker [data-topic="a"] > span {
-	width: 50px;
-}
-
-#colorpicker [data-topic="hexa"] {
-	float: right;
-	margin: 10px 0 0 0;
-}
-
-#colorpicker [data-topic="hexa"] > span {
-	display: none;
-}
-
-#colorpicker [data-topic="hexa"] > input {
-	width: 85px;
-	padding: 2px 0;
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-
-/*
- * UI Components
- */
-
-/* Property */
-
-.property {
-	height: 20px;
-	margin: 10px 0;
-}
-
-.property * {
-	float: left;
-	height: 100%;
-	line-height: 100%;
-}
-
-/* Slider */
-
-#controls .ui-slider-name {
-	margin: 0 10px 0 0;
-}
-
-/*
- * Output code styling
- */
-
-#output {
-	position: relative;
-}
-
-#output .menu {
-	max-width: 70%;
-	height: 20px;
-	position: absolute;
-	top: 2px;
-}
-
-#output .button {
-	width: 90px;
-	height: 22px;
-	margin: 0 5px 0 0;
-	text-align: center;
-	line-height: 20px;
-	font-size: 14px;
-	color: #FFF;
-	background-color: #999;
-	border-top-left-radius: 3px;
-	border-top-right-radius: 3px;
-	bottom: -5px;
-	float:left;
-}
-
-#output .button:hover {
-	color: #FFF;
-	background-color: #666;
-	cursor: pointer;
-}
-
-#output .menu [data-active="true"] {
-	color: #777;
-	background-color: #FFF;
-	border: 1px solid #CCC;
-	border-bottom: none;
-}
-
-#output .menu [data-topic="before"] {
-	left: 100px;
-}
-
-#output .menu [data-topic="after"] {
-	left: 200px;
-}
-
-#output .output {
-	width: 480px;
-	margin: 10px;
-	padding: 10px;
-	overflow: hidden;
-	color: #555;
-	font-size: 14px;
-	border: 1px dashed #CCC;
-	border-radius: 3px;
-	display: none;
-
-	-moz-box-sizing: border-box;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-
-	-moz-user-select: text;
-	-webkit-user-select: text;
-	-ms-user-select: text;
-}
-
-#output .css-property {
-	width: 100%;
-	float: left;
-	white-space: pre;
-}
-
-#output .name {
-	width: 35%;
-	float: left;
-}
-
-#output .value {
-	width: 65%;
-	float: left;
-}
-
-
- -

JavaScript Content

- -

-
-'use strict';
-
-/**
- * UI-SlidersManager
- */
-
-var SliderManager = (function SliderManager() {
-
-	var subscribers = {};
-	var sliders = [];
-
-	var Slider = function(node) {
-		var min = node.getAttribute('data-min') | 0;
-		var max = node.getAttribute('data-max') | 0;
-		var step = node.getAttribute('data-step') | 0;
-		var value = node.getAttribute('data-value') | 0;
-		var snap = node.getAttribute('data-snap');
-		var topic = node.getAttribute('data-topic');
-
-		this.min = min;
-		this.max = max > 0 ? max : 100;
-		this.step = step === 0 ? 1 : step;
-		this.value = value <= max && value >= min ? value : (min + max) / 2 | 0;
-		this.snap = snap === "true" ? true : false;
-		this.topic = topic;
-		this.node = node;
-
-		var pointer = document.createElement('div');
-		pointer.className = 'ui-slider-pointer';
-		node.appendChild(pointer);
-		this.pointer = pointer;
-
-		setMouseTracking(node, updateSlider.bind(this));
-
-		sliders[topic] = this;
-		setValue(topic, this.value);
-	}
-
-	var setButtonComponent = function setButtonComponent(node) {
-		var type = node.getAttribute('data-type');
-		var topic = node.getAttribute('data-topic');
-		if (type === "sub") {
-			node.textContent = '-';
-			node.addEventListener("click", function() {
-				decrement(topic);
-			});
-		}
-		if (type === "add") {
-			node.textContent = '+';
-			node.addEventListener("click", function() {
-				increment(topic);
-			});
-		}
-	}
-
-	var setInputComponent = function setInputComponent(node) {
-		var topic		= node.getAttribute('data-topic');
-		var unit_type	= node.getAttribute('data-unit');
-
-		var input = document.createElement('input');
-		var unit = document.createElement('span');
-		unit.textContent = unit_type;
-
-		input.setAttribute('type', 'text');
-		node.appendChild(input);
-		node.appendChild(unit);
-
-		input.addEventListener('click', function(e) {
-			this.select();
-		});
-
-		input.addEventListener('change', function(e) {
-			setValue(topic, e.target.value | 0);
-		});
-
-		subscribe(topic, function(value) {
-			node.children[0].value = value;
-		});
-	}
-
-	var increment = function increment(topic) {
-		var slider = sliders[topic];
-		if (slider === null || slider === undefined)
-			return;
-
-		if (slider.value + slider.step <= slider.max) {
-			slider.value += slider.step;
-			setValue(slider.topic, slider.value)
-			notify.call(slider);
-		}
-	};
-
-	var decrement = function decrement(topic) {
-		var slider = sliders[topic];
-		if (slider === null || slider === undefined)
-			return;
-
-		if (slider.value - slider.step >= slider.min) {
-			slider.value -= slider.step;
-			setValue(topic, slider.value)
-			notify.call(slider);
-		}
-	}
-
-	// this = Slider object
-	var updateSlider = function updateSlider(e) {
-		var node = this.node;
-		var pos = e.pageX - node.offsetLeft;
-		var width = node.clientWidth;
-		var delta = this.max - this.min;
-		var offset = this.pointer.clientWidth + 4; // border width * 2
-
-		if (pos < 0) pos = 0;
-		if (pos > width) pos = width;
-
-		var value = pos * delta / width | 0;
-		var precision = value % this.step;
-		value = value - precision + this.min;
-		if (precision > this.step / 2)
-			value = value + this.step;
-
-		if (this.snap)
-			pos =  (value - this.min) * width / delta;
-
-		this.pointer.style.left = pos - offset/2 + "px";
-		this.value = value;
-		node.setAttribute('data-value', value);
-		notify.call(this);
-	}
-
-	var setValue = function setValue(topic, value) {
-		var slider = sliders[topic];
-
-		if (value > slider.max || value < slider.min)
-			return;
-
-		var delta = slider.max - slider.min;
-		var width = slider.node.clientWidth;
-		var offset = slider.pointer.clientWidth;
-		var pos =  (value - slider.min) * width / delta;
-		slider.value = value;
-		slider.pointer.style.left = pos - offset / 2 + "px";
-		slider.node.setAttribute('data-value', value);
-		notify.call(slider);
-	}
-
-	var setMouseTracking = function setMouseTracking(elem, callback) {
-		elem.addEventListener("mousedown", function(e) {
-			callback(e);
-			document.addEventListener("mousemove", callback);
-		});
-
-		document.addEventListener("mouseup", function(e) {
-			document.removeEventListener("mousemove", callback);
-		});
-	}
-
-	var subscribe = function subscribe(topic, callback) {
-		if (subscribers[topic] === undefined)
-			subscribers[topic] = [];
-		subscribers[topic].push(callback);
-	}
-
-	var unsubscribe = function unsubscribe(topic, callback) {
-		subscribers[topic].indexOf(callback);
-		subscribers[topic].splice(index, 1);
-	}
-
-	var notify = function notify() {
-		if (subscribers[this.topic] === undefined)
-			return;
-
-		for (var i in subscribers[this.topic]) {
-			subscribers[this.topic][i](this.value);
-		}
-	}
-
-	var init = function init() {
-		var elem, size;
-
-		elem = document.querySelectorAll('.ui-slider-btn-set');
-		size = elem.length;
-		for (var i = 0; i < size; i++)
-			setButtonComponent(elem[i]);
-
-		elem = document.querySelectorAll('.ui-slider-input');
-		size = elem.length;
-		for (var i = 0; i < size; i++)
-			setInputComponent(elem[i]);
-
-		elem = document.querySelectorAll('.ui-slider');
-		size = elem.length;
-		for (var i = 0; i < size; i++)
-			new Slider(elem[i]);
-	}
-
-	return {
-		init : init,
-		setValue : setValue,
-		subscribe : subscribe,
-		unsubscribe : unsubscribe
-	}
-
-})();
-
-/**
- * UI-ButtonManager
- */
-
-var ButtonManager = (function CheckBoxManager() {
-
-	var subscribers = [];
-	var buttons = [];
-
-	var CheckBox = function CheckBox(node) {
-		var topic = node.getAttribute('data-topic');
-		var state = node.getAttribute('data-state');
-		var name = node.getAttribute('data-label');
-		var align = node.getAttribute('data-text-on');
-
-		state = (state === "true");
-
-		var checkbox = document.createElement("input");
-		var label = document.createElement("label");
-
-		var id = 'checkbox-' + topic;
-		checkbox.id = id;
-		checkbox.setAttribute('type', 'checkbox');
-		checkbox.checked = state;
-
-		label.setAttribute('for', id);
-		if (name) {
-			label.className = 'text';
-			if (align)
-				label.className += ' ' + align;
-			label.textContent = name;
-		}
-
-		node.appendChild(checkbox);
-		node.appendChild(label);
-
-		this.node = node;
-		this.topic = topic;
-		this.checkbox = checkbox;
-
-		checkbox.addEventListener('change', function(e) {
-			notify.call(this);
-		}.bind(this));
-
-		buttons[topic] = this;
-	}
-
-	var getNode =  function getNode(topic) {
-		return buttons[topic].node;
-	}
-
-	var setValue = function setValue(topic, value) {
-		try {
-			buttons[topic].checkbox.checked = value;
-			notify.call(buttons[topic]);
-		}
-		catch(error) {
-			console.log(error, topic, value);
-		}
-	}
-
-	var subscribe = function subscribe(topic, callback) {
-		if (subscribers[topic] === undefined)
-			subscribers[topic] = [];
-
-		subscribers[topic].push(callback);
-	}
-
-	var unsubscribe = function unsubscribe(topic, callback) {
-		subscribers[topic].indexOf(callback);
-		subscribers[topic].splice(index, 1);
-	}
-
-	var notify = function notify() {
-		if (subscribers[this.topic] === undefined)
-			return;
-		for (var i = 0; i < subscribers[this.topic].length; i++)
-			subscribers[this.topic][i](this.checkbox.checked);
-	}
-
-	var init = function init() {
-		var elem = document.querySelectorAll('.ui-checkbox');
-		var size = elem.length;
-		for (var i = 0; i < size; i++)
-			new CheckBox(elem[i]);
-	}
-
-	return {
-		init : init,
-		setValue : setValue,
-		subscribe : subscribe,
-		unsubscribe : unsubscribe
-	}
-
-})();
-
-
-window.addEventListener("load", function(){
-	BoxShadow.init();
-});
-
-var BoxShadow = (function BoxShadow() {
-
-	function getElemById(id) {
-		return document.getElementById(id);
-	}
-
-	/**
-	 * RGBA Color class
-	 */
-
-	function Color() {
-		this.r = 0;
-		this.g = 0;
-		this.b = 0;
-		this.a = 1;
-		this.hue = 0;
-		this.saturation = 0;
-		this.value = 0;
-	}
-
-	Color.prototype.copy = function copy(obj) {
-		if(obj instanceof Color !== true) {
-			console.log("Typeof instance not Color");
-			return;
-		}
-
-		this.r = obj.r;
-		this.g = obj.g;
-		this.b = obj.b;
-		this.a = obj.a;
-		this.hue = obj.hue;
-		this.saturation = obj.saturation;
-		this.value = obj.value;
-	}
-
-	Color.prototype.setRGBA = function setRGBA(red, green, blue, alpha) {
-		if (red != undefined)
-			this.r = red | 0;
-		if (green != undefined)
-			this.g = green | 0;
-		if (blue != undefined)
-			this.b = blue | 0;
-		if (alpha != undefined)
-			this.a = alpha | 0;
-	}
-
-	/**
-	 * HSV/HSB (hue, saturation, value / brightness)
-	 * @param hue			0-360
-	 * @param saturation	0-100
-	 * @param value 		0-100
-	 */
-	Color.prototype.setHSV = function setHSV(hue, saturation, value) {
-		this.hue = hue;
-		this.saturation = saturation;
-		this.value = value;
-		this.updateRGB();
-	}
-
-	Color.prototype.updateRGB = function updateRGB() {
-		var sat = this.saturation / 100;
-		var value = this.value / 100;
-		var C = sat * value;
-		var H = this.hue / 60;
-		var X = C * (1 - Math.abs(H % 2 - 1));
-		var m = value - C;
-		var precision = 255;
-
-		C = (C + m) * precision;
-		X = (X + m) * precision;
-		m = m * precision;
-
-		if (H >= 0 && H < 1) {	this.setRGBA(C, X, m);	return; }
-		if (H >= 1 && H < 2) {	this.setRGBA(X, C, m);	return; }
-		if (H >= 2 && H < 3) {	this.setRGBA(m, C, X);	return; }
-		if (H >= 3 && H < 4) {	this.setRGBA(m, X, C);	return; }
-		if (H >= 4 && H < 5) {	this.setRGBA(X, m, C);	return; }
-		if (H >= 5 && H < 6) {	this.setRGBA(C, m, X);	return; }
-	}
-
-	Color.prototype.updateHSV = function updateHSV() {
-		var red		= this.r / 255;
-		var green	= this.g / 255;
-		var blue	= this.b / 255;
-
-		var cmax = Math.max(red, green, blue);
-		var cmin = Math.min(red, green, blue);
-		var delta = cmax - cmin;
-		var hue = 0;
-		var saturation = 0;
-
-		if (delta) {
-			if (cmax === red ) { hue = ((green - blue) / delta); }
-			if (cmax === green ) { hue = 2 + (blue - red) / delta; }
-			if (cmax === blue ) { hue = 4 + (red - green) / delta; }
-			if (cmax) saturation = delta / cmax;
-		}
-
-		this.hue = 60 * hue | 0;
-		if (this.hue < 0) this.hue += 360;
-		this.saturation = (saturation * 100) | 0;
-		this.value = (cmax * 100) | 0;
-	}
-
-	Color.prototype.setHexa = function setHexa(value) {
-		var valid  = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)/i.test(value)
-		if (valid !== true)
-			return;
-
-		if (value[0] === '#')
-			value = value.slice(1, value.length);
-
-		if (value.length === 3)
-			value = value.replace(/([0-9A-F])([0-9A-F])([0-9A-F])/i,"$1$1$2$2$3$3");
-
-		this.r = parseInt(value.substr(0, 2), 16);
-		this.g = parseInt(value.substr(2, 2), 16);
-		this.b = parseInt(value.substr(4, 2), 16);
-
-		this.alpha	= 1;
-	}
-
-	Color.prototype.getHexa = function getHexa() {
-		var r = this.r.toString(16);
-		var g = this.g.toString(16);
-		var b = this.b.toString(16);
-		if (this.r < 16) r = '0' + r;
-		if (this.g < 16) g = '0' + g;
-		if (this.b < 16) b = '0' + b;
-		var value = '#' + r + g + b;
-		return value.toUpperCase();
-	}
-
-	Color.prototype.getRGBA = function getRGBA() {
-
-		var rgb = "(" + this.r + ", " + this.g + ", " + this.b;
-		var a = '';
-		var v = '';
-		if (this.a !== 1) {
-			a = 'a';
-			v = ', ' + this.a;
-		}
-
-		var value = "rgb" + a + rgb + v + ")";
-		return value;
-	}
-
-	Color.prototype.getColor = function getColor() {
-		if (this.a | 0 === 1)
-			return this.getHexa();
-		return this.getRGBA();
-	}
-
-	/**
-	 * Shadow Object
-	 */
-	function Shadow() {
-		this.inset  = false;
-		this.posX   = 5;
-		this.posY   = -5;
-		this.blur   = 5;
-		this.spread = 0;
-		this.color  = new Color();
-
-		var hue			= (Math.random() * 360) | 0;
-		var saturation	= (Math.random() * 75) | 0;
-		var value 		= (Math.random() * 50 + 50) | 0;
-		this.color.setHSV(hue, saturation, value, 1);
-	}
-
-	Shadow.prototype.computeCSS = function computeCSS() {
-		var value = "";
-		if (this.inset === true)
-			value += "inset ";
-		value += this.posX + "px ";
-		value += this.posY + "px ";
-		value += this.blur + "px ";
-		value += this.spread + "px ";
-		value += this.color.getColor();
-
-		return value;
-	}
-
-	Shadow.prototype.toggleInset = function toggleInset(value) {
-		if (value !== undefined || typeof value === "boolean")
-			this.inset = value;
-		else
-			this.inset = this.inset === true ? false : true;
-	}
-
-	Shadow.prototype.copy = function copy(obj) {
-		if(obj instanceof Shadow !== true) {
-			console.log("Typeof instance not Shadow");
-			return;
-		}
-
-		this.inset  = obj.inset;
-		this.posX   = obj.posX;
-		this.posY   = obj.posY;
-		this.blur   = obj.blur;
-		this.spread = obj.spread;
-		this.color.copy(obj.color);
-	}
-
-	/**
-	 * Color Picker
-	 */
-	var ColoPicker = (function ColoPicker() {
-
-		var colorpicker;
-		var hue_area;
-		var gradient_area;
-		var alpha_area;
-		var gradient_picker;
-		var hue_selector;
-		var alpha_selector;
-		var pick_object;
-		var info_rgb;
-		var info_hsv;
-		var info_hexa;
-		var output_color;
-		var color = new Color();
-		var subscribers = [];
-
-		var updateColor = function updateColor(e) {
-			var x = e.pageX - gradient_area.offsetLeft;
-			var y = e.pageY - gradient_area.offsetTop;
-
-			// width and height should be the same
-			var size = gradient_area.clientWidth;
-
-			if (x > size)
-				x = size;
-			if (y > size)
-				y = size;
-
-			if (x < 0) x = 0;
-			if (y < 0) y = 0;
-
-			var value = 100 - (y * 100 / size) | 0;
-			var saturation = x * 100 / size | 0;
-
-			color.setHSV(color.hue, saturation, value);
-			// should update just
-			// color pointer location
-			updateUI();
-			notify("color", color);
-		}
-
-		var updateHue = function updateHue(e) {
-			var x = e.pageX - hue_area.offsetLeft;
-			var width = hue_area.clientWidth;
-
-			if (x < 0) x = 0;
-			if (x > width) x = width;
-
-			var hue = ((360 * x) / width) | 0;
-			if (hue === 360) hue = 359;
-
-			color.setHSV(hue, color.saturation, color.value);
-
-			// should update just
-			// hue pointer location
-			// picker area background
-			// alpha area background
-			updateUI();
-			notify("color", color);
-		}
-
-		var updateAlpha = function updateAlpha(e) {
-			var x = e.pageX - alpha_area.offsetLeft;
-			var width = alpha_area.clientWidth;
-
-			if (x < 0) x = 0;
-			if (x > width) x = width;
-
-			color.a = (x / width).toFixed(2);
-
-			// should update just
-			// alpha pointer location
-			updateUI();
-			notify("color", color);
-		}
-
-		var setHueGfx = function setHueGfx(hue) {
-			var sat = color.saturation;
-			var val = color.value;
-			var alpha = color.a;
-
-			color.setHSV(hue, 100, 100);
-			gradient_area.style.backgroundColor = color.getHexa();
-
-			color.a = 0;
-			var start = color.getRGBA();
-			color.a = 1;
-			var end = color.getRGBA();
-			color.a = alpha;
-
-			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
-			alpha_area.style.background = gradient;
-		}
-
-		var updateUI = function updateUI() {
-			var x, y;		// coordinates
-			var size;		// size of the area
-			var offset;		// pointer graphic selector offset
-
-			// Set color pointer location
-			size = gradient_area.clientWidth;
-			offset = gradient_picker.clientWidth / 2 + 2;
-
-			x = (color.saturation * size / 100) | 0;
-			y = size - (color.value * size / 100) | 0;
-
-			gradient_picker.style.left = x - offset + "px";
-			gradient_picker.style.top = y - offset + "px";
-
-			// Set hue pointer location
-			size = hue_area.clientWidth;
-			offset = hue_selector.clientWidth/2;
-			x = (color.hue * size / 360 ) | 0;
-			hue_selector.style.left = x - offset + "px";
-
-			// Set alpha pointer location
-			size = alpha_area.clientWidth;
-			offset = alpha_selector.clientWidth/2;
-			x = (color.a * size) | 0;
-			alpha_selector.style.left = x - offset + "px";
-
-			// Set picker area background
-			var nc = new Color();
-			nc.copy(color);
-			if (nc.hue === 360) nc.hue = 0;
-			nc.setHSV(nc.hue, 100, 100);
-			gradient_area.style.backgroundColor = nc.getHexa();
-
-			// Set alpha area background
-			nc.copy(color);
-			nc.a = 0;
-			var start = nc.getRGBA();
-			nc.a = 1;
-			var end = nc.getRGBA();
-			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
-			alpha_area.style.background = gradient;
-
-			// Update color info
-			notify("color", color);
-			notify("hue", color.hue);
-			notify("saturation", color.saturation);
-			notify("value", color.value);
-			notify("r", color.r);
-			notify("g", color.g);
-			notify("b", color.b);
-			notify("a", color.a);
-			notify("hexa", color.getHexa());
-			output_color.style.backgroundColor = color.getRGBA();
-		}
-
-		var setInputComponent = function setInputComponent(node) {
-			var topic = node.getAttribute('data-topic');
-			var title = node.getAttribute('data-title');
-			var action = node.getAttribute('data-action');
-			title = title === null ? '' : title;
-
-			var input = document.createElement('input');
-			var info = document.createElement('span');
-			info.textContent = title;
-
-			input.setAttribute('type', 'text');
-			input.setAttribute('data-action', 'set-' + action + '-' + topic);
-			node.appendChild(info);
-			node.appendChild(input);
-
-			input.addEventListener('click', function(e) {
-				this.select();
-			});
-
-			input.addEventListener('change', function(e) {
-				if (action === 'HSV')
-					inputChangeHSV(topic);
-				if (action === 'RGB')
-					inputChangeRGB(topic);
-				if (action === 'alpha')
-					inputChangeAlpha(topic);
-				if (action === 'hexa')
-					inputChangeHexa(topic);
-			});
-
-			subscribe(topic, function(value) {
-				node.children[1].value = value;
-			});
-		}
-
-		var inputChangeHSV = function actionHSV(topic) {
-			var selector = "[data-action='set-HSV-" + topic + "']";
-			var node = document.querySelector("#colorpicker " + selector);
-			var value = parseInt(node.value);
-
-			if (typeof value === 'number' && isNaN(value) === false &&
-				value >= 0 && value < 360)
-				color[topic] = value;
-
-			color.updateRGB();
-			updateUI();
-		}
-
-		var inputChangeRGB = function inputChangeRGB(topic) {
-			var selector = "[data-action='set-RGB-" + topic + "']";
-			var node = document.querySelector("#colorpicker " + selector);
-			var value = parseInt(node.value);
-
-			if (typeof value === 'number' && isNaN(value) === false &&
-				value >= 0 && value <= 255)
-				color[topic] = value;
-
-			color.updateHSV();
-			updateUI();
-		}
-
-		var inputChangeAlpha = function inputChangeAlpha(topic) {
-			var selector = "[data-action='set-alpha-" + topic + "']";
-			var node = document.querySelector("#colorpicker " + selector);
-			var value = parseFloat(node.value);
-
-			if (typeof value === 'number' && isNaN(value) === false &&
-				value >= 0 && value <= 1)
-				color.a = value.toFixed(2);
-
-			updateUI();
-		}
-
-		var inputChangeHexa = function inputChangeHexa(topic) {
-			var selector = "[data-action='set-hexa-" + topic + "']";
-			var node = document.querySelector("#colorpicker " + selector);
-			var value = node.value;
-			color.setHexa(value);
-			color.updateHSV();
-			updateUI();
-		}
-
-		var setMouseTracking = function setMouseTracking(elem, callback) {
-
-			elem.addEventListener("mousedown", function(e) {
-				callback(e);
-				document.addEventListener("mousemove", callback);
-			});
-
-			document.addEventListener("mouseup", function(e) {
-				document.removeEventListener("mousemove", callback);
-			});
-		}
-
-		/*
-		 * Observer
-		 */
-		var setColor = function setColor(obj) {
-			if(obj instanceof Color !== true) {
-				console.log("Typeof instance not Color");
-				return;
-			}
-			color.copy(obj);
-			updateUI();
-		}
-
-		var subscribe = function subscribe(topic, callback) {
-			if (subscribers[topic] === undefined)
-				subscribers[topic] = [];
-
-			subscribers[topic].push(callback);
-		}
-
-		var unsubscribe = function unsubscribe(callback) {
-			subscribers.indexOf(callback);
-			subscribers.splice(index, 1);
-		}
-
-		var notify = function notify(topic, value) {
-			for (var i in subscribers[topic])
-				subscribers[topic][i](value);
-		}
-
-		var init = function init() {
-			colorpicker		= getElemById("colorpicker");
-			hue_area		= getElemById("hue");
-			gradient_area	= getElemById("gradient");
-			alpha_area		= getElemById("alpha");
-			gradient_picker	= getElemById("gradient_picker");
-			hue_selector	= getElemById("hue_selector");
-			alpha_selector	= getElemById("alpha_selector");
-			output_color	= getElemById("output_color");
-
-			var elem = document.querySelectorAll('#colorpicker .input');
-			var size = elem.length;
-			for (var i = 0; i < size; i++)
-				setInputComponent(elem[i]);
-
-			setMouseTracking(gradient_area, updateColor);
-			setMouseTracking(hue_area, updateHue);
-			setMouseTracking(alpha_area, updateAlpha);
-
-		}
-
-		return {
-			init : init,
-			setColor : setColor,
-			subscribe : subscribe,
-			unsubscribe : unsubscribe
-		}
-
-	})();
-
-	/**
-	 * Shadow dragging
-	 */
-	var PreviewMouseTracking = (function Drag() {
-		var active = false;
-		var lastX = 0;
-		var lastY = 0;
-		var subscribers = [];
-
-		var init = function init(id) {
-			var elem = getElemById(id);
-			elem.addEventListener('mousedown', dragStart, false);
-			document.addEventListener('mouseup', dragEnd, false);
-		}
-
-		var dragStart = function dragStart(e) {
-			if (e.button !== 0)
-				return;
-
-			active = true;
-			lastX = e.clientX;
-			lastY = e.clientY;
-			document.addEventListener('mousemove', mouseDrag, false);
-		}
-
-		var dragEnd = function dragEnd(e) {
-			if (e.button !== 0)
-				return;
-
-			if (active === true) {
-				active = false;
-				document.removeEventListener('mousemove', mouseDrag, false);
-			}
-		}
-
-		var mouseDrag = function mouseDrag(e) {
-			notify(e.clientX - lastX, e.clientY - lastY);
-			lastX = e.clientX;
-			lastY = e.clientY;
-		}
-
-		var subscribe = function subscribe(callback) {
-			subscribers.push(callback);
-		}
-
-		var unsubscribe = function unsubscribe(callback) {
-			var index = subscribers.indexOf(callback);
-			subscribers.splice(index, 1);
-		}
-
-		var notify = function notify(deltaX, deltaY) {
-			for (var i in subscribers)
-				subscribers[i](deltaX, deltaY);
-		}
-
-		return {
-			init : init,
-			subscribe : subscribe,
-			unsubscribe : unsubscribe
-		}
-
-	})();
-
-	/*
-	 * Element Class
-	 */
-	var CssClass = function CssClass(id) {
-		this.left = 0;
-		this.top = 0;
-		this.rotate = 0;
-		this.width = 300;
-		this.height = 100;
-		this.display = true;
-		this.border = true;
-		this.zIndex = -1;
-		this.bgcolor = new Color();
-		this.id = id;
-		this.node = getElemById('obj-' + id);
-		this.object = getElemById(id);
-		this.shadowID = null;
-		this.shadows = []
-		this.render = [];
-		this.init();
-	}
-
-	CssClass.prototype.init = function init() {
-		this.left = ((this.node.parentNode.clientWidth - this.node.clientWidth) / 2) | 0;
-		this.top = ((this.node.parentNode.clientHeight - this.node.clientHeight) / 2) | 0;
-
-		this.setTop(this.top);
-		this.setLeft(this.left);
-		this.setHeight(this.height);
-		this.setWidth(this.width);
-		this.bgcolor.setHSV(0, 0, 100);
-		this.updateBgColor(this.bgcolor);
-	}
-
-	CssClass.prototype.updatePos = function updatePos(deltaX, deltaY) {
-		this.left += deltaX;
-		this.top += deltaY;
-		this.node.style.top = this.top + "px";
-		this.node.style.left = this.left + "px";
-		SliderManager.setValue("left", this.left);
-		SliderManager.setValue("top", this.top);
-	}
-
-	CssClass.prototype.setLeft = function setLeft(value) {
-		this.left = value;
-		this.node.style.left = this.left + "px";
-		OutputManager.updateProperty(this.id, 'left', this.left + 'px');
-	}
-
-	CssClass.prototype.setTop = function setTop(value) {
-		this.top = value;
-		this.node.style.top = this.top + 'px';
-		OutputManager.updateProperty(this.id, 'top', this.top + 'px');
-	}
-
-	CssClass.prototype.setWidth = function setWidth(value) {
-		this.width = value;
-		this.node.style.width = this.width + 'px';
-		OutputManager.updateProperty(this.id, 'width', this.width + 'px');
-	}
-
-	CssClass.prototype.setHeight = function setHeight(value) {
-		this.height = value;
-		this.node.style.height = this.height + 'px';
-		OutputManager.updateProperty(this.id, 'height', this.height + 'px');
-	}
-
-	// Browser support
-	CssClass.prototype.setRotate = function setRotate(value) {
-		var cssvalue = 'rotate(' + value +'deg)';
-
-		this.node.style.transform = cssvalue;
-		this.node.style.webkitTransform = cssvalue;
-		this.node.style.msTransform = cssvalue;
-
-		if (value !== 0) {
-			if (this.rotate === 0) {
-				OutputManager.toggleProperty(this.id, 'transform', true);
-				OutputManager.toggleProperty(this.id, '-webkit-transform', true);
-				OutputManager.toggleProperty(this.id, '-ms-transform', true);
-			}
-		}
-		else {
-			OutputManager.toggleProperty(this.id, 'transform', false);
-			OutputManager.toggleProperty(this.id, '-webkit-transform', false);
-			OutputManager.toggleProperty(this.id, '-ms-transform', false);
-		}
-
-		OutputManager.updateProperty(this.id, 'transform', cssvalue);
-		OutputManager.updateProperty(this.id, '-webkit-transform', cssvalue);
-		OutputManager.updateProperty(this.id, '-ms-transform', cssvalue);
-		this.rotate = value;
-	}
-
-	CssClass.prototype.setzIndex = function setzIndex(value) {
-		this.node.style.zIndex = value;
-		OutputManager.updateProperty(this.id, 'z-index', value);
-		this.zIndex = value;
-	}
-
-	CssClass.prototype.toggleDisplay = function toggleDisplay(value) {
-		if (typeof value !== "boolean" || this.display === value)
-			return;
-
-		this.display = value;
-		var display = this.display === true ? "block" : "none";
-		this.node.style.display = display;
-		this.object.style.display = display;
-	}
-
-	CssClass.prototype.toggleBorder = function toggleBorder(value) {
-		if (typeof value !== "boolean" || this.border === value)
-			return;
-
-		this.border = value;
-		var border = this.border === true ? "1px solid #CCC" : "none";
-		this.node.style.border = border;
-	}
-
-	CssClass.prototype.updateBgColor = function updateBgColor(color) {
-		this.bgcolor.copy(color);
-		this.node.style.backgroundColor = color.getColor();
-		OutputManager.updateProperty(this.id, 'background-color', color.getColor());
-	}
-
-	CssClass.prototype.updateShadows = function updateShadows() {
-		if (this.render.length === 0)
-			OutputManager.toggleProperty(this.id, 'box-shadow', false);
-		if (this.render.length === 1)
-			OutputManager.toggleProperty(this.id, 'box-shadow', true);
-
-		this.node.style.boxShadow = this.render.join(", ");
-		OutputManager.updateProperty(this.id, 'box-shadow', this.render.join(", \n"));
-
-	}
-
-
-	/**
-	 * Tool Manager
-	 */
-	var Tool = (function Tool() {
-
-		var preview;
-		var classes = [];
-		var active = null;
-		var animate = false;
-
-		/*
-		 * Toll actions
-		 */
-		var addCssClass = function addCssClass(id) {
-			classes[id] = new CssClass(id);
-		}
-
-		var setActiveClass = function setActiveClass(id) {
-			active = classes[id];
-			active.shadowID = null;
-			ColoPicker.setColor(classes[id].bgcolor);
-			SliderManager.setValue("top", active.top);
-			SliderManager.setValue("left", active.left);
-			SliderManager.setValue("rotate", active.rotate);
-			SliderManager.setValue("z-index", active.zIndex);
-			SliderManager.setValue("width", active.width);
-			SliderManager.setValue("height", active.height);
-			ButtonManager.setValue("border-state", active.border);
-			active.updateShadows();
-		}
-
-		var disableClass = function disableClass(topic) {
-			classes[topic].toggleDisplay(false);
-			ButtonManager.setValue(topic, false);
-		}
-
-		var addShadow = function addShadow(position) {
-			if (animate === true)
-				return -1;
-
-			active.shadows.splice(position, 0, new Shadow());
-			active.render.splice(position, 0, null);
-		}
-
-		var swapShadow = function swapShadow(id1, id2) {
-			var x = active.shadows[id1];
-			active.shadows[id1] = active.shadows[id2];
-			active.shadows[id2] = x;
-			updateShadowCSS(id1);
-			updateShadowCSS(id2);
-		}
-
-		var deleteShadow = function deleteShadow(position) {
-			active.shadows.splice(position, 1);
-			active.render.splice(position, 1);
-			active.updateShadows();
-		}
-
-		var setActiveShadow = function setActiveShadow(id, glow) {
-			active.shadowID = id;
-			ColoPicker.setColor(active.shadows[id].color);
-			ButtonManager.setValue("inset", active.shadows[id].inset);
-			SliderManager.setValue("blur", active.shadows[id].blur);
-			SliderManager.setValue("spread", active.shadows[id].spread);
-			SliderManager.setValue("posX", active.shadows[id].posX);
-			SliderManager.setValue("posY", active.shadows[id].posY);
-			if (glow === true)
-				addGlowEffect(id);
-		}
-
-		var addGlowEffect = function addGlowEffect(id) {
-			if (animate === true)
-				return;
-
-			animate = true;
-			var store = new Shadow();
-			var shadow = active.shadows[id];
-
-			store.copy(shadow);
-			shadow.color.setRGBA(40, 125, 200, 1);
-			shadow.blur = 10;
-			shadow.spread = 10;
-
-			active.node.style.transition = "box-shadow 0.2s";
-			updateShadowCSS(id);
-
-			setTimeout(function() {
-				shadow.copy(store);
-				updateShadowCSS(id);
-				setTimeout(function() {
-					active.node.style.removeProperty("transition");
-					animate = false;
-				}, 100);
-			}, 200);
-		}
-
-		var updateActivePos = function updateActivePos(deltaX, deltaY) {
-			if (active.shadowID === null)
-				active.updatePos(deltaX, deltaY);
-			else
-				updateShadowPos(deltaX, deltaY);
-		}
-
-		/*
-		 * Shadow properties
-		 */
-		var updateShadowCSS = function updateShadowCSS(id) {
-			active.render[id] = active.shadows[id].computeCSS();
-			active.updateShadows();
-		}
-
-		var toggleShadowInset = function toggleShadowInset(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].toggleInset(value);
-			updateShadowCSS(active.shadowID);
-		}
-
-		var updateShadowPos = function updateShadowPos(deltaX, deltaY) {
-			var shadow = active.shadows[active.shadowID];
-			shadow.posX += deltaX;
-			shadow.posY += deltaY;
-			SliderManager.setValue("posX", shadow.posX);
-			SliderManager.setValue("posY", shadow.posY);
-			updateShadowCSS(active.shadowID);
-		}
-
-		var setShadowPosX = function setShadowPosX(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].posX = value;
-			updateShadowCSS(active.shadowID);
-		}
-
-		var setShadowPosY = function setShadowPosY(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].posY = value;
-			updateShadowCSS(active.shadowID);
-		}
-
-		var setShadowBlur = function setShadowBlur(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].blur = value;
-			updateShadowCSS(active.shadowID);
-		}
-
-		var setShadowSpread = function setShadowSpread(value) {
-			if (active.shadowID === null)
-				return;
-			active.shadows[active.shadowID].spread = value;
-			updateShadowCSS(active.shadowID);
-		}
-
-		var updateShadowColor = function updateShadowColor(color) {
-			active.shadows[active.shadowID].color.copy(color);
-			updateShadowCSS(active.shadowID);
-		}
-
-		/*
-		 * Element Properties
-		 */
-		var updateColor = function updateColor(color) {
-			if (active.shadowID === null)
-				active.updateBgColor(color);
-			else
-				updateShadowColor(color);
-		}
-
-		var init = function init() {
-			preview = getElemById("preview");
-
-			ColoPicker.subscribe("color", updateColor);
-			PreviewMouseTracking.subscribe(updateActivePos);
-
-			// Affects shadows
-			ButtonManager.subscribe("inset", toggleShadowInset);
-			SliderManager.subscribe("posX", setShadowPosX);
-			SliderManager.subscribe("posY", setShadowPosY);
-			SliderManager.subscribe("blur", setShadowBlur);
-			SliderManager.subscribe("spread", setShadowSpread);
-
-			// Affects element
-			SliderManager.subscribe("top", function(value){
-				active.setTop(value);
-			});
-			SliderManager.subscribe("left", function(value){
-				active.setLeft(value);
-			});
-			SliderManager.subscribe("rotate", function(value) {
-				if (active == classes["element"])
-					return;
-				active.setRotate(value);
-			});
-
-			SliderManager.subscribe("z-index", function(value) {
-				if (active == classes["element"])
-					return;
-				active.setzIndex(value);
-			});
-
-			SliderManager.subscribe("width", function(value) {
-				active.setWidth(value)
-			});
-
-			SliderManager.subscribe("height", function(value) {
-				active.setHeight(value)
-			});
-
-			// Actions
-			classes['before'].top = -30;
-			classes['before'].left = -30;
-			classes['after'].top = 30;
-			classes['after'].left = 30;
-			classes['before'].toggleDisplay(false);
-			classes['after'].toggleDisplay(false);
-			ButtonManager.setValue('before', false);
-			ButtonManager.setValue('after', false);
-
-			ButtonManager.subscribe("before", classes['before'].toggleDisplay.bind(classes['before']));
-			ButtonManager.subscribe("after", classes['after'].toggleDisplay.bind(classes['after']));
-
-			ButtonManager.subscribe("border-state", function(value) {
-				active.toggleBorder(value);
-			});
-
-		}
-
-		return {
-			init 			: init,
-			addShadow		: addShadow,
-			swapShadow		: swapShadow,
-			addCssClass		: addCssClass,
-			disableClass	: disableClass,
-			deleteShadow	: deleteShadow,
-			setActiveClass	: setActiveClass,
-			setActiveShadow : setActiveShadow
-		}
-
-	})();
-
-	/**
-	 * Layer Manager
-	 */
-	var LayerManager = (function LayerManager() {
-		var stacks = [];
-		var active = {
-			node : null,
-			stack : null
-		}
-		var elements = {};
-
-		var mouseEvents = function mouseEvents(e) {
-			var node = e.target;
-			var type = node.getAttribute('data-type');
-
-			if (type === 'subject')
-				setActiveStack(stacks[node.id]);
-
-			if (type === 'disable') {
-				Tool.disableClass(node.parentNode.id);
-				setActiveStack(stacks['element']);
-			}
-
-			if (type === 'add')
-				active.stack.addLayer();
-
-			if (type === 'layer')
-				active.stack.setActiveLayer(node);
-
-			if (type === 'delete')
-				active.stack.deleteLayer(node.parentNode);
-
-			if (type === 'move-up')
-				active.stack.moveLayer(1);
-
-			if (type === 'move-down')
-				active.stack.moveLayer(-1);
-		}
-
-		var setActiveStack = function setActiveStack(stackObj) {
-			active.stack.hide();
-			active.stack = stackObj;
-			active.stack.show();
-		}
-
-		/*
-		 * Stack object
-		 */
-		var Stack = function Stack(subject) {
-			var S = document.createElement('div');
-			var title = document.createElement('div');
-			var stack = document.createElement('div');
-
-			S.className = 'container';
-			stack.className = 'stack';
-			title.className = 'title';
-			title.textContent = subject.getAttribute('data-title');
-			S.appendChild(title);
-			S.appendChild(stack);
-
-			this.id = subject.id;
-			this.container = S;
-			this.stack = stack;
-			this.subject = subject;
-			this.order = [];
-			this.uid = 0;
-			this.count = 0;
-			this.layer = null;
-			this.layerID = 0;
-		}
-
-		Stack.prototype.addLayer = function addLayer() {
-			if (Tool.addShadow(this.layerID) == -1)
-				return;
-
-			var uid = this.getUID();
-			var layer = this.createLayer(uid);
-
-			if (this.layer === null && this.stack.children.length >= 1)
-				this.layer = this.stack.children[0];
-
-			this.stack.insertBefore(layer, this.layer);
-			this.order.splice(this.layerID, 0, uid);
-			this.count++;
-			this.setActiveLayer(layer);
-		}
-
-		Stack.prototype.createLayer = function createLayer(uid) {
-			var layer = document.createElement('div');
-			var del = document.createElement('span');
-
-			layer.className = 'node';
-			layer.setAttribute('data-shid', uid);
-			layer.setAttribute('data-type', 'layer');
-			layer.textContent = 'тень ' + uid;
-
-			del.className = 'delete';
-			del.setAttribute('data-type', 'delete');
-
-			layer.appendChild(del);
-			return layer;
-		}
-
-		Stack.prototype.getUID = function getUID() {
-			return this.uid++;
-		}
-
-		// SOLVE IE BUG
-		Stack.prototype.moveLayer = function moveLayer(direction) {
-			if (this.count <= 1 || this.layer === null)
-				return;
-			if (direction === -1 && this.layerID === (this.count - 1) )
-				return;
-			if (direction === 1 && this.layerID === 0 )
-				return;
-
-			if (direction === -1) {
-				var before = null;
-				Tool.swapShadow(this.layerID, this.layerID + 1);
-				this.swapOrder(this.layerID, this.layerID + 1);
-				this.layerID += 1;
-
-				if (this.layerID + 1 !== this.count)
-					before = this.stack.children[this.layerID + 1];
-
-				this.stack.insertBefore(this.layer, before);
-				Tool.setActiveShadow(this.layerID, false);
-			}
-
-			if (direction === 1) {
-				Tool.swapShadow(this.layerID, this.layerID - 1);
-				this.swapOrder(this.layerID, this.layerID - 1);
-				this.layerID -= 1;
-				this.stack.insertBefore(this.layer, this.stack.children[this.layerID]);
-				Tool.setActiveShadow(this.layerID, false);
-			}
-		}
-
-		Stack.prototype.swapOrder = function swapOrder(pos1, pos2) {
-			var x = this.order[pos1];
-			this.order[pos1] = this.order[pos2];
-			this.order[pos2] = x;
-		}
-
-		Stack.prototype.deleteLayer = function deleteLayer(node) {
-			var shadowID =  node.getAttribute('data-shid') | 0;
-			var index = this.order.indexOf(shadowID);
-			this.stack.removeChild(this.stack.children[index]);
-			this.order.splice(index, 1);
-			this.count--;
-
-			Tool.deleteShadow(index);
-
-			if (index > this.layerID)
-				return;
-
-			if (index == this.layerID) {
-				if (this.count >= 1) {
-					this.layerID = 0;
-					this.setActiveLayer(this.stack.children[0], true);
-				}
-				else {
-					this.layer = null;
-					this.show();
-				}
-			}
-
-			if (index < this.layerID) {
-				this.layerID--;
-				Tool.setActiveShadow(this.layerID, true);
-			}
-
-		}
-
-		Stack.prototype.setActiveLayer = function setActiveLayer(node) {
-			elements.shadow_properties.style.display = 'block';
-			elements.element_properties.style.display = 'none';
-
-			if (this.layer)
-				this.layer.removeAttribute('data-active');
-
-			this.layer = node;
-			this.layer.setAttribute('data-active', 'layer');
-
-			var shadowID =  node.getAttribute('data-shid') | 0;
-			this.layerID = this.order.indexOf(shadowID);
-			Tool.setActiveShadow(this.layerID, true);
-		}
-
-		Stack.prototype.unsetActiveLayer = function unsetActiveLayer() {
-			if (this.layer)
-				this.layer.removeAttribute('data-active');
-
-			this.layer = null;
-			this.layerID = 0;
-		}
-
-		Stack.prototype.hide = function hide() {
-			this.unsetActiveLayer();
-			this.subject.removeAttribute('data-active');
-			var style = this.container.style;
-			style.left = '100%';
-			style.zIndex = '0';
-		}
-
-		Stack.prototype.show = function show() {
-			elements.shadow_properties.style.display = 'none';
-			elements.element_properties.style.display = 'block';
-
-			if (this.id === 'element') {
-				elements.zIndex.style.display = 'none';
-				elements.transform_rotate.style.display = 'none';
-			}
-			else {
-				elements.zIndex.style.display = 'block';
-				elements.transform_rotate.style.display = 'block';
-			}
-
-			this.subject.setAttribute('data-active', 'subject');
-			var style = this.container.style;
-			style.left = '0';
-			style.zIndex = '10';
-			Tool.setActiveClass(this.id);
-		}
-
-		function init() {
-
-			var elem, size;
-			var layerManager = getElemById("layer_manager");
-			var layerMenu = getElemById("layer_menu");
-			var container = getElemById("stack_container");
-
-			elements.shadow_properties = getElemById('shadow_properties');
-			elements.element_properties = getElemById('element_properties');
-			elements.transform_rotate = getElemById('transform_rotate');
-			elements.zIndex = getElemById('z-index');
-
-			elem = document.querySelectorAll('#layer_menu [data-type="subject"]');
-			size = elem.length;
-
-			for (var i = 0; i < size; i++) {
-				var S = new Stack(elem[i]);
-				stacks[elem[i].id] = S;
-				container.appendChild(S.container);
-				Tool.addCssClass(elem[i].id);
-			}
-
-			active.stack = stacks['element'];
-			stacks['element'].show();
-
-			layerManager.addEventListener("click", mouseEvents);
-			layerMenu.addEventListener("click", mouseEvents);
-
-			ButtonManager.subscribe("before", function(value) {
-				if (value === false && active.stack === stacks['before'])
-					setActiveStack(stacks['element'])
-				if (value === true && active.stack !== stacks['before'])
-					setActiveStack(stacks['before'])
-			});
-
-			ButtonManager.subscribe("after", function(value) {
-				if (value === false && active.stack === stacks['after'])
-					setActiveStack(stacks['element'])
-				if (value === true && active.stack !== stacks['after'])
-					setActiveStack(stacks['after'])
-			});
-		}
-
-		return {
-			init : init
-		}
-	})();
-
-	/*
-	 * OutputManager
-	 */
-	var OutputManager = (function OutputManager() {
-		var classes = [];
-		var buttons = [];
-		var active = null;
-		var menu = null;
-		var button_offset = 0;
-
-		var crateOutputNode = function(topic, property) {
-
-			var prop = document.createElement('div');
-			var name = document.createElement('span');
-			var value = document.createElement('span');
-
-			var pmatch = property.match(/(^([a-z0-9\-]*)=\[([a-z0-9\-\"]*)\])|^([a-z0-9\-]*)/i);
-
-			name.textContent = '\t' + pmatch[4];
-
-			if (pmatch[3] !== undefined) {
-				name.textContent = '\t' + pmatch[2];
-				value.textContent = pmatch[3] + ';';
-			}
-
-			name.textContent += ': ';
-			prop.className = 'css-property';
-			name.className = 'name';
-			value.className = 'value';
-			prop.appendChild(name);
-			prop.appendChild(value);
-
-			classes[topic].node.appendChild(prop);
-			classes[topic].line[property] = prop;
-			classes[topic].prop[property] = value;
-		}
-
-		var OutputClass = function OutputClass(node) {
-			var topic = node.getAttribute('data-topic');
-			var prop = node.getAttribute('data-prop');
-			var name = node.getAttribute('data-name');
-			var properties = prop.split(' ');
-
-			classes[topic] = {};
-			classes[topic].node = node;
-			classes[topic].prop = [];
-			classes[topic].line = [];
-			classes[topic].button = new Button(topic);
-
-			var open_decl = document.createElement('div');
-			var end_decl = document.createElement('div');
-
-			open_decl.textContent = name + ' {';
-			end_decl.textContent = '}';
-			node.appendChild(open_decl);
-
-			for (var i in properties)
-				crateOutputNode(topic, properties[i]);
-
-			node.appendChild(end_decl);
-		}
-
-		var Button = function Button(topic) {
-			var button = document.createElement('div');
-
-			button.className = 'button';
-			button.textContent = topic;
-			button.style.left = button_offset + 'px';
-			button_offset += 100;
-
-			button.addEventListener("click", function() {
-				toggleDisplay(topic);
-			})
-
-			menu.appendChild(button);
-			return button;
-		}
-
-		var toggleDisplay = function toggleDisplay(topic) {
-			active.button.removeAttribute('data-active');
-			active.node.style.display = 'none';
-			active = classes[topic];
-			active.node.style.display = 'block';
-			active.button.setAttribute('data-active', 'true');
-		}
-
-		var toggleButton = function toggleButton(topic, value) {
-			var display = (value === true) ? 'block' : 'none';
-			classes[topic].button.style.display = display;
-
-			if (value === true)
-				toggleDisplay(topic);
-			else
-				toggleDisplay('element');
-		}
-
-		var updateProperty = function updateProperty(topic, property, data) {
-			try {
-				classes[topic].prop[property].textContent = data + ';';
-			}
-			catch(error) {
-				// console.log("ERROR undefined : ", topic, property, data);
-			}
-		}
-
-		var toggleProperty = function toggleProperty(topic, property, value) {
-			var display = (value === true) ? 'block' : 'none';
-			try {
-				classes[topic].line[property].style.display = display;
-			}
-			catch(error) {
-				// console.log("ERROR undefined : ",classes, topic, property, value);
-			}
-		}
-
-		var init = function init() {
-
-			menu = getElemById('menu');
-
-			var elem = document.querySelectorAll('#output .output');
-			var size = elem.length;
-			for (var i = 0; i < size; i++)
-				OutputClass(elem[i]);
-
-			active = classes['element'];
-			toggleDisplay('element');
-
-			ButtonManager.subscribe("before", function(value) {
-				toggleButton('before', value);
-			});
-
-			ButtonManager.subscribe("after", function(value) {
-				toggleButton('after', value);
-			});
-		}
-
-		return {
-			init : init,
-			updateProperty : updateProperty,
-			toggleProperty : toggleProperty
-		}
-
-	})();
-
-
-	/**
-	 * Init Tool
-	 */
-	var init = function init() {
-		ButtonManager.init();
-		OutputManager.init();
-		ColoPicker.init();
-		SliderManager.init();
-		LayerManager.init();
-		PreviewMouseTracking.init("preview");
-		Tool.init();
-	}
-
-	return {
-		init : init
-	}
-
-})();
-
-
-
-
- -
{{ EmbedLiveSample('box-shadow_generator', '100%', '1100px', '') }}
- -

Похожий инструмент: Генератор CSS Box Shadow

diff --git a/files/ru/web/css/css_box_model/introduction_to_the_css_box_model/index.html b/files/ru/web/css/css_box_model/introduction_to_the_css_box_model/index.html new file mode 100644 index 0000000000..6868871c5a --- /dev/null +++ b/files/ru/web/css/css_box_model/introduction_to_the_css_box_model/index.html @@ -0,0 +1,66 @@ +--- +title: 'Блоковая модель (боксовая модель, box model)' +slug: Web/CSS/box_model +tags: + - CSS + - Guide + - Веб +translation_of: Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model +--- +

Описание

+ +

В HTML-документе каждому элементу на странице соответствует прямоугольная область (бокс или блок). Движок рендеринга в браузере определяет размеры и положение боксов на странице, а также их свойства вроде цвета, фоновой картинки для того, чтобы отобразить их на экране.

+ +

В языке CSS есть специальная боксовая модель (также блоковая модель или блочная модель, англ. box model), которая описывает, из чего состоит бокс и какие свойства влияют на его размеры. В ней у каждого бокса есть 4 области: margin (внешние отступы), border (рамка), padding (внутренние поля), и content (контент или содержимое).

+ +

CSS Box model

+ +

Внутренняя область элемента (content area) содержит текст и другие элементы, расположенные внутри (контент или содержимое). У неё часто бывает фон, цвет или изображение (в таком порядке: фоновый цвет скрывается под непрозрачным изображением), и она находится внутри content edge; её размеры называются ширина контента (content width или content-box width), и высота контента (content height или content-box height). Иногда еще говорят «внутренняя ширина/высота элемента»

+ +

По умолчанию, если CSS-свойство {{ cssxref("box-sizing") }} не задано, размер внутренней области с содержимым задается свойствами {{ cssxref("width") }}, {{ cssxref("min-width") }}, {{ cssxref("max-width") }}, {{ cssxref("height") }}, {{ cssxref("min-height") }} and {{ cssxref("max-height") }}. Если же свойство  {{ cssxref("box-sizing") }} задано, то оно определяет, для какой области указаны размеры.

+ +

Поля элемента (padding area) — это пустая область, окружающая контент. Она может быть залита каким-то цветом, покрыта фоновый картинкой, а её границы называются края полей (padding edge).

+ +

Размеры полей задаются по отдельности с разных сторон свойствами {{ cssxref("padding-top") }}, {{ cssxref("padding-right") }}, {{ cssxref("padding-bottom") }}, {{ cssxref("padding-left") }} или общим свойством {{ cssxref("padding") }}.

+ +

Область рамки (border area) окружает поля элемента, а ее граница называется края рамки (border edge). Ширина рамки задается отдельным свойством  {{ cssxref("border-width") }} или в составе свойства {{ cssxref("border") }}. Размеры элемента с учетом полей и рамки иногда называют внешней шириной/высотой элемента.

+ +

Отступы (margin area) добавляют пустое пространство вокруг элемента и определяют расстояние до соседних элементов.

+ +

Величина отступов задается по отдельности в разных направлениях свойствами {{ cssxref("margin-top") }}, {{ cssxref("margin-right") }}, {{ cssxref("margin-bottom") }}, {{ cssxref("margin-left") }} или общим свойством {{ cssxref("margin") }}.

+ +

Отступы двух соседних элементов, расположенных друг над другом или вложенных друг в друга, могут накладываться. Это называется схлопывание границ (margin collapsing). Схлопываются только вертикальные отступы.

+ +

Для элементов с {{ cssxref("display") }}: inline (или inline-block, inline-table) на занимаемое по высоте место также влияет значение свойства {{ cssxref('line-height') }}.

+ +

Стандарты

+ + + + + + + + + + + + + + + + + + + + + +
СтандартСтатусПримечание
CSS Level 2 (revision 1){{ Spec2('CSS2.1') }}Though more precisely worded, there is no practical change
CSS Level 1{{ Spec2('CSS1') }} 
+ +

Смотрите также

+ + diff --git a/files/ru/web/css/css_color/index.html b/files/ru/web/css/css_color/index.html new file mode 100644 index 0000000000..c6225aec39 --- /dev/null +++ b/files/ru/web/css/css_color/index.html @@ -0,0 +1,117 @@ +--- +title: CSS Colors +slug: Web/CSS/CSS_Colors +tags: + - CSS + - Цвета + - Цвета в CSS +translation_of: Web/CSS/CSS_Color +translation_of_original: Web/CSS/CSS_Colors +--- +
{{CSSRef}}
+ +

CSS Colors - модуль в CSS, который работает с цветами, типами цветов и прозрачностью.

+ +

Руководство

+ +

Свойства

+ +
+ +
+ +

Типы данных в CSS

+ +

{{cssxref("<color>")}}

+ +

Руководства

+ +

Нет.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('CSS3 Colors')}}{{Spec2('CSS3 Colors')}} 
{{SpecName('CSS2.1', 'colors.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Изначальное определение
+ +

Поддержка браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка1.0{{CompatGeckoDesktop("1")}}3.03.51.0
+
+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка1.0{{CompatGeckoMobile("1")}}6.06.01.0
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/css/css_colors/index.html b/files/ru/web/css/css_colors/index.html deleted file mode 100644 index c6225aec39..0000000000 --- a/files/ru/web/css/css_colors/index.html +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: CSS Colors -slug: Web/CSS/CSS_Colors -tags: - - CSS - - Цвета - - Цвета в CSS -translation_of: Web/CSS/CSS_Color -translation_of_original: Web/CSS/CSS_Colors ---- -
{{CSSRef}}
- -

CSS Colors - модуль в CSS, который работает с цветами, типами цветов и прозрачностью.

- -

Руководство

- -

Свойства

- -
- -
- -

Типы данных в CSS

- -

{{cssxref("<color>")}}

- -

Руководства

- -

Нет.

- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('CSS3 Colors')}}{{Spec2('CSS3 Colors')}} 
{{SpecName('CSS2.1', 'colors.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Изначальное определение
- -

Поддержка браузерами

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка1.0{{CompatGeckoDesktop("1")}}3.03.51.0
-
- -
- - - - - - - - - - - - - - - - - - - -
ВозможностьAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Базовая поддержка1.0{{CompatGeckoMobile("1")}}6.06.01.0
-
- -

Смотрите также

- - diff --git a/files/ru/web/css/css_columns/using_multi-column_layouts/index.html b/files/ru/web/css/css_columns/using_multi-column_layouts/index.html new file mode 100644 index 0000000000..65e96fcdcf --- /dev/null +++ b/files/ru/web/css/css_columns/using_multi-column_layouts/index.html @@ -0,0 +1,124 @@ +--- +title: Использование CSS разметки для многих колонок +slug: Web/Guide/CSS/Using_multi-column_layouts +translation_of: Web/CSS/CSS_Columns/Using_multi-column_layouts +--- +

{{CSSRef("CSS Multi-columns")}}

+ +

CSS разметка для многих колонок расширяет способ блочной разметки, чтобы позволить легкое описание нескольких колонок текста. Людям сложно читать текст, если строки слишком длинные; это занимает слишком много времени для глаз, чтобы перемещать взгляд с конца одной на начало следующей строки, и они забывают на какой строке находились. Поэтому, чтобы использовать большие дисплеи по максимуму, авторам следует ограничить ширину колонок текст расположенных бок о бок, как в газетах.

+ +

К несчастью, это невозможно сделать с CSS и HTML без принудительного разбиения колонки в фиксированных позициях, или строго ограничить допустимую разметку в тексте, или использовать экстраординарный скрипт. Это ограничение снимается с помощью добавления новых CSS свойств, чтобы расширить традиционный блочный способ разметки.

+ +

Использование колонок

+ +

Количество колонок и ширина

+ +

Два свойства CSS контролируют появятся ли колонки и как много их будет: {{ Cssxref("column-count") }} and {{ Cssxref("column-width") }}.

+ +

Свойство column-count устанавливает количество колонок определённым числом. Пример,

+ +
<div style="column-count:2;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

отобразит содержимое в двух колонках (если вы используете многоколоночно совместимый браузер):

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Свойство column-width устанавливает минимальную желаемую ширину колонки. Если column-count также не установлено, тогда браузер автоматически сделает столько колонок, сколько нужно, чтобы заполнить  доступную ширину.

+ +
<div style="column-width:20em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

становится:

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Подробные детали описаны в CSS3 спецификации.

+ +

В многоколончатом блоке, содержимое автоматически перетекает из одной колонки в следующую, как это необходимо. Вся HTML, CSS и DOM функциональность поддерживается внутри колонок, как например редактирование и печать.

+ +

Краткая запись columns

+ +

В большинстве случаев веб-разработчики используют одно из двух свойств CSS: {{ cssxref("column-count") }} или {{ cssxref("column-width") }}. Так как значения для этих свойств не пересекаются, то часто удобно использовать короткую запись {{ cssxref("columns") }}. Пример:

+ +

CSS объявление  column-width:12em может быть заменено:

+ +
<div style="columns:12em">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

CSS объявление column-count:4 может быть заменено:

+ +
<div style="columns:4">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Два CSS объявления column-width:8em и column-count:12 могут быть заменены:

+ +
<div style="columns:12 8em">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Выравнивание высоты

+ +

CSS3-спецификация колонок требует, чтобы высота колонки была выровнена, т.е. браузер автоматически устанавливает максимальную высоту колонки, для того, чтобы высота содержимого в каждой из них была приблизительно одинаковая. Firefox так и делает.

+ +

Однако, в некоторых ситуациях полезно установить максимальную высоту колонок явно, тогда расположение содержимого, начиная с первой колонки и последующих созданных, как необходимо, возможно, перекроют правую границу. Поэтому, если высота ограничена, с помощью CSS {{ cssxref("height") }} или {{ cssxref("max-height") }} свойств на многоколончатом блоке, каждой колонке разрешено расти до этой высоты, но не более, пока не добавится новая колонка. Этот режим также более эффективен для разметки.

+ +

Промежутки между колонками

+ +

Существует промежуток между колонками. По умолчанию рекомендовано значение 1em. Это значение можно изменить, применяя свойство {{ Cssxref("column-gap") }} на многоколончатом блоке:

+ +
<div style="column-width:20em; column-gap:2em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
+qui officia deserunt mollit anim id est laborum</div>
+
+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

+ +

Постепенное ухудшение

+ +

Свойства колонки будут просто проигнорированы браузерами, которые не поддерживают многоколончатый режим. Поэтому соответственно легче создать разметку, которая отобразит содержимое в одной колонке и будет использовать несколько колонок в тех браузерах, которые поддерживают многоколончатый режим.

+ +

Обратите внимание, что не все браузеры поддерживают эти свойства без префикса. Чтобы использовать эти свойства в большинстве современных браузеров, каждое свойство должно быть написано трижды: одно с префиксом {{ property_prefix("-moz") }} , одно с префиксом {{ property_prefix("-webkit") }} и третье без префикса.

+ +

Заключение

+ +

CSS3 колонки - примитивная разметка, которая поможет Веб-разработчикам лучше воспользоваться реальным участком экрана. Разработчики с воображением могут найти много способов для их использования, особенно с автоматическим выравниванием высоты.

+ +

Смотрите также

+ + diff --git a/files/ru/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.html b/files/ru/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.html new file mode 100644 index 0000000000..9fe0b2932f --- /dev/null +++ b/files/ru/web/css/css_flexible_box_layout/aligning_items_in_a_flex_container/index.html @@ -0,0 +1,213 @@ +--- +title: Выравнивание элементов во Flex контейнере +slug: Web/CSS/CSS_Flexible_Box_Layout/Выравнивание_элементов_в_Flex_контейнере +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container +--- +

{{CSSRef}}

+ +

Одной из причин быстрого роста популярности flexbox среди веб-разработчиков было то, что впервые были предоставлены адекватные возможности выравнивания. Он предоставил адекватное вертикальное выравнивание, и стало возможным, наконец, легко поместить элемент в центр по вертикали. В этом руководстве детально рассматривается, как выравнивание и распределение работают во Flexbox.

+ +

Для центрирования элемента по перекрёстной оси (в данном случае - вертикальной) используется свойство align-items. Для центрирования элемента по главной оси (в данном случае - горизонтально), используется свойство justify-content.

+ +

A containing element with another box centered inside it.

+ + + +

На примере ниже можно изменить размер контейнера или вложенного элемента, но элемент всегда останется по центру.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/intro.html", '100%', 700)}}

+ +

Свойства управления выравниванием

+ +

В этом руководстве рассматриваются следующие свойства:

+ + + +

Также будет рассмотрены авто-отступы для выравнивания элементов во flexbox.

+ +
+

Замечание: Свойства выравнивания во Flexbox помещены в отдельную спецификацию — CSS Box Alignment Level 3. Ожидается, что данная спецификация в конце концов заменит свойства, определённые во Flexbox Level One.

+
+ +

Перекрёстная ось

+ +

Свойства align-items и align-self управляют выравниванием flex элементов по перекрёстной оси: вертикальной для flex-direction установленным в row, и горизонтальной для flex-direction установленным в column.

+ +

Рассмотрим выравнивание по перекрёстной оси на простейшем примере. Если установить display: flex у контейнера, все дочерние элементы становятся flex элементами, выстроенными в ряд. Все они по вертикали примут размер самого высокого элемента, который станет определяющим вертикального размера. Если у flex контейнера задана высота, то все элементы растянутся до высоты контейнера, независимо от размера содержимого.

+ +

Three items, one with additional text causing it to be taller than the others.

+ +

Three items stretched to 200 pixels tall

+ +

Все элементы становятся одной высоты, т.к. по умолчанию свойство align-items имеет значение stretch.

+ +

Другие возможные значения свойства:

+ + + +

В примере ниже значение свойств align-items установлено в stretch. Попробуйте другие значения для понимания их действия.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-items.html", '100%', 520)}} 

+ +

Выравнивание одного элемента при помощи align-self

+ +

Свойство align-items устанавливает align-self для всех flex элементов как для группы. Это означает, что можно явно указать значение align-self для конкретного элемента. Свойство align-self может принимать все те же значения, что и свойство align-items, а так же значение auto, которое сбросит значение, установленное в flex контейнере.

+ +

В следующем примере, у flex контейнера установлено align-items: flex-start, означающее, что все элементы будут выравнены по началу перекрёстной оси. У первого элемента с помощью first-child селектора установлено align-items: stretch; у следующего элемента с классом selected установлено align-self: center. Можно изменять значение align-items на контейнере или align-self на элементе для изучения их работы.8н

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self.html", '100%', 650)}} 

+ +

Изменение основной оси

+ +

До сего момента мы изучали поведение при flex-direction установленном в row, в языке, использующем написание сверху вниз. Это означает, что основная ось идёт горизонтально, а выравнивание по перекрёстной оси сдвигает элементы вверх или вниз.

+ +

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.

+ +

Если изменить flex-direction на column, align-items и align-self будут сдвигать элементы влево или вправо.

+ +

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the horizontal axis.

+ +

Можно попробовать пример ниже, где установлено flex-direction: column.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self-column.html", '100%', 730)}} 

+ +

Выравнивание содержимого по перекрёстной оси — свойство align-content

+ +

До сих пор мы выравнивали элементы внутри flex-контейнера. Если содержимое вашего flex контейнера переносится на несколько строк, используйте свойство align-content для управления свободным пространством между строками. В спецификации это описано как упаковка flex-строк.

+ +

Чтобы свойство align-content работало, необходимо, чтобы в flex-контейнере было больше места, что требуется для отображения всего содержимого. Оно применяется ко всем элементам как группе, и управляет распределением свободного места и положением всей группы элементов внутри контейнера.

+ +

Свойство align-content принимает следующие значения:

+ + + +

В примере ниже flex контейнер имеет высоту 400 пикселей - больше, чем необходимо для отображения всех элементов. Значение align-content установлено в space-between, означающее, что свободное пространство разделено между строками, расположенными вплотную к началу и концу контейнера по перекрёстной оси.

+ +

Попробуйте другие значения align-content для понимания принципа их работы.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-content.html", '100%', 850)}} 

+ +

Также можно сменить значение flex-direction на column и увидеть, как наше свойство работает в режиме колонок. Как и ранее, что увидеть работу свойства, у контейнера должно быть больше свободного места, чем требуется содержимому.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-content-column.html", '100%', 860)}} 

+ +
+

Замечание: значение space-evenly не определено в спецификации flexbox и добавлено позже в спецификацию Box Alignment. Поддержка браузерами этого значение не так широка, как значений определённым в спецификации flexbox.

+
+ +

В документации по justify-content на MDN приведено больше деталей о всех значениях и поддержке браузерами.

+ +

Выравнивание содержимого по главной оси

+ +

Теперь, когда мы увидели, как работает выравнивание по перекрёстной оси, можно посмотреть на главную ось. Здесь нам доступно только одно свойство — justify-content. Это обсуловлено тем, что с элементами на  главной оси мы работаем только как с группой. Используя свойство justify-content, мы контролируем, что происходит со свободным пространством на главной оси, и требуется ли нам больше пространства, чем нужно для отображения наших элементов.

+ +

В нашем первом примере с использованием свойства display: flex, примененным к контейнеру, элементы отображаются как строка и выстраиваются в начале блока. Это обусловлено тем, что свойство justify-content имеет начальное значение flex-start. Все свободное место располагается в конце контейнера.

+ +

Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.

+ +

Свойство justify-content может принимать те же самые значения, что и align-content.

+ + + +

В примере ниже, свойству justify-content задано значение space-between. Все доступное пространство распределяется между элементами после их позиционирования в контейнере. Первый и последний элементы занимают положения в начале и в конце контейнера соответственно.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content.html", '100%', 480)}}

+ +

Если свойство flex-direction имеет значение column, то свойство justify-content распределит доступное пространство в контейнере между элементами.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-column.html", '100%', 880)}} 

+ +

Выравнивание и режим записи

+ +

Необходимо помнить, что при использовании свойств flex-start иflex-end элементы позиционируются в режиме записи. Если свойству justify-content задано значение start и стоит режим записи left-to-right (слева-направо), как в английском, то элементы выравниваются, начиная с левой стороны контейнера.

+ +

Three items lined up on the left

+ +

Однако, если задан режим записи right-to-left (справа-налево), как в арабском языке, то элементы будут выстраиваться с правой стороны контейнера.

+ +

Three items lined up from the right

+ +

В примере ниже свойству property задано значение rtl, которое изменяет порядок наших элементов. Вы можете удалить это свойство или изменить значение свойства justify-content, чтобы увидеть, как работает flexbox, когда отображение элементов начинается справа.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-writing-mode.html", '100%', 440)}} 

+ +

Выравнивание и гибкое-направление

+ +

Начальное положение элементов поменяется, если вы измените значение свойства flex-direction — например установите row-reverse вместо row.

+ +

В следующем примере заданы следующие свойства: flex-direction: row-reverse и justify-content: flex-end. В языках с параметром записи ltr все элементы будут отображаться с левой стороны. Попробуйте изменить свойство flex-direction: row-reverse на flex-direction: row. Вы увидите, что теперь элементы отображаются реверсивно.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-reverse.html", '100%', 440)}} 

+ +

Может показаться немного запутанным, но главное правило, которое необходимо запомить – до тех пор, пока вы не измените свойство flex-direction, элементы контейнера выстраиваются в режиме записи вашего языка (ltr или rtl). 

+ +

Diagram showing start on the left and end on the right.

+ +

Вы можете сделать отображение элементов контейнера блочным, задав свойству flex-direction значение  column. Свойство flex-start будет отображать элементы в столбец сверху вниз. Таким образом, первый элемент будет первым параграфом.

+ +

Diagram showing start at the top and end at the bottom.

+ +

Если вы зададите свойству flex-direction реверсивное значение, то элементы будут позиционироваться в обратном порядке. Так, свойство flex-start будет брать начало в конце контейнера. Первый элемент будет находится в конце строки, если задано строчное отображение элементов или в конце параграфа, если задано блочное отображение.   

+ +

Diagram showing start on the right and end on the left.

+ +

Diagram showing end at the top and start at the bottom

+ +

Использование авто отступов для выравнивания по главной оси

+ +

Так как элементы, расположенные на главной оси, обрабатываются как группа, свойства justify-items или justify-self становятся недоступными. Тем не менее, существует способ отделить конкретный элемент или группу элементов от остальных, используя внешний отступ margin со значением auto

+ +

Распространённый пример — панель навигации, в которой отдельные важные элементы выровнены по правому краю, а основная группа элементов — по левому.

+ +

На первый взгляд может показаться, что это юзкейс для свойства justify-self. Однако, рассмотрим следующий ниже пример. Имеется три элемента с одной стороны и два — с другой. Если бы мы могли использовать justify-self на элементе d, это также изменило бы выравнивание следующего элемента — e, что может противоречить первоначальному замыслу.

+ +

Five items, in two groups. Three on the left and two on the right.

+ +

Вместо этого мы можем выбрать четвёртый элемент (d) и отделить его от первых трёх, задав ему значение auto для margin-left. Авто-margin заполнит всё доступное свободное место по своей оси. Тем же образом cработает margin-right. Оба свойства со значениями auto отцентрируют блок, так как каждый из отступов будет пытаться занять максимум пространства.

+ +

В интерактивном примере ниже у нас имеется простой ряд из флекс-элементов и класс push с заданным margin-left: auto. Вы можете, например, попробовать удалить это значение или добавить класс другому элементу, чтобы увидеть, как работает этот метод. 

+ +

{{EmbedGHLiveSample("css-examples/flexbox/alignment/auto-margins.html", '100%', 470)}} 

+ +

Будущие функции выравнивания для Flexbox

+ +

В начале этой статьи объясняется, что свойства выравнивания, которые в настоящее время содержатся в спецификации Flexbox Level 1, также включены в спецификацию Box Alignment Level 3, которая в дальнейшем может расширить эти свойства и значения. Мы уже видели, как это произошло с введением значения space-evenly для свойств align-content и justify-content.

+ +

Выравнивание во Flexbox также включает в себя другие методы создания пространства между элементами, такие как column-gap and row-gap, как показано в макете CSS Grid Layout. Включение этих свойств в Box Alignment означает, что в будущем мы также сможем использовать column-gap и row-gap во Flexbox разметке. Это означает, что вам не нужно будет использовать отступы, чтобы создать пространство между элементами.

+ +

Мое предложение заключается в том, чтобы при изучении выравнивания во Flexbox, делать это параллельно с выравниванием в Grid Layout. В обеих спецификациях используются свойства выравнивания, подобные Flexbox. Вы можете видеть, как эти свойства ведут себя при работе с сеткой в статье Box Alignment in Grid Layout, а также рассмотреть как выравнивание работает в этих спецификациях в статье Box Alignment Cheatsheet.

+ +

Смотрите Также

+ + diff --git a/files/ru/web/css/css_flexible_box_layout/controlling_ratios_of_flex_items_along_the_main_ax/index.html b/files/ru/web/css/css_flexible_box_layout/controlling_ratios_of_flex_items_along_the_main_ax/index.html new file mode 100644 index 0000000000..97e521c2e1 --- /dev/null +++ b/files/ru/web/css/css_flexible_box_layout/controlling_ratios_of_flex_items_along_the_main_ax/index.html @@ -0,0 +1,194 @@ +--- +title: Управление соотношением элементов вдоль главной оси +slug: >- + Web/CSS/CSS_Flexible_Box_Layout/Контролирование_соотношения_элементов_вдоль_главной_оси +translation_of: >- + Web/CSS/CSS_Flexible_Box_Layout/Controlling_Ratios_of_Flex_Items_Along_the_Main_Ax +--- +
{{CSSRef}}
+ +
+ +
В данном руководстве, мы исследуем три свойства  применяемые к flex элементам, которые позволяют нам контролировать размер и  гибкость flex элементов по основной(main) оси. Полное понимание, как эти свойства работают,  при увеличение и уменьшение элементов, есть ключ к мастерству flexbox.
+ +

A first look

+ +

Our three properties control the following aspects of a flex item's flexibility:

+ + + +

The properties are usually expressed as the shorthand {{CSSxRef("flex")}} property. The following code would set the flex-grow property to 2, flex-shrink to 1 and flex-basis to auto.

+ +
.item {
+  flex: 2 1 auto;
+}
+ +

If you have read the article Basic Concepts of Flexbox, then you will have already had an introduction to the properties. Here we will explore them in depth in order that you can fully understand what the browser is doing when you use them.

+ +

Important concepts when working on the main axis

+ +

There are a few concepts worth digging into before looking at how the flex properties work to control ratios along the main axis. These relate to the natural size of flex items before any growing or shrinking takes place, and to the concept of free space.

+ +

Flex item sizing

+ +

In order to work out how much space there is available to lay out flex items, the browser needs to know how big the item is to start with. How is this worked out for items that don’t have a width or a height applied using an absolute length unit?

+ +

There is a concept in CSS of {{CSSxRef('width','min-content','#min-content')}} and {{CSSxRef('width','max-content','#max-content')}} — these keywords are defined in the CSS Intrinsic and Extrinsic Sizing Specification, and can be used in place of a length unit.

+ +

In the live example below for instance I have two paragraph elements that contain a string of text. The first paragraph has a width of min-content. In a browser that supports this keyword you should be able to see that the text has taken all of the soft wrapping opportunities available to it, becoming as small as it can be without overflowing. This then, is the min-content size of that string. Essentially, the longest word in the string is dictating the size.

+ +

The second paragraph has a value of max-content and so it does the opposite. It gets as big as it possibly can be, taking no soft-wrapping opportunities. It would overflow the box it is in if that container was too narrow.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/min-max-content.html", '100%', 750)}}

+ +

If your browser does not yet support these keywords both paragraphs will be rendered as normal paragraphs in block flow; the below screenshots show the expected rendering.

+ +

The first paragraph is wrapped to the longest word, the second stretched out so as to cause overflow.

+ +

Remember this behaviour and what effects min-content and max-content have as we explore flex-grow and flex-shrink later in this article.

+ +

Positive and negative free space

+ +

To talk about these properties we need to understand the concept of positive and negative free space. When a flex container has positive free space, it has more space than is required to display the flex items inside the container. For example, if I have a 500 pixel-wide container, {{CSSxRef("flex-direction")}} is row, and I have three flex items each 100 pixels wide, then I have 200 pixels of positive free space, which could be distributed between the items if I wanted them to fill the container.

+ +

Image showing space left over after items have been displayed.

+ +

We have negative free space when the natural size of the items adds up to larger than the available space in the flex container. If I have a 500 pixel-wide container like the one above, but the three flex items are each 200 pixels wide, the total space I need will be 600 pixels, so I have 100 pixels of negative free space. This could be removed from the items in order to make them fit the container.

+ +

The items overflow the container

+ +

It is this distribution of positive free space and removal of negative free space that we need to understand in order to understand the flex properties.

+ +

In the following examples I am working with {{CSSxRef("flex-direction")}} set to row, therefore the size of items will always come from their width. We will be calculating the positive and negative free space created by comparing the total width of all the items with the container width. You could equally try out each example with flex-direction: column. The main axis would then be the column, and you would then need to compare the height of the items and that of the container they are in to work out the positive and negative free space.

+ +

The flex-basis property

+ +

The {{CSSxRef("flex-basis")}} property specifies the initial size of the flex item before any space distribution happens. The initial value for this property is auto. If flex-basis is set to auto then to work out the initial size of the item the browser first checks if the main size of the item has an absolute size set. This would be the case if you had given your item a width of 200 pixels. In that case 200px would be the flex-basis for this item.

+ +

If your item is instead auto-sized, then auto resolves to the size of its content. At this point your knowledge of min- and max-content sizing becomes useful, as flexbox will take the max-content size of the item as the flex-basis. The following live example can help to demonstrate this.

+ +

In this example I have created a series of inflexible boxes, with both flex-grow and flex-shrink set to 0. Here we can see how the first item — which has an explicit width of 150 pixels set as the main size — takes a flex-basis of 150px, whereas the other two items have no width and so are sized according to their content width.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-basis.html", '100%', 500)}}

+ +

In addition to the auto keyword, you can use the content keyword as the flex-basis. This will result in the flex-basis being taken from the content size even if there is a width set on the item. This is a newer keyword and has less browser support, however you can always get the same effect by using auto as the flex-basis and ensuring that your item does not have a width set, in order that it will be auto-sized.

+ +

If you want flexbox to completely ignore the size of the item when doing space distribution then set flex-basis to 0. This essentially tells flexbox that all the space is up for grabs, and to share it out in proportion. We will see examples of this as we move on to look at flex-grow.

+ +

The flex-grow property

+ +

The {{CSSxRef("flex-grow")}} property specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items in the flex container when the positive free space is distributed.

+ +

If all of your items have the same flex-grow factor then space will be distributed evenly between all of them. If this is the situation that you want then typically you would use 1 as the value, however you could give them all a flex-grow of 88, or 100, or 1.2 if you like — it is a ratio. If the factor is the same for all, and there is positive free space in the flex container then it will be distributed equally to all.

+ +

Combining flex-grow and flex-basis

+ +

Things can get confusing in terms of how flex-grow and flex-basis interact. Let's consider the case of three flex items of differing content lengths and the following flex rules applied to them:

+ +

flex: 1 1 auto;

+ +

In this case the flex-basis value is auto and the items don’t have a width set, and so are auto-sized. This means that flexbox is looking at the max-content size of the items. After laying the items out we have some positive free space in the flex container, shown in this image as the hatched area:

+ +

Images shows the positive free space as a hatched area

+ +

We are working with a flex-basis equal to the content size so the available space to distribute is subtracted from the total available space (the width of the flex container), and the leftover space is then shared out equally among each item. Our bigger item ends up bigger because it started from a bigger size, even though it has the same amount of spare space assigned to it as the others:

+ +

The positive space is distributed between items

+ +

If what you actually want is three equally-sized items, even if they start out at different sizes, you should use this:

+ +

flex: 1 1 0;

+ +

Here we are saying that the size of the item for the purposes of our space distribution calculation is 0 — all the space is up for grabs and as all of the items have the same flex-grow factor, they each get an equal amount of space distributed. The end result is three equal width, flexible items.

+ +

Try changing the flex-grow factor from 1 to 0 in this live example to see the different behavior:

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-grow.html", '100%', 520)}}

+ +

Giving items different flex-grow factors

+ +

Our understanding of how flex-grow works with flex-basis allows us to have further control over our individual item sizes by assigning items different flex-grow factors. If we keep our flex-basis at 0 so all of the space can be distributed, we could assign each of the three flex items a different flex-grow factor. In the example below I am using the following values:

+ + + +

Working from a flex-basis of 0 this means that the available space is distributed as follows. We need to add up the flex grow factors, then divide the total amount of positive free space in the flex container by that number, which in this case is 4. We then share out the space according to the individual values — the first item gets one part, the second one part, the third two parts. This means that the third item is twice the size of the first and second items.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-grow-ratios.html", '100%', 520)}}

+ +

Remember that you can use any positive value here. It is the ratio between one item and the others that matters. You can use large numbers, or decimals — it is up to you. To test that out change the values assigned in the above example to .25, .25, and .50 — you should see the same result.

+ +

The flex-shrink property

+ +

The {{CSSxRef("flex-shrink")}} property specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed.

+ +

This property deals with situations where the browser calculates the flex-basis values of the flex items, and finds that they are too large to fit into the flex container. As long as flex-shrink has a positive value the items will shrink in order that they do not overflow the container.

+ +

So where flex-grow deals with adding available space, flex-shrink manages taking away space to make boxes fit into their container without overflowing.

+ +

In the next live example I have three items in a flex container; I’ve given each a width of 200 pixels, and the container is 500 pixels wide. With flex-shrink set to 0 the items are not allowed to shrink and so they overflow the box.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink.html", '100%', 500)}}

+ +

Change the flex-shrink value to 1 and you will see each item shrink by the same amount, in order that all of the items now fit in the box. They have become smaller than their initial width in order to do so.

+ +

Combining flex-shrink and flex-basis

+ +

You could say that flex-shrink works in pretty much the same way as flex-grow. However there are two reasons why it isn’t quite the same.

+ +

While it is usually subtle, defined in the specification is one reason why flex-shrink isn’t quite the same for negative space as flex-grow is for positive space:

+ +
+

“Note: The flex shrink factor is multiplied by the flex base size when distributing negative space. This distributes negative space in proportion to how much the item is able to shrink, so that e.g. a small item won’t shrink to zero before a larger item has been noticeably reduced.”

+
+ +

The second reason is that flexbox prevents small items from shrinking to zero size during this removal of negative free space. The items will be floored at their min-content size — the size that they become if they take advantage of any soft wrapping opportunities available to them.

+ +

You can see this min-content flooring happen in the below example, where the flex-basis is resolving to the size of the content. If you change the width on the flex container — increasing it to 700px for example — and then reduce the flex item width, you can see that the first two items will wrap, however they will never become smaller than that min-content size. As the box gets smaller space is then just removed from the third item.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink-min-content.html", '100%', 500)}}

+ +

In practice the shrinking behaviour does tend to give you reasonable results. You don’t usually want your content to disappear completely or for boxes to get smaller than their minimum content, so the above rules make sense in terms of sensible behaviour for content that needs to be shrunk in order to fit into a container.

+ +

Giving items different flex-shrink factors

+ +

In the same way as flex-grow, you can give flex-items different flex-shrink factors. This can help change the default behaviour if, for example, you want an item to shrink more or less rapidly than its siblings or not shrink at all.

+ +

In the following live example the first item has a flex-shrink factor of 1, the second 0 (so it won’t shrink at all), and the third 4. The third item therefore shrinks more rapidly than the first. Play around with the different values — as for flex-grow you can use decimals or larger numbers here. Choose whatever makes most sense to you.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink-ratios.html", '100%', 570)}}

+ +

Mastering sizing of flex items

+ +

The key to really understanding how flex item sizing works is in understanding the number of things that come into play. Consider the following aspects, which we have already discussed in these guides:

+ +

What sets the base size of the item?

+ +
    +
  1. Is flex-basis set to auto, and does the item have a width set? If so, the size will be based on that width.
  2. +
  3. Is flex-basis set to auto or content (in a supporting browser)? If so, the size is based on the item size.
  4. +
  5. Is flex-basis a length unit, but not zero? If so this is the size of the item.
  6. +
  7. Is flex-basis set to 0? if so then the item size is not taken into consideration for the space-sharing calculation.
  8. +
+ +

Do we have available space?

+ +

Items can’t grow with no positive free space, and they won’t shrink unless there is negative free space.

+ +
    +
  1. If we took all of the items and added up their widths (or heights if working in a column), is that total less than the total width (or height) of the container? If so, then you have positive free space and flex-grow comes into play.
  2. +
  3. If we took all of the items and added up their widths (or heights if working in a column), is that total more than the total width (or height) of the container? If so, you have negative free space and flex-shrink comes into play.
  4. +
+ +

Other ways to distribute space

+ +

If you do not want space added to the items, remember that you can deal with free space between or around items using the alignment properties described in the guide to aligning items in a flex container. The {{CSSxRef("justify-content")}} property will enable the distribution of free space between or around items. You can also use auto margins on flex items to absorb space and create gaps between items.

+ +

With all the flex tools at your disposal you will find that most tasks can be achieved, although it might take a little bit of experimentation at first.

diff --git a/files/ru/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html b/files/ru/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html deleted file mode 100644 index 3f0b229d20..0000000000 --- a/files/ru/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html +++ /dev/null @@ -1,379 +0,0 @@ ---- -title: Используем CSS Flexible Boxes -slug: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox -translation_of_original: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes ---- -
Эта статья устарела и удалена из английской версии. Вместо неё идёт перенаправление на статью: -

Основные понятия Flexbox

- - - -

У меня не поднялась рука удалить эту статью окончательно, но я рекомендую Вам вместо неё, всё-таки, прочитать ту.

-
- -
{{CSSRef}}
- -

CSS3 Flexible Box, или просто flexbox — это режим разметки, созданный для упорядочения элементов на странице таким образом, чтобы они вели себя предсказуемо в случаях, когда разметка страницы адаптирована под различные размеры экрана и устройства. Во многих случаях флексбоксы лучше блочной модели разметки, поскольку не использует обтекания (floats) и не выполняет схлопывание отступлений flex-контейнера и его содержимого (margin collapse).

- -

Для многих дизайнеров модель использования флексбоксов будет более простой для применения. Дочерние элементы внутри флексбокса могут размещаться в любом направлении и могут менять размер, чтобы адаптироваться к различным размерам дисплея. Позиционирование элементов в таком случае является простым и комплексная разметка достигается значительно легче и с более чистым кодом, поскольку порядок отображения элементов не связан с их порядком в коде. Эта независимость умышленно касается только визуального рендеринга, оставляя порядок интерпретации и навигацию зависимыми от порядка в исходниках.

- -
Внимание: некоторые браузеры все еще могут частично или полностью не поддерживать флексбоксы. Ознакомьтесь с таблицей совместимости.
- -

Концепция Flexbox

- -

Главной концепцией Flexbox есть возможность изменения высоты и/или ширины его элементов, чтобы лучше заполнять пространство любого дисплея. Flex-контейнер увеличивает элементы, чтобы заполнить доступное пространство или уменьшает чтобы предотвратить перекрытие.

- -

Алгоритм разметки флексбоксами агностичено направлен в противовес блочной разметке, которая ориентирована строго вертикально, или горизонтально-ориентированной инлайн-разметке. Несмотря на то что разметка блоками хорошо подходит для страницы, ей не хватает объективного механизма для поддержки компонентов, которые должны менять ориентацию, размеры а также растягиваться или сжиматься при изменениях размера экрана, изменении ориентации с вертикальной на горизонтальную и так далее. Разметка флексбоксами наиболее желательна для компонентов приложения и шаблонов, которые мало масштабируются, тогда как grid-разметка создана для больших шаблонов. Обе технологии являются частью разработки CSS Working Group которая должна способствовать совместимости web-приложений с различными браузерами, режимами а также большей гибкости.

- -

Терминология

- -

Поскольку описание флексбоксов не включает таких словосочетаний, как горизонтальная / inline и вертикальная / block оси, объяснение модели предусматривает новую терминологию. Используйте следующую диаграмму при просмотре словаря терминов. Она изображает flex-контейнер, имеющий flex-направление ряда, что означает, что каждый flex item расположен горизонтально, друг за другом по главной оси (main axis) в соответствии с установленным направлением написания текста элемента. Слева направо в данном случае.

- -

flex_terms.png

- -
-
Flex-контейнер
-
Родительский элемент, в котором содержатся flex-элементы. Flex-контейнер определяется установкой свойства {{Cssxref("display")}} в flex или inline-flex.
-
Flex-элемент, flex item
-
-

Каждый дочерний элемент flex-контейнера становится flex-элементом. Текст, который напрямую содержится в flex-контейнере, оборачивается анонимным flex-элементом.

-
-
Оси
-
-

Каждый flexible-бокс шаблон строится по двум осям. Главная ось (main axis) — это ось, вдоль которой flex-элементы следуют один за другим, а перекрёстная ось (cross axis) перпендикулярна ей.

- -
    -
  • Свойство {{Cssxref("flex-direction")}} устанавливает главную ось.
  • -
  • Свойство {{Cssxref("justify-content")}} определяет расположение элементов вдоль главной оси в текущем ряду.
  • -
  • Свойство align-items расположение элементов вдоль перекрёстной оси в текущем ряду.
  • -
  • Свойство align-self устанавливает, как отдельный flex-элемент выровнен по перекрёстной оси, переопределяя значения, установленные с помощью align-items.
  • -
-
-
Направления
-
-

Главное начало и конец (main) и перекрёстное начало и конец (cross start/end) — это стороны контейнера, определяющие начало и окончание потока flex-элемментов. Они следуют по главной и перекрестной осями flex-контейнера в векторе, установленном режимом написания ({{Cssxref("writing-mode")}}) (слева направо, справа налево и т. д.).

- -
    -
  • Свойство {{Cssxref("order")}} присваивает элементы порядковым группам и определяет, в каком порядке их показывать.
  • -
  • Свойство {{Cssxref("flex-flow")}} — это короткая форма, состоящая из свойств {{Cssxref("flex-direction")}} и {{Cssxref("flex-wrap")}}, определяющих расплолжение элементов.
  • -
-
-
Линии
-
-

Flex-элементы могут размещаться на одной или нескольких линиях в зависимости от значения свойства {{Cssxref("flex-wrap")}}, которое контролирует направление перекрестных линий и направление в котором складываются новые линии.

-
-
Размеры
-
-

Флекс элементы агностически эквивалентны высоте и ширине главного размера и поперечного размера, которые равны, соответственно,  главной оси (main axis) и поперечной оси (cross axis) флекс-контейнера.

- - -
-
- -

Делаем элемент флексбоксом

- -

Чтобы сделать элемент flexible-боксом, укажите значение {{cssxref("display")}} следующим образом:

- -
display: flex
- -

или

- -
display: inline-flex
- -

Таким образом мы определяем элемент как флексбокс, а его дочерниие элементы — как flex-элементы. Значение flex делает контейнер блочным элементом, а inline-flex значение превращает его в инлайн-элемент.

- -
Внимание: для указания префикса вендора, добавьте строку в значение атрибута, а не к самому атрибуту. Например, display: -webkit-flex.
- -

Рассмотрим flex-элементы

- -

Текст, который содержится непосредственно внутри flex-контейнера, автоматически оборачивается анонимным flex-элементом. Однако, анонимный flex-элемент, содержащий только пробелы, не отображается (как будто было указано значение display: none).

- -

Абсолютно позиционированные дочерние элементы flex-контейнера позиционируются так, что их статическое положение определяется относительно главного начального угла содержащего их flex-контейнера.

- -

Отступы (margin) соседних flex-контейнеров не схлопываются. Установка значений margin: auto поглощает дополнительное место в вертикальном или горизонтальном направлении и может быть использовано для выравнивания или для разделения соседних flex-элементов. См. Выравнивание при помощи 'автоматических' отступов в разделе "Модель расположения при помощи flex-контейнеров" спецификации W3C.

- -

Свойства выравнивания flexbox выполняют "истинное" центрирование в отличие от других способов центрирования в CSS. Это означает, что flex-элементы будут оставаться отцентрированными даже если они переполняют flex-контейнер. Впрочем, это может иногда быть проблематичным, если они вылезают за верхний или левый край страницы (в языках с написанием слева направо; в языках с написанием справа налево, таких как арабский, возникает проблема с правой границей), так как вы не можете прокрутить страницу в данную область даже если там есть содержимое! В будущем релизе свойства выравнивания будут также дополнены "безопасной" опцией. На данный момент, если это проблема, вы можете использовать отступы (margin) для достижения центрирования, так как они сработают "безопасно" и центрирование будет прекращено при переполнении. Вместо использования свойства align- просто установите автоматические отступы (margin: auto) для flex-элементов, которые вы хотите отцентрировать. Вместо свойств justify- установите margin: auto на внешние края первого и последнего элемента в flex-контейнере. Автоматические отступы будут "подстраиваться" и занимать оставшееся место, центрируя flex-элементы при наличии свободного места и используя стандартное выравнивание при его отсутствии. Тем не менее, если вы пытаетесь заменить justify-content центрированием, основанным на отступах (margin-based) в многострочном flexbox, вам, видимо, не повезло, так как вам необходимо установить отступы для первого и последнего элемента на каждой строке. Если вы не можете предугадать заранее на какой строке окажется каждый элемент, вы не сможете надежно использовать центрирование, основанное на отступах, на основной оси для замены свойства justify-content.

- -

Помните, что, несмотря на то, что порядок отображения элементов не зависит от их положения в исходном коде, эта независимость затрагивает только визуальное отображение, оставляя навигацию и голосовую помощь в исходном порядке. Даже свойство {{cssxref("order")}} не влияет на очередность голосовой помощи и навигации. Таким образом, разработчики должны уделять внимание правильному порядку элементов в исходном коде, чтобы не навредить доступности документа.

- -

Свойства Flexbox

- -

Свойства, не влияющие на Flexbox

- -

Так как flexbox используют другой алгоритм расположения, некоторые свойства не имеют смысла для flex-контейнера:

- - - -

Пример

- -

Типичный пример flex

- -

Типичный пример показывает как применять "flex-эффект" к элементам и как соседние элементы ведут себя в состоянии flex.

- -
​<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <style>
-    .flex {
-        /* basic styling */
-        width: 350px;
-        height: 200px;
-        border: 1px solid #555;
-        font: 14px Arial;
-
-        /* flexbox setup */
-        display: flex;
-        flex-direction: row;
-    }
-
-    .flex > div {
-        flex: 1 1 auto;
-        width: 30px; /* To make the transition work nicely. (Transitions to/from
-                        "width:auto" are buggy in Gecko and Webkit, at least.
-                        See http://bugzil.la/731886 for more info.) */
-        transition: width 0.7s ease-out;
-    }
-
-    /* colors */
-    .flex > div:nth-child(1){ background: #009246; }
-    .flex > div:nth-child(2){ background: #F1F2F1; }
-    .flex > div:nth-child(3){ background: #CE2B37; }
-
-    .flex > div:hover {
-        width: 200px;
-    }
-
-    </style>
-  </head>
-  <body>
-    <p>Flexbox nuovo</p>
-    <div class="flex">
-      <div>uno</div>
-      <div>due</div>
-      <div>tre</div>
-    </div>
-  </body>
-</html>
- -

Пример расположения "Священный Грааль"

- -

Данный пример показывает как flexbox предоставляет возможность динамически изменять расположение для различных разрешений экрана. Следующая схема иллюстрирует преобразование.

- -

HolyGrailLayout.png

- -

Здесь изображен случай, когда расположение, подходящее для окна браузера должно быть оптимизировано для экрана смартфона. Не только элементы должны уменьшиться в размере, но и порядок, в котором они отображаются, должен измениться. Flexbox сильно упрощает это.

- -
​<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <style>
-    body {
-        font: 24px Helvetica;
-        background: #999999;
-    }
-
-    #main {
-        min-height: 800px;
-        margin: 0px;
-        padding: 0px;
-        display: flex;
-        flex-flow: row;
-    }
-
-    #main > article {
-        margin: 4px;
-        padding: 5px;
-        border: 1px solid #cccc33;
-        border-radius: 7pt;
-        background: #dddd88;
-        flex: 3 1 60%;
-        order: 2;
-    }
-
-    #main > nav {
-        margin: 4px;
-        padding: 5px;
-        border: 1px solid #8888bb;
-        border-radius: 7pt;
-        background: #ccccff;
-        flex: 1 6 20%;
-        order: 1;
-    }
-
-    #main > aside {
-        margin: 4px;
-        padding: 5px;
-        border: 1px solid #8888bb;
-        border-radius: 7pt;
-        background: #ccccff;
-        flex: 1 6 20%;
-        order: 3;
-    }
-
-    header, footer {
-        display: block;
-        margin: 4px;
-        padding: 5px;
-        min-height: 100px;
-        border: 1px solid #eebb55;
-        border-radius: 7pt;
-        background: #ffeebb;
-    }
-
-    /* Too narrow to support three columns */
-    @media all and (max-width: 640px) {
-        #main, #page {
-            flex-direction: column;
-        }
-
-        #main > article, #main > nav, #main > aside {
-        /* Return them to document order */
-            order: 0;
-        }
-
-        #main > nav, #main > aside, header, footer {
-            min-height: 50px;
-            max-height: 50px;
-        }
-    }
-    </style>
-  </head>
-  <body>
-    <header>header</header>
-    <div id='main'>
-      <article>article</article>
-      <nav>nav</nav>
-      <aside>aside</aside>
-    </div>
-    <footer>footer</footer>
-  </body>
-</html>
- -

Песочница

- -

Существует несколько песочниц с flexbox, доступных онлайн для экспериментов:

- - - -

О чем нужно помнить

- -

Алгоритм, описывающий как flex-элементы располагаются, иногда может быть довольно запутанным. Вот несколько правильных решений, которые позволят избежать неприятных сюрпризов при верстке с использованием flexbox.

- -

Flexbox располагаются в соответствие с направлением письма, что означает, что главное начало и главный конец располагаются в зависимости от положения начала и конца (строки - прим.).

- -

Перекрестное начало и перекрестный конец полагаются на определение позиции начала и конца, которое зависит от значения свойства {{cssxref("direction")}}.

- -

Разрывы страницы допустимы в расположении flex-контейнеров, когда это позволяет свойство break-. Свойства CSS3 break-after, break-before и break-inside, а также свойства CSS 2.1 page-break-before, page-break-after и page-break-inside работают на flex-контейнере, flex-элементах, а также внутри flex-элементов.

- -

Совместимость с браузерами

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support (single-line flexbox){{CompatGeckoDesktop("18.0")}}[6]{{property_prefix("-moz")}}[2]
- {{CompatGeckoDesktop("22.0")}}
21.0{{property_prefix("-webkit")}}
- 29.0
11[3]12.10{{property_prefix("-webkit")}}[5]6.1{{property_prefix("-webkit")}}[1]
Multi-line flexbox{{CompatGeckoDesktop("28.0")}}21.0{{property_prefix("-webkit")}}
- 29.0
11[3]12.10[5]
- 15 {{property_prefix("-webkit")}}
6.1{{property_prefix("-webkit")}}[1]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureFirefox Mobile (Gecko)Firefox OSAndroidIE PhoneOpera MobileSafari Mobile
Basic support (single-line flexbox){{CompatGeckoMobile("18.0")}}{{property_prefix("-moz")}}[2]
- {{CompatGeckoMobile("22.0")}}
-

1.0{{property_prefix("-moz")}}[2]
- 1.1

-
2.1{{property_prefix("-webkit")}}[4]
- 4.4
1112.10[5]
- 15{{property_prefix("-webkit")}}
7{{property_prefix("-webkit")}}[1]
Multi-line flexbox{{CompatGeckoMobile("28.0")}}1.32.1{{property_prefix("-webkit")}}[4]
- 4.4
1112.10[5]
- 15{{property_prefix("-webkit")}}
7{{property_prefix("-webkit")}}[1]
-
- -

[1] Safari до версии 6.0 (iOS.1) поддерживал старую несовместимую черновую версию спецификации. Safari 6.1 (и Safari на iOS 7) был обновлен для поддержки финальной версии.

- -

[2] До Firefox 22, чтобы активировать поддержку flexbox, пользователь должен установить параметр about:config layout.css.flexbox.enabled в значение true. Начиная с Firefox 22 по Firefox 27, параметр установлен в true по умолчанию, и полностью исключен в Firefox 28.

- -

[3] Internet Explorer 10 поддерживает старую несовместимую черновую версию спецификации; Internet Explorer 11 был обновлен для поддержки финальной версии.

- -

[4] Android browser до версии 4.3 поддерживал старую несовместимую черновую версию спецификации. Android 4.4 был обновлен для поддержки финальной версии.

- -

[5] Хотя изначальная реализация в Opera 12.10 flexbox была без приставки, она получила приставку {{property_prefix("-webkit")}} в версиях с 15 по 16 Opera и с 15 по 19 Opera Mobile. Приставка была снова убрана в Opera 17 и Opera Mobile 24.

- -

[6] До Firefox 29, установка visibility: collapse для flex-элемента заставляет его обрабатываться как display: none вместо предполагаемого поведения, обрабатывающего его как visibility: hidden. Предложенное решение - использовать visibility:hidden для flex-элементов, которые должны вести себя как при установленном visibility:collapse. Для большей информации, см {{bug(783470)}}.

- -

См. также

- - diff --git "a/files/ru/web/css/css_flexible_box_layout/\320\262\321\213\321\200\320\260\320\262\320\275\320\270\320\262\320\260\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262_flex_\320\272\320\276\320\275\321\202\320\265\320\271\320\275\320\265\321\200\320\265/index.html" "b/files/ru/web/css/css_flexible_box_layout/\320\262\321\213\321\200\320\260\320\262\320\275\320\270\320\262\320\260\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262_flex_\320\272\320\276\320\275\321\202\320\265\320\271\320\275\320\265\321\200\320\265/index.html" deleted file mode 100644 index 9fe0b2932f..0000000000 --- "a/files/ru/web/css/css_flexible_box_layout/\320\262\321\213\321\200\320\260\320\262\320\275\320\270\320\262\320\260\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262_flex_\320\272\320\276\320\275\321\202\320\265\320\271\320\275\320\265\321\200\320\265/index.html" +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: Выравнивание элементов во Flex контейнере -slug: Web/CSS/CSS_Flexible_Box_Layout/Выравнивание_элементов_в_Flex_контейнере -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container ---- -

{{CSSRef}}

- -

Одной из причин быстрого роста популярности flexbox среди веб-разработчиков было то, что впервые были предоставлены адекватные возможности выравнивания. Он предоставил адекватное вертикальное выравнивание, и стало возможным, наконец, легко поместить элемент в центр по вертикали. В этом руководстве детально рассматривается, как выравнивание и распределение работают во Flexbox.

- -

Для центрирования элемента по перекрёстной оси (в данном случае - вертикальной) используется свойство align-items. Для центрирования элемента по главной оси (в данном случае - горизонтально), используется свойство justify-content.

- -

A containing element with another box centered inside it.

- - - -

На примере ниже можно изменить размер контейнера или вложенного элемента, но элемент всегда останется по центру.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/intro.html", '100%', 700)}}

- -

Свойства управления выравниванием

- -

В этом руководстве рассматриваются следующие свойства:

- - - -

Также будет рассмотрены авто-отступы для выравнивания элементов во flexbox.

- -
-

Замечание: Свойства выравнивания во Flexbox помещены в отдельную спецификацию — CSS Box Alignment Level 3. Ожидается, что данная спецификация в конце концов заменит свойства, определённые во Flexbox Level One.

-
- -

Перекрёстная ось

- -

Свойства align-items и align-self управляют выравниванием flex элементов по перекрёстной оси: вертикальной для flex-direction установленным в row, и горизонтальной для flex-direction установленным в column.

- -

Рассмотрим выравнивание по перекрёстной оси на простейшем примере. Если установить display: flex у контейнера, все дочерние элементы становятся flex элементами, выстроенными в ряд. Все они по вертикали примут размер самого высокого элемента, который станет определяющим вертикального размера. Если у flex контейнера задана высота, то все элементы растянутся до высоты контейнера, независимо от размера содержимого.

- -

Three items, one with additional text causing it to be taller than the others.

- -

Three items stretched to 200 pixels tall

- -

Все элементы становятся одной высоты, т.к. по умолчанию свойство align-items имеет значение stretch.

- -

Другие возможные значения свойства:

- - - -

В примере ниже значение свойств align-items установлено в stretch. Попробуйте другие значения для понимания их действия.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-items.html", '100%', 520)}} 

- -

Выравнивание одного элемента при помощи align-self

- -

Свойство align-items устанавливает align-self для всех flex элементов как для группы. Это означает, что можно явно указать значение align-self для конкретного элемента. Свойство align-self может принимать все те же значения, что и свойство align-items, а так же значение auto, которое сбросит значение, установленное в flex контейнере.

- -

В следующем примере, у flex контейнера установлено align-items: flex-start, означающее, что все элементы будут выравнены по началу перекрёстной оси. У первого элемента с помощью first-child селектора установлено align-items: stretch; у следующего элемента с классом selected установлено align-self: center. Можно изменять значение align-items на контейнере или align-self на элементе для изучения их работы.8н

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self.html", '100%', 650)}} 

- -

Изменение основной оси

- -

До сего момента мы изучали поведение при flex-direction установленном в row, в языке, использующем написание сверху вниз. Это означает, что основная ось идёт горизонтально, а выравнивание по перекрёстной оси сдвигает элементы вверх или вниз.

- -

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.

- -

Если изменить flex-direction на column, align-items и align-self будут сдвигать элементы влево или вправо.

- -

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the horizontal axis.

- -

Можно попробовать пример ниже, где установлено flex-direction: column.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-self-column.html", '100%', 730)}} 

- -

Выравнивание содержимого по перекрёстной оси — свойство align-content

- -

До сих пор мы выравнивали элементы внутри flex-контейнера. Если содержимое вашего flex контейнера переносится на несколько строк, используйте свойство align-content для управления свободным пространством между строками. В спецификации это описано как упаковка flex-строк.

- -

Чтобы свойство align-content работало, необходимо, чтобы в flex-контейнере было больше места, что требуется для отображения всего содержимого. Оно применяется ко всем элементам как группе, и управляет распределением свободного места и положением всей группы элементов внутри контейнера.

- -

Свойство align-content принимает следующие значения:

- - - -

В примере ниже flex контейнер имеет высоту 400 пикселей - больше, чем необходимо для отображения всех элементов. Значение align-content установлено в space-between, означающее, что свободное пространство разделено между строками, расположенными вплотную к началу и концу контейнера по перекрёстной оси.

- -

Попробуйте другие значения align-content для понимания принципа их работы.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-content.html", '100%', 850)}} 

- -

Также можно сменить значение flex-direction на column и увидеть, как наше свойство работает в режиме колонок. Как и ранее, что увидеть работу свойства, у контейнера должно быть больше свободного места, чем требуется содержимому.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/align-content-column.html", '100%', 860)}} 

- -
-

Замечание: значение space-evenly не определено в спецификации flexbox и добавлено позже в спецификацию Box Alignment. Поддержка браузерами этого значение не так широка, как значений определённым в спецификации flexbox.

-
- -

В документации по justify-content на MDN приведено больше деталей о всех значениях и поддержке браузерами.

- -

Выравнивание содержимого по главной оси

- -

Теперь, когда мы увидели, как работает выравнивание по перекрёстной оси, можно посмотреть на главную ось. Здесь нам доступно только одно свойство — justify-content. Это обсуловлено тем, что с элементами на  главной оси мы работаем только как с группой. Используя свойство justify-content, мы контролируем, что происходит со свободным пространством на главной оси, и требуется ли нам больше пространства, чем нужно для отображения наших элементов.

- -

В нашем первом примере с использованием свойства display: flex, примененным к контейнеру, элементы отображаются как строка и выстраиваются в начале блока. Это обусловлено тем, что свойство justify-content имеет начальное значение flex-start. Все свободное место располагается в конце контейнера.

- -

Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.

- -

Свойство justify-content может принимать те же самые значения, что и align-content.

- - - -

В примере ниже, свойству justify-content задано значение space-between. Все доступное пространство распределяется между элементами после их позиционирования в контейнере. Первый и последний элементы занимают положения в начале и в конце контейнера соответственно.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content.html", '100%', 480)}}

- -

Если свойство flex-direction имеет значение column, то свойство justify-content распределит доступное пространство в контейнере между элементами.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-column.html", '100%', 880)}} 

- -

Выравнивание и режим записи

- -

Необходимо помнить, что при использовании свойств flex-start иflex-end элементы позиционируются в режиме записи. Если свойству justify-content задано значение start и стоит режим записи left-to-right (слева-направо), как в английском, то элементы выравниваются, начиная с левой стороны контейнера.

- -

Three items lined up on the left

- -

Однако, если задан режим записи right-to-left (справа-налево), как в арабском языке, то элементы будут выстраиваться с правой стороны контейнера.

- -

Three items lined up from the right

- -

В примере ниже свойству property задано значение rtl, которое изменяет порядок наших элементов. Вы можете удалить это свойство или изменить значение свойства justify-content, чтобы увидеть, как работает flexbox, когда отображение элементов начинается справа.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-writing-mode.html", '100%', 440)}} 

- -

Выравнивание и гибкое-направление

- -

Начальное положение элементов поменяется, если вы измените значение свойства flex-direction — например установите row-reverse вместо row.

- -

В следующем примере заданы следующие свойства: flex-direction: row-reverse и justify-content: flex-end. В языках с параметром записи ltr все элементы будут отображаться с левой стороны. Попробуйте изменить свойство flex-direction: row-reverse на flex-direction: row. Вы увидите, что теперь элементы отображаются реверсивно.

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/justify-content-reverse.html", '100%', 440)}} 

- -

Может показаться немного запутанным, но главное правило, которое необходимо запомить – до тех пор, пока вы не измените свойство flex-direction, элементы контейнера выстраиваются в режиме записи вашего языка (ltr или rtl). 

- -

Diagram showing start on the left and end on the right.

- -

Вы можете сделать отображение элементов контейнера блочным, задав свойству flex-direction значение  column. Свойство flex-start будет отображать элементы в столбец сверху вниз. Таким образом, первый элемент будет первым параграфом.

- -

Diagram showing start at the top and end at the bottom.

- -

Если вы зададите свойству flex-direction реверсивное значение, то элементы будут позиционироваться в обратном порядке. Так, свойство flex-start будет брать начало в конце контейнера. Первый элемент будет находится в конце строки, если задано строчное отображение элементов или в конце параграфа, если задано блочное отображение.   

- -

Diagram showing start on the right and end on the left.

- -

Diagram showing end at the top and start at the bottom

- -

Использование авто отступов для выравнивания по главной оси

- -

Так как элементы, расположенные на главной оси, обрабатываются как группа, свойства justify-items или justify-self становятся недоступными. Тем не менее, существует способ отделить конкретный элемент или группу элементов от остальных, используя внешний отступ margin со значением auto

- -

Распространённый пример — панель навигации, в которой отдельные важные элементы выровнены по правому краю, а основная группа элементов — по левому.

- -

На первый взгляд может показаться, что это юзкейс для свойства justify-self. Однако, рассмотрим следующий ниже пример. Имеется три элемента с одной стороны и два — с другой. Если бы мы могли использовать justify-self на элементе d, это также изменило бы выравнивание следующего элемента — e, что может противоречить первоначальному замыслу.

- -

Five items, in two groups. Three on the left and two on the right.

- -

Вместо этого мы можем выбрать четвёртый элемент (d) и отделить его от первых трёх, задав ему значение auto для margin-left. Авто-margin заполнит всё доступное свободное место по своей оси. Тем же образом cработает margin-right. Оба свойства со значениями auto отцентрируют блок, так как каждый из отступов будет пытаться занять максимум пространства.

- -

В интерактивном примере ниже у нас имеется простой ряд из флекс-элементов и класс push с заданным margin-left: auto. Вы можете, например, попробовать удалить это значение или добавить класс другому элементу, чтобы увидеть, как работает этот метод. 

- -

{{EmbedGHLiveSample("css-examples/flexbox/alignment/auto-margins.html", '100%', 470)}} 

- -

Будущие функции выравнивания для Flexbox

- -

В начале этой статьи объясняется, что свойства выравнивания, которые в настоящее время содержатся в спецификации Flexbox Level 1, также включены в спецификацию Box Alignment Level 3, которая в дальнейшем может расширить эти свойства и значения. Мы уже видели, как это произошло с введением значения space-evenly для свойств align-content и justify-content.

- -

Выравнивание во Flexbox также включает в себя другие методы создания пространства между элементами, такие как column-gap and row-gap, как показано в макете CSS Grid Layout. Включение этих свойств в Box Alignment означает, что в будущем мы также сможем использовать column-gap и row-gap во Flexbox разметке. Это означает, что вам не нужно будет использовать отступы, чтобы создать пространство между элементами.

- -

Мое предложение заключается в том, чтобы при изучении выравнивания во Flexbox, делать это параллельно с выравниванием в Grid Layout. В обеих спецификациях используются свойства выравнивания, подобные Flexbox. Вы можете видеть, как эти свойства ведут себя при работе с сеткой в статье Box Alignment in Grid Layout, а также рассмотреть как выравнивание работает в этих спецификациях в статье Box Alignment Cheatsheet.

- -

Смотрите Также

- - diff --git "a/files/ru/web/css/css_flexible_box_layout/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\201\320\276\320\276\321\202\320\275\320\276\321\210\320\265\320\275\320\270\321\217_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262\320\264\320\276\320\273\321\214_\320\263\320\273\320\260\320\262\320\275\320\276\320\271_\320\276\321\201\320\270/index.html" "b/files/ru/web/css/css_flexible_box_layout/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\201\320\276\320\276\321\202\320\275\320\276\321\210\320\265\320\275\320\270\321\217_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262\320\264\320\276\320\273\321\214_\320\263\320\273\320\260\320\262\320\275\320\276\320\271_\320\276\321\201\320\270/index.html" deleted file mode 100644 index 97e521c2e1..0000000000 --- "a/files/ru/web/css/css_flexible_box_layout/\320\272\320\276\320\275\321\202\321\200\320\276\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\321\201\320\276\320\276\321\202\320\275\320\276\321\210\320\265\320\275\320\270\321\217_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\262\320\264\320\276\320\273\321\214_\320\263\320\273\320\260\320\262\320\275\320\276\320\271_\320\276\321\201\320\270/index.html" +++ /dev/null @@ -1,194 +0,0 @@ ---- -title: Управление соотношением элементов вдоль главной оси -slug: >- - Web/CSS/CSS_Flexible_Box_Layout/Контролирование_соотношения_элементов_вдоль_главной_оси -translation_of: >- - Web/CSS/CSS_Flexible_Box_Layout/Controlling_Ratios_of_Flex_Items_Along_the_Main_Ax ---- -
{{CSSRef}}
- -
- -
В данном руководстве, мы исследуем три свойства  применяемые к flex элементам, которые позволяют нам контролировать размер и  гибкость flex элементов по основной(main) оси. Полное понимание, как эти свойства работают,  при увеличение и уменьшение элементов, есть ключ к мастерству flexbox.
- -

A first look

- -

Our three properties control the following aspects of a flex item's flexibility:

- - - -

The properties are usually expressed as the shorthand {{CSSxRef("flex")}} property. The following code would set the flex-grow property to 2, flex-shrink to 1 and flex-basis to auto.

- -
.item {
-  flex: 2 1 auto;
-}
- -

If you have read the article Basic Concepts of Flexbox, then you will have already had an introduction to the properties. Here we will explore them in depth in order that you can fully understand what the browser is doing when you use them.

- -

Important concepts when working on the main axis

- -

There are a few concepts worth digging into before looking at how the flex properties work to control ratios along the main axis. These relate to the natural size of flex items before any growing or shrinking takes place, and to the concept of free space.

- -

Flex item sizing

- -

In order to work out how much space there is available to lay out flex items, the browser needs to know how big the item is to start with. How is this worked out for items that don’t have a width or a height applied using an absolute length unit?

- -

There is a concept in CSS of {{CSSxRef('width','min-content','#min-content')}} and {{CSSxRef('width','max-content','#max-content')}} — these keywords are defined in the CSS Intrinsic and Extrinsic Sizing Specification, and can be used in place of a length unit.

- -

In the live example below for instance I have two paragraph elements that contain a string of text. The first paragraph has a width of min-content. In a browser that supports this keyword you should be able to see that the text has taken all of the soft wrapping opportunities available to it, becoming as small as it can be without overflowing. This then, is the min-content size of that string. Essentially, the longest word in the string is dictating the size.

- -

The second paragraph has a value of max-content and so it does the opposite. It gets as big as it possibly can be, taking no soft-wrapping opportunities. It would overflow the box it is in if that container was too narrow.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/min-max-content.html", '100%', 750)}}

- -

If your browser does not yet support these keywords both paragraphs will be rendered as normal paragraphs in block flow; the below screenshots show the expected rendering.

- -

The first paragraph is wrapped to the longest word, the second stretched out so as to cause overflow.

- -

Remember this behaviour and what effects min-content and max-content have as we explore flex-grow and flex-shrink later in this article.

- -

Positive and negative free space

- -

To talk about these properties we need to understand the concept of positive and negative free space. When a flex container has positive free space, it has more space than is required to display the flex items inside the container. For example, if I have a 500 pixel-wide container, {{CSSxRef("flex-direction")}} is row, and I have three flex items each 100 pixels wide, then I have 200 pixels of positive free space, which could be distributed between the items if I wanted them to fill the container.

- -

Image showing space left over after items have been displayed.

- -

We have negative free space when the natural size of the items adds up to larger than the available space in the flex container. If I have a 500 pixel-wide container like the one above, but the three flex items are each 200 pixels wide, the total space I need will be 600 pixels, so I have 100 pixels of negative free space. This could be removed from the items in order to make them fit the container.

- -

The items overflow the container

- -

It is this distribution of positive free space and removal of negative free space that we need to understand in order to understand the flex properties.

- -

In the following examples I am working with {{CSSxRef("flex-direction")}} set to row, therefore the size of items will always come from their width. We will be calculating the positive and negative free space created by comparing the total width of all the items with the container width. You could equally try out each example with flex-direction: column. The main axis would then be the column, and you would then need to compare the height of the items and that of the container they are in to work out the positive and negative free space.

- -

The flex-basis property

- -

The {{CSSxRef("flex-basis")}} property specifies the initial size of the flex item before any space distribution happens. The initial value for this property is auto. If flex-basis is set to auto then to work out the initial size of the item the browser first checks if the main size of the item has an absolute size set. This would be the case if you had given your item a width of 200 pixels. In that case 200px would be the flex-basis for this item.

- -

If your item is instead auto-sized, then auto resolves to the size of its content. At this point your knowledge of min- and max-content sizing becomes useful, as flexbox will take the max-content size of the item as the flex-basis. The following live example can help to demonstrate this.

- -

In this example I have created a series of inflexible boxes, with both flex-grow and flex-shrink set to 0. Here we can see how the first item — which has an explicit width of 150 pixels set as the main size — takes a flex-basis of 150px, whereas the other two items have no width and so are sized according to their content width.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-basis.html", '100%', 500)}}

- -

In addition to the auto keyword, you can use the content keyword as the flex-basis. This will result in the flex-basis being taken from the content size even if there is a width set on the item. This is a newer keyword and has less browser support, however you can always get the same effect by using auto as the flex-basis and ensuring that your item does not have a width set, in order that it will be auto-sized.

- -

If you want flexbox to completely ignore the size of the item when doing space distribution then set flex-basis to 0. This essentially tells flexbox that all the space is up for grabs, and to share it out in proportion. We will see examples of this as we move on to look at flex-grow.

- -

The flex-grow property

- -

The {{CSSxRef("flex-grow")}} property specifies the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items in the flex container when the positive free space is distributed.

- -

If all of your items have the same flex-grow factor then space will be distributed evenly between all of them. If this is the situation that you want then typically you would use 1 as the value, however you could give them all a flex-grow of 88, or 100, or 1.2 if you like — it is a ratio. If the factor is the same for all, and there is positive free space in the flex container then it will be distributed equally to all.

- -

Combining flex-grow and flex-basis

- -

Things can get confusing in terms of how flex-grow and flex-basis interact. Let's consider the case of three flex items of differing content lengths and the following flex rules applied to them:

- -

flex: 1 1 auto;

- -

In this case the flex-basis value is auto and the items don’t have a width set, and so are auto-sized. This means that flexbox is looking at the max-content size of the items. After laying the items out we have some positive free space in the flex container, shown in this image as the hatched area:

- -

Images shows the positive free space as a hatched area

- -

We are working with a flex-basis equal to the content size so the available space to distribute is subtracted from the total available space (the width of the flex container), and the leftover space is then shared out equally among each item. Our bigger item ends up bigger because it started from a bigger size, even though it has the same amount of spare space assigned to it as the others:

- -

The positive space is distributed between items

- -

If what you actually want is three equally-sized items, even if they start out at different sizes, you should use this:

- -

flex: 1 1 0;

- -

Here we are saying that the size of the item for the purposes of our space distribution calculation is 0 — all the space is up for grabs and as all of the items have the same flex-grow factor, they each get an equal amount of space distributed. The end result is three equal width, flexible items.

- -

Try changing the flex-grow factor from 1 to 0 in this live example to see the different behavior:

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-grow.html", '100%', 520)}}

- -

Giving items different flex-grow factors

- -

Our understanding of how flex-grow works with flex-basis allows us to have further control over our individual item sizes by assigning items different flex-grow factors. If we keep our flex-basis at 0 so all of the space can be distributed, we could assign each of the three flex items a different flex-grow factor. In the example below I am using the following values:

- - - -

Working from a flex-basis of 0 this means that the available space is distributed as follows. We need to add up the flex grow factors, then divide the total amount of positive free space in the flex container by that number, which in this case is 4. We then share out the space according to the individual values — the first item gets one part, the second one part, the third two parts. This means that the third item is twice the size of the first and second items.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-grow-ratios.html", '100%', 520)}}

- -

Remember that you can use any positive value here. It is the ratio between one item and the others that matters. You can use large numbers, or decimals — it is up to you. To test that out change the values assigned in the above example to .25, .25, and .50 — you should see the same result.

- -

The flex-shrink property

- -

The {{CSSxRef("flex-shrink")}} property specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed.

- -

This property deals with situations where the browser calculates the flex-basis values of the flex items, and finds that they are too large to fit into the flex container. As long as flex-shrink has a positive value the items will shrink in order that they do not overflow the container.

- -

So where flex-grow deals with adding available space, flex-shrink manages taking away space to make boxes fit into their container without overflowing.

- -

In the next live example I have three items in a flex container; I’ve given each a width of 200 pixels, and the container is 500 pixels wide. With flex-shrink set to 0 the items are not allowed to shrink and so they overflow the box.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink.html", '100%', 500)}}

- -

Change the flex-shrink value to 1 and you will see each item shrink by the same amount, in order that all of the items now fit in the box. They have become smaller than their initial width in order to do so.

- -

Combining flex-shrink and flex-basis

- -

You could say that flex-shrink works in pretty much the same way as flex-grow. However there are two reasons why it isn’t quite the same.

- -

While it is usually subtle, defined in the specification is one reason why flex-shrink isn’t quite the same for negative space as flex-grow is for positive space:

- -
-

“Note: The flex shrink factor is multiplied by the flex base size when distributing negative space. This distributes negative space in proportion to how much the item is able to shrink, so that e.g. a small item won’t shrink to zero before a larger item has been noticeably reduced.”

-
- -

The second reason is that flexbox prevents small items from shrinking to zero size during this removal of negative free space. The items will be floored at their min-content size — the size that they become if they take advantage of any soft wrapping opportunities available to them.

- -

You can see this min-content flooring happen in the below example, where the flex-basis is resolving to the size of the content. If you change the width on the flex container — increasing it to 700px for example — and then reduce the flex item width, you can see that the first two items will wrap, however they will never become smaller than that min-content size. As the box gets smaller space is then just removed from the third item.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink-min-content.html", '100%', 500)}}

- -

In practice the shrinking behaviour does tend to give you reasonable results. You don’t usually want your content to disappear completely or for boxes to get smaller than their minimum content, so the above rules make sense in terms of sensible behaviour for content that needs to be shrunk in order to fit into a container.

- -

Giving items different flex-shrink factors

- -

In the same way as flex-grow, you can give flex-items different flex-shrink factors. This can help change the default behaviour if, for example, you want an item to shrink more or less rapidly than its siblings or not shrink at all.

- -

In the following live example the first item has a flex-shrink factor of 1, the second 0 (so it won’t shrink at all), and the third 4. The third item therefore shrinks more rapidly than the first. Play around with the different values — as for flex-grow you can use decimals or larger numbers here. Choose whatever makes most sense to you.

- -

{{EmbedGHLiveSample("css-examples/flexbox/ratios/flex-shrink-ratios.html", '100%', 570)}}

- -

Mastering sizing of flex items

- -

The key to really understanding how flex item sizing works is in understanding the number of things that come into play. Consider the following aspects, which we have already discussed in these guides:

- -

What sets the base size of the item?

- -
    -
  1. Is flex-basis set to auto, and does the item have a width set? If so, the size will be based on that width.
  2. -
  3. Is flex-basis set to auto or content (in a supporting browser)? If so, the size is based on the item size.
  4. -
  5. Is flex-basis a length unit, but not zero? If so this is the size of the item.
  6. -
  7. Is flex-basis set to 0? if so then the item size is not taken into consideration for the space-sharing calculation.
  8. -
- -

Do we have available space?

- -

Items can’t grow with no positive free space, and they won’t shrink unless there is negative free space.

- -
    -
  1. If we took all of the items and added up their widths (or heights if working in a column), is that total less than the total width (or height) of the container? If so, then you have positive free space and flex-grow comes into play.
  2. -
  3. If we took all of the items and added up their widths (or heights if working in a column), is that total more than the total width (or height) of the container? If so, you have negative free space and flex-shrink comes into play.
  4. -
- -

Other ways to distribute space

- -

If you do not want space added to the items, remember that you can deal with free space between or around items using the alignment properties described in the guide to aligning items in a flex container. The {{CSSxRef("justify-content")}} property will enable the distribution of free space between or around items. You can also use auto margins on flex items to absorb space and create gaps between items.

- -

With all the flex tools at your disposal you will find that most tasks can be achieved, although it might take a little bit of experimentation at first.

diff --git a/files/ru/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html b/files/ru/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html new file mode 100644 index 0000000000..86879d343e --- /dev/null +++ b/files/ru/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html @@ -0,0 +1,123 @@ +--- +title: Блочное и строчное расположение в нормальном потоке +slug: Web/CSS/CSS_Flow_Layout/Блочное_и_строчное_размещение_в_нормальном_потоке +tags: + - CSS + - Макет + - Макет потока CSS + - Отступы + - Руководство + - Средний уровень + - поток +translation_of: Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow +--- +
{{CSSRef}}
+ +

В этом руководстве мы исследуем основы поведения блочных и строчных элементов - участников нормального потока.

+ +

Normal Flow is defined in the CSS 2.1 specification, which explains that any boxes in normal flow will be part of a formatting context. They can be either block or inline, but not both at once. We describe block-level boxes as participating in a block formatting context, and inline-level boxes as participating in an inline formatting context.

+ +

The behaviour of elements which have a block or inline formatting context is also defined in this specification. For elements with a block formatting context, the spec says:

+ +
+

“In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
+
+ In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).” - 9.4.1

+
+ +

For elements with an inline formatting context:

+ +
+

“In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.” - 9.4.2

+
+ +

Note that the CSS 2.1 specification describes documents as being in a horizontal, top to bottom writing mode. For example, by describing vertical distance between block boxes. The behavior on block and inline elements is the same when working in a vertical writing mode, and we will explore this in a future guide on Flow Layout and Writing Modes.

+ +

Elements participating in a block formatting context

+ +

Block elements in a horizontal writing mode such as English, layout vertically, one below the other.

+ +

+ +

In a vertical writing mode then would lay out horizontally.

+ +

+ +

In this guide, we will be working in English and therefore a horizontal writing mode. However, everything described should work in the same way if your document is in a vertical writing mode.

+ +

As defined in the specification, the margins between two block boxes are what creates separation between the elements. We see this with a very simple layout of two paragraphs, to which I have added a border. The default browser stylesheet adds spacing between the paragraphs by way of adding a margin to the top and bottom.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow.html", '100%', 700)}}

+ +

If we set margins on the paragraph element to 0 then the borders will touch.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-margin-zero.html", '100%', 700)}}

+ +

By default block elements will consume all of the space in the inline direction, so our paragraphs spread out and get as big as they can inside their containing block. If we give them a width, they will continue to lay out one below the other - even if there would be space for them to be side by side. Each will start against the start edge of the containing block, so the place at which sentences would begin in that writing mode.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-width.html", '100%', 700)}}

+ +

Margin collapsing

+ +

The spec explains that margins between block elements collapse. This means that if you have an element with a top margin immediately after an element with a bottom margin, rather than the total space being the sum of these two margins, the margin collapses, and so will essentially become as large as the larger of the two margins.

+ +

In the example below, the paragraphs have a top margin of 20px and a bottom margin of 40px. The size of the margin between the paragraphs is 40px as the smaller top margin on the second paragraph has collapsed with the larger bottom margin of the first.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-collapsing.html", '100%', 500)}}

+ +

You can read more about margin collapsing in our article Mastering Margin Collapsing.

+ +
+

Note: if you are not sure whether margins are collapsing, check the Box Model values in your browser DevTools. This will give you the actual size of the margin which can help you to identify what is happening.

+ +

+
+ +

Elements participating in an inline formatting context

+ +

Inline elements display one after the other in the direction that sentences run in that particular writing mode. While we don’t tend to think of inline elements as having a box, as with everything in CSS they do. These inline boxes are arranged one after the other. If there is not enough space in the containing block for all of the boxes a box can break onto a new line. The lines created are known as line boxes.

+ +

In the following example, we have three inline boxes created by a paragraph with a {{HTMLElement("strong")}} element inside it.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/inline.html", '100%', 500)}}

+ +

The boxes around the words before the <strong> element and after the <strong> element are referred to as anonymous boxes, boxes introduced to ensure that everything is wrapped in a box, but ones that we cannot target directly.

+ +

The line box size in the block direction (so the height when working in English) is defined by the tallest box inside it. In the next example, I have made the <strong> element 300%; that content now defines the height of the line box on that line.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/line-box.html", '100%', 500)}}

+ +

Find out more about how Block and Inline Boxes behave in our Guide to the Visual Formatting Model.

+ +

The display property and flow layout

+ +

In addition to the rules existing in CSS2.1, new levels of CSS further describe the behaviour of block and inline boxes. The {{cssxref("display")}} property defines how a box and any boxes inside it behave. In the CSS Display Model Level 3, we can learn more about how the display property changes the behaviour of boxes and the boxes they generate.

+ +

The display type of an element defines the outer display type; this dictates how the box displays alongside other elements in the same formatting context. It also defines the inner display type, which dictates how boxes inside this element behave. We can see this very clearly when considering a flex layout. In the example below I have a {{HTMLElement("div")}}, which I have given display: flex. The flex container behaves like a block element: it displays on a new line and takes up all of the space it can in the inline direction. This is the outer display type of block.

+ +

The flex items however are participating in a flex formatting context, because their parent is the element with display: flex, which has an inner display type of flex, establishing the flex formatting context for the direct children.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/flex.html", '100%', 500)}}

+ +

Therefore you can think of every box in CSS working in this way. The box itself has an outer display type, so it knows how to behave alongside other boxes. It then has an inner display type which changes the way its children behave. Those children then have an outer and inner display type too. The flex items in the previous example become flex level boxes, so their outer display type is dictated by way of them being part of the flex formatting context. They have an inner display type of flow however, meaning that their children participate in normal flow. Items nested inside our flex item lay themselves out as block and inline elements unless something changes their display type.

+ +

This concept of the outer and inner display type is important as this tells us that a container using a layout method such as Flexbox (display: flex) and Grid Layout (display: grid) is still participating in block and inline layout, due to the outer display type of those methods being block.

+ +

Changing the Formatting Context an element participates in

+ +

Browsers display items as part of a block or inline formatting context in terms of what normally makes sense for that element. For example, a {{HTMLElement("strong")}} element is used to highlight a word and displays bold in browsers. It would not generally make sense for that <strong> element to be displayed as a block level element, breaking onto a new line. If you did want all <strong> elements to display as block elements, you could do so by setting display: block on <strong>. This means that you can always use most of the semantic HTML elements to markup your content, and then change the way it displays using CSS.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/change-formatting.html", '100%', 500)}}

+ +

Summary

+ +

In this guide, we have looked at how elements display in normal flow, as block and inline elements. Due to the default behaviour of these elements, an HTML document with no CSS styling at all, will display in a readable way. By understanding how normal flow works you will find layout easier, as you understand the starting point for making changes to how elements are displayed.

+ +

See Also

+ + diff --git a/files/ru/web/css/css_flow_layout/intro_to_formatting_contexts/index.html b/files/ru/web/css/css_flow_layout/intro_to_formatting_contexts/index.html new file mode 100644 index 0000000000..c027e8eb3b --- /dev/null +++ b/files/ru/web/css/css_flow_layout/intro_to_formatting_contexts/index.html @@ -0,0 +1,85 @@ +--- +title: Введение в контексты форматирования +slug: Web/CSS/CSS_Flow_Layout/Введение_в_контексты_форматирования +translation_of: Web/CSS/CSS_Flow_Layout/Intro_to_formatting_contexts +--- +
{{CSSRef}}
+ +

В этой статье представлена концепция контекстов форматирования (formatting context). Существует несколько типов контекстов форматирования, например, блочный контекст форматирования (block formatting context, BFC), строчный контекст форматирования (inline formatting context), флексовый контекст форматирования (flex formatting context). В статье даны основы того, как они себя ведут, и как вы можете использовать это поведение.

+ +

Всё на странице является частью контекста форматирования (formatting context), который представляет собой область, в которой происходит раскладка контента по определенным правилам. Блочный контекст форматирования (block formatting context, BFC) делает раскладку своих дочерних элементов в соответствии с правилами блочной раскладки, флексовый контекст форматирования (flex formatting context) раскладывает свои дочерние элементы как {{Glossary("flex item", "флекс-элементы")}} и т.д. Каждый контекст форматирования использует свои правила раскладки.

+ +

Блочные контексты форматирования

+ +

Самый внешний элемент в документе, который использует правила блочной раскладки, устанавливает первый или начальный блочный контекст форматирования (initial block formatting context). Это означает, что все элементы внутри элемента <html> раскладываются в соответствии с нормальным потоком, следуя правилам блочной и строчной раскладки. Элементы, участвующие в БКФ, используют правила, описанные в модели бокса (CSS Box Model), которая определяет, как поля (margins), границы (borders) и отступы (paddings) элемента взаимодействуют с другими блоками в том же контексте.

+ +

Создание нового блочного контекста форматирования

+ +

Элемент {{HTMLElement("html")}} не единственный, кто может создавать блочный контекст форматирования. Любой элемент, который по умолчанию представляет собой блок, также создает блочный контекст форматирования для своих потомков. Кроме того, существуют свойства CSS, которые могут заставить элемент создавать БКФ, даже если он не делает этого по умолчанию. Это может быть полезным поскольку новый БКФ будет вести себя во многом как внешний документа, в том смысле, что он создает новую мини-раскладку в основной раскладке. БКФ содержит все внутри себя, {{cssxref("float")}} and {{cssxref("clear")}} применяются только к элементам, которые находится в том же контексте форматирования, также как и поля (margings) схлопываются только между элементами одного и того же контекста форматирования.

+ +

Кроме корневого элемента ({{HTMLElement("html")}}) новый БКФ создается в следующих случаях:

+ + + + + +

Let's have a look at a couple of these in order to see the effect creating a new BFC.

+ +

In the example below, we have a floated element inside a <div> with a border applied. The content of that div has floated alongside the floated element. As the content of the float is taller than the content alongside it, the border of the div now runs through the float. As explained in the guide to in-flow and out of flow elements, the float has been taken out of flow so the background and border of the div only contain the content and not the float.

+ +

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/float.html", '100%', 720)}}

+ +

Creating a new BFC would contain the float. A typical way to do this in the past has been to set overflow: auto or set other values than the initial value of overflow: visible.

+ +

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/bfc-overflow.html", '100%', 720)}}

+ +

Setting  overflow: auto created a new BFC containing the float. Our div now becomes a mini-layout inside our layout. Any child element will be contained inside it.

+ +

The problem with using overflow to create a new BFC is that the overflow property is meant for telling the browser how you wish to deal with overflowing content. There are some occasions in which you will find you get unwanted scrollbars or clipped shadows when you use this property purely to create a BFC. In addition, it is potentially not very readable for a future developer, as it may not be obvious why you used overflow for this purpose. If you do this, it would be a good idea to comment the code to explain.

+ +

Explicitly creating a BFC using display: flow-root

+ +

Using display: flow-root (or display: flow-root list-item) on the containing block will create a new BFC without any other potentially problematic side-effects.

+ +

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/bfc-flow-root.html", '100%', 720)}}

+ +

With display: flow-root on the {{HTMLElement("div")}}, everything inside that container participates in the block formatting context of that container, and floats will not poke out of the bottom of the element.

+ +

The name of the flow-root keyword refers to the fact that you're creating something that serves, in essence, like a new root element (like {{HTMLElement("html")}} does), given how the new context is created and its flow layout functions.

+ +

Inline formatting contexts

+ +

Inline formatting contexts exist inside other formatting contexts and can be thought of as the context of a paragraph. The paragraph creates an inline formatting context inside which such things as {{HTMLElement("strong")}}, {{HTMLElement("a")}}, or {{HTMLElement("span")}} elements are used on text.

+ +

The box model does not fully apply to items participating in an inline formatting context. In a horizontal writing mode line, horizontal padding, borders and margin will be applied to the element and push the text away left and right. However, margins above and below the element will not be applied. Vertical padding and borders will be applied but may  overlap content above and below as, in the inline formatting context, the line boxes will not be pushed apart by padding and borders.

+ +

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/inline.html", '100%', 720)}}

+ +

Other formatting contexts

+ +

This guide covers flow layout and is therefore not referring to other possible formatting contexts. As such, it is useful to understand that creating any kind of formatting context will change the way elements inside that formatting context behave. This behavior is always described in the specification and also here on MDN.

+ +

Summary

+ +

In this guide, we have looked in more detail at the block and Inline formatting contexts and the important subject of creating a block formatting context (BFC). In the next guide, we will find out how normal flow interacts with different writing modes.

+ +

See also

+ + diff --git "a/files/ru/web/css/css_flow_layout/\320\261\320\273\320\276\321\207\320\275\320\276\320\265_\320\270_\321\201\321\202\321\200\320\276\321\207\320\275\320\276\320\265_\321\200\320\260\320\267\320\274\320\265\321\211\320\265\320\275\320\270\320\265_\320\262_\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\320\276\320\274_\320\277\320\276\321\202\320\276\320\272\320\265/index.html" "b/files/ru/web/css/css_flow_layout/\320\261\320\273\320\276\321\207\320\275\320\276\320\265_\320\270_\321\201\321\202\321\200\320\276\321\207\320\275\320\276\320\265_\321\200\320\260\320\267\320\274\320\265\321\211\320\265\320\275\320\270\320\265_\320\262_\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\320\276\320\274_\320\277\320\276\321\202\320\276\320\272\320\265/index.html" deleted file mode 100644 index 86879d343e..0000000000 --- "a/files/ru/web/css/css_flow_layout/\320\261\320\273\320\276\321\207\320\275\320\276\320\265_\320\270_\321\201\321\202\321\200\320\276\321\207\320\275\320\276\320\265_\321\200\320\260\320\267\320\274\320\265\321\211\320\265\320\275\320\270\320\265_\320\262_\320\275\320\276\321\200\320\274\320\260\320\273\321\214\320\275\320\276\320\274_\320\277\320\276\321\202\320\276\320\272\320\265/index.html" +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: Блочное и строчное расположение в нормальном потоке -slug: Web/CSS/CSS_Flow_Layout/Блочное_и_строчное_размещение_в_нормальном_потоке -tags: - - CSS - - Макет - - Макет потока CSS - - Отступы - - Руководство - - Средний уровень - - поток -translation_of: Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow ---- -
{{CSSRef}}
- -

В этом руководстве мы исследуем основы поведения блочных и строчных элементов - участников нормального потока.

- -

Normal Flow is defined in the CSS 2.1 specification, which explains that any boxes in normal flow will be part of a formatting context. They can be either block or inline, but not both at once. We describe block-level boxes as participating in a block formatting context, and inline-level boxes as participating in an inline formatting context.

- -

The behaviour of elements which have a block or inline formatting context is also defined in this specification. For elements with a block formatting context, the spec says:

- -
-

“In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
-
- In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).” - 9.4.1

-
- -

For elements with an inline formatting context:

- -
-

“In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.” - 9.4.2

-
- -

Note that the CSS 2.1 specification describes documents as being in a horizontal, top to bottom writing mode. For example, by describing vertical distance between block boxes. The behavior on block and inline elements is the same when working in a vertical writing mode, and we will explore this in a future guide on Flow Layout and Writing Modes.

- -

Elements participating in a block formatting context

- -

Block elements in a horizontal writing mode such as English, layout vertically, one below the other.

- -

- -

In a vertical writing mode then would lay out horizontally.

- -

- -

In this guide, we will be working in English and therefore a horizontal writing mode. However, everything described should work in the same way if your document is in a vertical writing mode.

- -

As defined in the specification, the margins between two block boxes are what creates separation between the elements. We see this with a very simple layout of two paragraphs, to which I have added a border. The default browser stylesheet adds spacing between the paragraphs by way of adding a margin to the top and bottom.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow.html", '100%', 700)}}

- -

If we set margins on the paragraph element to 0 then the borders will touch.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-margin-zero.html", '100%', 700)}}

- -

By default block elements will consume all of the space in the inline direction, so our paragraphs spread out and get as big as they can inside their containing block. If we give them a width, they will continue to lay out one below the other - even if there would be space for them to be side by side. Each will start against the start edge of the containing block, so the place at which sentences would begin in that writing mode.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-width.html", '100%', 700)}}

- -

Margin collapsing

- -

The spec explains that margins between block elements collapse. This means that if you have an element with a top margin immediately after an element with a bottom margin, rather than the total space being the sum of these two margins, the margin collapses, and so will essentially become as large as the larger of the two margins.

- -

In the example below, the paragraphs have a top margin of 20px and a bottom margin of 40px. The size of the margin between the paragraphs is 40px as the smaller top margin on the second paragraph has collapsed with the larger bottom margin of the first.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-collapsing.html", '100%', 500)}}

- -

You can read more about margin collapsing in our article Mastering Margin Collapsing.

- -
-

Note: if you are not sure whether margins are collapsing, check the Box Model values in your browser DevTools. This will give you the actual size of the margin which can help you to identify what is happening.

- -

-
- -

Elements participating in an inline formatting context

- -

Inline elements display one after the other in the direction that sentences run in that particular writing mode. While we don’t tend to think of inline elements as having a box, as with everything in CSS they do. These inline boxes are arranged one after the other. If there is not enough space in the containing block for all of the boxes a box can break onto a new line. The lines created are known as line boxes.

- -

In the following example, we have three inline boxes created by a paragraph with a {{HTMLElement("strong")}} element inside it.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/inline.html", '100%', 500)}}

- -

The boxes around the words before the <strong> element and after the <strong> element are referred to as anonymous boxes, boxes introduced to ensure that everything is wrapped in a box, but ones that we cannot target directly.

- -

The line box size in the block direction (so the height when working in English) is defined by the tallest box inside it. In the next example, I have made the <strong> element 300%; that content now defines the height of the line box on that line.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/line-box.html", '100%', 500)}}

- -

Find out more about how Block and Inline Boxes behave in our Guide to the Visual Formatting Model.

- -

The display property and flow layout

- -

In addition to the rules existing in CSS2.1, new levels of CSS further describe the behaviour of block and inline boxes. The {{cssxref("display")}} property defines how a box and any boxes inside it behave. In the CSS Display Model Level 3, we can learn more about how the display property changes the behaviour of boxes and the boxes they generate.

- -

The display type of an element defines the outer display type; this dictates how the box displays alongside other elements in the same formatting context. It also defines the inner display type, which dictates how boxes inside this element behave. We can see this very clearly when considering a flex layout. In the example below I have a {{HTMLElement("div")}}, which I have given display: flex. The flex container behaves like a block element: it displays on a new line and takes up all of the space it can in the inline direction. This is the outer display type of block.

- -

The flex items however are participating in a flex formatting context, because their parent is the element with display: flex, which has an inner display type of flex, establishing the flex formatting context for the direct children.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/flex.html", '100%', 500)}}

- -

Therefore you can think of every box in CSS working in this way. The box itself has an outer display type, so it knows how to behave alongside other boxes. It then has an inner display type which changes the way its children behave. Those children then have an outer and inner display type too. The flex items in the previous example become flex level boxes, so their outer display type is dictated by way of them being part of the flex formatting context. They have an inner display type of flow however, meaning that their children participate in normal flow. Items nested inside our flex item lay themselves out as block and inline elements unless something changes their display type.

- -

This concept of the outer and inner display type is important as this tells us that a container using a layout method such as Flexbox (display: flex) and Grid Layout (display: grid) is still participating in block and inline layout, due to the outer display type of those methods being block.

- -

Changing the Formatting Context an element participates in

- -

Browsers display items as part of a block or inline formatting context in terms of what normally makes sense for that element. For example, a {{HTMLElement("strong")}} element is used to highlight a word and displays bold in browsers. It would not generally make sense for that <strong> element to be displayed as a block level element, breaking onto a new line. If you did want all <strong> elements to display as block elements, you could do so by setting display: block on <strong>. This means that you can always use most of the semantic HTML elements to markup your content, and then change the way it displays using CSS.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/change-formatting.html", '100%', 500)}}

- -

Summary

- -

In this guide, we have looked at how elements display in normal flow, as block and inline elements. Due to the default behaviour of these elements, an HTML document with no CSS styling at all, will display in a readable way. By understanding how normal flow works you will find layout easier, as you understand the starting point for making changes to how elements are displayed.

- -

See Also

- - diff --git "a/files/ru/web/css/css_flow_layout/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_\320\272\320\276\320\275\321\202\320\265\320\272\321\201\321\202\321\213_\321\204\320\276\321\200\320\274\320\260\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" "b/files/ru/web/css/css_flow_layout/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_\320\272\320\276\320\275\321\202\320\265\320\272\321\201\321\202\321\213_\321\204\320\276\321\200\320\274\320\260\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" deleted file mode 100644 index c027e8eb3b..0000000000 --- "a/files/ru/web/css/css_flow_layout/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265_\320\262_\320\272\320\276\320\275\321\202\320\265\320\272\321\201\321\202\321\213_\321\204\320\276\321\200\320\274\320\260\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\321\217/index.html" +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Введение в контексты форматирования -slug: Web/CSS/CSS_Flow_Layout/Введение_в_контексты_форматирования -translation_of: Web/CSS/CSS_Flow_Layout/Intro_to_formatting_contexts ---- -
{{CSSRef}}
- -

В этой статье представлена концепция контекстов форматирования (formatting context). Существует несколько типов контекстов форматирования, например, блочный контекст форматирования (block formatting context, BFC), строчный контекст форматирования (inline formatting context), флексовый контекст форматирования (flex formatting context). В статье даны основы того, как они себя ведут, и как вы можете использовать это поведение.

- -

Всё на странице является частью контекста форматирования (formatting context), который представляет собой область, в которой происходит раскладка контента по определенным правилам. Блочный контекст форматирования (block formatting context, BFC) делает раскладку своих дочерних элементов в соответствии с правилами блочной раскладки, флексовый контекст форматирования (flex formatting context) раскладывает свои дочерние элементы как {{Glossary("flex item", "флекс-элементы")}} и т.д. Каждый контекст форматирования использует свои правила раскладки.

- -

Блочные контексты форматирования

- -

Самый внешний элемент в документе, который использует правила блочной раскладки, устанавливает первый или начальный блочный контекст форматирования (initial block formatting context). Это означает, что все элементы внутри элемента <html> раскладываются в соответствии с нормальным потоком, следуя правилам блочной и строчной раскладки. Элементы, участвующие в БКФ, используют правила, описанные в модели бокса (CSS Box Model), которая определяет, как поля (margins), границы (borders) и отступы (paddings) элемента взаимодействуют с другими блоками в том же контексте.

- -

Создание нового блочного контекста форматирования

- -

Элемент {{HTMLElement("html")}} не единственный, кто может создавать блочный контекст форматирования. Любой элемент, который по умолчанию представляет собой блок, также создает блочный контекст форматирования для своих потомков. Кроме того, существуют свойства CSS, которые могут заставить элемент создавать БКФ, даже если он не делает этого по умолчанию. Это может быть полезным поскольку новый БКФ будет вести себя во многом как внешний документа, в том смысле, что он создает новую мини-раскладку в основной раскладке. БКФ содержит все внутри себя, {{cssxref("float")}} and {{cssxref("clear")}} применяются только к элементам, которые находится в том же контексте форматирования, также как и поля (margings) схлопываются только между элементами одного и того же контекста форматирования.

- -

Кроме корневого элемента ({{HTMLElement("html")}}) новый БКФ создается в следующих случаях:

- - - - - -

Let's have a look at a couple of these in order to see the effect creating a new BFC.

- -

In the example below, we have a floated element inside a <div> with a border applied. The content of that div has floated alongside the floated element. As the content of the float is taller than the content alongside it, the border of the div now runs through the float. As explained in the guide to in-flow and out of flow elements, the float has been taken out of flow so the background and border of the div only contain the content and not the float.

- -

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/float.html", '100%', 720)}}

- -

Creating a new BFC would contain the float. A typical way to do this in the past has been to set overflow: auto or set other values than the initial value of overflow: visible.

- -

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/bfc-overflow.html", '100%', 720)}}

- -

Setting  overflow: auto created a new BFC containing the float. Our div now becomes a mini-layout inside our layout. Any child element will be contained inside it.

- -

The problem with using overflow to create a new BFC is that the overflow property is meant for telling the browser how you wish to deal with overflowing content. There are some occasions in which you will find you get unwanted scrollbars or clipped shadows when you use this property purely to create a BFC. In addition, it is potentially not very readable for a future developer, as it may not be obvious why you used overflow for this purpose. If you do this, it would be a good idea to comment the code to explain.

- -

Explicitly creating a BFC using display: flow-root

- -

Using display: flow-root (or display: flow-root list-item) on the containing block will create a new BFC without any other potentially problematic side-effects.

- -

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/bfc-flow-root.html", '100%', 720)}}

- -

With display: flow-root on the {{HTMLElement("div")}}, everything inside that container participates in the block formatting context of that container, and floats will not poke out of the bottom of the element.

- -

The name of the flow-root keyword refers to the fact that you're creating something that serves, in essence, like a new root element (like {{HTMLElement("html")}} does), given how the new context is created and its flow layout functions.

- -

Inline formatting contexts

- -

Inline formatting contexts exist inside other formatting contexts and can be thought of as the context of a paragraph. The paragraph creates an inline formatting context inside which such things as {{HTMLElement("strong")}}, {{HTMLElement("a")}}, or {{HTMLElement("span")}} elements are used on text.

- -

The box model does not fully apply to items participating in an inline formatting context. In a horizontal writing mode line, horizontal padding, borders and margin will be applied to the element and push the text away left and right. However, margins above and below the element will not be applied. Vertical padding and borders will be applied but may  overlap content above and below as, in the inline formatting context, the line boxes will not be pushed apart by padding and borders.

- -

{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/inline.html", '100%', 720)}}

- -

Other formatting contexts

- -

This guide covers flow layout and is therefore not referring to other possible formatting contexts. As such, it is useful to understand that creating any kind of formatting context will change the way elements inside that formatting context behave. This behavior is always described in the specification and also here on MDN.

- -

Summary

- -

In this guide, we have looked in more detail at the block and Inline formatting contexts and the important subject of creating a block formatting context (BFC). In the next guide, we will find out how normal flow interacts with different writing modes.

- -

See also

- - diff --git a/files/ru/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html b/files/ru/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html deleted file mode 100644 index 48eec35abe..0000000000 --- a/files/ru/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html +++ /dev/null @@ -1,498 +0,0 @@ ---- -title: 'CSS grids, logical values and writing modes' -slug: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' -translation_of: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' ---- -

В этих руководствах я уже затронул важную особенность grid layout: поддержка различных режимов записи, встроенных в спецификацию. В этом руководстве мы рассмотрим эту особенность grid и других современных методов компоновки, немного узнав о режимах записи и логических и физических свойствах, когда мы это делаем.

- -

Логические и физические свойства и ценности

- -

CSS полон физических слов позиционирования - слева и справа, сверху и снизу. Если мы позиционируем элемент с использованием абсолютного позиционирования, мы используем эти физические ключевые слова в качестве значений смещения, чтобы обжимать элемент вокруг. В нижеприведенном фрагменте кода элемент помещается в 20 пикселей сверху и 30 пикселей слева от контейнера:

- -
.container {
-  position: relative;
-}
-.item {
-  position: absolute;
-  top: 20px;
-  left: 30px;
-}
-
- -
<div class="container">
-  <div class="item">Item</div>
-</div>
-
- -

Еще одно место, где вы можете увидеть используемые физические ключевые слова, - это использовать text-align: right выравнивать текст вправо. В CSS есть также физические свойства. Мы добавляем поля, дополнения и границы, используя эти физические свойства {{cssxref ("margin-left")}}, {{cssxref ("padding-left")}} и т. д.

- -

Мы называем эти ключевые слова и свойства физическими, потому что они относятся к экрану, на который вы смотрите. Слева всегда слева, независимо от того, в каком направлении работает ваш текст.

- -

Это может стать проблемой при разработке сайта, который должен работать на нескольких языках, включая языки с текстом, начинающимся справа, а не слева. Браузеры хорошо справляются с направлением текста и вам даже не нужно работать на языке {{glossary ("rtl")}}, чтобы посмотреть. В приведенном ниже примере у меня есть два абзаца. У одного не установлено {{cssxref ("text-align")}}, второе имеет выравнивание текста (text-align) влево. Я добавил dir = "rtl" в элемент html, который переключает режим записи по умолчанию для документа на английском языке ltr. Вы можете видеть, что первый абзац остается слева направо, из-за оставленного значения выравнивания текста. Второе, однако, переключает направление и текст пробегает справа налево.

- -

A simple example of text direction.

- -

Это очень простой пример проблемы с физическими значениями и свойствами, которые используются в CSS. Они не позволяют браузеру выполнять работу по переключению режима записи, поскольку они делают предположение, что текст течет слева направо и сверху вниз.

- -

Логические свойства и значения

- -

Логические свойства и значения не делают предположения о направлении текста. Именно поэтому в Grid Layout мы используем ключевое слово start при выравнивании чего-либо с началом контейнера. Для меня, работая на английском языке, start может быть слева, но это не обязательно и слово start не имеет физического местоположения.

- -

Block и Inline

- -

Как только мы начнем заниматься логическими, а не физическими свойствами, мы перестаем видеть мир как слева направо, так и сверху вниз. Нам нужна новая контрольная точка и именно здесь понимание использования блока и встроенных осей, которые мы встретили ранее в руководстве по выравниванию, становится очень полезным. Если вы можете начать видеть макет с точки зрения блочного и встроенного, то, как все работает в сетке, становится намного больше смысла.

- -

An image showing the default direction of the Block and Inline Axes.

- -

Режимы записи CSS

- -

Я собираюсь представить здесь еще одну спецификацию, которую я буду использовать в своих примерах: спецификация CSS Writing Modes. Эта спецификация подробно описывает, как мы можем использовать эти разные режимы записи в CSS, а не только для поддержки языков, которые имеют другой режим записи на английском языке, но также и для творческих целей. Я буду использовать свойство {{cssxref ("write-mode")}}, чтобы внести изменения в режим записи, применяемый к нашей сетке, чтобы продемонстрировать, как работают логические значения. Однако, если вы хотите, чтобы вы меняли в режиме записи, я бы рекомендовал вам прочитать Jen Simmons отличную статью о CSS Writing Modes. Это более подробно описано в этой спецификации, чем мы коснемся здесь.

- -

writing-mode

- -

Режимы записи - это больше, чем текст слева направо и справа налево, а свойство writing-mode помогает отображать текст в других направлениях. Свойство {{cssxref ("write-mode")}} может иметь значения:

- - - -

Значение horizontal-tb является значением по умолчанию для текста в Интернете. Это направление, в котором вы читаете это руководство. Другие свойства изменят способ передачи текста в нашем документе, соответствующий различным режимам записи, найденным по всему миру. Опять же, для получения полной информации об этом см. Jen’s article. В качестве простого примера у меня есть два параграфа ниже. Первый использует по умолчанию horizontal-tb, а второй использует vertical-rl. В тексте режима все еще выполняется влево-вправо, однако направление текста вертикально - встроенный текст теперь проходит вниз по странице, сверху вниз.

- -
- - -
<div class="wrapper">
-   <p style="writing-mode: horizontal-tb">I have writing mode set to the default <code>horizontal-tb</code></p>
-  <p style="writing-mode: vertical-rl">I have writing mode set to <code>vertical-rl</code></p>
-</div>
-
- -

{{ EmbedLiveSample('writing_1', '500', '420') }}

-
- -

Writing modes в grid layouts

- -

Если мы сейчас рассмотрим пример компоновки сетки, мы увидим, как изменение режима записи означает изменение нашей идеи о том, где находятся Block и Inline Axis.

- -

В моем следующем примере сетка имеет три столбца и две строки. Это означает, что на оси блока есть три дорожки. В режиме записи по умолчанию сетка автоматически помещает элементы, начинающиеся в верхнем левом углу, перемещаясь вправо, заполняя три ячейки на встроенной оси. Затем он переходит на следующую строку, создавая новый дорожку Row и заполняя больше элементов:

- -
- - -
.wrapper {
-  display: grid;
-  grid-template-columns: repeat(3, 100px);
-  grid-template-rows: repeat(2, 100px);
-  grid-gap: 10px;
-}
-
- -
<div class="wrapper">
-  <div class="item1">Item 1</div>
-  <div class="item2">Item 2</div>
-  <div class="item3">Item 3</div>
-  <div class="item4">Item 4</div>
-  <div class="item5">Item 5</div>
-</div>
-
- -

{{ EmbedLiveSample('writing_2', '500', '330') }}

-
- -

Если мы добавим writing-mode: vertical-lr в контейнер сетки, мы увидим, что блок и встроенная ось теперь работают в другом направлении. Ось блока или столбца теперь проходит через страницу слева направо, Inline запускается вниз по странице, создавая строки сверху вниз.

- -
- - -
.wrapper {
-  writing-mode: vertical-lr;
-  display: grid;
-  grid-template-columns: repeat(3, 100px);
-  grid-template-rows: repeat(2, 100px);
-  grid-gap: 10px;
-}
-
- -
<div class="wrapper">
-  <div class="item1">Item 1</div>
-  <div class="item2">Item 2</div>
-  <div class="item3">Item 3</div>
-  <div class="item4">Item 4</div>
-  <div class="item5">Item 5</div>
-</div>
-
- -

{{ EmbedLiveSample('writing_3', '500', '330') }}

-
- -

A image showing the direction of Block and Inline when writing-mode is vertical-lr

- -

Логические значения для выравнивания

- -

Когда блок и встроенная ось могут изменять направление, логические значения свойств выравнивания начинают иметь больше смысла.

- -

В следующем примере я использую выравнивание для выравнивания элементов внутри сетки, которая настроена на writing-mode: vertical-lr. start и end свойства работают точно так же, как в режиме записи по умолчанию, и остаются логичными в том смысле, что использование левого и правого, верхнего и нижнего уровней для выравнивания элементов не будет выполнено. Это происходит, когда мы перевернули сетку сбоку, например:

- -
- - -
.wrapper {
-  writing-mode: vertical-lr;
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  grid-template-rows: repeat(3, 100px);
-  grid-gap: 10px;
-}
-
-.item1 {
-    grid-column: 1 / 4;
-    align-self: start;
-}
-
-.item2 {
-    grid-column: 1 / 3;
-    grid-row: 2 / 4;
-    align-self: start;
-}
-
-.item3 {
-    grid-column: 3;
-    grid-row: 2 / 4;
-    align-self: end;
-    justify-self: end;
-}
-
- -
<div class="wrapper">
-  <div class="item1">Item 1</div>
-  <div class="item2">Item 2</div>
-  <div class="item3">Item 3</div>
-</div>
-
- -

{{ EmbedLiveSample('writing_4', '500', '330') }}

-
- -

Если вы хотите посмотреть, как они работают, как справа, так и сверху вниз, переключите vertical-lr на vertical-rl, который является вертикальным режимом записи, работающим справа налево.

- -

Auto-placement and Writing Modes

- -

В примере, который уже показан, вы можете видеть, как режим записи меняет направление, в котором элементы помещаются в сетку. Элементы по умолчанию помещают себя вдоль оси Inline, а затем переходят в новую строку. Однако эта линейная ось может не всегда выполняться слева направо.

- -

Линейное размещение и режимы записи

- -

Главное, что следует помнить при размещении элементов по номеру строки, является то, что строка 1 является стартовой линией, независимо от того, в каком режиме записи вы находитесь. Строка -1 - это конечная строка, независимо от того, в каком режиме записи вы находитесь.

- -

В следующем примере у меня есть сетка, которая находится в направлении по умолчанию ltr. Я разместил три элемента, используя линейное размещение.

- - - -
- - -
.wrapper {
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  grid-template-rows: repeat(2, 100px);
-  grid-gap: 10px;
-}
-.item1 {
-    grid-column: 1 ;
-}
-.item2 {
-    grid-column: -1 / -3;
-}
-.item3 {
-    grid-column: 1 / 3;
-    grid-row: 2;
-}
-
- -
<div class="wrapper">
-        <div class="item1">Item 1</div>
-        <div class="item2">Item 2</div>
-        <div class="item3">Item 3</div>
-    </div>
-
- -

{{ EmbedLiveSample('writing_5', '500', '330') }}

-
- -

Если теперь добавить свойство {{cssxref ("direction")}} со значением rtl в контейнер сетки, строка 1 станет правой частью сетки, а строка -1 - слева.

- -
- - -
.wrapper {
-  direction: rtl;
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  grid-template-rows: repeat(2, 100px);
-  grid-gap: 10px;
-}
-.item1 {
-    grid-column: 1 ;
-}
-.item2 {
-    grid-column: -1 / -3;
-}
-.item3 {
-    grid-column: 1 / 3;
-    grid-row: 2;
-}
-
- -
<div class="wrapper">
-        <div class="item1">Item 1</div>
-        <div class="item2">Item 2</div>
-        <div class="item3">Item 3</div>
-    </div>
-
- -

{{ EmbedLiveSample('writing_6', '500', '330') }}

-
- -

То, что это демонстрирует, заключается в том, что если вы переключаете направление текста на целые страницы или на части страниц и используете строки: вы можете назвать свои строки, если вы не хотите, чтобы макет полностью переключал направление , для некоторых вещей, например, когда сетка содержит текстовое содержимое, это переключение может быть именно тем, что вы хотите. Для других целей это не так.

- -

Странный порядок значений в свойстве grid-area

- -

Вы можете использовать свойство {{cssxref ("grid-area")}}, чтобы указать все четыре строки области сетки как одно значение. Когда люди впервые сталкиваются с этим, они часто удивляются тому, что значения не следуют тому же порядку, что и сокращенное поле, которое работает по часовой стрелке: сверху, справа, внизу, слева.

- -

Порядок значений grid-area:

- - - -

Что для английского языка, слева направо означает, что заказ:

- - - -

Это против часовой стрелки! Итак, обратное тому, что мы делаем для полей и заполнения. Как только вы поймете, что grid-area видит мир как "block и inline", вы можете помнить, что мы устанавливаем два запуска, а затем два конца. Когда вы знаете, это становится намного логичнее!

- -

Смешанные режимы записи и макет сетки

- -

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

- -
-
.wrapper {
-    display: grid;
-    grid-gap: 20px;
-    grid-template-columns: 1fr auto;
-    font: 1em Helvetica, Arial, sans-serif;
-}
-.wrapper nav {
-    writing-mode: vertical-lr;
-}
-.wrapper ul {
-    list-style: none;
-    margin: 0;
-    padding: 1em;
-    display: flex;
-    justify-content: space-between;
-}
-.wrapper a {
-    text-decoration: none;
-}
-
- -
<div class="wrapper">
-        <div class="content">
-            <p>Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato scallion desert raisin horseradish spinach carrot soko. Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn amaranth salsify bunya nuts nori azuki bean chickweed potato bell pepper artichoke.</p>
-
-<p>Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi leek soko chicory celtuce parsley jícama salsify.</p>
-        </div>
-        <nav>
-            <ul>
-                <li><a href="">Link 1</a></li>
-                <li><a href="">Link 2</a></li>
-                <li><a href="">Link 3</a></li>
-            </ul>
-        </nav>
-    </div>
-
- -

{{ EmbedLiveSample('writing_7', '500', '330') }}

-
- -

Физические значения и grid layout

- -

Мы часто сталкиваемся с физическими свойствами при создании веб-сайтов и в то время как свойства и значения размещения и выравнивания сетки соответствуют режимам записи, есть вещи, которые вы можете сделать с Grid, которые заставляют вас использовать физические свойства и значения. В руководстве по выравниванию ячеек и сеткам я продемонстрировал, как автоматические поля работают в области сетки. Использование автоматической маржи, чтобы оттолкнуть один элемент от других, является общим трюком flexbox, однако это также связывает макет с физическим пространством.

- -

Если вы используете абсолютное позиционирование в области сетки, то вы снова будете использовать физические смещения, чтобы нажимать элемент вокруг области сетки. Главное, что нужно знать, - это напряжение между физическими и логическими свойствами и ценностями. Например, имейте в виду, что вам может потребоваться внести изменения в ваш CSS, чтобы справиться с переходом от ltr до rtl.

- -

Логические свойства для всего!

- -

Наши новые методы компоновки дают нам возможность использовать эти логические значения для размещения элементов, однако, как только мы начнем объединять их с физическими свойствами, используемыми для полей и отступов, нам нужно помнить, что эти физические свойства не изменятся в соответствии с режимом записи.

- -

Спецификация логических свойств CSS имеет целью изменить это и в будущем мы сможем использовать логические эквиваленты для свойств, такие как {{cssxref ("margin-left")}} и {{cssxref ("margin-right") }}, в нашем CSS. Firefox уже реализовал их, поэтому вы можете попробовать их прямо сейчас в Firefox. Я знаю в будущем, как только эти корабли повсюду, ваши знания «Блокировать и встроить» с помощью Grid означают, что вы точно знаете, как их использовать.

- - diff --git a/files/ru/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html b/files/ru/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html new file mode 100644 index 0000000000..48eec35abe --- /dev/null +++ b/files/ru/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html @@ -0,0 +1,498 @@ +--- +title: 'CSS grids, logical values and writing modes' +slug: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' +translation_of: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' +--- +

В этих руководствах я уже затронул важную особенность grid layout: поддержка различных режимов записи, встроенных в спецификацию. В этом руководстве мы рассмотрим эту особенность grid и других современных методов компоновки, немного узнав о режимах записи и логических и физических свойствах, когда мы это делаем.

+ +

Логические и физические свойства и ценности

+ +

CSS полон физических слов позиционирования - слева и справа, сверху и снизу. Если мы позиционируем элемент с использованием абсолютного позиционирования, мы используем эти физические ключевые слова в качестве значений смещения, чтобы обжимать элемент вокруг. В нижеприведенном фрагменте кода элемент помещается в 20 пикселей сверху и 30 пикселей слева от контейнера:

+ +
.container {
+  position: relative;
+}
+.item {
+  position: absolute;
+  top: 20px;
+  left: 30px;
+}
+
+ +
<div class="container">
+  <div class="item">Item</div>
+</div>
+
+ +

Еще одно место, где вы можете увидеть используемые физические ключевые слова, - это использовать text-align: right выравнивать текст вправо. В CSS есть также физические свойства. Мы добавляем поля, дополнения и границы, используя эти физические свойства {{cssxref ("margin-left")}}, {{cssxref ("padding-left")}} и т. д.

+ +

Мы называем эти ключевые слова и свойства физическими, потому что они относятся к экрану, на который вы смотрите. Слева всегда слева, независимо от того, в каком направлении работает ваш текст.

+ +

Это может стать проблемой при разработке сайта, который должен работать на нескольких языках, включая языки с текстом, начинающимся справа, а не слева. Браузеры хорошо справляются с направлением текста и вам даже не нужно работать на языке {{glossary ("rtl")}}, чтобы посмотреть. В приведенном ниже примере у меня есть два абзаца. У одного не установлено {{cssxref ("text-align")}}, второе имеет выравнивание текста (text-align) влево. Я добавил dir = "rtl" в элемент html, который переключает режим записи по умолчанию для документа на английском языке ltr. Вы можете видеть, что первый абзац остается слева направо, из-за оставленного значения выравнивания текста. Второе, однако, переключает направление и текст пробегает справа налево.

+ +

A simple example of text direction.

+ +

Это очень простой пример проблемы с физическими значениями и свойствами, которые используются в CSS. Они не позволяют браузеру выполнять работу по переключению режима записи, поскольку они делают предположение, что текст течет слева направо и сверху вниз.

+ +

Логические свойства и значения

+ +

Логические свойства и значения не делают предположения о направлении текста. Именно поэтому в Grid Layout мы используем ключевое слово start при выравнивании чего-либо с началом контейнера. Для меня, работая на английском языке, start может быть слева, но это не обязательно и слово start не имеет физического местоположения.

+ +

Block и Inline

+ +

Как только мы начнем заниматься логическими, а не физическими свойствами, мы перестаем видеть мир как слева направо, так и сверху вниз. Нам нужна новая контрольная точка и именно здесь понимание использования блока и встроенных осей, которые мы встретили ранее в руководстве по выравниванию, становится очень полезным. Если вы можете начать видеть макет с точки зрения блочного и встроенного, то, как все работает в сетке, становится намного больше смысла.

+ +

An image showing the default direction of the Block and Inline Axes.

+ +

Режимы записи CSS

+ +

Я собираюсь представить здесь еще одну спецификацию, которую я буду использовать в своих примерах: спецификация CSS Writing Modes. Эта спецификация подробно описывает, как мы можем использовать эти разные режимы записи в CSS, а не только для поддержки языков, которые имеют другой режим записи на английском языке, но также и для творческих целей. Я буду использовать свойство {{cssxref ("write-mode")}}, чтобы внести изменения в режим записи, применяемый к нашей сетке, чтобы продемонстрировать, как работают логические значения. Однако, если вы хотите, чтобы вы меняли в режиме записи, я бы рекомендовал вам прочитать Jen Simmons отличную статью о CSS Writing Modes. Это более подробно описано в этой спецификации, чем мы коснемся здесь.

+ +

writing-mode

+ +

Режимы записи - это больше, чем текст слева направо и справа налево, а свойство writing-mode помогает отображать текст в других направлениях. Свойство {{cssxref ("write-mode")}} может иметь значения:

+ + + +

Значение horizontal-tb является значением по умолчанию для текста в Интернете. Это направление, в котором вы читаете это руководство. Другие свойства изменят способ передачи текста в нашем документе, соответствующий различным режимам записи, найденным по всему миру. Опять же, для получения полной информации об этом см. Jen’s article. В качестве простого примера у меня есть два параграфа ниже. Первый использует по умолчанию horizontal-tb, а второй использует vertical-rl. В тексте режима все еще выполняется влево-вправо, однако направление текста вертикально - встроенный текст теперь проходит вниз по странице, сверху вниз.

+ +
+ + +
<div class="wrapper">
+   <p style="writing-mode: horizontal-tb">I have writing mode set to the default <code>horizontal-tb</code></p>
+  <p style="writing-mode: vertical-rl">I have writing mode set to <code>vertical-rl</code></p>
+</div>
+
+ +

{{ EmbedLiveSample('writing_1', '500', '420') }}

+
+ +

Writing modes в grid layouts

+ +

Если мы сейчас рассмотрим пример компоновки сетки, мы увидим, как изменение режима записи означает изменение нашей идеи о том, где находятся Block и Inline Axis.

+ +

В моем следующем примере сетка имеет три столбца и две строки. Это означает, что на оси блока есть три дорожки. В режиме записи по умолчанию сетка автоматически помещает элементы, начинающиеся в верхнем левом углу, перемещаясь вправо, заполняя три ячейки на встроенной оси. Затем он переходит на следующую строку, создавая новый дорожку Row и заполняя больше элементов:

+ +
+ + +
.wrapper {
+  display: grid;
+  grid-template-columns: repeat(3, 100px);
+  grid-template-rows: repeat(2, 100px);
+  grid-gap: 10px;
+}
+
+ +
<div class="wrapper">
+  <div class="item1">Item 1</div>
+  <div class="item2">Item 2</div>
+  <div class="item3">Item 3</div>
+  <div class="item4">Item 4</div>
+  <div class="item5">Item 5</div>
+</div>
+
+ +

{{ EmbedLiveSample('writing_2', '500', '330') }}

+
+ +

Если мы добавим writing-mode: vertical-lr в контейнер сетки, мы увидим, что блок и встроенная ось теперь работают в другом направлении. Ось блока или столбца теперь проходит через страницу слева направо, Inline запускается вниз по странице, создавая строки сверху вниз.

+ +
+ + +
.wrapper {
+  writing-mode: vertical-lr;
+  display: grid;
+  grid-template-columns: repeat(3, 100px);
+  grid-template-rows: repeat(2, 100px);
+  grid-gap: 10px;
+}
+
+ +
<div class="wrapper">
+  <div class="item1">Item 1</div>
+  <div class="item2">Item 2</div>
+  <div class="item3">Item 3</div>
+  <div class="item4">Item 4</div>
+  <div class="item5">Item 5</div>
+</div>
+
+ +

{{ EmbedLiveSample('writing_3', '500', '330') }}

+
+ +

A image showing the direction of Block and Inline when writing-mode is vertical-lr

+ +

Логические значения для выравнивания

+ +

Когда блок и встроенная ось могут изменять направление, логические значения свойств выравнивания начинают иметь больше смысла.

+ +

В следующем примере я использую выравнивание для выравнивания элементов внутри сетки, которая настроена на writing-mode: vertical-lr. start и end свойства работают точно так же, как в режиме записи по умолчанию, и остаются логичными в том смысле, что использование левого и правого, верхнего и нижнего уровней для выравнивания элементов не будет выполнено. Это происходит, когда мы перевернули сетку сбоку, например:

+ +
+ + +
.wrapper {
+  writing-mode: vertical-lr;
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  grid-template-rows: repeat(3, 100px);
+  grid-gap: 10px;
+}
+
+.item1 {
+    grid-column: 1 / 4;
+    align-self: start;
+}
+
+.item2 {
+    grid-column: 1 / 3;
+    grid-row: 2 / 4;
+    align-self: start;
+}
+
+.item3 {
+    grid-column: 3;
+    grid-row: 2 / 4;
+    align-self: end;
+    justify-self: end;
+}
+
+ +
<div class="wrapper">
+  <div class="item1">Item 1</div>
+  <div class="item2">Item 2</div>
+  <div class="item3">Item 3</div>
+</div>
+
+ +

{{ EmbedLiveSample('writing_4', '500', '330') }}

+
+ +

Если вы хотите посмотреть, как они работают, как справа, так и сверху вниз, переключите vertical-lr на vertical-rl, который является вертикальным режимом записи, работающим справа налево.

+ +

Auto-placement and Writing Modes

+ +

В примере, который уже показан, вы можете видеть, как режим записи меняет направление, в котором элементы помещаются в сетку. Элементы по умолчанию помещают себя вдоль оси Inline, а затем переходят в новую строку. Однако эта линейная ось может не всегда выполняться слева направо.

+ +

Линейное размещение и режимы записи

+ +

Главное, что следует помнить при размещении элементов по номеру строки, является то, что строка 1 является стартовой линией, независимо от того, в каком режиме записи вы находитесь. Строка -1 - это конечная строка, независимо от того, в каком режиме записи вы находитесь.

+ +

В следующем примере у меня есть сетка, которая находится в направлении по умолчанию ltr. Я разместил три элемента, используя линейное размещение.

+ + + +
+ + +
.wrapper {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  grid-template-rows: repeat(2, 100px);
+  grid-gap: 10px;
+}
+.item1 {
+    grid-column: 1 ;
+}
+.item2 {
+    grid-column: -1 / -3;
+}
+.item3 {
+    grid-column: 1 / 3;
+    grid-row: 2;
+}
+
+ +
<div class="wrapper">
+        <div class="item1">Item 1</div>
+        <div class="item2">Item 2</div>
+        <div class="item3">Item 3</div>
+    </div>
+
+ +

{{ EmbedLiveSample('writing_5', '500', '330') }}

+
+ +

Если теперь добавить свойство {{cssxref ("direction")}} со значением rtl в контейнер сетки, строка 1 станет правой частью сетки, а строка -1 - слева.

+ +
+ + +
.wrapper {
+  direction: rtl;
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  grid-template-rows: repeat(2, 100px);
+  grid-gap: 10px;
+}
+.item1 {
+    grid-column: 1 ;
+}
+.item2 {
+    grid-column: -1 / -3;
+}
+.item3 {
+    grid-column: 1 / 3;
+    grid-row: 2;
+}
+
+ +
<div class="wrapper">
+        <div class="item1">Item 1</div>
+        <div class="item2">Item 2</div>
+        <div class="item3">Item 3</div>
+    </div>
+
+ +

{{ EmbedLiveSample('writing_6', '500', '330') }}

+
+ +

То, что это демонстрирует, заключается в том, что если вы переключаете направление текста на целые страницы или на части страниц и используете строки: вы можете назвать свои строки, если вы не хотите, чтобы макет полностью переключал направление , для некоторых вещей, например, когда сетка содержит текстовое содержимое, это переключение может быть именно тем, что вы хотите. Для других целей это не так.

+ +

Странный порядок значений в свойстве grid-area

+ +

Вы можете использовать свойство {{cssxref ("grid-area")}}, чтобы указать все четыре строки области сетки как одно значение. Когда люди впервые сталкиваются с этим, они часто удивляются тому, что значения не следуют тому же порядку, что и сокращенное поле, которое работает по часовой стрелке: сверху, справа, внизу, слева.

+ +

Порядок значений grid-area:

+ + + +

Что для английского языка, слева направо означает, что заказ:

+ + + +

Это против часовой стрелки! Итак, обратное тому, что мы делаем для полей и заполнения. Как только вы поймете, что grid-area видит мир как "block и inline", вы можете помнить, что мы устанавливаем два запуска, а затем два конца. Когда вы знаете, это становится намного логичнее!

+ +

Смешанные режимы записи и макет сетки

+ +

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

+ +
+
.wrapper {
+    display: grid;
+    grid-gap: 20px;
+    grid-template-columns: 1fr auto;
+    font: 1em Helvetica, Arial, sans-serif;
+}
+.wrapper nav {
+    writing-mode: vertical-lr;
+}
+.wrapper ul {
+    list-style: none;
+    margin: 0;
+    padding: 1em;
+    display: flex;
+    justify-content: space-between;
+}
+.wrapper a {
+    text-decoration: none;
+}
+
+ +
<div class="wrapper">
+        <div class="content">
+            <p>Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato scallion desert raisin horseradish spinach carrot soko. Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn amaranth salsify bunya nuts nori azuki bean chickweed potato bell pepper artichoke.</p>
+
+<p>Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi leek soko chicory celtuce parsley jícama salsify.</p>
+        </div>
+        <nav>
+            <ul>
+                <li><a href="">Link 1</a></li>
+                <li><a href="">Link 2</a></li>
+                <li><a href="">Link 3</a></li>
+            </ul>
+        </nav>
+    </div>
+
+ +

{{ EmbedLiveSample('writing_7', '500', '330') }}

+
+ +

Физические значения и grid layout

+ +

Мы часто сталкиваемся с физическими свойствами при создании веб-сайтов и в то время как свойства и значения размещения и выравнивания сетки соответствуют режимам записи, есть вещи, которые вы можете сделать с Grid, которые заставляют вас использовать физические свойства и значения. В руководстве по выравниванию ячеек и сеткам я продемонстрировал, как автоматические поля работают в области сетки. Использование автоматической маржи, чтобы оттолкнуть один элемент от других, является общим трюком flexbox, однако это также связывает макет с физическим пространством.

+ +

Если вы используете абсолютное позиционирование в области сетки, то вы снова будете использовать физические смещения, чтобы нажимать элемент вокруг области сетки. Главное, что нужно знать, - это напряжение между физическими и логическими свойствами и ценностями. Например, имейте в виду, что вам может потребоваться внести изменения в ваш CSS, чтобы справиться с переходом от ltr до rtl.

+ +

Логические свойства для всего!

+ +

Наши новые методы компоновки дают нам возможность использовать эти логические значения для размещения элементов, однако, как только мы начнем объединять их с физическими свойствами, используемыми для полей и отступов, нам нужно помнить, что эти физические свойства не изменятся в соответствии с режимом записи.

+ +

Спецификация логических свойств CSS имеет целью изменить это и в будущем мы сможем использовать логические эквиваленты для свойств, такие как {{cssxref ("margin-left")}} и {{cssxref ("margin-right") }}, в нашем CSS. Firefox уже реализовал их, поэтому вы можете попробовать их прямо сейчас в Firefox. Я знаю в будущем, как только эти корабли повсюду, ваши знания «Блокировать и встроить» с помощью Grid означают, что вы точно знаете, как их использовать.

+ + diff --git a/files/ru/web/css/css_grid_layout/grid_template_areas/index.html b/files/ru/web/css/css_grid_layout/grid_template_areas/index.html new file mode 100644 index 0000000000..6d2d3b6892 --- /dev/null +++ b/files/ru/web/css/css_grid_layout/grid_template_areas/index.html @@ -0,0 +1,529 @@ +--- +title: Шаблоны грид-областей +slug: Web/CSS/CSS_Grid_Layout/Грид-области +translation_of: Web/CSS/CSS_Grid_Layout/Grid_Template_Areas +--- +

В предыдущем обзоре мы рассмотрели грид-линии и то, как с их помощью размещать элементы в гридах. Когда Вы работаете с CSS Grid Layout, у Вас всегда есть грид-линии, поэтому они - быстрый, прямой и надежный способ расположить элементы. Как бы то ни было, существует альтернативный метод, и этот метод можно использовать как в одиночку, так и в сочетании с расположением элементов по грид-линиям. В этом методе элементы располагаются с помощью именнованных, заранее определенных грид-областей. Давайте рассмотрим, как он работает, и Вы скоро поймете, почему его называют методом ascii-искусства в концепции макетов на гридах!

+ +

Имя для грид-области

+ +

Вы уже знакомы со свойством {{cssxref("grid-area")}}. Это то свойство, которое принимает в качестве значения номера четырех грид-линий, определяющих расположение грид-области.

+ +
.box1 {
+   grid-area: 1 / 1 / 4 / 2;
+}
+
+ +

Что мы делаем, когда задаем все четыре значения? Мы определяем область, ограниченную данными грид-линиями. 

+ +

The Grid Area defined by lines

+ +

Другой способ определить грид-область, - задать ей имя и определить местоположение как значения свойства {{cssxref("grid-template-areas")}}. Вы можете выбрать для грид-области любое имя. Например, если нам нужно создать макет согласно картинке ниже, мы можем назвать четыре основных области следующим образом:

+ + + +

An image showing a simple two column layout with header and footer

+ +

С помощью свойства {{cssxref("grid-area")}} мы можем назначить каждой из этих областей свое собственное имя. Именование областей еще не создает никакого макета, однако теперь у нас есть именнованные области, которые мы можем в нем использовать.

+ +
+
.header {
+    grid-area: hd;
+}
+.footer {
+    grid-area: ft;
+}
+.content {
+    grid-area: main;
+}
+.sidebar {
+    grid-area: sd;
+}
+
+ +

Определив имена, мы можем приступить к созданию макета. На этот раз вместо того, чтобы расположить элементы с помощью номеров линий, заданных для самих элементов, мы создаем весь макет в грид-контейнере.

+ +
.wrapper {
+    display: grid;
+    grid-template-columns: repeat(9, 1fr);
+    grid-auto-rows: minmax(100px, auto);
+    grid-template-areas:
+      "hd hd hd hd   hd   hd   hd   hd   hd"
+      "sd sd sd main main main main main main"
+      "ft ft ft ft   ft   ft   ft   ft   ft";
+}
+
+ + + +

 

+ +
<div class="wrapper">
+    <div class="header">Header</div>
+    <div class="sidebar">Sidebar</div>
+    <div class="content">Content</div>
+    <div class="footer">Footer</div>
+</div>
+ +

{{ EmbedLiveSample('Grid_Area_1', '300', '330') }}

+
+ +

Если мы используем этот метод, то нам не нужно задавать что-то отдельно для грид-элементов, все задается для грид-контейнера. Весь макет описывается значением свойства {{cssxref("grid-template-areas")}}.

+ +

Оставляем ячейку пустой

+ +

В данном примере мы полностью заполнили грид областями и не оставили пустого пространства. Однако, наш метод также позволяет оставлять грид-ячейки пустыми. Чтобы сделать это воспользуйтесь символом точки, '.'. Если нам нужно отображать футер только под основным содержимым страницы, значит, мы должны оставить три ячейки под сайдбаром пустыми.

+ +
.header {
+    grid-area: hd;
+}
+.footer {
+    grid-area: ft;
+}
+.content {
+    grid-area: main;
+}
+.sidebar {
+    grid-area: sd;
+}
+
+ + + +
.wrapper {
+    display: grid;
+    grid-template-columns: repeat(9, 1fr);
+    grid-auto-rows: minmax(100px, auto);
+    grid-template-areas:
+      "hd hd hd hd   hd   hd   hd   hd   hd"
+      "sd sd sd main main main main main main"
+      ".  .  .  ft   ft   ft   ft   ft   ft";
+}
+
+ +
<div class="wrapper">
+    <div class="header">Header</div>
+    <div class="sidebar">Sidebar</div>
+    <div class="content">Content</div>
+    <div class="footer">Footer</div>
+</div>
+ +

{{ EmbedLiveSample('Leaving_a_grid_cell_empty', '300', '330') }}

+ +

Чтобы сделать наш макет чище, мы можем использовать множество символов .. Если между точками нет пробелов, то они считаются одной ячейкой. В комплексных макетах подобная возможность помогает аккуратно выравнивать строки и колонки. То есть, Вы прямо в CSS можете видеть, как выглядит Ваш макет.

+ +

Охватываем несколько ячеек

+ +

В нашем примере каждая из областей охватывает несколько грид-ячеек, и получаем мы подобный эффект за счет того, что через пробел повторяем имя этой грид-области несколько раз. Вы можете добавить дополнительные пробелы, чтобы аккуратно выравнять значения в grid-template-areas. В нашем примере мы пробелами подравняли hd и ft , чтобы они коррелировали с  main.

+ +

Область, которую мы создаем подобными цепочками имен, должна быть прямоугольной. На данном этапе нельзя создать L-образную область. В спецификации говорится, что, возможно, в будущем подобная функциональность добавится. А сейчас мы можем охватывать строки так же легко, как и колонки. Например, давайте сделаем так, чтобы наш сайдбар простирался до конца футера. Для этого поменяем . на sd.

+ +
.header {
+    grid-area: hd;
+}
+.footer {
+    grid-area: ft;
+}
+.content {
+    grid-area: main;
+}
+.sidebar {
+    grid-area: sd;
+}
+
+ + + +
.wrapper {
+    display: grid;
+    grid-template-columns: repeat(9, 1fr);
+    grid-auto-rows: minmax(100px, auto);
+    grid-template-areas:
+      "hd hd hd hd   hd   hd   hd   hd   hd"
+      "sd sd sd main main main main main main"
+      "sd sd sd  ft  ft   ft   ft   ft   ft";
+}
+
+ + + +

{{ EmbedLiveSample('Spanning_multiple_cells', '300', '330') }}

+ +

Значение {{cssxref("grid-template-areas")}} должно отображать законченный грид, а иначе оно невалидно (и игнорируется!). Это значит, что у Вас должно быть одинаковое количество ячеек в каждой строке, а если какая-то ячейка должна быть пустой, то вместо имени в ней должна быть точка. Грид будет также невалидным, если области в нем не прямоугольные.

+ +

Переопределение грида с медиа-запросами

+ +

Поскольку наш макет теперь содержится в одной части CSS, вносить изменения для различных контрольных точек (breakpoints) становится крайне легко. Сделать это можно либо переопределив сам грид, либо положение элементов на гриде, либо и то, и другое одновеременно.

+ +

При этом определяйте имена для ваших грид-областей за пределами медиа-запросов. В таком случае, область основного содержимого (content) всегда будет называться main независимо от того, где она находится на сетке.

+ +

Мы можем теперь изменить наш макет для узкой ширины экрана на более простой, где все грид-области будут друг над другом в одном столбце.

+ + + +
.header {
+    grid-area: hd;
+}
+.footer {
+    grid-area: ft;
+}
+.content {
+    grid-area: main;
+}
+.sidebar {
+    grid-area: sd;
+}
+
+.wrapper {
+    display: grid;
+    grid-auto-rows: minmax(100px, auto);
+    grid-template-columns: 1fr;
+    grid-template-areas:
+      "hd"
+      "main"
+      "sd"
+      "ft";
+}
+
+ +

Внутри медиа-запросов, мы переопределяем этот макет на двухколонный, а при увеличении свободного пространства, на трехколонный. Обратите внимание, что для широкого макета я оставляю свою девятиколонную трековую сетку, а с помощью grid-template-areas я указываю куда стоит разместить грид-области. 

+ +
@media (min-width: 500px) {
+    .wrapper {
+        grid-template-columns: repeat(9, 1fr);
+        grid-template-areas:
+          "hd hd hd hd   hd   hd   hd   hd   hd"
+          "sd sd sd main main main main main main"
+          "sd sd sd  ft  ft   ft   ft   ft   ft";
+    }
+}
+@media (min-width: 700px) {
+    .wrapper {
+        grid-template-areas:
+          "hd hd hd   hd   hd   hd   hd   hd hd"
+          "sd sd main main main main main ft ft";
+    }
+}
+
+ + + +

{{ EmbedLiveSample('Redefining_the_grid_using_media_queries', '550', '330') }}

+ +

Использование grid-template-areas для элементов UI

+ +

Многие из примеров grid, которые вы найдете в Интернете, предполагают, что вы будете использовать grid для макета главной страницы, однако grid может быть столь же полезна для небольших элементов. Использование {{cssxref ("grid-template-areas")}} может быть особенно приятным, так как в коде легко видеть, как выглядит ваш элемент.

+ +

В качестве очень простого примера мы можем создать «медиа-объект». Это компонент с пространством для изображения или другого носителя с одной стороны, а контент - с другой. Изображение может отображаться справа или слева от окна.

+ +

Images showing an example media object design

+ +

Наша сетка представляет собой двухколоночную трековую сетку, со столбцом для изображения размером 1fr и текстом 3fr. Если вы хотите область с фиксированной шириной изображения, тогда вы можете установить столбец изображения как ширину пикселя и назначить текстовую область 1fr. Одна колонка трека 1fr затем займет оставшуюся часть пространства.

+ +

Мы предоставляем области изображения имя области сетки img и содержимое текстовой области, затем мы можем выложить их, используя свойство grid-template-areas.

+ +
+
* {box-sizing: border-box;}
+
+.media {
+    border: 2px solid #f76707;
+    border-radius: 5px;
+    background-color: #fff4e6;
+    max-width: 400px;
+}
+.media {
+    display: grid;
+    grid-template-columns: 1fr 3fr;
+    grid-template-areas: "img content";
+    margin-bottom: 1em;
+}
+
+.media .image {
+    grid-area: img;
+    background-color: #ffd8a8;
+}
+
+.media .text {
+    grid-area: content;
+    padding: 10px;
+
+}
+
+ +
<div class="media">
+    <div class="image"></div>
+    <div class="text">This is a media object example.
+      We can use grid-template-areas to switch around the image and text part of the media object.
+    </div>
+</div>
+ +

{{ EmbedLiveSample('Media_1', '300', '200') }}

+
+ +

Отображение изображения с другой стороны окна

+ +

Возможно, нам захочется отобразить нашу коробку с изображением наоборот. Для этого мы переопределим сетку, чтобы поместить последний трек 1fr и просто переверните значения {{cssxref ("grid-template-areas")}}.

+ +
+
* {box-sizing: border-box;}
+
+.media {
+    border: 2px solid #f76707;
+    border-radius: 5px;
+    background-color: #fff4e6;
+    max-width: 400px;
+}
+.media {
+    display: grid;
+    grid-template-columns: 1fr 3fr;
+    grid-template-areas: "img content";
+    margin-bottom: 1em;
+}
+
+.media.flipped {
+    grid-template-columns: 3fr 1fr;
+    grid-template-areas: "content img";
+}
+
+.media .image {
+    grid-area: img;
+    background-color: #ffd8a8;
+}
+
+.media .text {
+    grid-area: content;
+    padding: 10px;
+
+}
+
+ +
<div class="media flipped">
+    <div class="image"></div>
+    <div class="text">This is a media object example.
+      We can use grid-template-areas to switch around the image and text part of the media object.
+    </div>
+</div>
+ +

{{ EmbedLiveSample('Media_2', '300', '200') }}

+
+ +

Сокращения определения сетки

+ +

Рассмотрев различные способы размещения элементов на наших сетках и многие свойства, используемые для определения сетки, самое время взглянуть на пару сокращений, доступных для определения сетки и многое из всего этого в одной строке CSS.

+ +

Они могут быстро стать трудными для чтения для других разработчиков или даже для вашего будущего. Однако они являются частью спецификации и, вероятно, вы столкнетесь с ними в примерах или в использовании другими разработчиками, даже если вы решите не использовать их.

+ +

Прежде чем использовать какиу-либо сокращения (shorthand), стоит помнить, что shorthand не только позволяют устанавливать множество свойств за один раз, но также действуют, чтобы сбросить объекты до их начальных значений, которых вы не используете, или не можете установить в сокращении. Поэтому, если вы используете сокращения, помните, что оно может сбросить все, что вы применили в другом месте.

+ +

Два сокращения (shorthand) для контейнера сетки - это Explicit Grid Shorthand grid-template и Grid Definition Shorthand grid.

+ +

grid-template

+ +

Свойство {{cssxref ("grid-template")}} задает следующие свойства:

+ + + +

Свойство называется явным сокращением сетки, потому что оно устанавливает те вещи, которые вы контролируете, когда вы определяете явную сетку, а не те, которые влияют на любые неявные строки или столбцы, которые могут быть созданы.

+ +

Следующий код создает макет, используя {{cssxref ("grid-template")}}, который совпадает с макетом, созданным ранее в этом руководстве.

+ +
.wrapper {
+    display: grid;
+    grid-template:
+      "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
+      "sd sd sd main main main main main main" minmax(100px, auto)
+      "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
+             / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
+}
+
+ +

Первое значение - это значение нашей grid-template-areas, но мы также объявляем размер строки в конце каждой строки. Это то, что делает minmax (100px, auto).

+ +

Затем после grid-template-areas у нас есть косая черта, после чего явный список треков столбцов.

+ +

grid

+ +

Сокращение {{cssxref ("grid")}} идет еще дальше, а также задает свойства, используемые неявной сеткой. Таким образом, вы будете устанавливать:

+ + + +

Свойство также сбрасывает {{cssxref ("grid-gap")}} свойство на 0, однако вы не можете указывать пробелы в этой сокращенности.

+ +

Вы можете использовать этот синтаксис точно так же, как сокращение {{cssxref ("grid-template")}}, просто знайте, что при этом вы сбросите другие значения, установленные этим свойством.

+ +
.wrapper {
+    display: grid;
+    grid: "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
+    "sd sd sd main main main main main main" minmax(100px, auto)
+    "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
+    / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
+}
+
+ +

Мы снова рассмотрим другие функции, предлагаемые этом сокращением позже в этих руководствах, когда мы рассмотрим автоматическое размещение и свойство grid-auto-flow.

+ +

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

+ + diff --git a/files/ru/web/css/css_grid_layout/line-based_placement_with_css_grid/index.html b/files/ru/web/css/css_grid_layout/line-based_placement_with_css_grid/index.html new file mode 100644 index 0000000000..e470a72ce7 --- /dev/null +++ b/files/ru/web/css/css_grid_layout/line-based_placement_with_css_grid/index.html @@ -0,0 +1,652 @@ +--- +title: Расположение элементов по грид-линиям с помощью CSS Grid +slug: >- + Web/CSS/CSS_Grid_Layout/Расположение_элементов_по_грид-линиям_с_помощью_CSS_Grid +tags: + - CSS + - CSS Grid + - Грид + - Руководство + - Сетка +translation_of: Web/CSS/CSS_Grid_Layout/Line-based_Placement_with_CSS_Grid +--- +

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

+ +

Собственно, начать квест по гридам со знакомства с пронумерованными линиями - логично, потому что в ситуации, когда Вы работаете с гридами, пронумерованные линии у Вас есть всегда. Линии нумеруются и для колонок, и для строк, отсчет начинается с 1. Нужно заметить, что грид индексируется в соответствии с режимом написания (writing mode) документа. В языках с написанием слева направо, таких как русский, например, линия 1 - самая левая линия грида. Если написание справа налево, то линия 1 будет, соответственно, самой правой линией в гриде. По ходу изучения недр мы детально узнаем, как гриды взаимодействуют с режимами написания, поэтому не исчезайте, впереди много интересного.

+ +

Базовый пример

+ +

В качестве крайне простого примера давайте возьмем грид с тремя треками-колонками и тремя треками-строками. Такой грид дает нам по 4 линии для каждого направления.

+ +

Внутри нашего грид-контейнера у нас есть четыре дочерних элемента. Если мы не размещаем их явным образом, эти элементы будут расположены в гриде в соответствии с правилами авторазмещения, то есть, по одному элементу - в каждой из четырех первых ячеек. Если Вы воспользуетесь Firefox Grid Highlighter , то увидете, как грид инициирует колонки и строки.

+ +

Our Grid highlighted in DevTools

+ + + +
.wrapper {
+   display: grid;
+   grid-template-columns: repeat(3, 1fr);
+   grid-template-rows: repeat(3, 100px);
+}
+
+ +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +

{{ EmbedLiveSample('A_basic_example', '300', '330') }}

+ +

Позиционирование элементов по номерам линий

+ +

Мы можем воспользоваться размещением по линиям (line-based placement), чтобы расположить элементы на гриде. Например, нам нужно, чтобы первый элемент начинался от левого края и занимал один трек-колонку. Пусть он также начинается с первой строчной линии,  то есть, от верхнего края грида, и занимает пространство до четвертой строчной линии.

+ +
+
.box1 {
+   grid-column-start: 1;
+   grid-column-end: 2;
+   grid-row-start: 1;
+   grid-row-end: 4;
+}
+
+ +

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

+ +

Задавая адреса для каждого элемента по отдельности, мы можем разместить все наши четыре элемента по колонкам и строкам. Заметьте, что при желании можно оставить ячейки пустыми. Одна из самых приятных вещей при работе с Grid Layout - возможность создавать негативное пространство (пустые области в макете) без кувырков через голову и прочих хаков.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box2 {
+   grid-column-start: 3;
+   grid-column-end: 4;
+   grid-row-start: 1;
+   grid-row-end: 3;
+}
+.box3 {
+   grid-column-start: 2;
+   grid-column-end: 3;
+   grid-row-start: 1;
+   grid-row-end: 2;
+}
+.box4 {
+   grid-column-start: 2;
+   grid-column-end: 4;
+   grid-row-start: 3;
+   grid-row-end: 4;
+}
+
+ +

{{ EmbedLiveSample('Line_Number', '300', '330') }}

+
+ +
+

Сокращения grid-column и grid-row

+ +

Мы написали много кода, чтобы разместить каждый элемент. Неудивительно, что существует краткая форма записи свойств. {{cssxref("grid-column-start")}} и {{cssxref("grid-column-end")}} могут быть объединены в одном {{cssxref("grid-column")}}, а {{cssxref("grid-row-start")}} и {{cssxref("grid-row-end")}} - в {{cssxref("grid-row")}}.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column: 1 / 2;
+   grid-row: 1 / 4;
+}
+.box2 {
+   grid-column: 3 / 4;
+   grid-row: 1 / 3;
+}
+.box3 {
+   grid-column: 2 / 3;
+   grid-row: 1 /  2;
+}
+.box4 {
+   grid-column: 2 / 4;
+   grid-row: 3 / 4;
+}
+
+ +

{{ EmbedLiveSample('Grid_Shorthands', '300', '330') }}

+
+ +

Расположение элемента по умолчанию

+ +

В примерах выше мы задавали конечную линию для строки и колонки, чтобы продемонстрировать работу свойств, однако, если элемент занимает только один трек, Вы можете опустить значение grid-column-end или grid-row-end. Грид по умолчанию размещает элемент таким образом, чтобы он занимал всего один трек. Это значит, что длинная запись свойств в нашем первоначальном примере может выглядеть вот так:

+ +
+ + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column-start: 1;
+   grid-row-start: 1;
+   grid-row-end: 4;
+}
+.box2 {
+   grid-column-start: 3;
+   grid-row-start: 1;
+   grid-row-end: 3;
+}
+.box3 {
+   grid-column-start: 2;
+   grid-row-start: 1;
+}
+.box4 {
+   grid-column-start: 2;
+   grid-column-end: 4;
+   grid-row-start: 3;
+}
+
+ +

{{ EmbedLiveSample('End_Lines', '300', '330') }}

+
+ +

Поэтому, если мы хотим, чтобы элементы занимали только один трек, наша сокращенная запись будет выглядеть вот так, без слэша и без второго значения:

+ +
+ + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column: 1 ;
+   grid-row: 1 / 4;
+}
+.box2 {
+   grid-column: 3 ;
+   grid-row: 1 / 3;
+}
+.box3 {
+   grid-column: 2 ;
+   grid-row: 1 ;
+}
+.box4 {
+   grid-column: 2 / 4;
+   grid-row: 3 ;
+}
+
+ +

{{ EmbedLiveSample('New_Shorthand', '300', '330') }}

+
+ +

Свойство grid-area

+ +

Мы можем пойти еще дальше и определить целую область с помощью одного единственного свойства – {{cssxref("grid-area")}}. Порядок свойств для грид-области следующий:

+ + + + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-area: 1 / 1 / 4 / 2;
+}
+.box2 {
+   grid-area: 1 / 3 / 3 / 4;
+}
+.box3 {
+   grid-area: 1 / 2 / 2 / 3;
+}
+.box4 {
+   grid-area: 3 / 2 / 4 / 4;
+}
+
+ +

{{ EmbedLiveSample('The_grid-area_property', '300', '330') }}

+ +

Порядок значений для grid-area может показаться немного странным, он противоположен тому порядку, в котором мы, например, записываем значения для сокращенных свойств margin и padding. Но сделано это потому, что грид работает с направлениями относительно потока, определенными в спецификации CSS Writing Modes. В дальнейшем мы рассмотрим, как гриды взаимодействуют с режимами написания (writing modes), но пока давайте примем за данность, что мы имеем дело с концепцией четырех направлений относительно потока:

+ + + +

Мы работаем с русским, языком с написанием слева направо. Начало нашего блока (block-start) - верхняя строчная линия грид-контейнера, конец блока (block-end) - последняя строчная линия контейнера. Начало строки (inline-start) - самая левая колоночная линия, поскольку начало строки - это всегда точка, с которой начинается написание текста в заданном режиме написания. Конец строки (inline-end) - последняя колоночная линия грида.

+ +

Когда мы задаем нашу грид-область с помощью свойства grid-area , мы сначала определяем обе начальные линии block-start и inline-start, а затем обе конечные линии  block-end и inline-end. Поскольку мы давно работаем с физическими свойствами top, right, bottom и left, поначалу это кажется непривычным, но вполне осмысленно, если осознать, что относительно режима написания вебсайты - многонаправленные структуры.

+ +

Считая с конца

+ +

Мы также можем отсчитывать грид-линии с конца, то есть с последней (для русского языка - самой правой) колоночной и последней (самой нижней) строчной линий. Индекс этих линий будет -1, а линий непосредственно перед ними -2, и так далее. Нужно помнить, что под последней линией понимается последняя линия явного грида (explicit grid), то есть грида, определенного с помощью grid-template-columns иgrid-template-rows. Любые линии строк и колонок, добавленные неявным гридом (implicit grid) не считаются.

+ +

В примере ниже мы "перевернули" определение нашего грида, при размещении элементов задавая линии с конца, то есть, от правого и нижнего краев.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column-start: -1;
+   grid-column-end: -2;
+   grid-row-start: -1;
+   grid-row-end: -4;
+}
+.box2 {
+   grid-column-start: -3;
+   grid-column-end: -4;
+   grid-row-start: -1;
+   grid-row-end: -3;
+}
+.box3 {
+   grid-column-start: -2;
+   grid-column-end: -3;
+   grid-row-start: -1;
+   grid-row-end: -2;
+}
+.box4 {
+   grid-column-start: -2;
+   grid-column-end: -4;
+   grid-row-start: -3;
+   grid-row-end: -4;
+}
+
+ +

{{ EmbedLiveSample('Counting_backwards', '300', '330') }}

+ +

Как растянуть элемент на длину всего грида?

+ +

Возможность адресовать и первую, и последнюю линии грида становится крайне полезной, если нам нужно растянуть элемент на всю длину грида. Сделать это можно вот так:

+ +
.item {
+  grid-column: 1 / -1;
+}
+
+ +

Зазоры (Gutters) или аллеи (Alleys)

+ +

Спецификация CSS Grid включает возможность добавлять промежутки (зазоры) между треками-колонками и треками-строками с помощью свойств {{cssxref("grid-column-gap")}} и {{cssxref("grid-row-gap")}}. Эти свойства задают промежутки, которые во многом действуют точно так же, как свойство {{cssxref("column-gap")}} в многоколоночных макетах.

+ +

Зазоры появляются только между треками и не добавляют пространство сверху, снизу, справа или слева грид-контейнеру. Мы можем добавить зазоры в предыдущий пример, дописав эти свойства грид-контейнеру.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+   grid-column: 1 ;
+   grid-row: 1 / 4;
+}
+.box2 {
+   grid-column: 3 ;
+   grid-row: 1 / 3;
+}
+.box3 {
+   grid-column: 2 ;
+   grid-row: 1 ;
+}
+.box4 {
+   grid-column: 2 / 4;
+   grid-row: 3 ;
+}
+.wrapper {
+     display: grid;
+     grid-template-columns: repeat(3, 1fr);
+     grid-template-rows: repeat(3, 100px);
+     grid-column-gap: 20px;
+     grid-row-gap: 1em;
+}
+
+ +

{{ EmbedLiveSample('Gutters_or_Alleys', '300', '350') }}

+ +

Сокращенная запись для грид-зазоров

+ +

Оба свойства также можно записать с помощью свойства-сокращения {{cssxref("grid-gap")}}. Если задать только одно значение, то оно определит размер зазоров и между колонками, и между строками. Если мы задаем два значения, то первое используется для grid-row-gap , а второе - для grid-column-gap.

+ +
.wrapper {
+     display: grid;
+     grid-template-columns: repeat(3, 1fr);
+     grid-template-rows: repeat(3, 100px);
+     grid-gap: 1em 20px;
+}
+
+ +

В терминах расположения элементов по грид-линиям (line-based positioning) зазоры ведут себя так, как если бы самой линии была добавлена толщина. Все, что должно было начинаться от линии, начинается от нее на расстоянии зазора, и Вы не можете адресовать зазор напрямую или поместить в него что-нибудь. Если Вам нужны зазоры, которые ведут себя, как обыкновенные треки, что же - определите трек, а не зазор.

+ +

Использование ключевого слова span 

+ +

В дополнение к возможности обращаться к начальной и конечной линии по их номерам Вы можете задать номер начальной линии, а после - количество треков, которые должен занять элемент.

+ + + +
<div class="wrapper">
+   <div class="box1">One</div>
+   <div class="box2">Two</div>
+   <div class="box3">Three</div>
+   <div class="box4">Four</div>
+</div>
+
+ +
.box1 {
+  grid-column: 1;
+  grid-row: 1 / span 3;
+}
+.box2 {
+   grid-column: 3;
+   grid-row: 1 / span 2;
+}
+.box3 {
+   grid-column: 2;
+   grid-row: 1;
+}
+.box4 {
+   grid-column: 2 / span 2;
+   grid-row: 3;
+}
+
+ +

{{ EmbedLiveSample('Using_the_span_keyword', '300', '330') }}

+ +

Ключево слово  span также можно использовать в качестве значения grid-row-start/grid-row-end иgrid-column-start/grid-column-end. Два примера ниже создают одну и ту же грид-область. В первом примере мы задаем начальную строчную линию, а после говорим свойству, отвечающему за конечную линию: эй, мы хотим занять под этот элемент три линии. В итоге, грид-область начинается с первой линии и занимает пространство до 4-ой.

+ +
.box1 {
+    grid-column-start: 1;
+    grid-row-start: 1;
+    grid-row-end: span 3;
+}
+
+ +

Во втором примере поступим наоборот: зададим конечную строчную линию, а в значении свойства, отвечающего за начальную линию, напишем span 3. Это значит, что элемент должен занять три трека до заданной конечной линии. Грид-область начинается с линии 4 и занимает три трека до линии 1.

+ +
.box1 {
+    grid-column-start: 1;
+    grid-row-start: span 3;
+    grid-row-end: 4;
+}
+
+ +

Чтобы лучше освоиться с размещением элементов по грид-линиям, попробуйте собрать несколько распространенных макетов, располагая элементы на гридах с различным количеством колонок. Помните, что если вы не размещаете все Ваши элементы, оставшиеся располагаются в соответствии с правилами авторазмещения. В результате может получиться как раз тот макет, который Вам нужен, но не факт, и если что-то пошло не так, проверьте, определили ли Вы позицию для проблемного элемента.

+ +

Также помните, что элементы на гриде могут перекрывать друг друга, если Вы намеренно разместили их так, чтобы они друг друга перекрывали. Подобное поведение позволяет получить интересные эффекты, но, если Вы некорректно задали начальные и конечные линии, результат может неприятно Вас удивить. Firefox Grid Highlighter будет крайне полезен в процессе обучения, особенно, когда Вы строите сложные гриды.

+ + diff --git "a/files/ru/web/css/css_grid_layout/\320\263\321\200\320\270\320\264-\320\276\320\261\320\273\320\260\321\201\321\202\320\270/index.html" "b/files/ru/web/css/css_grid_layout/\320\263\321\200\320\270\320\264-\320\276\320\261\320\273\320\260\321\201\321\202\320\270/index.html" deleted file mode 100644 index 6d2d3b6892..0000000000 --- "a/files/ru/web/css/css_grid_layout/\320\263\321\200\320\270\320\264-\320\276\320\261\320\273\320\260\321\201\321\202\320\270/index.html" +++ /dev/null @@ -1,529 +0,0 @@ ---- -title: Шаблоны грид-областей -slug: Web/CSS/CSS_Grid_Layout/Грид-области -translation_of: Web/CSS/CSS_Grid_Layout/Grid_Template_Areas ---- -

В предыдущем обзоре мы рассмотрели грид-линии и то, как с их помощью размещать элементы в гридах. Когда Вы работаете с CSS Grid Layout, у Вас всегда есть грид-линии, поэтому они - быстрый, прямой и надежный способ расположить элементы. Как бы то ни было, существует альтернативный метод, и этот метод можно использовать как в одиночку, так и в сочетании с расположением элементов по грид-линиям. В этом методе элементы располагаются с помощью именнованных, заранее определенных грид-областей. Давайте рассмотрим, как он работает, и Вы скоро поймете, почему его называют методом ascii-искусства в концепции макетов на гридах!

- -

Имя для грид-области

- -

Вы уже знакомы со свойством {{cssxref("grid-area")}}. Это то свойство, которое принимает в качестве значения номера четырех грид-линий, определяющих расположение грид-области.

- -
.box1 {
-   grid-area: 1 / 1 / 4 / 2;
-}
-
- -

Что мы делаем, когда задаем все четыре значения? Мы определяем область, ограниченную данными грид-линиями. 

- -

The Grid Area defined by lines

- -

Другой способ определить грид-область, - задать ей имя и определить местоположение как значения свойства {{cssxref("grid-template-areas")}}. Вы можете выбрать для грид-области любое имя. Например, если нам нужно создать макет согласно картинке ниже, мы можем назвать четыре основных области следующим образом:

- - - -

An image showing a simple two column layout with header and footer

- -

С помощью свойства {{cssxref("grid-area")}} мы можем назначить каждой из этих областей свое собственное имя. Именование областей еще не создает никакого макета, однако теперь у нас есть именнованные области, которые мы можем в нем использовать.

- -
-
.header {
-    grid-area: hd;
-}
-.footer {
-    grid-area: ft;
-}
-.content {
-    grid-area: main;
-}
-.sidebar {
-    grid-area: sd;
-}
-
- -

Определив имена, мы можем приступить к созданию макета. На этот раз вместо того, чтобы расположить элементы с помощью номеров линий, заданных для самих элементов, мы создаем весь макет в грид-контейнере.

- -
.wrapper {
-    display: grid;
-    grid-template-columns: repeat(9, 1fr);
-    grid-auto-rows: minmax(100px, auto);
-    grid-template-areas:
-      "hd hd hd hd   hd   hd   hd   hd   hd"
-      "sd sd sd main main main main main main"
-      "ft ft ft ft   ft   ft   ft   ft   ft";
-}
-
- - - -

 

- -
<div class="wrapper">
-    <div class="header">Header</div>
-    <div class="sidebar">Sidebar</div>
-    <div class="content">Content</div>
-    <div class="footer">Footer</div>
-</div>
- -

{{ EmbedLiveSample('Grid_Area_1', '300', '330') }}

-
- -

Если мы используем этот метод, то нам не нужно задавать что-то отдельно для грид-элементов, все задается для грид-контейнера. Весь макет описывается значением свойства {{cssxref("grid-template-areas")}}.

- -

Оставляем ячейку пустой

- -

В данном примере мы полностью заполнили грид областями и не оставили пустого пространства. Однако, наш метод также позволяет оставлять грид-ячейки пустыми. Чтобы сделать это воспользуйтесь символом точки, '.'. Если нам нужно отображать футер только под основным содержимым страницы, значит, мы должны оставить три ячейки под сайдбаром пустыми.

- -
.header {
-    grid-area: hd;
-}
-.footer {
-    grid-area: ft;
-}
-.content {
-    grid-area: main;
-}
-.sidebar {
-    grid-area: sd;
-}
-
- - - -
.wrapper {
-    display: grid;
-    grid-template-columns: repeat(9, 1fr);
-    grid-auto-rows: minmax(100px, auto);
-    grid-template-areas:
-      "hd hd hd hd   hd   hd   hd   hd   hd"
-      "sd sd sd main main main main main main"
-      ".  .  .  ft   ft   ft   ft   ft   ft";
-}
-
- -
<div class="wrapper">
-    <div class="header">Header</div>
-    <div class="sidebar">Sidebar</div>
-    <div class="content">Content</div>
-    <div class="footer">Footer</div>
-</div>
- -

{{ EmbedLiveSample('Leaving_a_grid_cell_empty', '300', '330') }}

- -

Чтобы сделать наш макет чище, мы можем использовать множество символов .. Если между точками нет пробелов, то они считаются одной ячейкой. В комплексных макетах подобная возможность помогает аккуратно выравнивать строки и колонки. То есть, Вы прямо в CSS можете видеть, как выглядит Ваш макет.

- -

Охватываем несколько ячеек

- -

В нашем примере каждая из областей охватывает несколько грид-ячеек, и получаем мы подобный эффект за счет того, что через пробел повторяем имя этой грид-области несколько раз. Вы можете добавить дополнительные пробелы, чтобы аккуратно выравнять значения в grid-template-areas. В нашем примере мы пробелами подравняли hd и ft , чтобы они коррелировали с  main.

- -

Область, которую мы создаем подобными цепочками имен, должна быть прямоугольной. На данном этапе нельзя создать L-образную область. В спецификации говорится, что, возможно, в будущем подобная функциональность добавится. А сейчас мы можем охватывать строки так же легко, как и колонки. Например, давайте сделаем так, чтобы наш сайдбар простирался до конца футера. Для этого поменяем . на sd.

- -
.header {
-    grid-area: hd;
-}
-.footer {
-    grid-area: ft;
-}
-.content {
-    grid-area: main;
-}
-.sidebar {
-    grid-area: sd;
-}
-
- - - -
.wrapper {
-    display: grid;
-    grid-template-columns: repeat(9, 1fr);
-    grid-auto-rows: minmax(100px, auto);
-    grid-template-areas:
-      "hd hd hd hd   hd   hd   hd   hd   hd"
-      "sd sd sd main main main main main main"
-      "sd sd sd  ft  ft   ft   ft   ft   ft";
-}
-
- - - -

{{ EmbedLiveSample('Spanning_multiple_cells', '300', '330') }}

- -

Значение {{cssxref("grid-template-areas")}} должно отображать законченный грид, а иначе оно невалидно (и игнорируется!). Это значит, что у Вас должно быть одинаковое количество ячеек в каждой строке, а если какая-то ячейка должна быть пустой, то вместо имени в ней должна быть точка. Грид будет также невалидным, если области в нем не прямоугольные.

- -

Переопределение грида с медиа-запросами

- -

Поскольку наш макет теперь содержится в одной части CSS, вносить изменения для различных контрольных точек (breakpoints) становится крайне легко. Сделать это можно либо переопределив сам грид, либо положение элементов на гриде, либо и то, и другое одновеременно.

- -

При этом определяйте имена для ваших грид-областей за пределами медиа-запросов. В таком случае, область основного содержимого (content) всегда будет называться main независимо от того, где она находится на сетке.

- -

Мы можем теперь изменить наш макет для узкой ширины экрана на более простой, где все грид-области будут друг над другом в одном столбце.

- - - -
.header {
-    grid-area: hd;
-}
-.footer {
-    grid-area: ft;
-}
-.content {
-    grid-area: main;
-}
-.sidebar {
-    grid-area: sd;
-}
-
-.wrapper {
-    display: grid;
-    grid-auto-rows: minmax(100px, auto);
-    grid-template-columns: 1fr;
-    grid-template-areas:
-      "hd"
-      "main"
-      "sd"
-      "ft";
-}
-
- -

Внутри медиа-запросов, мы переопределяем этот макет на двухколонный, а при увеличении свободного пространства, на трехколонный. Обратите внимание, что для широкого макета я оставляю свою девятиколонную трековую сетку, а с помощью grid-template-areas я указываю куда стоит разместить грид-области. 

- -
@media (min-width: 500px) {
-    .wrapper {
-        grid-template-columns: repeat(9, 1fr);
-        grid-template-areas:
-          "hd hd hd hd   hd   hd   hd   hd   hd"
-          "sd sd sd main main main main main main"
-          "sd sd sd  ft  ft   ft   ft   ft   ft";
-    }
-}
-@media (min-width: 700px) {
-    .wrapper {
-        grid-template-areas:
-          "hd hd hd   hd   hd   hd   hd   hd hd"
-          "sd sd main main main main main ft ft";
-    }
-}
-
- - - -

{{ EmbedLiveSample('Redefining_the_grid_using_media_queries', '550', '330') }}

- -

Использование grid-template-areas для элементов UI

- -

Многие из примеров grid, которые вы найдете в Интернете, предполагают, что вы будете использовать grid для макета главной страницы, однако grid может быть столь же полезна для небольших элементов. Использование {{cssxref ("grid-template-areas")}} может быть особенно приятным, так как в коде легко видеть, как выглядит ваш элемент.

- -

В качестве очень простого примера мы можем создать «медиа-объект». Это компонент с пространством для изображения или другого носителя с одной стороны, а контент - с другой. Изображение может отображаться справа или слева от окна.

- -

Images showing an example media object design

- -

Наша сетка представляет собой двухколоночную трековую сетку, со столбцом для изображения размером 1fr и текстом 3fr. Если вы хотите область с фиксированной шириной изображения, тогда вы можете установить столбец изображения как ширину пикселя и назначить текстовую область 1fr. Одна колонка трека 1fr затем займет оставшуюся часть пространства.

- -

Мы предоставляем области изображения имя области сетки img и содержимое текстовой области, затем мы можем выложить их, используя свойство grid-template-areas.

- -
-
* {box-sizing: border-box;}
-
-.media {
-    border: 2px solid #f76707;
-    border-radius: 5px;
-    background-color: #fff4e6;
-    max-width: 400px;
-}
-.media {
-    display: grid;
-    grid-template-columns: 1fr 3fr;
-    grid-template-areas: "img content";
-    margin-bottom: 1em;
-}
-
-.media .image {
-    grid-area: img;
-    background-color: #ffd8a8;
-}
-
-.media .text {
-    grid-area: content;
-    padding: 10px;
-
-}
-
- -
<div class="media">
-    <div class="image"></div>
-    <div class="text">This is a media object example.
-      We can use grid-template-areas to switch around the image and text part of the media object.
-    </div>
-</div>
- -

{{ EmbedLiveSample('Media_1', '300', '200') }}

-
- -

Отображение изображения с другой стороны окна

- -

Возможно, нам захочется отобразить нашу коробку с изображением наоборот. Для этого мы переопределим сетку, чтобы поместить последний трек 1fr и просто переверните значения {{cssxref ("grid-template-areas")}}.

- -
-
* {box-sizing: border-box;}
-
-.media {
-    border: 2px solid #f76707;
-    border-radius: 5px;
-    background-color: #fff4e6;
-    max-width: 400px;
-}
-.media {
-    display: grid;
-    grid-template-columns: 1fr 3fr;
-    grid-template-areas: "img content";
-    margin-bottom: 1em;
-}
-
-.media.flipped {
-    grid-template-columns: 3fr 1fr;
-    grid-template-areas: "content img";
-}
-
-.media .image {
-    grid-area: img;
-    background-color: #ffd8a8;
-}
-
-.media .text {
-    grid-area: content;
-    padding: 10px;
-
-}
-
- -
<div class="media flipped">
-    <div class="image"></div>
-    <div class="text">This is a media object example.
-      We can use grid-template-areas to switch around the image and text part of the media object.
-    </div>
-</div>
- -

{{ EmbedLiveSample('Media_2', '300', '200') }}

-
- -

Сокращения определения сетки

- -

Рассмотрев различные способы размещения элементов на наших сетках и многие свойства, используемые для определения сетки, самое время взглянуть на пару сокращений, доступных для определения сетки и многое из всего этого в одной строке CSS.

- -

Они могут быстро стать трудными для чтения для других разработчиков или даже для вашего будущего. Однако они являются частью спецификации и, вероятно, вы столкнетесь с ними в примерах или в использовании другими разработчиками, даже если вы решите не использовать их.

- -

Прежде чем использовать какиу-либо сокращения (shorthand), стоит помнить, что shorthand не только позволяют устанавливать множество свойств за один раз, но также действуют, чтобы сбросить объекты до их начальных значений, которых вы не используете, или не можете установить в сокращении. Поэтому, если вы используете сокращения, помните, что оно может сбросить все, что вы применили в другом месте.

- -

Два сокращения (shorthand) для контейнера сетки - это Explicit Grid Shorthand grid-template и Grid Definition Shorthand grid.

- -

grid-template

- -

Свойство {{cssxref ("grid-template")}} задает следующие свойства:

- - - -

Свойство называется явным сокращением сетки, потому что оно устанавливает те вещи, которые вы контролируете, когда вы определяете явную сетку, а не те, которые влияют на любые неявные строки или столбцы, которые могут быть созданы.

- -

Следующий код создает макет, используя {{cssxref ("grid-template")}}, который совпадает с макетом, созданным ранее в этом руководстве.

- -
.wrapper {
-    display: grid;
-    grid-template:
-      "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
-      "sd sd sd main main main main main main" minmax(100px, auto)
-      "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
-             / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
-}
-
- -

Первое значение - это значение нашей grid-template-areas, но мы также объявляем размер строки в конце каждой строки. Это то, что делает minmax (100px, auto).

- -

Затем после grid-template-areas у нас есть косая черта, после чего явный список треков столбцов.

- -

grid

- -

Сокращение {{cssxref ("grid")}} идет еще дальше, а также задает свойства, используемые неявной сеткой. Таким образом, вы будете устанавливать:

- - - -

Свойство также сбрасывает {{cssxref ("grid-gap")}} свойство на 0, однако вы не можете указывать пробелы в этой сокращенности.

- -

Вы можете использовать этот синтаксис точно так же, как сокращение {{cssxref ("grid-template")}}, просто знайте, что при этом вы сбросите другие значения, установленные этим свойством.

- -
.wrapper {
-    display: grid;
-    grid: "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
-    "sd sd sd main main main main main main" minmax(100px, auto)
-    "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
-    / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
-}
-
- -

Мы снова рассмотрим другие функции, предлагаемые этом сокращением позже в этих руководствах, когда мы рассмотрим автоматическое размещение и свойство grid-auto-flow.

- -

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

- - diff --git "a/files/ru/web/css/css_grid_layout/\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276_\320\263\321\200\320\270\320\264-\320\273\320\270\320\275\320\270\321\217\320\274_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_css_grid/index.html" "b/files/ru/web/css/css_grid_layout/\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276_\320\263\321\200\320\270\320\264-\320\273\320\270\320\275\320\270\321\217\320\274_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_css_grid/index.html" deleted file mode 100644 index e470a72ce7..0000000000 --- "a/files/ru/web/css/css_grid_layout/\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\320\265_\321\215\320\273\320\265\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276_\320\263\321\200\320\270\320\264-\320\273\320\270\320\275\320\270\321\217\320\274_\321\201_\320\277\320\276\320\274\320\276\321\211\321\214\321\216_css_grid/index.html" +++ /dev/null @@ -1,652 +0,0 @@ ---- -title: Расположение элементов по грид-линиям с помощью CSS Grid -slug: >- - Web/CSS/CSS_Grid_Layout/Расположение_элементов_по_грид-линиям_с_помощью_CSS_Grid -tags: - - CSS - - CSS Grid - - Грид - - Руководство - - Сетка -translation_of: Web/CSS/CSS_Grid_Layout/Line-based_Placement_with_CSS_Grid ---- -

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

- -

Собственно, начать квест по гридам со знакомства с пронумерованными линиями - логично, потому что в ситуации, когда Вы работаете с гридами, пронумерованные линии у Вас есть всегда. Линии нумеруются и для колонок, и для строк, отсчет начинается с 1. Нужно заметить, что грид индексируется в соответствии с режимом написания (writing mode) документа. В языках с написанием слева направо, таких как русский, например, линия 1 - самая левая линия грида. Если написание справа налево, то линия 1 будет, соответственно, самой правой линией в гриде. По ходу изучения недр мы детально узнаем, как гриды взаимодействуют с режимами написания, поэтому не исчезайте, впереди много интересного.

- -

Базовый пример

- -

В качестве крайне простого примера давайте возьмем грид с тремя треками-колонками и тремя треками-строками. Такой грид дает нам по 4 линии для каждого направления.

- -

Внутри нашего грид-контейнера у нас есть четыре дочерних элемента. Если мы не размещаем их явным образом, эти элементы будут расположены в гриде в соответствии с правилами авторазмещения, то есть, по одному элементу - в каждой из четырех первых ячеек. Если Вы воспользуетесь Firefox Grid Highlighter , то увидете, как грид инициирует колонки и строки.

- -

Our Grid highlighted in DevTools

- - - -
.wrapper {
-   display: grid;
-   grid-template-columns: repeat(3, 1fr);
-   grid-template-rows: repeat(3, 100px);
-}
-
- -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -

{{ EmbedLiveSample('A_basic_example', '300', '330') }}

- -

Позиционирование элементов по номерам линий

- -

Мы можем воспользоваться размещением по линиям (line-based placement), чтобы расположить элементы на гриде. Например, нам нужно, чтобы первый элемент начинался от левого края и занимал один трек-колонку. Пусть он также начинается с первой строчной линии,  то есть, от верхнего края грида, и занимает пространство до четвертой строчной линии.

- -
-
.box1 {
-   grid-column-start: 1;
-   grid-column-end: 2;
-   grid-row-start: 1;
-   grid-row-end: 4;
-}
-
- -

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

- -

Задавая адреса для каждого элемента по отдельности, мы можем разместить все наши четыре элемента по колонкам и строкам. Заметьте, что при желании можно оставить ячейки пустыми. Одна из самых приятных вещей при работе с Grid Layout - возможность создавать негативное пространство (пустые области в макете) без кувырков через голову и прочих хаков.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box2 {
-   grid-column-start: 3;
-   grid-column-end: 4;
-   grid-row-start: 1;
-   grid-row-end: 3;
-}
-.box3 {
-   grid-column-start: 2;
-   grid-column-end: 3;
-   grid-row-start: 1;
-   grid-row-end: 2;
-}
-.box4 {
-   grid-column-start: 2;
-   grid-column-end: 4;
-   grid-row-start: 3;
-   grid-row-end: 4;
-}
-
- -

{{ EmbedLiveSample('Line_Number', '300', '330') }}

-
- -
-

Сокращения grid-column и grid-row

- -

Мы написали много кода, чтобы разместить каждый элемент. Неудивительно, что существует краткая форма записи свойств. {{cssxref("grid-column-start")}} и {{cssxref("grid-column-end")}} могут быть объединены в одном {{cssxref("grid-column")}}, а {{cssxref("grid-row-start")}} и {{cssxref("grid-row-end")}} - в {{cssxref("grid-row")}}.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column: 1 / 2;
-   grid-row: 1 / 4;
-}
-.box2 {
-   grid-column: 3 / 4;
-   grid-row: 1 / 3;
-}
-.box3 {
-   grid-column: 2 / 3;
-   grid-row: 1 /  2;
-}
-.box4 {
-   grid-column: 2 / 4;
-   grid-row: 3 / 4;
-}
-
- -

{{ EmbedLiveSample('Grid_Shorthands', '300', '330') }}

-
- -

Расположение элемента по умолчанию

- -

В примерах выше мы задавали конечную линию для строки и колонки, чтобы продемонстрировать работу свойств, однако, если элемент занимает только один трек, Вы можете опустить значение grid-column-end или grid-row-end. Грид по умолчанию размещает элемент таким образом, чтобы он занимал всего один трек. Это значит, что длинная запись свойств в нашем первоначальном примере может выглядеть вот так:

- -
- - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column-start: 1;
-   grid-row-start: 1;
-   grid-row-end: 4;
-}
-.box2 {
-   grid-column-start: 3;
-   grid-row-start: 1;
-   grid-row-end: 3;
-}
-.box3 {
-   grid-column-start: 2;
-   grid-row-start: 1;
-}
-.box4 {
-   grid-column-start: 2;
-   grid-column-end: 4;
-   grid-row-start: 3;
-}
-
- -

{{ EmbedLiveSample('End_Lines', '300', '330') }}

-
- -

Поэтому, если мы хотим, чтобы элементы занимали только один трек, наша сокращенная запись будет выглядеть вот так, без слэша и без второго значения:

- -
- - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column: 1 ;
-   grid-row: 1 / 4;
-}
-.box2 {
-   grid-column: 3 ;
-   grid-row: 1 / 3;
-}
-.box3 {
-   grid-column: 2 ;
-   grid-row: 1 ;
-}
-.box4 {
-   grid-column: 2 / 4;
-   grid-row: 3 ;
-}
-
- -

{{ EmbedLiveSample('New_Shorthand', '300', '330') }}

-
- -

Свойство grid-area

- -

Мы можем пойти еще дальше и определить целую область с помощью одного единственного свойства – {{cssxref("grid-area")}}. Порядок свойств для грид-области следующий:

- - - - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-area: 1 / 1 / 4 / 2;
-}
-.box2 {
-   grid-area: 1 / 3 / 3 / 4;
-}
-.box3 {
-   grid-area: 1 / 2 / 2 / 3;
-}
-.box4 {
-   grid-area: 3 / 2 / 4 / 4;
-}
-
- -

{{ EmbedLiveSample('The_grid-area_property', '300', '330') }}

- -

Порядок значений для grid-area может показаться немного странным, он противоположен тому порядку, в котором мы, например, записываем значения для сокращенных свойств margin и padding. Но сделано это потому, что грид работает с направлениями относительно потока, определенными в спецификации CSS Writing Modes. В дальнейшем мы рассмотрим, как гриды взаимодействуют с режимами написания (writing modes), но пока давайте примем за данность, что мы имеем дело с концепцией четырех направлений относительно потока:

- - - -

Мы работаем с русским, языком с написанием слева направо. Начало нашего блока (block-start) - верхняя строчная линия грид-контейнера, конец блока (block-end) - последняя строчная линия контейнера. Начало строки (inline-start) - самая левая колоночная линия, поскольку начало строки - это всегда точка, с которой начинается написание текста в заданном режиме написания. Конец строки (inline-end) - последняя колоночная линия грида.

- -

Когда мы задаем нашу грид-область с помощью свойства grid-area , мы сначала определяем обе начальные линии block-start и inline-start, а затем обе конечные линии  block-end и inline-end. Поскольку мы давно работаем с физическими свойствами top, right, bottom и left, поначалу это кажется непривычным, но вполне осмысленно, если осознать, что относительно режима написания вебсайты - многонаправленные структуры.

- -

Считая с конца

- -

Мы также можем отсчитывать грид-линии с конца, то есть с последней (для русского языка - самой правой) колоночной и последней (самой нижней) строчной линий. Индекс этих линий будет -1, а линий непосредственно перед ними -2, и так далее. Нужно помнить, что под последней линией понимается последняя линия явного грида (explicit grid), то есть грида, определенного с помощью grid-template-columns иgrid-template-rows. Любые линии строк и колонок, добавленные неявным гридом (implicit grid) не считаются.

- -

В примере ниже мы "перевернули" определение нашего грида, при размещении элементов задавая линии с конца, то есть, от правого и нижнего краев.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column-start: -1;
-   grid-column-end: -2;
-   grid-row-start: -1;
-   grid-row-end: -4;
-}
-.box2 {
-   grid-column-start: -3;
-   grid-column-end: -4;
-   grid-row-start: -1;
-   grid-row-end: -3;
-}
-.box3 {
-   grid-column-start: -2;
-   grid-column-end: -3;
-   grid-row-start: -1;
-   grid-row-end: -2;
-}
-.box4 {
-   grid-column-start: -2;
-   grid-column-end: -4;
-   grid-row-start: -3;
-   grid-row-end: -4;
-}
-
- -

{{ EmbedLiveSample('Counting_backwards', '300', '330') }}

- -

Как растянуть элемент на длину всего грида?

- -

Возможность адресовать и первую, и последнюю линии грида становится крайне полезной, если нам нужно растянуть элемент на всю длину грида. Сделать это можно вот так:

- -
.item {
-  grid-column: 1 / -1;
-}
-
- -

Зазоры (Gutters) или аллеи (Alleys)

- -

Спецификация CSS Grid включает возможность добавлять промежутки (зазоры) между треками-колонками и треками-строками с помощью свойств {{cssxref("grid-column-gap")}} и {{cssxref("grid-row-gap")}}. Эти свойства задают промежутки, которые во многом действуют точно так же, как свойство {{cssxref("column-gap")}} в многоколоночных макетах.

- -

Зазоры появляются только между треками и не добавляют пространство сверху, снизу, справа или слева грид-контейнеру. Мы можем добавить зазоры в предыдущий пример, дописав эти свойства грид-контейнеру.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-   grid-column: 1 ;
-   grid-row: 1 / 4;
-}
-.box2 {
-   grid-column: 3 ;
-   grid-row: 1 / 3;
-}
-.box3 {
-   grid-column: 2 ;
-   grid-row: 1 ;
-}
-.box4 {
-   grid-column: 2 / 4;
-   grid-row: 3 ;
-}
-.wrapper {
-     display: grid;
-     grid-template-columns: repeat(3, 1fr);
-     grid-template-rows: repeat(3, 100px);
-     grid-column-gap: 20px;
-     grid-row-gap: 1em;
-}
-
- -

{{ EmbedLiveSample('Gutters_or_Alleys', '300', '350') }}

- -

Сокращенная запись для грид-зазоров

- -

Оба свойства также можно записать с помощью свойства-сокращения {{cssxref("grid-gap")}}. Если задать только одно значение, то оно определит размер зазоров и между колонками, и между строками. Если мы задаем два значения, то первое используется для grid-row-gap , а второе - для grid-column-gap.

- -
.wrapper {
-     display: grid;
-     grid-template-columns: repeat(3, 1fr);
-     grid-template-rows: repeat(3, 100px);
-     grid-gap: 1em 20px;
-}
-
- -

В терминах расположения элементов по грид-линиям (line-based positioning) зазоры ведут себя так, как если бы самой линии была добавлена толщина. Все, что должно было начинаться от линии, начинается от нее на расстоянии зазора, и Вы не можете адресовать зазор напрямую или поместить в него что-нибудь. Если Вам нужны зазоры, которые ведут себя, как обыкновенные треки, что же - определите трек, а не зазор.

- -

Использование ключевого слова span 

- -

В дополнение к возможности обращаться к начальной и конечной линии по их номерам Вы можете задать номер начальной линии, а после - количество треков, которые должен занять элемент.

- - - -
<div class="wrapper">
-   <div class="box1">One</div>
-   <div class="box2">Two</div>
-   <div class="box3">Three</div>
-   <div class="box4">Four</div>
-</div>
-
- -
.box1 {
-  grid-column: 1;
-  grid-row: 1 / span 3;
-}
-.box2 {
-   grid-column: 3;
-   grid-row: 1 / span 2;
-}
-.box3 {
-   grid-column: 2;
-   grid-row: 1;
-}
-.box4 {
-   grid-column: 2 / span 2;
-   grid-row: 3;
-}
-
- -

{{ EmbedLiveSample('Using_the_span_keyword', '300', '330') }}

- -

Ключево слово  span также можно использовать в качестве значения grid-row-start/grid-row-end иgrid-column-start/grid-column-end. Два примера ниже создают одну и ту же грид-область. В первом примере мы задаем начальную строчную линию, а после говорим свойству, отвечающему за конечную линию: эй, мы хотим занять под этот элемент три линии. В итоге, грид-область начинается с первой линии и занимает пространство до 4-ой.

- -
.box1 {
-    grid-column-start: 1;
-    grid-row-start: 1;
-    grid-row-end: span 3;
-}
-
- -

Во втором примере поступим наоборот: зададим конечную строчную линию, а в значении свойства, отвечающего за начальную линию, напишем span 3. Это значит, что элемент должен занять три трека до заданной конечной линии. Грид-область начинается с линии 4 и занимает три трека до линии 1.

- -
.box1 {
-    grid-column-start: 1;
-    grid-row-start: span 3;
-    grid-row-end: 4;
-}
-
- -

Чтобы лучше освоиться с размещением элементов по грид-линиям, попробуйте собрать несколько распространенных макетов, располагая элементы на гридах с различным количеством колонок. Помните, что если вы не размещаете все Ваши элементы, оставшиеся располагаются в соответствии с правилами авторазмещения. В результате может получиться как раз тот макет, который Вам нужен, но не факт, и если что-то пошло не так, проверьте, определили ли Вы позицию для проблемного элемента.

- -

Также помните, что элементы на гриде могут перекрывать друг друга, если Вы намеренно разместили их так, чтобы они друг друга перекрывали. Подобное поведение позволяет получить интересные эффекты, но, если Вы некорректно задали начальные и конечные линии, результат может неприятно Вас удивить. Firefox Grid Highlighter будет крайне полезен в процессе обучения, особенно, когда Вы строите сложные гриды.

- - diff --git a/files/ru/web/css/css_positioning/understanding_z_index/adding_z-index/index.html b/files/ru/web/css/css_positioning/understanding_z_index/adding_z-index/index.html new file mode 100644 index 0000000000..2fff1726d3 --- /dev/null +++ b/files/ru/web/css/css_positioning/understanding_z_index/adding_z-index/index.html @@ -0,0 +1,157 @@ +--- +title: Using z-index +slug: Web/Guide/CSS/Understanding_z_index/Adding_z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index +--- +
{{cssref}}
+ +

The first part of this article, Stacking without the z-index property, explains how stacking is arranged by default. If you want to create a custom stacking order, you can use the {{cssxref("z-index")}} property on a positioned element.

+ +

Свойство z-index может иметь значение в целых числах (положительные, ноль, или отрицательные), что представляет собой позицию єлемента вдоль оси z. Если вы не знакомы с осью z, представьте себе страницу как стопку слоев, имеющих собственое порядковое число. Слои представлены в числовом порядке, with larger numbers above smaller numbers.

+ + + +
+

Notes:

+ + +
+ +

In the following example, the layers' stacking order is rearranged using z-index. The z-index of element #5 has no effect since it is not a positioned element.

+ +

{{EmbedLiveSample("Source_code_for_the_example", 600, 400)}}

+ +

Source code for the example

+ +

HTML

+ +
<div id="abs1">
+  <b>DIV #1</b>
+  <br />position: absolute;
+  <br />z-index: 5;
+</div>
+
+<div id="rel1">
+  <b>DIV #2</b>
+  <br />position: relative;
+  <br />z-index: 3;
+</div>
+
+<div id="rel2">
+  <b>DIV #3</b>
+  <br />position: relative;
+  <br />z-index: 2;
+</div>
+
+<div id="abs2">
+  <b>DIV #4</b>
+  <br />position: absolute;
+  <br />z-index: 1;
+</div>
+
+<div id="sta1">
+  <b>DIV #5</b>
+  <br />no positioning
+  <br />z-index: 8;
+</div>
+
+ +

CSS

+ +
div {
+  padding: 10px;
+  opacity: 0.7;
+  text-align: center;
+}
+
+b {
+  font-family: sans-serif;
+}
+
+#abs1 {
+  z-index: 5;
+  position: absolute;
+  width: 150px;
+  height: 350px;
+  top: 10px;
+  left: 10px;
+  border: 1px dashed #900;
+  background-color: #fdd;
+}
+
+#rel1 {
+  z-index: 3;
+  height: 100px;
+  position: relative;
+  top: 30px;
+  border: 1px dashed #696;
+  background-color: #cfc;
+  margin: 0px 50px 0px 50px;
+}
+
+#rel2 {
+  z-index: 2;
+  height: 100px;
+  position: relative;
+  top: 15px;
+  left: 20px;
+  border: 1px dashed #696;
+  background-color: #cfc;
+  margin: 0px 50px 0px 50px;
+}
+
+#abs2 {
+  z-index: 1;
+  position: absolute;
+  width: 150px;
+  height: 350px;
+  top: 10px;
+  right: 10px;
+  border: 1px dashed #900;
+  background-color: #fdd;
+}
+
+#sta1 {
+  z-index: 8;
+  height: 70px;
+  border: 1px dashed #996;
+  background-color: #ffc;
+  margin: 0px 50px 0px 50px;
+}
+
+ +

See also

+ + + +
+

Original Document Information

+ + +
diff --git a/files/ru/web/css/css_positioning/understanding_z_index/index.html b/files/ru/web/css/css_positioning/understanding_z_index/index.html new file mode 100644 index 0000000000..0074ff2577 --- /dev/null +++ b/files/ru/web/css/css_positioning/understanding_z_index/index.html @@ -0,0 +1,51 @@ +--- +title: Понимание CSS z-index +slug: Web/Guide/CSS/Understanding_z_index +tags: + - Advanced + - CSS + - Guide + - NeedsTranslation + - TopicStub + - Understanding_CSS_z-index + - Web + - z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index +--- +

Обычно HTML страницы можно считать двухмерными, потому что текст, картинки и другие элементы расположены на странице без перекрытия. Существует единый нормальный поток отрисовки (rendering flow) и элементы избегают пространства, занятого другими.{{cssxref("z-index")}} атрибут позволяет регулировать порядок наложения объектов друг на друга в процессе отрисовки контента (rendering content).

+ +
+

В CSS 2.1, позиция каждого блока была в трех измерениях. В дополнении к их горизонтальной и вертикальной позиции блоки лежали вдоль оси "z" и распологались один поверх другого. Позиция относительно оси "z" особенно актуальна, когда блоки визуально накладываются друг на друга. 

+
+ +

(from CSS 2.1 Section 9.9.1 - Layered presentation)

+ +

Это означает, что правила стиля CSS позволяют вам позиционировать блоки на слоях в дополнение к обычному слою рендеринга (слой 0). Положение Z каждого слоя выражается как целое число, представляющее порядок наложения для рендеринга. Большие числа означают ближе к наблюдателю. Положение Z можно контролировать с помощью свойства CSS z-index.

+ +

Использование z-index кажется чрезвычайно простым: одно свойство, которому присваивается одно целое число, с простым для понимания поведением. Однако, когда z-index применяется к сложным иерархиям элементов HTML, его поведение может быть трудно понять или предсказать. Это обьясняется целым комплексом правил "укладки" элементов. Фактически в спецификации  CSS-2.1 Appendix E (CSS-2.1 Приложение Е) зарезервирован целый раздел, подробно обьясняющий эти правила.

+ +

Данная статья попытается объяснить эти правила, с некоторым упрощением и несколькими примерами.

+ +
    +
  1. Позиционирование без z-индекса : правила по умолчанию
  2. +
  3. Позиционирование и float : как себя поводят float элементы c позиционированием
  4. +
  5. Использование z-index : Using z-index to change default stacking
  6. +
  7. The stacking context : Notes on the stacking context
  8. +
  9. Stacking context example 1 : 2-level HTML hierarchy, z-index on the last level
  10. +
  11. Stacking context example 2 : 2-level HTML hierarchy, z-index on all levels
  12. +
  13. Stacking context example 3 : 3-level HTML hierarchy, z-index on the second level
  14. +
+ +
+

Информация о документе

+ + + +

Примечание автора: спасибо Владимиру Паланту и Роду Уайтли за обзор.

+ +
+
diff --git a/files/ru/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html b/files/ru/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html new file mode 100644 index 0000000000..7f4eb09133 --- /dev/null +++ b/files/ru/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html @@ -0,0 +1,140 @@ +--- +title: Stacking without z-index +slug: Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index +tags: + - CSS + - z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index +--- +

« CSS « Понимание CSS z-index

+ +

Наложения без Z-индекса

+ +

Когда элементы не имеют z-индека, они накладываються в таком порядке(снизу вверх):

+ +

1. Фон и границы корневого элемента.

+ +

2. Дочерние блоки в нормальном потоке в порядке размещения(в HTML порядке).

+ +

3. Дочерние позиционированные элементы, в порядке размещения (в HTML порядке).

+ +

В следующем примере, абсолютно и относительно спозиционированным блокам определена величина  и позиция таким образом, чтобы продемонстировать правила наложения.

+ +
+

Заметки:

+ + +
+ +

understanding_zindex_01.png

+ +

Пример

+ +

HTML

+ +
<div id="absdiv1">
+    <br /><span class="bold">DIV #1</span>
+    <br />position: absolute; </div>
+<div id="reldiv1">
+    <br /><span class="bold">DIV #2</span>
+    <br />position: relative; </div>
+<div id="reldiv2">
+    <br /><span class="bold">DIV #3</span>
+    <br />position: relative; </div>
+<div id="absdiv2">
+    <br /><span class="bold">DIV #4</span>
+    <br />position: absolute; </div>
+<div id="normdiv">
+    <br /><span class="bold">DIV #5</span>
+    <br />no positioning </div>
+
+ +

CSS

+ +
 .bold {
+     font-weight: bold;
+     font: 12px Arial;
+ }
+ #normdiv {
+     height: 70px;
+     border: 1px dashed #999966;
+     background-color: #ffffcc;
+     margin: 0px 50px 0px 50px;
+     text-align: center;
+ }
+ #reldiv1 {
+     opacity: 0.7;
+     height: 100px;
+     position: relative;
+     top: 30px;
+     border: 1px dashed #669966;
+     background-color: #ccffcc;
+     margin: 0px 50px 0px 50px;
+     text-align: center;
+ }
+ #reldiv2 {
+     opacity: 0.7;
+     height: 100px;
+     position: relative;
+     top: 15px;
+     left: 20px;
+     border: 1px dashed #669966;
+     background-color: #ccffcc;
+     margin: 0px 50px 0px 50px;
+     text-align: center;
+ }
+ #absdiv1 {
+     opacity: 0.7;
+     position: absolute;
+     width: 150px;
+     height: 350px;
+     top: 10px;
+     left: 10px;
+     border: 1px dashed #990000;
+     background-color: #ffdddd;
+     text-align: center;
+ }
+ #absdiv2 {
+     opacity: 0.7;
+     position: absolute;
+     width: 150px;
+     height: 350px;
+     top: 10px;
+     right: 10px;
+     border: 1px dashed #990000;
+     background-color: #ffdddd;
+     text-align: center;
+ }
+
+ +

Результат

+ +

(If the image does not display in CodePen, click the Tidy button in the CSS section)

+ +

{{ EmbedLiveSample('Example', '', '', '', 'Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index') }}

+ +

Так же посмотрите

+ + + +
+

Original Document Information

+ + +
diff --git a/files/ru/web/css/css_selectors/index.html b/files/ru/web/css/css_selectors/index.html new file mode 100644 index 0000000000..8745681718 --- /dev/null +++ b/files/ru/web/css/css_selectors/index.html @@ -0,0 +1,122 @@ +--- +title: CSS-селекторы +slug: Web/CSS/CSS_Селекторы +tags: + - CSS + - Обзор + - Селекторы +translation_of: Web/CSS/CSS_Selectors +--- +
{{CSSRef}}
+ +

Селектор определяет, к какому элементу применять то или иное CSS-правило.

+ +

Обратите внимание - не существует селекторов, которые бы позволили выбрать родителя (содержащий контейнер) или соседа родителя или потомков соседа родителя.

+ +

Базовые селекторы

+ +
+
Универсальный селектор
+
Выбирает все элементы. По желанию, он может быть ограничен определенным пространством имен или относиться ко всему пространству имён.
+ Синтаксис: * ns|* *|*
+ Пример: * будет соответствовать всем элементам на странице.
+
+ +
+
Селекторы по типу элемента
+
Этот базовый селектор выбирает тип элементов, к которым будет применяться правило.
+ Синтаксис: элемент
+ Пример: селектор input выберет все элементы {{HTMLElement('input')}}.
+
Селекторы по классу
+
Этот базовый селектор выбирает элементы, основываясь на значении их атрибута class.
+ Синтаксис: .имяКласса
+ Пример: селектор .index выберет все элементы с соответствующим классом (который был определен в атрибуте class="index").
+
Селекторы по идентификатору
+
Этот базовый селектор выбирает элементы, основываясь на значении их id атрибута. Не забывайте, что идентификатор должен быть уникальным, т. е. использоваться только для одного элемента в HTML-документе. 
+ Синтаксис: #имяИдентификатора
+ Пример: селектор #toc выберет элемент с идентификатором toc (который был определен в атрибуте id="toc").
+
Селекторы по атрибуту
+
Этот селектор выбирает все элементы, имеющие данный атрибут или атрибут с определённым значением.
+ Синтаксис: [attr] [attr=value] [attr~=value] [attr|=value] [attr^=value] [attr$=value] [attr*=value]
+ Пример: селектор [autoplay] выберет все элементы, у которых есть  атрибут autoplay (независимо от его значения).
+ Ещё пример: a[href$=".jpg"] выберет все ссылки, у которых адрес заканчивается на ".jpg".
+ Ещё пример: a[href^="https"] выберет все ссылки, у которых адрес начинается на "https".
+
+ +

Комбинаторы

+ +
+
Комбинатор запятая
+
Комбинатор , это способ группировки, он выбирает все совпадающие узлы.
+ Синтаксис: A, B
+ Пример: div, span выберет оба элемента - и {{HTMLElement("div")}} и {{HTMLElement("span")}}.
+
Комбинатор потомков
+
Комбинатор ' ' (пробел) выбирает элементы, которые находятся внутри указанного элемента (вне зависимости от уровня вложенности).
+ Синтаксис: A B
+ Пример: селектор div span выберет все элементы {{HTMLElement('span')}}, которые находятся внутри элемента {{HTMLElement('div')}}.
+
Дочерние селекторы
+
Комбинатор '>' в отличие от пробела выбирает только те элементы, которые являются дочерними непосредственно по отношению к указанному элементу.
+ Синтаксис: A > B
+ Пример: селектор ul > li выберет только дочерние элементы {{HTMLElement('li')}}, которые находятся внутри, на первом уровне вложенности по отношению к элементу {{HTMLElement('ul')}}.
+
Комбинатор всех соседних элементов
+
Комбинатор '~' выбирает элементы, которые находятся на этом же уровне вложенности, после указанного элемента, с тем же родителем.
+ Синтаксис: A ~ B
+ Пример: p ~ span выберет все элементы {{HTMLElement('span')}}, которые находятся после элемента {{HTMLElement('p')}} внутри одного родителя.
+
Комбинатор следующего соседнего элемента
+
Комбинатор '+' выбирает элемент, который находится непосредственно после указанного элемента, если у них общий родитель.
+ Синтаксис: A + B
+ Пример: селектор ul + li выберет любой {{HTMLElement('li')}} элемент, который  находится непосредственно после элемента {{HTMLElement('ul')}}.
+
+ +

Псевдо

+ +
+
Псевдоклассы
+
Знак : позволяет выбрать элементы, основываясь на информации, которой нет в дереве элементов.
+ Пример: a:visited соответствует всем элементам {{HTMLElement("a")}} которые имеют статус "посещённые".
+ Ещё пример: div:hover соответствует элементу, над которым проходит указатель мыши.
+ Ещё пример: input:focus соответствует полю ввода, которое получило фокус.
+
Псевдоэлементы
+
Знак :: позволяет выбрать вещи, которых нет в HTML.
+ Пример: p::first-line соответствует первой линии абзаца {{HTMLElement("p")}}.
+
+ +

Версии CSS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName('CSS4 Selectors')}}{{Spec2('CSS4 Selectors')}}Добавление комбинатора колонок || , селекторов структуры сеточной разметки (CSS grid selector), логических комбинаторов, местоположения, временных, состояния ресурсов, лингвистических и UI псевдоклассов, модификаторов для ASCII регистрозависимых и регистронезависимых атрибутов со значениями и без них.
{{SpecName('CSS3 Selectors')}}{{Spec2('CSS3 Selectors')}}Добавлен комбинатор ~ и древовидные структурные псевдоклассы.
+ Сделаны псевдоэлементы, использующие префик :: двойное двоеточие. Селекторы дополнительных атрибутов.
{{SpecName('CSS2.1', 'selector.html')}}{{Spec2('CSS2.1')}}Добавлен комбинатор потомков > и комбинатор следующего соседа + .
+ Добавлен универсальный (*)  комбинатор и селектор атрибутов.
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Первоначальное определение.
+ +

См. также

+ +

CSS специфичность

diff --git a/files/ru/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html b/files/ru/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html new file mode 100644 index 0000000000..f737d2cb6d --- /dev/null +++ b/files/ru/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html @@ -0,0 +1,62 @@ +--- +title: 'Использование псевдокласса :target в селекторах' +slug: 'Web/CSS/CSS_Селекторы/Using_the_:target_pseudo-class_in_selectors' +translation_of: 'Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors' +--- +
{{CSSRef}}
+ +

Иногда пользователям трудно заметить, что URL указывает на определённую часть документа.  Узнайте, как можно использовать простое CSS правило, чтобы привлечь внимание пользователей к цели указания URL и улучшить их впечатления.

+ +

Выбор целевых элементов

+ +

Псевдокласс {{cssxref(":target")}} используется для стилизации целевого элемента URL, содержащего идентификатор фрагмента. Например, URL http://developer.mozilla.org/en/docs/Using_the_:target_selector#example содержит идентификатор фрагмента #example. В HTML, идентификаторы определяются значениями атрибутов  id или name, т.к. эти аттрибуты разделяют одно пространство имён. Таким образом,  в вышеприведённом примере URL указывает на первый элемент "example" в документе.

+ +

Пердположим, вы хотите стилизовать любой элемент h2, который является целью URL, но не хотите, чтобы другие элементы получили стиль цели. Сделать это довольно просто:

+ +
h2:target { font-weight: bold; }
+ +

Также возможно создать стили, специфичные для определённого фрагмента документа. Это достигается использованием такого же идентификационного значения, как в URI. Таким образом, чтобы добавить рамку к фрагменту #example , напишем:

+ +
#example:target { border: 1px solid black; }
+ +

Отметка всех элементов, как целевых

+ +

Если вы намерены создать общий стиль, который будет применяться ко всем целевым элементам, то вам пригодится следующий универсальный селектор:

+ +
:target { color: red; }
+
+ +

Пример

+ +

В данном примере имеются пять ссылок, которые ссылаются на элементы одного и того же документа. Выбор ссылки "First" , например, приведёт к тому, что  <h1 id="one"> станет целевым элементом.  Заметьте, что при прокутке документа целевые элементы располагаются вверху окна браузера, если это возможно.

+ +
+
<h4 id="one">...</h4> <p id="two">...</p>
+<div id="three">...</div> <a id="four">...</a> <em id="five">...</em>
+
+<a href="#one">First</a>
+<a href="#two">Second</a>
+<a href="#three">Third</a>
+<a href="#four">Fourth</a>
+<a href="#five">Fifth</a>
+
+ +

Вывод

+ +

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

+ + + + + +
+

Original Document Information

+ + +
diff --git a/files/ru/web/css/css_user_interface/index.html b/files/ru/web/css/css_user_interface/index.html deleted file mode 100644 index 2a4028644d..0000000000 --- a/files/ru/web/css/css_user_interface/index.html +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: CSS Basic User Interface -slug: Web/CSS/CSS_User_Interface -tags: - - CSS - - CSS Basic User Interface - - NeedsTranslation - - Overview - - Reference - - TopicStub -translation_of: Web/CSS/CSS_Basic_User_Interface -translation_of_original: Web/CSS/CSS_User_Interface ---- -
{{CSSRef}}
- -

CSS User Interface is a CSS module that lets you define the rendering and functionality of features related to the user interface.

- -

Reference

- -

Preferences

- -
- -
- -

Guides

- -
-
Using URL values for the cursor property
-
Explains how a URL can be used with the {{cssxref("cursor")}} property to produce custom cursors.
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Basic UI')}}{{Spec2('CSS3 Basic UI')}} 
{{SpecName('CSS2.1', 'ui.html')}}{{Spec2('CSS2.1')}}Initial definition
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support1.01.5 (1.8)8.07.01.2 (125)
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support1.0{{CompatGeckoMobile(1.8)}}8.06.03.1
-
diff --git "a/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" "b/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" deleted file mode 100644 index 8745681718..0000000000 --- "a/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/index.html" +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: CSS-селекторы -slug: Web/CSS/CSS_Селекторы -tags: - - CSS - - Обзор - - Селекторы -translation_of: Web/CSS/CSS_Selectors ---- -
{{CSSRef}}
- -

Селектор определяет, к какому элементу применять то или иное CSS-правило.

- -

Обратите внимание - не существует селекторов, которые бы позволили выбрать родителя (содержащий контейнер) или соседа родителя или потомков соседа родителя.

- -

Базовые селекторы

- -
-
Универсальный селектор
-
Выбирает все элементы. По желанию, он может быть ограничен определенным пространством имен или относиться ко всему пространству имён.
- Синтаксис: * ns|* *|*
- Пример: * будет соответствовать всем элементам на странице.
-
- -
-
Селекторы по типу элемента
-
Этот базовый селектор выбирает тип элементов, к которым будет применяться правило.
- Синтаксис: элемент
- Пример: селектор input выберет все элементы {{HTMLElement('input')}}.
-
Селекторы по классу
-
Этот базовый селектор выбирает элементы, основываясь на значении их атрибута class.
- Синтаксис: .имяКласса
- Пример: селектор .index выберет все элементы с соответствующим классом (который был определен в атрибуте class="index").
-
Селекторы по идентификатору
-
Этот базовый селектор выбирает элементы, основываясь на значении их id атрибута. Не забывайте, что идентификатор должен быть уникальным, т. е. использоваться только для одного элемента в HTML-документе. 
- Синтаксис: #имяИдентификатора
- Пример: селектор #toc выберет элемент с идентификатором toc (который был определен в атрибуте id="toc").
-
Селекторы по атрибуту
-
Этот селектор выбирает все элементы, имеющие данный атрибут или атрибут с определённым значением.
- Синтаксис: [attr] [attr=value] [attr~=value] [attr|=value] [attr^=value] [attr$=value] [attr*=value]
- Пример: селектор [autoplay] выберет все элементы, у которых есть  атрибут autoplay (независимо от его значения).
- Ещё пример: a[href$=".jpg"] выберет все ссылки, у которых адрес заканчивается на ".jpg".
- Ещё пример: a[href^="https"] выберет все ссылки, у которых адрес начинается на "https".
-
- -

Комбинаторы

- -
-
Комбинатор запятая
-
Комбинатор , это способ группировки, он выбирает все совпадающие узлы.
- Синтаксис: A, B
- Пример: div, span выберет оба элемента - и {{HTMLElement("div")}} и {{HTMLElement("span")}}.
-
Комбинатор потомков
-
Комбинатор ' ' (пробел) выбирает элементы, которые находятся внутри указанного элемента (вне зависимости от уровня вложенности).
- Синтаксис: A B
- Пример: селектор div span выберет все элементы {{HTMLElement('span')}}, которые находятся внутри элемента {{HTMLElement('div')}}.
-
Дочерние селекторы
-
Комбинатор '>' в отличие от пробела выбирает только те элементы, которые являются дочерними непосредственно по отношению к указанному элементу.
- Синтаксис: A > B
- Пример: селектор ul > li выберет только дочерние элементы {{HTMLElement('li')}}, которые находятся внутри, на первом уровне вложенности по отношению к элементу {{HTMLElement('ul')}}.
-
Комбинатор всех соседних элементов
-
Комбинатор '~' выбирает элементы, которые находятся на этом же уровне вложенности, после указанного элемента, с тем же родителем.
- Синтаксис: A ~ B
- Пример: p ~ span выберет все элементы {{HTMLElement('span')}}, которые находятся после элемента {{HTMLElement('p')}} внутри одного родителя.
-
Комбинатор следующего соседнего элемента
-
Комбинатор '+' выбирает элемент, который находится непосредственно после указанного элемента, если у них общий родитель.
- Синтаксис: A + B
- Пример: селектор ul + li выберет любой {{HTMLElement('li')}} элемент, который  находится непосредственно после элемента {{HTMLElement('ul')}}.
-
- -

Псевдо

- -
-
Псевдоклассы
-
Знак : позволяет выбрать элементы, основываясь на информации, которой нет в дереве элементов.
- Пример: a:visited соответствует всем элементам {{HTMLElement("a")}} которые имеют статус "посещённые".
- Ещё пример: div:hover соответствует элементу, над которым проходит указатель мыши.
- Ещё пример: input:focus соответствует полю ввода, которое получило фокус.
-
Псевдоэлементы
-
Знак :: позволяет выбрать вещи, которых нет в HTML.
- Пример: p::first-line соответствует первой линии абзаца {{HTMLElement("p")}}.
-
- -

Версии CSS

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарии
{{SpecName('CSS4 Selectors')}}{{Spec2('CSS4 Selectors')}}Добавление комбинатора колонок || , селекторов структуры сеточной разметки (CSS grid selector), логических комбинаторов, местоположения, временных, состояния ресурсов, лингвистических и UI псевдоклассов, модификаторов для ASCII регистрозависимых и регистронезависимых атрибутов со значениями и без них.
{{SpecName('CSS3 Selectors')}}{{Spec2('CSS3 Selectors')}}Добавлен комбинатор ~ и древовидные структурные псевдоклассы.
- Сделаны псевдоэлементы, использующие префик :: двойное двоеточие. Селекторы дополнительных атрибутов.
{{SpecName('CSS2.1', 'selector.html')}}{{Spec2('CSS2.1')}}Добавлен комбинатор потомков > и комбинатор следующего соседа + .
- Добавлен универсальный (*)  комбинатор и селектор атрибутов.
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Первоначальное определение.
- -

См. также

- -

CSS специфичность

diff --git "a/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/using_the__colon_target_pseudo-class_in_selectors/index.html" "b/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/using_the__colon_target_pseudo-class_in_selectors/index.html" deleted file mode 100644 index f737d2cb6d..0000000000 --- "a/files/ru/web/css/css_\321\201\320\265\320\273\320\265\320\272\321\202\320\276\321\200\321\213/using_the__colon_target_pseudo-class_in_selectors/index.html" +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: 'Использование псевдокласса :target в селекторах' -slug: 'Web/CSS/CSS_Селекторы/Using_the_:target_pseudo-class_in_selectors' -translation_of: 'Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors' ---- -
{{CSSRef}}
- -

Иногда пользователям трудно заметить, что URL указывает на определённую часть документа.  Узнайте, как можно использовать простое CSS правило, чтобы привлечь внимание пользователей к цели указания URL и улучшить их впечатления.

- -

Выбор целевых элементов

- -

Псевдокласс {{cssxref(":target")}} используется для стилизации целевого элемента URL, содержащего идентификатор фрагмента. Например, URL http://developer.mozilla.org/en/docs/Using_the_:target_selector#example содержит идентификатор фрагмента #example. В HTML, идентификаторы определяются значениями атрибутов  id или name, т.к. эти аттрибуты разделяют одно пространство имён. Таким образом,  в вышеприведённом примере URL указывает на первый элемент "example" в документе.

- -

Пердположим, вы хотите стилизовать любой элемент h2, который является целью URL, но не хотите, чтобы другие элементы получили стиль цели. Сделать это довольно просто:

- -
h2:target { font-weight: bold; }
- -

Также возможно создать стили, специфичные для определённого фрагмента документа. Это достигается использованием такого же идентификационного значения, как в URI. Таким образом, чтобы добавить рамку к фрагменту #example , напишем:

- -
#example:target { border: 1px solid black; }
- -

Отметка всех элементов, как целевых

- -

Если вы намерены создать общий стиль, который будет применяться ко всем целевым элементам, то вам пригодится следующий универсальный селектор:

- -
:target { color: red; }
-
- -

Пример

- -

В данном примере имеются пять ссылок, которые ссылаются на элементы одного и того же документа. Выбор ссылки "First" , например, приведёт к тому, что  <h1 id="one"> станет целевым элементом.  Заметьте, что при прокутке документа целевые элементы располагаются вверху окна браузера, если это возможно.

- -
-
<h4 id="one">...</h4> <p id="two">...</p>
-<div id="three">...</div> <a id="four">...</a> <em id="five">...</em>
-
-<a href="#one">First</a>
-<a href="#two">Second</a>
-<a href="#three">Third</a>
-<a href="#four">Fourth</a>
-<a href="#five">Fifth</a>
-
- -

Вывод

- -

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

- - - - - -
-

Original Document Information

- - -
diff --git a/files/ru/web/css/filter-function/url/index.html b/files/ru/web/css/filter-function/url/index.html deleted file mode 100644 index 755d1adfe4..0000000000 --- a/files/ru/web/css/filter-function/url/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: url() -slug: Web/CSS/filter-function/url -tags: - - CSS - - Начинающий - - Ссылка - - Функция -translation_of: Web/CSS/url() -translation_of_original: Web/CSS/filter-function/url ---- -
{{cssref}}
- -

url() - это CSS функция, использующая SVG filter для измения внешнего вида у выводимого изображения.

- -

Синтаксис

- -
url(расположение)
- -

Параметры

- -
-
расположение
-
В {{cssxref("<URL-адрес>")}} из {{glossary("XML")}} указывается файл, который задает фильтр SVG, а также может включать в себя привязки к конкретному фильтрующему элементу.
-
- -

Пример

- -
url(resources.svg#c1)
- -

Изучите также

- - diff --git a/files/ru/web/css/grid-gap/index.html b/files/ru/web/css/grid-gap/index.html deleted file mode 100644 index 90daa7c0ea..0000000000 --- a/files/ru/web/css/grid-gap/index.html +++ /dev/null @@ -1,194 +0,0 @@ ---- -title: grid-gap -slug: Web/CSS/grid-gap -translation_of: Web/CSS/gap -translation_of_original: Web/CSS/grid-gap ---- -

{{Deprecated_Header}}

- -
-

Примечание. Свойство CSS с разделительной сеткой было переименовано в свойство prefix-less {{cssxref('gap')}}.

-
- -

Свойство CSS grid-gap является сокращенным свойством для {{cssxref("grid-row-gap")}} и {{cssxref("grid-column-gap")}}, определяющего желоба между строками и столбцами сетки.

- -
{{EmbedInteractiveExample("pages/css/grid-gap.html")}}
- - - -

Syntax

- -
/* Одно <length> значение */
-grid-gap: 20px;
-grid-gap: 1em;
-grid-gap: 3vmin;
-grid-gap: 0.5cm;
-
-/* Одно <percentage> значение */
-grid-gap: 16%;
-grid-gap: 100%;
-
-/* Два <length> значения */
-grid-gap: 20px 10px;
-grid-gap: 1em 0.5em;
-grid-gap: 3vmin 2vmax;
-grid-gap: 0.5cm 2mm;
-
-/* Один или два <percentage> значения */
-grid-gap: 16% 100%;
-grid-gap: 21px 82%;
-
-/* calc() значения */
-grid-gap: calc(10% + 20px);
-grid-gap: calc(20px + 10%) calc(10% - 5px);
-
-/* Глобальные значения */
-grid-gap: inherit;
-grid-gap: initial;
-grid-gap: unset;
-
- -

Это свойство указывается как значение для <'grid-row-gap'> , за которым необязательно следует значение для <'grid-column-gap'>. Если <'grid-column-gap'> опущено, для него устанавливается то же значение, что и <'grid-row-gap'>.

- -

Каждое из свойств <'grid-row-gap'> и <'grid-column-gap'> указываются как <length> или <percentage>.

- -

Значения

- -
-
<length>
-
Ширина отступа, разделяющего линии сетки.
-
<percentage>
-
Ширина отступа, разделяющего линии сетки относительно размеров элемента.
-
- -

Формальный синтаксис

- -
{{csssyntax}}
- -

Примеры

- -

HTML Контент

- -
<div id="grid">
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-</div>
- -

CSS Контент

- -
#grid {
-  display: grid;
-  height: 200px;
-  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
-  grid-gap: 20px 5px;
-}
-
-#grid > div {
-  background-color: lime;
-}
-
- -

{{EmbedLiveSample("Example", "100%", "200px")}}

- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName("CSS3 Box Alignment", "#propdef-grid-gap", "grid-gap")}}{{Spec2("CSS3 Box Alignment")}}Устарело в пользу gap
{{SpecName("CSS3 Grid", "#gutters", "grid-gap")}}{{Spec2("CSS3 Grid")}}Начальное определение
- -

{{cssinfo}}

- -

Совместимость с браузерами

- - - -

{{Compat("css.properties.grid-gap")}}

- -

Смотрите также

- - - - diff --git a/files/ru/web/css/layout_mode/index.html b/files/ru/web/css/layout_mode/index.html new file mode 100644 index 0000000000..dcf1440cb5 --- /dev/null +++ b/files/ru/web/css/layout_mode/index.html @@ -0,0 +1,28 @@ +--- +title: Способ разметки +slug: Web/CSS/Способ_расположения +tags: + - CSS +translation_of: Web/CSS/Layout_mode +--- +

CSS способ разметки (или раскладки, или англ. layout) — это алгоритм определения позиции и размеров блоков, основанный на способе, которым они взаимодействуют с родственными блоками. Существует несколько типов разметки:

+ + + +
+

Примечание: не все CSS свойства применимы ко всем способам разметки. Большинство из них применяются к одному или двум из них и не действуют, если применяются на элементе, участвующем в другом режиме разметки.

+
+ +

Смотрите также

+ + diff --git a/files/ru/web/css/length/index.html b/files/ru/web/css/length/index.html new file mode 100644 index 0000000000..4fd88f8cc2 --- /dev/null +++ b/files/ru/web/css/length/index.html @@ -0,0 +1,153 @@ +--- +title: +slug: Web/CSS/размер +tags: + - CSS + - CSS Тип Данных + - Величина + - Разметка + - длина +translation_of: Web/CSS/length +--- +
{{CSSRef}}
+ +

CSS тип данных <length> представляет единицу длины. Длина может быть использована в таких свойствах CSS как {{Cssxref("width")}}, {{Cssxref("height")}}, {{Cssxref("margin")}}, {{Cssxref("padding")}}, {{Cssxref("border-width")}}, {{Cssxref("font-size")}}, и {{Cssxref("text-shadow")}}.

+ +
+

Обратите внимание: Хоть значения {{cssxref("<percentage>")}} также определяют размеры и могут использоваться в некоторых свойствах, принимающих значения типа <length>, они не являются <length> значениями.

+
+ +

Синтаксис

+ +

Тип данных <length> состоит из {{cssxref("<number>")}}, за которым следует одна из единиц измерения, перечисленных ниже. Как и у любых единиц измерения CSS между числом и единицей нет знака пробела. После числа 0 единица измерения необязательна.

+ +
+

Обратите внимание: Некоторые свойства допускают использование отрицательных значений <length>, а некоторые нет.

+
+ +

Единицы измерения

+ +

Относительные единицы измерения

+ +

Относительные единицы измерения представляют расстояние, определённое какой-либо другой величиной. В зависимости от единицы, это может быть размер определённого символа, высота строки или размер {{glossary("viewport")}}.

+ +
Единицы, зависящие от шрифта
+ +

Единицы, зависящие от шрифта, определяют значение <length>, используя размер какого-либо символа или характеристики шрифта, который применяется к элементу или его родителю.

+ +
+

Обратите внимание: Эти единицы, особенно em и rem, часто используются для создания адаптивных разметок, которые сохраняют вертикальную структуру страницы даже если пользователь изменяет размер шрифта.

+
+ +
+
cap {{experimental_inline}}
+
Представляет высоту заглавных букв в шрифте, применённом к элементу.
+
ch
+
Представляет ширину символа "0" (ноль, символ Юникод U+0030) в шрифте, применённом к элементу.
+
em
+
Представляет подсчитанный размер шрифта элемента. Если используется в свойстве {{Cssxref("font-size")}}, представляет унаследованный размер шрифта.
+
ex
+
Представляет x-height (обычно высоту буквы x) в шрифте, применённом к элементу. В шрифтах с буквой x это обычно высота букв в нижнем регистре; во многих шрифтах 1ex ≈ 0.5em.
+
ic {{experimental_inline}}
+
Равна используемой в шрифте ширине символа "" (ККЯ, символ "вода", U+6C34).
+
lh {{experimental_inline}}
+
Равна рассчитанному значению свойства {{Cssxref("line-height")}}, переведённому в абсолютные единицы измерения.
+
rem
+
Представляет размер шрифта корневого элемента (обычно {{HTMLElement("html")}}). Когда используется в свойстве {{Cssxref("font-size")}} корневого элемента, представляет значение по умолчанию (в большинстве браузеров 16px, но настройки пользователя могут переопределить это значение).
+
rlh {{experimental_inline}}
+
Равна рассчитанному значению свойства {{Cssxref("line-height")}} корневого эдемента (обычно {{HTMLElement("html")}}), переведённому в абсолютные единицы измерения. Когда используется в свойстве {{Cssxref("font-size")}} корневого элемента, представляет значение по умолчанию.
+
+ +
Единицы, зависящие от размеров экрана
+ +

Эти единицы определяют значение <length> относительно размеров экрана, то есть видимой части документа. эти единицы недопустимы в блоках {{cssxref("@page")}}.

+ +
+
vh
+
Равна 1% высоты блока содержимого.
+
vw
+
Равна 1% ширины блока содержимого.
+
vi {{experimental_inline}}
+
Равна 1% размера блока содержимого по направлению выстраивания строчных элементов.
+
vb {{experimental_inline}}
+
Равна 1% размера блока содержимого по направлению выстраивания блочных элементов.
+
vmin
+
Равна vh или vw в зависимости от того, что из них меньше.
+
vmax
+
Равна vh или vw в зависимости от того, что из них больше.
+
+ +

Абсолютные единицы измерения

+ +

Абсолютные единицы измерения представляют физические расстояния, когда известны физические свойтсва устройства вывода. Одна из единиц привязывается к физической единице, а все остальные к ней. Привязка делается по-разному для устройств с низким разрешением, таких как экраны, и высоким, таких как принтеры.

+ +

Для устройств с маленьким dpi (dots per inch — количество точек на дюйм) единица измерения px представляет физический пиксель; остальные единицы определяются относительно него. Таким образом, 1in определяется как 96px, что равно 72pt. Последствием такого способа определения является то, что длины, описанные в дюймах (in), сантиметрах (cm) или миллиметрах (mm) необязательно равны одноимённым физическим единицам.

+ +

Для устройств с высоким dpi дюймы (in),сантиметры (cm) и миллиметры (mm) такие же, как и соответствующие физические единицы. Таким образов, единица px определяется относительно их (1/96 одного дюйма).

+ +
+

Обратите внимание: Многие пользователи увеличивают стандартный размер шрифта браузера для удобства чтения. Длины, заданные абсолютными единицами могут вызвать проблемы с доступностью, так как они привязаны к физическим величинам и не масштабируются при изменении настроек. Поэтому предпочтительнее использовать относительные единицы (такие как em или rem) в свойстве font-size.

+
+ +
+
px
+
Один пиксель. Для устройств с дисплеев традиционно представляет одну точку. Тем не менее, на принтерах и экранах с высоким разрешением один пиксель CSS равен нескольким пикселям дисплея. 1px = 1/96  от 1in.
+
cm
+
Один сантиметр. 1cm = 96px/2.54.
+
mm
+
Один миллиметр. 1mm = 1/10 от 1cm.
+
Q {{experimental_inline}}
+
Четверть миллиметра. 1Q = 1/40 от 1cm.
+
in
+
Один дюйм. 1in = 2.54cm = 96px.
+
pc
+
Одна пайка. 1pc = 12pt = 1/6 от 1in.
+
pt
+
Одна точка. 1pt = 1/72 от1in.
+
mozmm {{non-standard_inline}}, удалена в Firefox 59
+
Экспериметальная единица, которая равна одному физическому миллиметру вне зависимости от размера и разрешения экрана. Такая единица требуется очень редко, но может понадобиться, особенно на маленьких устройствах.
+
+ +

Интерполяция

+ +

При анимации значения <length> интерполируются как реальные числа с плавающей запятой. Интерполяция происходит над рассчитанным значением. Скорость интерполяции определяется временной функцией анимации.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS4 Values', '#lengths', '<length>')}}{{Spec2('CSS4 Values')}}Добавлены единицы vi, vb, ic, lh, и rlh.
{{SpecName('CSS3 Values', '#lengths', '<length>')}}{{Spec2('CSS3 Values')}}Добавлены единицы ch, rem, vw, vh, vmin, vmax, и Q.
{{SpecName('CSS2.1', 'syndata.html#length-units', '<length>')}}{{Spec2('CSS2.1')}}Явно определены единицы empt, pc, и px.
{{SpecName('CSS1', '#length-units', '<length>')}}{{Spec2('CSS1')}}Первое определение. Неявно определены единицы empt, pc, и px.
+ +

Поддержка браузерами

+ + + +

{{Compat("css.types.length")}}

diff --git a/files/ru/web/css/media_queries/testing_media_queries/index.html b/files/ru/web/css/media_queries/testing_media_queries/index.html new file mode 100644 index 0000000000..878621ebd3 --- /dev/null +++ b/files/ru/web/css/media_queries/testing_media_queries/index.html @@ -0,0 +1,83 @@ +--- +title: Тестирование медиа-запросов программно +slug: Web/CSS/Media_Queries/Тестирование_медиа_запросы +tags: + - Запросы + - медиа-запросы +translation_of: Web/CSS/Media_Queries/Testing_media_queries +--- +
{{cssref}}
+ +

 {{Glossary("DOM")}} предоставляет возможности, позволяющие тестировать результат  медиа-запросов программно, с помощью интерфейса {{domxref("MediaQueryList") }}, его методов и свойств. Однажды, создав объект {{domxref("MediaQueryList") }} вы можете проверить результат запроса или получать уведомление, при изменении результата.

+ +

Создание списка медиа-запросов

+ +

Прежде, чем вы сможете оценить результаты медиа-запросов, вам необходимо создать объект {{domxref("MediaQueryList") }} , отражающий запрос. Для этого используйется метод {{domxref("window.matchMedia") }}.

+ +

Например, настройка списка запросов, который определяет, находится ли устройство в альбомной или книжной ориентации:

+ +
var mediaQueryList = window.matchMedia("(orientation: portrait)");
+
+ +

Проверка результата запроса

+ +

После того, как вы создали свой список медиа-запросов, вы можете проверить результат запроса, посмотрев на значение его свойства matches:

+ +
if (mediaQueryList.matches) {
+  /* Окно просмотра в настоящее время находится в книжной ориентации */
+} else {
+  /* Окно просмотра в настоящее время находится в альбомной ориентации */
+}
+
+ +

Получение уведомлений о запросах

+ +

Если вам необходимо постоянно следить за изменениями в результате запроса, эффективнее зарегистрировать слушатель, чем вытаскивать результат запросов.  Для этого вызовите метод addListener() объекта {{domxref("MediaQueryList") }} с функцией обратного вызова, которая вызывается при изменении статуса медиа-запроса (например, тест медиа-запроса переходит от true к false):

+ +
var mediaQueryList = window.matchMedia("(orientation: portrait)"); // Создание списка запросов.
+function handleOrientationChange(mql) { ... } // Определение функции обратного вызова для слушателя событий.
+mediaQueryList.addListener(handleOrientationChange); // Добавление функции обратного вызова в качестве слушателя к списку запросов.
+
+handleOrientationChange(mediaQueryList); // Запуск обработчика изменений, один раз.
+
+ +

Этот код создает список медиа-запросов для тестирование ориентации, а затем добавляет к нему слушатель событий. После добавления слушателя, мы, также, непосредственно вызываем слушателя. Это заставляет нашего слушателя выполнять настройки, основываясь на текущей ориентации устройства; в противном случае, наш код может предполагать, что устройство находится в книжной ориентации при запуске, даже если оно фактически находится в альбомном положении.

+ +

Функция handleOrientationChange() будет следить за результатом запроса и обрабатывать все, что нам нужно сделать при изменении ориентации:

+ +
function handleOrientationChange(evt) {
+  if (evt.matches) {
+    /* Окно просмотра в настоящее время находится в книжной ориентации */
+  } else {
+    /* Окно просмотра в настоящее время находится в альбомной ориентации */
+  }
+}
+
+ +

Выше, мы определяем параметры как evt — event объект. Это имеет значение, поскольку новые реализации MediaQueryList обрабатывают слушатели событий стандартным способом. Они больше не используют нестандартный механизм  {{domxref("MediaQueryListListener")}} , а используют стандартную настройку слушателя событий, передавая объект event  {{domxref("MediaQueryListEvent")}} как аргумент функции обратного вызова.

+ +

Этот event объект также включает свойства {{domxref("MediaQueryListEvent.media","media")}} и {{domxref("MediaQueryListEvent.matches","matches")}}, поэтому вы можете запросить эти свойства MediaQueryList путем прямого доступа к нему или доступа к event объекту.

+ +

Уведомление о завершении запроса

+ +

Для прекращения уведомлений об изменении значения вашего медиа-запроса вызовите метод removeListener() для {{domxref("MediaQueryList") }}, передав ему имя, ранее определенной функции:

+ +
mediaQueryList.removeListener(handleOrientationChange);
+
+ +

Поддержка браузеров

+ +

MediaQueryList interface

+ + + +

{{Compat("api.MediaQueryList")}}

+ +

See also

+ + diff --git "a/files/ru/web/css/media_queries/\321\202\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\274\320\265\320\264\320\270\320\260_\320\267\320\260\320\277\321\200\320\276\321\201\321\213/index.html" "b/files/ru/web/css/media_queries/\321\202\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\274\320\265\320\264\320\270\320\260_\320\267\320\260\320\277\321\200\320\276\321\201\321\213/index.html" deleted file mode 100644 index 878621ebd3..0000000000 --- "a/files/ru/web/css/media_queries/\321\202\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\274\320\265\320\264\320\270\320\260_\320\267\320\260\320\277\321\200\320\276\321\201\321\213/index.html" +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: Тестирование медиа-запросов программно -slug: Web/CSS/Media_Queries/Тестирование_медиа_запросы -tags: - - Запросы - - медиа-запросы -translation_of: Web/CSS/Media_Queries/Testing_media_queries ---- -
{{cssref}}
- -

 {{Glossary("DOM")}} предоставляет возможности, позволяющие тестировать результат  медиа-запросов программно, с помощью интерфейса {{domxref("MediaQueryList") }}, его методов и свойств. Однажды, создав объект {{domxref("MediaQueryList") }} вы можете проверить результат запроса или получать уведомление, при изменении результата.

- -

Создание списка медиа-запросов

- -

Прежде, чем вы сможете оценить результаты медиа-запросов, вам необходимо создать объект {{domxref("MediaQueryList") }} , отражающий запрос. Для этого используйется метод {{domxref("window.matchMedia") }}.

- -

Например, настройка списка запросов, который определяет, находится ли устройство в альбомной или книжной ориентации:

- -
var mediaQueryList = window.matchMedia("(orientation: portrait)");
-
- -

Проверка результата запроса

- -

После того, как вы создали свой список медиа-запросов, вы можете проверить результат запроса, посмотрев на значение его свойства matches:

- -
if (mediaQueryList.matches) {
-  /* Окно просмотра в настоящее время находится в книжной ориентации */
-} else {
-  /* Окно просмотра в настоящее время находится в альбомной ориентации */
-}
-
- -

Получение уведомлений о запросах

- -

Если вам необходимо постоянно следить за изменениями в результате запроса, эффективнее зарегистрировать слушатель, чем вытаскивать результат запросов.  Для этого вызовите метод addListener() объекта {{domxref("MediaQueryList") }} с функцией обратного вызова, которая вызывается при изменении статуса медиа-запроса (например, тест медиа-запроса переходит от true к false):

- -
var mediaQueryList = window.matchMedia("(orientation: portrait)"); // Создание списка запросов.
-function handleOrientationChange(mql) { ... } // Определение функции обратного вызова для слушателя событий.
-mediaQueryList.addListener(handleOrientationChange); // Добавление функции обратного вызова в качестве слушателя к списку запросов.
-
-handleOrientationChange(mediaQueryList); // Запуск обработчика изменений, один раз.
-
- -

Этот код создает список медиа-запросов для тестирование ориентации, а затем добавляет к нему слушатель событий. После добавления слушателя, мы, также, непосредственно вызываем слушателя. Это заставляет нашего слушателя выполнять настройки, основываясь на текущей ориентации устройства; в противном случае, наш код может предполагать, что устройство находится в книжной ориентации при запуске, даже если оно фактически находится в альбомном положении.

- -

Функция handleOrientationChange() будет следить за результатом запроса и обрабатывать все, что нам нужно сделать при изменении ориентации:

- -
function handleOrientationChange(evt) {
-  if (evt.matches) {
-    /* Окно просмотра в настоящее время находится в книжной ориентации */
-  } else {
-    /* Окно просмотра в настоящее время находится в альбомной ориентации */
-  }
-}
-
- -

Выше, мы определяем параметры как evt — event объект. Это имеет значение, поскольку новые реализации MediaQueryList обрабатывают слушатели событий стандартным способом. Они больше не используют нестандартный механизм  {{domxref("MediaQueryListListener")}} , а используют стандартную настройку слушателя событий, передавая объект event  {{domxref("MediaQueryListEvent")}} как аргумент функции обратного вызова.

- -

Этот event объект также включает свойства {{domxref("MediaQueryListEvent.media","media")}} и {{domxref("MediaQueryListEvent.matches","matches")}}, поэтому вы можете запросить эти свойства MediaQueryList путем прямого доступа к нему или доступа к event объекту.

- -

Уведомление о завершении запроса

- -

Для прекращения уведомлений об изменении значения вашего медиа-запроса вызовите метод removeListener() для {{domxref("MediaQueryList") }}, передав ему имя, ранее определенной функции:

- -
mediaQueryList.removeListener(handleOrientationChange);
-
- -

Поддержка браузеров

- -

MediaQueryList interface

- - - -

{{Compat("api.MediaQueryList")}}

- -

See also

- - diff --git a/files/ru/web/css/pseudo-classes/index.html b/files/ru/web/css/pseudo-classes/index.html new file mode 100644 index 0000000000..2c280be32b --- /dev/null +++ b/files/ru/web/css/pseudo-classes/index.html @@ -0,0 +1,146 @@ +--- +title: Псевдоклассы +slug: Web/CSS/Псевдо-классы +tags: + - CSS + - Reference + - Псевдоклассы + - Селекторы +translation_of: Web/CSS/Pseudo-classes +--- +
{{CSSRef}}
+ +

Псевдокласс в CSS — это ключевое слово, добавленное к селектору, которое определяет его особое состояние. Например, {{ Cssxref(":hover") }} может быть использован для изменения цвета кнопки при наведении курсора на неё.

+ +
div:hover {
+  background-color: #F89B4D;
+}
+ +

Псевдоклассы дают возможность стилизовать элемент на основе не только отношений в DOM-дереве, но и основываясь на внешних факторах, таких как история посещений (например, {{ cssxref(":visited") }}), состояние содержимого (вроде {{ cssxref(":checked") }} у некоторых элементов формы) или позиции курсора мыши (например, {{ cssxref(":hover") }} определяет, находится ли курсор мыши над элементом).

+ +
+

Примечание: В отличие от псевдоклассов, псевдоэлементы могут быть использованы для стилизации определённой части элемента.

+
+ +

Синтаксис

+ +
selector:pseudo-class {
+  property: value;
+}
+
+ +

Как и с обычными классами, можно совмещать вместе в одном селекторе любое число псевдоклассов.

+ +

Список стандартных псевдоклассов

+ +
+
    +
  • {{ Cssxref(":active") }}
  • +
  • {{ cssxref(':any')}}
  • +
  • {{ cssxref(':any-link')}}
  • +
  • {{ Cssxref(":checked") }}
  • +
  • {{ Cssxref(":default") }}
  • +
  • {{ Cssxref(":defined") }}
  • +
  • {{ Cssxref(":dir", ":dir()")}}
  • +
  • {{ Cssxref(":disabled") }}
  • +
  • {{ Cssxref(":empty") }}
  • +
  • {{ Cssxref(":enabled") }}
  • +
  • {{ Cssxref(":first") }}
  • +
  • {{ Cssxref(":first-child") }}
  • +
  • {{ Cssxref(":first-of-type") }}
  • +
  • {{ Cssxref(":fullscreen") }}
  • +
  • {{ Cssxref(":focus") }}
  • +
  • {{ Cssxref(":hover") }}
  • +
  • {{ Cssxref(":indeterminate") }}
  • +
  • {{ Cssxref(":in-range") }}
  • +
  • {{ Cssxref(":invalid") }}
  • +
  • {{ Cssxref(":lang", ":lang()") }}
  • +
  • {{ Cssxref(":last-child") }}
  • +
  • {{ Cssxref(":last-of-type") }}
  • +
  • {{ Cssxref(":left") }}
  • +
  • {{ Cssxref(":link") }}
  • +
  • {{ Cssxref(":not", ":not()") }}
  • +
  • {{ Cssxref(":nth-child", ":nth-child()") }}
  • +
  • {{ Cssxref(":nth-last-child", ":nth-last-child()") }}
  • +
  • {{ Cssxref(":nth-last-of-type", ":nth-last-of-type()") }}
  • +
  • {{ Cssxref(":nth-of-type", ":nth-of-type()") }}
  • +
  • {{ Cssxref(":only-child") }}
  • +
  • {{ Cssxref(":only-of-type") }}
  • +
  • {{ Cssxref(":optional") }}
  • +
  • {{ Cssxref(":out-of-range") }}
  • +
  • {{ Cssxref(":read-only") }}
  • +
  • {{ Cssxref(":read-write") }}
  • +
  • {{ Cssxref(":required") }}
  • +
  • {{ Cssxref(":right") }}
  • +
  • {{ Cssxref(":root") }}
  • +
  • {{ Cssxref(":scope") }}
  • +
  • {{ Cssxref(":target") }}
  • +
  • {{ Cssxref(":valid") }}
  • +
  • {{ Cssxref(":visited") }}
  • +
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{ SpecName('Fullscreen') }}{{ Spec2('Fullscreen') }}Определён :fullscreen.
{{ SpecName('HTML WHATWG') }}{{ Spec2('HTML WHATWG') }}Нет изменений от {{ SpecName('HTML5 W3C') }}.
{{SpecName('CSS4 Selectors')}}{{Spec2('CSS4 Selectors')}}Определены :any-link, :local-link, :scope, :active-drop-target, :valid-drop-target, :invalid-drop-target, :current, :past, :future, :placeholder-shown, :user-error, :blank, :nth-match(), :nth-last-match(), :nth-column(), :nth-last-column() и :matches().
+ Нет существенных изменений для псевдоклассов, определённых в {{SpecName('CSS3 Selectors')}} и {{SpecName('HTML5 W3C')}} (не рассматрия семантическое значение).
{{ SpecName('HTML5 W3C') }}{{ Spec2('HTML5 W3C') }}Определено семантическое значение в HTML контексте для  :link, :visited, :active, :enabled, :disabled, :checked и :indeterminate.
+ Определены :default, :valid, :invalid, :in-range, :out-of-range, :required, :optional, :read-only, :read-write и :dir().
{{ SpecName('CSS3 Basic UI') }}{{ Spec2('CSS3 Basic UI') }}Определены :default, :valid, :invalid, :in-range, :out-of-range, :required, :optional, :read-only и :read-write, но без связанного семантического значения.
{{SpecName('CSS3 Selectors')}}{{Spec2('CSS3 Selectors')}}Определены :target, :root, :nth-child(), :nth-last-of-child(), :nth-of-type(), :nth-last-of-type(), :last-child, :first-of-type, :last-of-type, :only-child, :only-of-type, :empty и :not().
+ Определён синтаксис для :enabled, :disabled, :checked и :indeterminate, но без связанного семантического значения.
+ Нет значительных изменений для псевдоклассов, определённых в {{SpecName('CSS2.1')}}.
{{SpecName('CSS2.1')}}{{Spec2('CSS2.1')}}Определены :lang(), :first-child, :hover и :focus.
+ Нет значительных изменений для псевдоклассов, определённых в {{SpecName('CSS1')}}.
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Определены :link, :visited и :active, но без связанного семантического значения.
+ +

См. также

+ + diff --git a/files/ru/web/css/replaced_element/index.html b/files/ru/web/css/replaced_element/index.html new file mode 100644 index 0000000000..a252cbad33 --- /dev/null +++ b/files/ru/web/css/replaced_element/index.html @@ -0,0 +1,49 @@ +--- +title: Замещаемый элемент +slug: Web/CSS/Замещаемый_элемент +tags: + - CSS + - Reference + - замещаемый элемент +translation_of: Web/CSS/Replaced_element +--- +
{{CSSRef}}
+ +

В CSS, замещаемый элемент — это элемент, чьё представление выходит за рамки CSS. Другими словами, это внешний объект, чьё представление независимо от модели форматирования CSS.

+ +

Замещаемые элементы

+ +

Типичные замещаемые элементы:

+ + + +

Некоторые элементы рассматриваются как замещаемые только в некоторых случаях:

+ + + +

Спецификация HTML также указывает, что элемент {{HTMLElement("input")}} может быть замещаемым, поскольку элемент {{HTMLElement("input")}} с типом image является замещаемым элементом наподобие {{HTMLElement("img")}}. Однако другие элементы форм, включая другие типы элементов {{HTMLElement("input")}}, явно отнесены к незамещаемым элементам (для описания их отображения по умолчанию, которое может быть разным на разных платформах, спецификация использует термин «Виджеты»).

+ +

Объекты, добавляемые с помощью CSS-свойства {{cssxref("content")}} являются анонимными замещаемыми элементами. Они «анонимные», так как они не существуют в HTML-разметке.

+ +

Использование CSS с замещаемыми элементами

+ +

CSS обрабатывает замещаемые элементы особым образом в некоторых случаях, например при расчёте внешних отступов и некоторых значений auto.

+ +

Заметим, что у некоторых замещаемых элементов, но не у всех, есть внутренние размеры или определённая базовая линия, которая используется CSS свойствами вроде {{cssxref("vertical-align")}}.

+ +

См. также

+ + diff --git a/files/ru/web/css/specified_value/index.html b/files/ru/web/css/specified_value/index.html new file mode 100644 index 0000000000..4f143afb74 --- /dev/null +++ b/files/ru/web/css/specified_value/index.html @@ -0,0 +1,43 @@ +--- +title: Указанное значение +slug: Web/CSS/Указанное_значение +tags: + - CSS + - CSS Reference +translation_of: Web/CSS/specified_value +--- +

{{CSSRef}}

+ +

Указанное значение CSS свойства может устанавливаться одним из 3 следующих способов.

+ +
    +
  1. Если в таблице стилей документа указано значение свойства, которое будет использоваться. Например, если свойство {{cssxref("color")}} устанавливается в green, то цвет текста соответствующего элемента становится зелёным.
  2. +
  3. Если в таблице стилей документа указано значение, которое может наследоваться от родительского элемента (если возможно). Например, у нас есть параграф ({{HTMLElement("p")}}) внутри {{HTMLElement("div")}}, а к {{HTMLElement("div")}} применено CSS свойство font со значением "Arial", а у {{HTMLElement("p")}} не установлено свойство font, то он унаследует значение шрифта "Arial".
  4. +
  5. Если не выполняется не то, не другое, начальное значение элемента применяется из CSS спецификации.
  6. +
+ +

Спецификации

+ + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName("CSS2.1", "cascade.html#specified-value", "cascaded value")}}{{Spec2("CSS2.1")}}Изначальное определение
+ +

Смотрите также

+ + diff --git a/files/ru/web/css/syntax/index.html b/files/ru/web/css/syntax/index.html new file mode 100644 index 0000000000..1adfb2fb04 --- /dev/null +++ b/files/ru/web/css/syntax/index.html @@ -0,0 +1,76 @@ +--- +title: Синтаксис +slug: Web/CSS/Синтаксис +translation_of: Web/CSS/Syntax +--- +
{{cssref}}
+ +
Основная задача Каскадных Стилей — это рассказать движку браузера, как отрисовать элементы страницы — каким цветом, как позиционировать их на странице, как украшать, и так далее. Синтаксис CSS построен следуя этой идее, и состоит из следующих основных блоков:
+ +
+ + + +

Объявления CSS

+ +

Задание CSS свойствам определенных значений — это основная функция CSS. Пара свойство-значение называется объявлением. Работа CSS движка заключается в поиске соответсвий между объявлениями стилей и элементом на странице, чтобы правильно отобразить и форматировать этот элемент.

+ +

И свойство, и значения регистрозависимы. Пара свойство-значение разделяется двоеточием, ':' (U+003A COLON), а пробелы до, между и после свойства или значения игнорируются.

+ +

css syntax - declaration.png

+ +

В CSS существует более ста различных свойств, и бесконечное число допустимых значений. Не все пары свойств и значений допускаются, и каждое свойство определяет, каковы допустимые значения. Когда значение не подходит для данного свойства, объявление считается недействительной и целиком игнорируются CSS-движком.

+ +

Блоки объявлений CSS

+ +

Объявления группируются в блоки, структура которых состоит из открывающейся , '{' (U+007B LEFT CURLY BRACKET), и закрывающейся, '}' (U+007D RIGHT CURLY BRACKET) фигурных скобок.

+ +

css syntax - block.png

+ +

Такие блоки называются блоками объявлений, и объявления в них разделяются точкой с запятой, ';' (U+003B SEMICOLON). Блок объявлений может быть пустым, т.е. не содержать объявлений. Пробелы между объявлениями игнорируются. Последнее объявление блока не нуждается в точке с запятой, хотя считается хорошим тоном добавить ее для того, чтобы не допустить упущение этого знака при добавлении другого объявления в будущем.

+ +

css syntax - declarations block.png

+ +
Содержимое блока объявлений CSS, т. е. объявления, разделенные точкой с запятой. Блок объявлений может быть помещен внутри атрибута style HTML-документа без фигурных скобок.
+ +

CSS rulesets

+ +

If style sheets could only apply a declaration to each element of a Web page, they would be pretty useless. The real goal is to apply different declarations to different parts of the document.

+ +

CSS allows this by associating conditions with declarations blocks. Each (valid) declaration block is preceded by a selector which is a condition selecting some elements of the page. The pair selector-declarations block is called a ruleset, or often simply a rule.

+ +

css syntax - ruleset.png

+ +

As an element of the page may be matched by several selectors, and therefore by several rules eventually containing a given property several times, with different values, the CSS standard defines which one has precedence over the other and must be applied: this is called the cascade algorithm.

+ +
It is important to note that even if a ruleset characterized by a group of selectors is a kind of shorthand replacing rulesets with a single selector each, this doesn't apply to the validity of the ruleset itself.
+
+This leads to an important consequence: if one single basic selector is invalid, like when using an unknown pseudo-element or pseudo-class, the whole selector is invalid and therefor the entire rule is ignored (as invalid too).
+ +

CSS statements

+ +

Rulesets are the main building blocks of a style sheet, which often consists of only a big list of them. But there is other information that a Web author wants to convey in the style sheet, like the character set, other external style sheets to import, font face or list counter descriptions and many more. It will use other and specific kinds of statements to do that.

+ +

A statement is a building block that begins with any non-space characters and ends at the first closing brace or semi-colon (outside a string, non-escaped and not included into another {}, () or [] pair).

+ +

css syntax - statements Venn diag.png

+ +

There are different kinds of statements:

+ + + +

Any statement which isn't a rule or an at-rule is invalid and ignored.

+ +

There is another group of statements, the nested statements, these are statements that can be used in a specific subset of at-rules, the conditional group rules. These statements only apply if a specific condition is matched: the @media at-rule content is applied only if the device on which runs the browser matches the expressed condition; the @document at-rule content is applied only if the current page matches some conditions, and so on. In CSS1 and CSS2.1, only rulesets could be used inside a conditional group rules. That was very restrictive and this restriction was lifted in CSS Conditionals Level 3. Now, though it still is experimental and not supported by every browser, a conditional group rules can contain a wider range of content, rulesets but also some, but not all, at-rules.

+ +

See also

+ + diff --git a/files/ru/web/css/url/index.html b/files/ru/web/css/url/index.html deleted file mode 100644 index 82965bf827..0000000000 --- a/files/ru/web/css/url/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: -slug: Web/CSS/url -tags: - - Адрес - - Типы данных - - относительный адрес -translation_of: Web/CSS/url() -translation_of_original: Web/CSS/url ---- -
{{CssRef}}
- -

Тип данных CSS <url> обозначает указатели на ресурсы, такие как изображения или шрифты. URL-адреса могут быть использованы в многочисленных свойствах CSS, таких как {{Cssxref("background-image")}}, {{Cssxref("cursor")}} или {{cssxref("list-style")}}.

- -
-

URI или URL? Существует разница между {{Glossary("URI")}} и {{Glossary("URL")}}. URI просто идентифицирует ресурс. URL является типом URI, и описывает месторасположение ресурса.URI может быть либо URL-адресом, либо именем ресурса ({{Glossary("URN")}}).

- -

В CSS Уровень 1, фунциональная нотация url()описывала только истинные URL-адреса. В CSS Уровень 2, определение url() было расширено для описания любого URI, будь то URL или URN. Неожиданно, что  url() может быть использовано для создания типа данных CSS <uri>. Это изменение было не только неожиданным, но и ненужным, так как URN почти не используется в реальном CSS. Для избежания путанницы, CSS Уровень 3 вернулся к более узкому, первоначальному определению. Сейчас url() означает только истинное значение <url>.

-
- -

Синтаксис

- -

Тип данных <url> является указанием к использованию функциональной нотации url(). Он  может быть задан без кавычек или с использованием одинарных или двойных кавычек. Допускаются относительные URL-адреса, относящиеся к URL-адресу страницы стилей (а не к URL-адресу веб-страницы).

- -
<a_css_property>: url("http://mysite.example.com/mycursor.png")
-<a_css_property>: url('http://mysite.example.com/mycursor.png')
-<a_css_property>: url(http://mysite.example.com/mycursor.png)
-
- -
-

Примечание: Контрольные символы выше 0x7e не допустимы в URL-адресах без кавычек, начиная с Firefox 15. Смотри {{Bug(752230)}} для более детальной информации.

-
- -

Примеры

- -
.topbanner {
-  background: url("topbanner.png") #00D no-repeat fixed;
-}
-
- -
ul {
-  list-style: square url(http://www.example.com/redball.png);
-}
-
- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('CSS4 Values', '#urls', '<url>')}}{{Spec2('CSS4 Values')}} 
{{SpecName('CSS3 Values', '#urls', '<url>')}}{{Spec2('CSS3 Values')}}Нет значительных изменений по сравнению с CSS Уровень 2 (Revision 1).
{{Specname('CSS2.1', 'syndata.html#uri', '<uri>')}}{{Spec2('CSS2.1')}}Нет значительных изменений по сравнению с CSS Уровень 1.
{{SpecName('CSS1', '#url', '<url>')}}{{Spec2('CSS1')}}первое определение.
- -

Поддержка браузерами

- - - -
{{Compat("css.types.url")}}
- -

Смотрите также

- -
    -
  • {{cssxref("<gradient>")}}
  • -
  • {{cssxref("element()")}}
  • -
  • {{cssxref("_image","image()")}}
  • -
  • {{cssxref("image-set","image-set()")}}
  • -
  • {{cssxref("cross-fade")}}
  • -
diff --git a/files/ru/web/css/visual_formatting_model/index.html b/files/ru/web/css/visual_formatting_model/index.html new file mode 100644 index 0000000000..7a5de35909 --- /dev/null +++ b/files/ru/web/css/visual_formatting_model/index.html @@ -0,0 +1,209 @@ +--- +title: Модель визуального форматирования +slug: Web/Guide/CSS/Visual_formatting_model +translation_of: Web/CSS/Visual_formatting_model +--- +

{{CSSRef}}

+ +

Модель визуального форматирования CSS  - это алгоритм, используемый для обработки документа и его визуального отображения. Это базовая концепция CSS. Модель визуального форматирования задаёт трансформацию каждого элемента в документе и создаёт ноль, одну или несколько боксов, согласно боксовой модели CSS. Расположение (layout) каждого бокса определяется:

+ +
    +
  • размерами бокса: точно заданными или заданными ограничениями. Если размеры не заданы, это правило игнорируется;
  • +
  • типом бокса: inline, inline-level, atomic inline-level, block box;
  • +
  • схемой позиционирования: normal flow, float или absolute;
  • +
  • другими элементами дерева: дочерними и соседними;
  • +
  • размерами и расположением окна просмотра ({{glossary("viewport")}});
  • +
  • внутренними размерами содержащихся изображений;
  • +
  • другой внешней информацией.
  • +
+ +

Бокс отображается относительно краев содержащего его блока. Как правило, бокс определяет родительский блок для своих потомков. Однако, стоит заметить, что бокс не ограничен содержащим его блоком. Такое поведение слоев, выходящих за пределы своих содержащих блоков, называется переполенинем (overflow).

+ +

Генерация бокса

+ +

Генерация бокса - часть алгоритма модели визуального форматирования, процедура, генерирующая блоки из элементов. Различные типы боксов определяют различное поведение в контексте форматирования. Тип бокса зависит от свойства CSS {{ cssxref("display") }}.

+ +

Блочные эклементы и блок-боксы

+ +

Говорят, что элемент является блочным, когда вычисленное значение его CSS свойства {{ cssxref("display") }} равно: blocklist-item, или table. Блочный элемент визуально форматируется как блок (например, параграф), предназначенный для вертикальной компоновки (в столбик).

+ +

Каждый элемент блочного уровня участвует в контексте блочного форматирования. Каждый элемент блочного уровня генерирует как миниум один блок-бокс, названный главным блок-боксом. Некоторые элементы, например, такие как list-item, создают дополнительные боксы для хранения маркеров и других типографических элементов, содержащихся в list item. Большинство блочных элементов генерирует только один, главный блок-бокс.

+ +

Главный блок-бокс содержит сгенериованные боксы-потомки и сгенериованный контекст. Он так же будет боксом, участвующем в схеме позиционирования.

+ +

venn_blocks.pngЭлемент блочного уровня так же может быть блоком-контейнером. Блок-контейнер - это блок, который содержит либо только другие элементы блочного уровня, либо создаёт контекст инлайнового форматирования и, таким образом, содержит только инлайновые элементы.

+ +

Важно понимать, что понятие блочного элемента и понятие блочного контейнера - это разные вещи. Первое описывает, как блок будет себя вести по отношению к своему родителю и своим соседям/братьям. А второе - описывает, как блок будет взаимодействовать со своими потомками. Некоторые элементы блочного уровня, например, таблицы, не являются содержащими блоками. И наоборот, некоторые блоки-контейнеры, например, ячейки таблицы, не являются элементами блочного уровня.

+ +

Элементы блочного уровня, которые так же являются контейнерами, называются блок-боксами.

+ +

Анонимные блок-боксы

+ +

В некоторых случаях алгоритм визуального форматирования  вынужден добавлять дополнительные боксы. Так как эти боксы невозможно как-то проименовать и к ним невозможно применить css-селекторы, поэтому эти боксы называют анонимными.

+ +

Из-за того, что к анонимным боксам невозможно применить селекторы, их невозможно изменить с помощью таблицы стилей. Это значит, что все наследуемые CSS свойства для них будут иметь значение inherit, а все ненаследуемые свойства будут иметь значение initial.

+ +

Блоки-контейнеры содержат либо только инлайн-боксы, либо только элементы блочного уровня. Но, как правило, документ содержит и те и другие. В этом случае анонимные блок-боксы создаются вокруг примыкающих к ним инлайн-боксов.

+ +

Пример

+ +

Возьмём следующий HTML код (со стилями по умолчанию, то есть элементы {{ HTMLElement("div") }} и {{ HTMLElement("p") }} имеют значение display:block :

+ +
<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>
+ +

Здесь создались два анонимных блока: один для текста перед параграфом (Some inline text), и второй для текста после параграфа (followed by more inline text.). И у нас получилась вот такая структура:

+ +

anonymous_block-level_boxes.png

+ +

Выглядеть это будет так:

+ +
Some inline text
+followed by a paragraph
+followed by more inline text.
+ +

В отличие от параграфа {{ HTMLElement("p") }}, Web разработчик не может напрямую контролировать стили этих двух анонимных боксов. Те свойства, которые наследуются, берут своё значение от элемента {{ HTMLElement("div") }}, например {{ cssxref("color") }}, определяющий цвет текста. А другие значения, ненаследуемые, устанавливаются в значение initial. Например, у них не будет своего свойства {{ cssxref("background-color") }}, он всегда будет в состоянии "прозрачный" (transparent), значении по умолчанию для этого свойства, и поэтому будет видно тот background, который установлен у элемента <div>. А вот для параграфа <p> можно установить своё свойство цвета фона. Таким образом, эти два анонимных бокса будут иметь один и тот же цвет текста.

+ +

Ещё один случай, который приводит к созданию анонимных блок-боксов, это случай, когда инлайн-бокс содержит один или несколько блок-боксов. В этом случае элемент, содержащий блок-боксы, делится на два инлайн-бокса - один перед, а второй после блок-бокса. И потом инлайн-элементы перед и после блок-бокса дополнительно заключаются в анонимные блок-боксы. Таким образом блок-бокс становится соседом для анонимных блок-боксов, содержащих инлайн-элементы.

+ +

Если есть несколько блок-боксов, идущих подряд, без инлайн-элементов между ними, то анонимные блок-боксы создаются только перед и после такого набора блок-боксов.

+ +

Пример

+ +

Возьмём следующий HTML код, где установим для элемента {{ HTMLElement("p") }} значение display:inline и для элемента {{ HTMLElement("span") }} значение display:block :

+ +
<p>Some <em>inline</em> text <span>followed by a paragraph</span> followed by more inline text.</p>
+ +

Создадутся два анонимных блок-бокса, один для текста перед элементом span (Some inline text) и один для текста после него (followed by more inline text), и у нас получится вот такая структура:

+ +

+ +

Выглядеть она будет так:

+ +
Some inline text
+followed by a paragraph
+followed by more inline text.
+ +

Элементы инлайн-уровня и инлайн-боксы

+ +

Элементы, которые называются элементами инлайн-уровня - это элементы, у которых вычисленное значение CSS свойства {{ cssxref("display") }} установлено в : inline, inline-block или inline-table. Визуально они не представляют собой какие-то отдельные блоки, но они они распологаются в одну линию с другим контентом инлайн-уровня. Например, содержание параграфа, с различным форматированием, таким как подчёркивание или картинка, состоит из элементов инлайн-уровня.

+ +

venn_inlines.png

+ +
+

Эта диаграмма использует устаревшую терминологию; см. примечания ниже. К тому же она некорректна, потому что жёлтый эллипс справа по определению должен быть изображён одинаковым по размеру с эллипсом слева или больше него  (it could be a mathematical superset), потому что в спецификации сказано: "Элементв инлайн-уровня генерируют боксы инлайн-уровня, участвующие в форматировании инлайн-уровня", см. CSS 2.2, глава 9.2.2

+
+ +

Элементы инлайн-уровня создают боксы инлайн-уровня, которые определены как боксы, участвующие в контексте форматирования инлайн-уровня. Inline boxes are both inline-level boxes and boxes, whose contents participate in their container's inline formatting context. This is the case, for example, for all non-replaced boxes with display:inline. Inline-level boxes, whose contents do not participate in an inline formatting context, are called atomic inline-level boxes. These boxes, generated by replaced inline-level elements or by elements with a calculated {{ cssxref("display") }} value of inline-block or inline-table, are never split into several boxes, as is possible with inline boxes.

+ +
Note: Initially, atomic inline-level boxes were called atomic inline boxes. This was unfortunate, as they are not inline boxes. This was corrected in an erratum to the spec. Nevertheless, you can harmlessly read atomic inline-level box each time you meet atomic inline box in the literature, as this is only a name change.
+ +
Atomic inline boxes cannot be split into several lines in an inline formatting context. +
+
<style>
+  span {
+    display:inline; /* default value*/
+  }
+</style>
+<div style="width:20em;">
+   The text in the span <span>can be split in several
+   lines as it</span> is an inline box.
+</div>
+
+
+ +

which leads to:

+ +
The text in the span can be split into several lines as it is an inline box.
+ +
<style>
+  span {
+    display:inline-block;
+  }
+</style>
+<div style="width:20em;">
+   The text in the span <span>cannot be split in several
+   lines as it</span> is an inline-block box.
+</div>
+ +
+
+

which leads to:

+ +
The text in the span cannot be split into several lines as it is an inline-block box.
+
+
+ +

Anonymous inline boxes

+ +

As for block boxes, there are a few cases where inline boxes are created automatically by the CSS engine. These inline boxes are also anonymous as they cannot be named by selectors; they inherit the value of all inheritable properties, setting it to initial for all others.

+ +

The most common case where an anonymous inline box is created, is when some text is found as a direct child of a block box creating an inline formatting context. In that case, this text is included in the largest possible anonymous inline box. Also, space content, which would be removed by the behavior set in the {{ cssxref("white-space") }} CSS property, does not generate anonymous inline boxes because they would end empty.

+ +
Example TBD
+ +

Other types of boxes

+ +

Line boxes

+ +

Line boxes are generated by the inline formatting context to represent a line of text. Inside a block box, a line box extends from one border of the box to the other. When there are floats, the line box starts at the rightmost border of the left floats and ends at the leftmost border of the right floats.

+ +

These boxes are technical, and Web authors do not usually have to bother with them.

+ +

Run-in boxes

+ +

Run-in boxes, defined using display:run-in, are boxes that are either block boxes or inline boxes, depending on the type of the following box. They can be used to create a title that runs inside its first paragraph when possible.

+ +
Note: Run-in boxes were removed from the CSS 2.1 standard, as they were insufficiently specified to allow for interoperable implementation. They may reappear in CSS3, but meanwhile, are considered experimental. They should not be used in production.
+ +

Model-induced boxes

+ +

Besides the inline and block formatting contexts, CSS specifies several additional content models that may be applied to elements. These additional models, used to describe specific layouts, may define additional box types:

+ +
    +
  • The table content model may create a table wrapper box and a table box, but also specific boxes like caption boxes.
  • +
  • The multi-column content model may create column boxes between the container box and the content.
  • +
  • The experimental grid, or flex-box content models, also create additional types of boxes.
  • +
+ +

Positioning schemes

+ +

Once boxes are generated, the CSS engine needs to position them on the layout. To do that, it uses one of the following algorithms:

+ +
    +
  • The normal flow - positions each box one after the other.
  • +
  • The floats algorithm - extracts the box from the normal flow and put it to the side of the containing box.
  • +
  • The absolute positioning scheme - positions a box within an absolute coordinate system that is established by its containing element. An absolutely positioned element can cover other elements.
  • +
+ +

Normal flow

+ +

In the normal flow, boxes are laid out one after the other. In a block formatting context, they are laid out vertically; in an inline formatting context, they are laid out horizontally. The normal flow is triggered when the CSS {{ cssxref("position") }} is set to the value static or relative, and if the CSS {{ cssxref("float") }} is set to the value none.

+ +

Example

+ +
When in the normal flow, in a block formatting context, boxes are laid vertically one after the other out.
+
+When in the normal flow, in an inline formatting context, boxes are laid horizontally one after the other out.
+ +
+

There are two sub-cases of the normal flow: static positioning and relative positioning:

+ +
    +
  • In static positioning, triggered by the value static of the {{ cssxref("position") }} property, the boxes are drawn at the exact position defined by the normal flow layout.
  • +
  • In relative positioning, triggered by the value relative of the {{ cssxref("position") }} property, the boxes are drawn with an offset defined by the {{ cssxref("top") }}, {{ cssxref("bottom") }}, {{ cssxref("left") }} and {{ cssxref("right") }} CSS properties.
  • +
+
+ +

Floats

+ +

In the float positioning scheme, specific boxes (called floating boxes or simply floats) are positioned at the beginning, or end of the current line. This leads to the property that text (and more generally anything within the normal flow) flows along the edge of the floating boxes, except if told differently by the {{ cssxref("clear") }} CSS property.

+ +

The float positioning scheme for a box is selected, by setting the {{ cssxref("float") }} CSS property on that box to a value different than none and {{ cssxref("position") }} to static or relative. If {{ cssxref("float") }} is set to left, the float is positioned at the beginning of the line box. If set to right, the float is positioned at the end of the line box. In either case, the line box is shrunk to fit alongside the float.

+ +

Absolute positioning

+ +

In the absolute positioning scheme, boxes are entirely removed from the flow and don't interact with it at all. They are positioned relative to their containing block using the {{ cssxref("top") }}, {{ cssxref("bottom") }}, {{ cssxref("left") }} and {{ cssxref("right") }} CSS properties.

+ +

An element is absolutely positioned if the {{ cssxref("position") }} is set to absolute or fixed.

+ +

With a fixed positioned element, the containing block is the viewport. The position of the element is absolute within the viewport. Scrolling does not change the position of the element.

diff --git "a/files/ru/web/css/\320\264\320\265\320\271\321\201\321\202\320\262\320\270\321\202\320\265\320\273\321\214\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" "b/files/ru/web/css/\320\264\320\265\320\271\321\201\321\202\320\262\320\270\321\202\320\265\320\273\321\214\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index da6231da1f..0000000000 --- "a/files/ru/web/css/\320\264\320\265\320\271\321\201\321\202\320\262\320\270\321\202\320\265\320\273\321\214\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Действительное значение -slug: Web/CSS/Действительное_значение -tags: - - CSS - - Guide - - Web -translation_of: Web/CSS/actual_value ---- -

{{CSSRef}}

- -

Описание

- -

Действительное значение CSS свойства - используемое после всех приближений значение. Например, браузер может отображать рамки только с целым значением пикселей и будет прининудительно округлять ширину.

- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('CSS2.1', 'cascade.html#actual-value', 'actual value')}}{{Spec2('CSS2.1')}}Изначальное определение
- -

Смотрите также

- - diff --git "a/files/ru/web/css/\320\267\320\260\320\274\320\265\321\211\320\260\320\265\320\274\321\213\320\271_\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" "b/files/ru/web/css/\320\267\320\260\320\274\320\265\321\211\320\260\320\265\320\274\321\213\320\271_\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" deleted file mode 100644 index a252cbad33..0000000000 --- "a/files/ru/web/css/\320\267\320\260\320\274\320\265\321\211\320\260\320\265\320\274\321\213\320\271_\321\215\320\273\320\265\320\274\320\265\320\275\321\202/index.html" +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Замещаемый элемент -slug: Web/CSS/Замещаемый_элемент -tags: - - CSS - - Reference - - замещаемый элемент -translation_of: Web/CSS/Replaced_element ---- -
{{CSSRef}}
- -

В CSS, замещаемый элемент — это элемент, чьё представление выходит за рамки CSS. Другими словами, это внешний объект, чьё представление независимо от модели форматирования CSS.

- -

Замещаемые элементы

- -

Типичные замещаемые элементы:

- -
    -
  • {{HTMLElement("iframe")}}
  • -
  • {{HTMLElement("video")}}
  • -
  • {{HTMLElement("embed")}}
  • -
  • {{HTMLElement("img")}}
  • -
- -

Некоторые элементы рассматриваются как замещаемые только в некоторых случаях:

- -
    -
  • {{HTMLElement("audio")}}
  • -
  • {{HTMLElement("canvas")}}
  • -
  • {{HTMLElement("object")}}
  • -
  • {{HTMLElement("applet")}}
  • -
- -

Спецификация HTML также указывает, что элемент {{HTMLElement("input")}} может быть замещаемым, поскольку элемент {{HTMLElement("input")}} с типом image является замещаемым элементом наподобие {{HTMLElement("img")}}. Однако другие элементы форм, включая другие типы элементов {{HTMLElement("input")}}, явно отнесены к незамещаемым элементам (для описания их отображения по умолчанию, которое может быть разным на разных платформах, спецификация использует термин «Виджеты»).

- -

Объекты, добавляемые с помощью CSS-свойства {{cssxref("content")}} являются анонимными замещаемыми элементами. Они «анонимные», так как они не существуют в HTML-разметке.

- -

Использование CSS с замещаемыми элементами

- -

CSS обрабатывает замещаемые элементы особым образом в некоторых случаях, например при расчёте внешних отступов и некоторых значений auto.

- -

Заметим, что у некоторых замещаемых элементов, но не у всех, есть внутренние размеры или определённая базовая линия, которая используется CSS свойствами вроде {{cssxref("vertical-align")}}.

- -

См. также

- -
    -
  • Спецификация HTML https://html.spec.whatwg.org/multipage/rendering.html#replaced-elements
  • -
  • {{CSS_key_concepts()}}
  • -
diff --git "a/files/ru/web/css/\320\277\321\201\320\265\320\262\320\264\320\276-\320\272\320\273\320\260\321\201\321\201\321\213/index.html" "b/files/ru/web/css/\320\277\321\201\320\265\320\262\320\264\320\276-\320\272\320\273\320\260\321\201\321\201\321\213/index.html" deleted file mode 100644 index 2c280be32b..0000000000 --- "a/files/ru/web/css/\320\277\321\201\320\265\320\262\320\264\320\276-\320\272\320\273\320\260\321\201\321\201\321\213/index.html" +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: Псевдоклассы -slug: Web/CSS/Псевдо-классы -tags: - - CSS - - Reference - - Псевдоклассы - - Селекторы -translation_of: Web/CSS/Pseudo-classes ---- -
{{CSSRef}}
- -

Псевдокласс в CSS — это ключевое слово, добавленное к селектору, которое определяет его особое состояние. Например, {{ Cssxref(":hover") }} может быть использован для изменения цвета кнопки при наведении курсора на неё.

- -
div:hover {
-  background-color: #F89B4D;
-}
- -

Псевдоклассы дают возможность стилизовать элемент на основе не только отношений в DOM-дереве, но и основываясь на внешних факторах, таких как история посещений (например, {{ cssxref(":visited") }}), состояние содержимого (вроде {{ cssxref(":checked") }} у некоторых элементов формы) или позиции курсора мыши (например, {{ cssxref(":hover") }} определяет, находится ли курсор мыши над элементом).

- -
-

Примечание: В отличие от псевдоклассов, псевдоэлементы могут быть использованы для стилизации определённой части элемента.

-
- -

Синтаксис

- -
selector:pseudo-class {
-  property: value;
-}
-
- -

Как и с обычными классами, можно совмещать вместе в одном селекторе любое число псевдоклассов.

- -

Список стандартных псевдоклассов

- -
-
    -
  • {{ Cssxref(":active") }}
  • -
  • {{ cssxref(':any')}}
  • -
  • {{ cssxref(':any-link')}}
  • -
  • {{ Cssxref(":checked") }}
  • -
  • {{ Cssxref(":default") }}
  • -
  • {{ Cssxref(":defined") }}
  • -
  • {{ Cssxref(":dir", ":dir()")}}
  • -
  • {{ Cssxref(":disabled") }}
  • -
  • {{ Cssxref(":empty") }}
  • -
  • {{ Cssxref(":enabled") }}
  • -
  • {{ Cssxref(":first") }}
  • -
  • {{ Cssxref(":first-child") }}
  • -
  • {{ Cssxref(":first-of-type") }}
  • -
  • {{ Cssxref(":fullscreen") }}
  • -
  • {{ Cssxref(":focus") }}
  • -
  • {{ Cssxref(":hover") }}
  • -
  • {{ Cssxref(":indeterminate") }}
  • -
  • {{ Cssxref(":in-range") }}
  • -
  • {{ Cssxref(":invalid") }}
  • -
  • {{ Cssxref(":lang", ":lang()") }}
  • -
  • {{ Cssxref(":last-child") }}
  • -
  • {{ Cssxref(":last-of-type") }}
  • -
  • {{ Cssxref(":left") }}
  • -
  • {{ Cssxref(":link") }}
  • -
  • {{ Cssxref(":not", ":not()") }}
  • -
  • {{ Cssxref(":nth-child", ":nth-child()") }}
  • -
  • {{ Cssxref(":nth-last-child", ":nth-last-child()") }}
  • -
  • {{ Cssxref(":nth-last-of-type", ":nth-last-of-type()") }}
  • -
  • {{ Cssxref(":nth-of-type", ":nth-of-type()") }}
  • -
  • {{ Cssxref(":only-child") }}
  • -
  • {{ Cssxref(":only-of-type") }}
  • -
  • {{ Cssxref(":optional") }}
  • -
  • {{ Cssxref(":out-of-range") }}
  • -
  • {{ Cssxref(":read-only") }}
  • -
  • {{ Cssxref(":read-write") }}
  • -
  • {{ Cssxref(":required") }}
  • -
  • {{ Cssxref(":right") }}
  • -
  • {{ Cssxref(":root") }}
  • -
  • {{ Cssxref(":scope") }}
  • -
  • {{ Cssxref(":target") }}
  • -
  • {{ Cssxref(":valid") }}
  • -
  • {{ Cssxref(":visited") }}
  • -
-
- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{ SpecName('Fullscreen') }}{{ Spec2('Fullscreen') }}Определён :fullscreen.
{{ SpecName('HTML WHATWG') }}{{ Spec2('HTML WHATWG') }}Нет изменений от {{ SpecName('HTML5 W3C') }}.
{{SpecName('CSS4 Selectors')}}{{Spec2('CSS4 Selectors')}}Определены :any-link, :local-link, :scope, :active-drop-target, :valid-drop-target, :invalid-drop-target, :current, :past, :future, :placeholder-shown, :user-error, :blank, :nth-match(), :nth-last-match(), :nth-column(), :nth-last-column() и :matches().
- Нет существенных изменений для псевдоклассов, определённых в {{SpecName('CSS3 Selectors')}} и {{SpecName('HTML5 W3C')}} (не рассматрия семантическое значение).
{{ SpecName('HTML5 W3C') }}{{ Spec2('HTML5 W3C') }}Определено семантическое значение в HTML контексте для  :link, :visited, :active, :enabled, :disabled, :checked и :indeterminate.
- Определены :default, :valid, :invalid, :in-range, :out-of-range, :required, :optional, :read-only, :read-write и :dir().
{{ SpecName('CSS3 Basic UI') }}{{ Spec2('CSS3 Basic UI') }}Определены :default, :valid, :invalid, :in-range, :out-of-range, :required, :optional, :read-only и :read-write, но без связанного семантического значения.
{{SpecName('CSS3 Selectors')}}{{Spec2('CSS3 Selectors')}}Определены :target, :root, :nth-child(), :nth-last-of-child(), :nth-of-type(), :nth-last-of-type(), :last-child, :first-of-type, :last-of-type, :only-child, :only-of-type, :empty и :not().
- Определён синтаксис для :enabled, :disabled, :checked и :indeterminate, но без связанного семантического значения.
- Нет значительных изменений для псевдоклассов, определённых в {{SpecName('CSS2.1')}}.
{{SpecName('CSS2.1')}}{{Spec2('CSS2.1')}}Определены :lang(), :first-child, :hover и :focus.
- Нет значительных изменений для псевдоклассов, определённых в {{SpecName('CSS1')}}.
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Определены :link, :visited и :active, но без связанного семантического значения.
- -

См. также

- - diff --git "a/files/ru/web/css/\321\200\320\260\320\267\320\274\320\265\321\200/index.html" "b/files/ru/web/css/\321\200\320\260\320\267\320\274\320\265\321\200/index.html" deleted file mode 100644 index 4fd88f8cc2..0000000000 --- "a/files/ru/web/css/\321\200\320\260\320\267\320\274\320\265\321\200/index.html" +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: -slug: Web/CSS/размер -tags: - - CSS - - CSS Тип Данных - - Величина - - Разметка - - длина -translation_of: Web/CSS/length ---- -
{{CSSRef}}
- -

CSS тип данных <length> представляет единицу длины. Длина может быть использована в таких свойствах CSS как {{Cssxref("width")}}, {{Cssxref("height")}}, {{Cssxref("margin")}}, {{Cssxref("padding")}}, {{Cssxref("border-width")}}, {{Cssxref("font-size")}}, и {{Cssxref("text-shadow")}}.

- -
-

Обратите внимание: Хоть значения {{cssxref("<percentage>")}} также определяют размеры и могут использоваться в некоторых свойствах, принимающих значения типа <length>, они не являются <length> значениями.

-
- -

Синтаксис

- -

Тип данных <length> состоит из {{cssxref("<number>")}}, за которым следует одна из единиц измерения, перечисленных ниже. Как и у любых единиц измерения CSS между числом и единицей нет знака пробела. После числа 0 единица измерения необязательна.

- -
-

Обратите внимание: Некоторые свойства допускают использование отрицательных значений <length>, а некоторые нет.

-
- -

Единицы измерения

- -

Относительные единицы измерения

- -

Относительные единицы измерения представляют расстояние, определённое какой-либо другой величиной. В зависимости от единицы, это может быть размер определённого символа, высота строки или размер {{glossary("viewport")}}.

- -
Единицы, зависящие от шрифта
- -

Единицы, зависящие от шрифта, определяют значение <length>, используя размер какого-либо символа или характеристики шрифта, который применяется к элементу или его родителю.

- -
-

Обратите внимание: Эти единицы, особенно em и rem, часто используются для создания адаптивных разметок, которые сохраняют вертикальную структуру страницы даже если пользователь изменяет размер шрифта.

-
- -
-
cap {{experimental_inline}}
-
Представляет высоту заглавных букв в шрифте, применённом к элементу.
-
ch
-
Представляет ширину символа "0" (ноль, символ Юникод U+0030) в шрифте, применённом к элементу.
-
em
-
Представляет подсчитанный размер шрифта элемента. Если используется в свойстве {{Cssxref("font-size")}}, представляет унаследованный размер шрифта.
-
ex
-
Представляет x-height (обычно высоту буквы x) в шрифте, применённом к элементу. В шрифтах с буквой x это обычно высота букв в нижнем регистре; во многих шрифтах 1ex ≈ 0.5em.
-
ic {{experimental_inline}}
-
Равна используемой в шрифте ширине символа "" (ККЯ, символ "вода", U+6C34).
-
lh {{experimental_inline}}
-
Равна рассчитанному значению свойства {{Cssxref("line-height")}}, переведённому в абсолютные единицы измерения.
-
rem
-
Представляет размер шрифта корневого элемента (обычно {{HTMLElement("html")}}). Когда используется в свойстве {{Cssxref("font-size")}} корневого элемента, представляет значение по умолчанию (в большинстве браузеров 16px, но настройки пользователя могут переопределить это значение).
-
rlh {{experimental_inline}}
-
Равна рассчитанному значению свойства {{Cssxref("line-height")}} корневого эдемента (обычно {{HTMLElement("html")}}), переведённому в абсолютные единицы измерения. Когда используется в свойстве {{Cssxref("font-size")}} корневого элемента, представляет значение по умолчанию.
-
- -
Единицы, зависящие от размеров экрана
- -

Эти единицы определяют значение <length> относительно размеров экрана, то есть видимой части документа. эти единицы недопустимы в блоках {{cssxref("@page")}}.

- -
-
vh
-
Равна 1% высоты блока содержимого.
-
vw
-
Равна 1% ширины блока содержимого.
-
vi {{experimental_inline}}
-
Равна 1% размера блока содержимого по направлению выстраивания строчных элементов.
-
vb {{experimental_inline}}
-
Равна 1% размера блока содержимого по направлению выстраивания блочных элементов.
-
vmin
-
Равна vh или vw в зависимости от того, что из них меньше.
-
vmax
-
Равна vh или vw в зависимости от того, что из них больше.
-
- -

Абсолютные единицы измерения

- -

Абсолютные единицы измерения представляют физические расстояния, когда известны физические свойтсва устройства вывода. Одна из единиц привязывается к физической единице, а все остальные к ней. Привязка делается по-разному для устройств с низким разрешением, таких как экраны, и высоким, таких как принтеры.

- -

Для устройств с маленьким dpi (dots per inch — количество точек на дюйм) единица измерения px представляет физический пиксель; остальные единицы определяются относительно него. Таким образом, 1in определяется как 96px, что равно 72pt. Последствием такого способа определения является то, что длины, описанные в дюймах (in), сантиметрах (cm) или миллиметрах (mm) необязательно равны одноимённым физическим единицам.

- -

Для устройств с высоким dpi дюймы (in),сантиметры (cm) и миллиметры (mm) такие же, как и соответствующие физические единицы. Таким образов, единица px определяется относительно их (1/96 одного дюйма).

- -
-

Обратите внимание: Многие пользователи увеличивают стандартный размер шрифта браузера для удобства чтения. Длины, заданные абсолютными единицами могут вызвать проблемы с доступностью, так как они привязаны к физическим величинам и не масштабируются при изменении настроек. Поэтому предпочтительнее использовать относительные единицы (такие как em или rem) в свойстве font-size.

-
- -
-
px
-
Один пиксель. Для устройств с дисплеев традиционно представляет одну точку. Тем не менее, на принтерах и экранах с высоким разрешением один пиксель CSS равен нескольким пикселям дисплея. 1px = 1/96  от 1in.
-
cm
-
Один сантиметр. 1cm = 96px/2.54.
-
mm
-
Один миллиметр. 1mm = 1/10 от 1cm.
-
Q {{experimental_inline}}
-
Четверть миллиметра. 1Q = 1/40 от 1cm.
-
in
-
Один дюйм. 1in = 2.54cm = 96px.
-
pc
-
Одна пайка. 1pc = 12pt = 1/6 от 1in.
-
pt
-
Одна точка. 1pt = 1/72 от1in.
-
mozmm {{non-standard_inline}}, удалена в Firefox 59
-
Экспериметальная единица, которая равна одному физическому миллиметру вне зависимости от размера и разрешения экрана. Такая единица требуется очень редко, но может понадобиться, особенно на маленьких устройствах.
-
- -

Интерполяция

- -

При анимации значения <length> интерполируются как реальные числа с плавающей запятой. Интерполяция происходит над рассчитанным значением. Скорость интерполяции определяется временной функцией анимации.

- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS4 Values', '#lengths', '<length>')}}{{Spec2('CSS4 Values')}}Добавлены единицы vi, vb, ic, lh, и rlh.
{{SpecName('CSS3 Values', '#lengths', '<length>')}}{{Spec2('CSS3 Values')}}Добавлены единицы ch, rem, vw, vh, vmin, vmax, и Q.
{{SpecName('CSS2.1', 'syndata.html#length-units', '<length>')}}{{Spec2('CSS2.1')}}Явно определены единицы empt, pc, и px.
{{SpecName('CSS1', '#length-units', '<length>')}}{{Spec2('CSS1')}}Первое определение. Неявно определены единицы empt, pc, и px.
- -

Поддержка браузерами

- - - -

{{Compat("css.types.length")}}

diff --git "a/files/ru/web/css/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\201/index.html" "b/files/ru/web/css/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\201/index.html" deleted file mode 100644 index 1adfb2fb04..0000000000 --- "a/files/ru/web/css/\321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\201/index.html" +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Синтаксис -slug: Web/CSS/Синтаксис -translation_of: Web/CSS/Syntax ---- -
{{cssref}}
- -
Основная задача Каскадных Стилей — это рассказать движку браузера, как отрисовать элементы страницы — каким цветом, как позиционировать их на странице, как украшать, и так далее. Синтаксис CSS построен следуя этой идее, и состоит из следующих основных блоков:
- -
- -
    -
  • Свойство (property) — идентификатор действия, которое будет применено к элементу (например, цвет, или размер границы, и т.д.).
  • -
  • Значение (value) — описывает, как именно свойство будет обработано браузером. Каждое свойство имеет набор допустимых значений, определенных формальными правилами, а также семантический смысл, реализованный движком браузера.
  • -
- -

Объявления CSS

- -

Задание CSS свойствам определенных значений — это основная функция CSS. Пара свойство-значение называется объявлением. Работа CSS движка заключается в поиске соответсвий между объявлениями стилей и элементом на странице, чтобы правильно отобразить и форматировать этот элемент.

- -

И свойство, и значения регистрозависимы. Пара свойство-значение разделяется двоеточием, ':' (U+003A COLON), а пробелы до, между и после свойства или значения игнорируются.

- -

css syntax - declaration.png

- -

В CSS существует более ста различных свойств, и бесконечное число допустимых значений. Не все пары свойств и значений допускаются, и каждое свойство определяет, каковы допустимые значения. Когда значение не подходит для данного свойства, объявление считается недействительной и целиком игнорируются CSS-движком.

- -

Блоки объявлений CSS

- -

Объявления группируются в блоки, структура которых состоит из открывающейся , '{' (U+007B LEFT CURLY BRACKET), и закрывающейся, '}' (U+007D RIGHT CURLY BRACKET) фигурных скобок.

- -

css syntax - block.png

- -

Такие блоки называются блоками объявлений, и объявления в них разделяются точкой с запятой, ';' (U+003B SEMICOLON). Блок объявлений может быть пустым, т.е. не содержать объявлений. Пробелы между объявлениями игнорируются. Последнее объявление блока не нуждается в точке с запятой, хотя считается хорошим тоном добавить ее для того, чтобы не допустить упущение этого знака при добавлении другого объявления в будущем.

- -

css syntax - declarations block.png

- -
Содержимое блока объявлений CSS, т. е. объявления, разделенные точкой с запятой. Блок объявлений может быть помещен внутри атрибута style HTML-документа без фигурных скобок.
- -

CSS rulesets

- -

If style sheets could only apply a declaration to each element of a Web page, they would be pretty useless. The real goal is to apply different declarations to different parts of the document.

- -

CSS allows this by associating conditions with declarations blocks. Each (valid) declaration block is preceded by a selector which is a condition selecting some elements of the page. The pair selector-declarations block is called a ruleset, or often simply a rule.

- -

css syntax - ruleset.png

- -

As an element of the page may be matched by several selectors, and therefore by several rules eventually containing a given property several times, with different values, the CSS standard defines which one has precedence over the other and must be applied: this is called the cascade algorithm.

- -
It is important to note that even if a ruleset characterized by a group of selectors is a kind of shorthand replacing rulesets with a single selector each, this doesn't apply to the validity of the ruleset itself.
-
-This leads to an important consequence: if one single basic selector is invalid, like when using an unknown pseudo-element or pseudo-class, the whole selector is invalid and therefor the entire rule is ignored (as invalid too).
- -

CSS statements

- -

Rulesets are the main building blocks of a style sheet, which often consists of only a big list of them. But there is other information that a Web author wants to convey in the style sheet, like the character set, other external style sheets to import, font face or list counter descriptions and many more. It will use other and specific kinds of statements to do that.

- -

A statement is a building block that begins with any non-space characters and ends at the first closing brace or semi-colon (outside a string, non-escaped and not included into another {}, () or [] pair).

- -

css syntax - statements Venn diag.png

- -

There are different kinds of statements:

- -
    -
  • Rulesets (or rules) that, as seen, associate a collection of CSS declarations to a condition described by a selector.
  • -
  • At-rules that start with an at sign, '@' (U+0040 COMMERCIAL AT), followed by an identifier and then continuing up the end of the statement, that is up to the next semi-colon (;) outside of a block, or the end of the next block. Each type of at-rules, defined by the identifier, may have its own internal syntax, and semantics of course. They are used to convey meta-data information (like {{ cssxref("@charset") }} or {{ cssxref("@import") }}), conditional information (like {{ cssxref("@media") }} or {{ cssxref("@document") }}), or descriptive information (like {{ cssxref("@font-face") }}).
  • -
- -

Any statement which isn't a rule or an at-rule is invalid and ignored.

- -

There is another group of statements, the nested statements, these are statements that can be used in a specific subset of at-rules, the conditional group rules. These statements only apply if a specific condition is matched: the @media at-rule content is applied only if the device on which runs the browser matches the expressed condition; the @document at-rule content is applied only if the current page matches some conditions, and so on. In CSS1 and CSS2.1, only rulesets could be used inside a conditional group rules. That was very restrictive and this restriction was lifted in CSS Conditionals Level 3. Now, though it still is experimental and not supported by every browser, a conditional group rules can contain a wider range of content, rulesets but also some, but not all, at-rules.

- -

See also

- -
    -
  • {{ CSS_key_concepts()}}
  • -
diff --git "a/files/ru/web/css/\321\201\320\277\320\276\321\201\320\276\320\261_\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\321\217/index.html" "b/files/ru/web/css/\321\201\320\277\320\276\321\201\320\276\320\261_\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\321\217/index.html" deleted file mode 100644 index dcf1440cb5..0000000000 --- "a/files/ru/web/css/\321\201\320\277\320\276\321\201\320\276\320\261_\321\200\320\260\321\201\320\277\320\276\320\273\320\276\320\266\320\265\320\275\320\270\321\217/index.html" +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Способ разметки -slug: Web/CSS/Способ_расположения -tags: - - CSS -translation_of: Web/CSS/Layout_mode ---- -

CSS способ разметки (или раскладки, или англ. layout) — это алгоритм определения позиции и размеров блоков, основанный на способе, которым они взаимодействуют с родственными блоками. Существует несколько типов разметки:

- -
    -
  • Обычная (Normal Flow) — все элементы являются частью обычного потока до тех пор, пока вы не переопределите это каким-либо образом. Обычный layout включает в себя блочную раскладку, созданную для расположения отдельных блоков, таких как параграфы, и линейную, для строчных элементов;
  • -
  • Табличная, спроектированная для расположения таблиц;
  • -
  • Float layout — для возможности обозначить элементы плавающими. Такой элемент начинает позиционироваться слева или справа отностительно содержимого обычного потока, элементы которого начинают обтекать него;
  • -
  • Позиционированная — для позиционирования элементов без особого взаимодействия с другими элементами;
  • -
  • Множественные столбцы — для расположения контента колонками, как в газетах;
  • -
  • Флексбокс (CSS Flexible Box Layout) — для расположения сложных страниц, которые плавно могут изменять свой размер; {{ experimental_inline() }}
  • -
  • Сеточная — для расположения элементов относительно фиксированной сетки. {{ experimental_inline() }}
  • -
- -
-

Примечание: не все CSS свойства применимы ко всем способам разметки. Большинство из них применяются к одному или двум из них и не действуют, если применяются на элементе, участвующем в другом режиме разметки.

-
- -

Смотрите также

- -
    -
  • {{ CSS_key_concepts() }}
  • -
diff --git "a/files/ru/web/css/\321\202\320\270\321\205\320\270\320\271/index.html" "b/files/ru/web/css/\321\202\320\270\321\205\320\270\320\271/index.html" deleted file mode 100644 index 1db7dd50b5..0000000000 --- "a/files/ru/web/css/\321\202\320\270\321\205\320\270\320\271/index.html" +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Комментарии -slug: Web/CSS/Тихий -tags: - - Beginner - - CSS - - CSS Reference - - Комментарии - - Новичку - - Руководство -translation_of: Web/CSS/Comments ---- -
{{CSSRef}}
- -

Описание

- -

Комментарии используются для добавления поясняющих заметок или для того, чтобы предотвратить интеграцию части кода в браузер.

- -

Синтаксис

- -
/* Комментарий */
- -

Примеры

- -
/* Однострочный комментарий */
-
-/*
-Комментарий
-который содержит
-несколько
-строк
-*/
-
- -

Замечания

- -

Данный /* */ синтаксис комментария используется для обоих вариантов, и однострочного и многострочного комментария. Нет других способов добавить комментарий во внешнюю таблицу стилей. Также, когда используется элемент <style>, вы можете использовать <!-- -->, чтобы спрятать CSS от старых браузеров, но это не рекомендуется. Как и в большинстве языков программирования, которые используют синтаксис комментариев /* */ , комментарии нельзя вкладывать друг в друга. Другими словами, данная часть синтаксиса */, которая следует за /* закрывает комментарий.

- -

Спецификации

- - - -

Смотрите также

- - diff --git "a/files/ru/web/css/\321\203\320\272\320\260\320\267\320\260\320\275\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" "b/files/ru/web/css/\321\203\320\272\320\260\320\267\320\260\320\275\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" deleted file mode 100644 index 4f143afb74..0000000000 --- "a/files/ru/web/css/\321\203\320\272\320\260\320\267\320\260\320\275\320\275\320\276\320\265_\320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265/index.html" +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Указанное значение -slug: Web/CSS/Указанное_значение -tags: - - CSS - - CSS Reference -translation_of: Web/CSS/specified_value ---- -

{{CSSRef}}

- -

Указанное значение CSS свойства может устанавливаться одним из 3 следующих способов.

- -
    -
  1. Если в таблице стилей документа указано значение свойства, которое будет использоваться. Например, если свойство {{cssxref("color")}} устанавливается в green, то цвет текста соответствующего элемента становится зелёным.
  2. -
  3. Если в таблице стилей документа указано значение, которое может наследоваться от родительского элемента (если возможно). Например, у нас есть параграф ({{HTMLElement("p")}}) внутри {{HTMLElement("div")}}, а к {{HTMLElement("div")}} применено CSS свойство font со значением "Arial", а у {{HTMLElement("p")}} не установлено свойство font, то он унаследует значение шрифта "Arial".
  4. -
  5. Если не выполняется не то, не другое, начальное значение элемента применяется из CSS спецификации.
  6. -
- -

Спецификации

- - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName("CSS2.1", "cascade.html#specified-value", "cascaded value")}}{{Spec2("CSS2.1")}}Изначальное определение
- -

Смотрите также

- - diff --git a/files/ru/web/events/abort/index.html b/files/ru/web/events/abort/index.html deleted file mode 100644 index d8029e2378..0000000000 --- a/files/ru/web/events/abort/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: abort -slug: Web/Events/abort -tags: - - Событие -translation_of: Web/API/HTMLMediaElement/abort_event -translation_of_original: Web/Events/abort ---- -

Событие "abort" вызывается когда загрузка какого-либо ресурса была прервана.

- -

Общая информация

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
{{domxref("UIEvent")}} если событие сгенерировано из пользовательского интерфейса, иначе {{domxref("Event")}}.
-
Всплывание
-
Нет
-
Отменяемость
-
Нет
-
Цель
-
{{domxref("window")}}, {{domxref("Element")}}
-
Действие по умолчанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СвойствоТипОписание
target {{readonlyInline}}EventTargetЦель события (самый вышележащий элемент в DOM дереве).
type {{readonlyInline}}DOMStringТип события.
bubbles {{readonlyInline}}BooleanПоднимается ли событие вверх как принято или нет.
cancelable {{readonlyInline}}BooleanЯвляется ли событие отменяемым или нет?
view {{readonlyInline}}WindowProxydocument.defaultView (свойство window  объекта document)
detail {{readonlyInline}}long (float)0.
diff --git a/files/ru/web/events/blur/index.html b/files/ru/web/events/blur/index.html deleted file mode 100644 index a29fa0debc..0000000000 --- a/files/ru/web/events/blur/index.html +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: blur (event) -slug: Web/Events/blur -tags: - - DOM - - DOM Events -translation_of: Web/API/Element/blur_event ---- -

Событие blur вызывается когда элемент теряет фокус. Главное отличие между этим событием и  focusout только в том что у последнего есть фаза всплытия.

- -

Основная информация

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
{{domxref("FocusEvent")}}
-
Всплытие
-
Нет
-
Отменяемый
-
Нет
-
Цель
-
Элемент
-
Действие по умолчанию
-
Нет
-
- -

{{NoteStart}}Значение {{domxref("Document.activeElement")}} меняется в зависимости от браузера во время выполнения этого события ({{bug(452307)}}): IE10 устанавливает его к элементу на который будет перемещен фокус, в то время как Firefox и Chrome обычно устанавливают его к body документа{{NoteEnd}}

- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target (DOM element)
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)null
- -

Делегирование события

- -

Есть два способа реализовать делегирование этого события: использовать событие focusout в браузерах которые поддерживают его (все браузеры, Firefox с 52+), или установить параметр "useCapture" метода addEventListener на true:

- -

HTML Content

- -
<form id="form">
-  <input type="text" placeholder="text input">
-  <input type="password" placeholder="password">
-</form>
- -

JavaScript Content

- -
var form = document.getElementById("form");
-form.addEventListener("focus", function( event ) {
-  event.target.style.background = "pink";
-}, true);
-form.addEventListener("blur", function( event ) {
-  event.target.style.background = "";
-}, true);
- -

{{EmbedLiveSample('Event_delegation')}}

- -

Совместимость с браузерами

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatVersionUnknown}}[1]612.15.1
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.053{{CompatUnknown}}10.012.15.1
-
- -

[1] В Gecko до 24 {{geckoRelease(24)}} интефейс для этого события был {{domxref("Event")}}, не {{domxref("FocusEvent")}}. Смотреть ({{bug(855741)}}).

- -

Похожие события

- -
    -
  • {{event("focus")}}
  • -
  • {{event("blur")}}
  • -
  • {{event("focusin")}}
  • -
  • {{event("focusout")}}
  • -
diff --git a/files/ru/web/events/domcontentloaded/index.html b/files/ru/web/events/domcontentloaded/index.html deleted file mode 100644 index 7702dcfd24..0000000000 --- a/files/ru/web/events/domcontentloaded/index.html +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: DOMContentLoaded -slug: Web/Events/DOMContentLoaded -tags: - - события -translation_of: Web/API/Window/DOMContentLoaded_event ---- -

Событие DOMContentLoaded происходит когда весь HTML был полностью загружен и пройден парсером, не дожидаясь окончания загрузки таблиц стилей, изображений и фреймов. Значительно отличающееся от него событие load используется для отслеживания только полностью загруженной страницы. Широко распространённой ошибкой является использование load в ситуации когда DOMContentLoaded является более подходящим, будьте внимательны.

- -

{{Note("Синхронный JavaScript останавливает парсинг DOM.")}}

- -

{{Note("Существуют различные библиотеки, как общего назначения так и специализированные, предлагающие кросс-браузерные методы, позволяющие определить, что DOM готов к использованию.")}}

- -

Ускорение работы

- -

Если вы хотите чтобы DOM был пройден парсером насколько возможно быстро, сразу после запроса пользователем страницы, вы можете попробовать выполнять JavaScript асинхронно и оптимизировать загрузку таблиц стилей которые обычно замедляют загрузку документа поскольку загружаясь одновременно "крадут" трафик у основного документа.

- -

Основная информация

- -
-
Спецификация
-
HTML5
-
Интерфейс 
-
Event
-
Всплывает
-
Да
-
Отменяемое
-
Да (несмотря на то, что в спецификации указано как простое событие, которое не является отменяемым)
-
Цель 
-
Document
-
Default Action
-
Нет.
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
- -

Пример

- -
<script>
-  document.addEventListener("DOMContentLoaded", function(event) {
-    console.log("DOM fully loaded and parsed");
-  });
-</script>
-
- -
<script>
-  document.addEventListener("DOMContentLoaded", function(event) {
-    console.log("DOM fully loaded and parsed");
-  });
-
-for(var i=0; i<1000000000; i++)
-{} // this synchronous script is going to delay parsing of the DOM. So the DOMContentLoaded event is going to launch later.
-</script>
-
- -

Поддержка браузерами

- -

{{CompatibilityTable}}

- - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка1.0[1]{{CompatGeckoDesktop("1")}}[1]9.0[2]9.03.1[1]
- - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatVersionUnknown}}[1]{{CompatGeckoMobile("1")}}[1]{{CompatUnknown}}[2]{{CompatVersionUnknown}}{{CompatVersionUnknown}}[1]
- -

[1] Всплытие для этого события поддерживается как минимум с версий Gecko 1.9.2, Chrome 6, и Safari 4.

- -

[2] Internet Explorer 8 поддерживает событие readystatechange, которое можно использовать для определения готовности DOM. В более ранних версиях Internet Explorer,это событие можно определить циклическим выполнением document.documentElement.doScroll("left");, это событие будет выбрасывать ошибку если DOM не готов.

- -

Связанные события

- -
    -
  • {{event("DOMContentLoaded")}}
  • -
  • {{event("readystatechange")}}
  • -
  • {{event("load")}}
  • -
  • {{event("beforeunload")}}
  • -
  • {{event("unload")}}
  • -
diff --git a/files/ru/web/events/error/index.html b/files/ru/web/events/error/index.html deleted file mode 100644 index 787fb9a4fa..0000000000 --- a/files/ru/web/events/error/index.html +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: error -slug: Web/Events/error -tags: - - DOM - - UI события - - Видео - - Запись - - Медия - - Обработка ошибок - - Ошибки - - Событие - - аудио - - события -translation_of: Web/API/Element/error_event ---- -

Событие error возникает, когда произошла какая-либо ошибка. Точные обстоятельства могут быть различными, потому что события с этим именем используются множеством различных API.

- -

Общая информация

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
{{domxref("UIEvent")}} если создается элементом пользовательского интерфейса, {{domxref("MediaRecorderErrorEvent")}} если генерируется API записи MediaStream, и {{domxref("Event")}} иначе.
-
Вплывающее
-
Нет
-
Отменяемое
-
Нет
-
Цель
-
Элемент
-
Действие по умолчанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}EventTargetЦель события (наиболее верхлежащий элемент в DOM дереве).
type {{readonlyInline}}DOMStringТип события.
bubbles {{readonlyInline}}BooleanЯвляется ли событие вплывающим в стандартных условиях или нет.
cancelable {{readonlyInline}}BooleanЯвляется ли событие отменяемым или нет.
view {{readonlyInline}}WindowProxydocument.defaultView (свойство window объекта document)
detail {{readonlyInline}}long (float)0.
- -

Для MediaStream Recording событий

- -

Эти события типа {{domxref("MediaRecorderErrorEvent")}}.

- -

{{page("/en-US/docs/Web/API/MediaRecorderErrorEvent", "Properties")}}

- -

Смотрите также

- -
-
{{domxref("GlobalEventHandlers.onerror")}}
-
События отсылаются в {{domxref("Window.onerror")}} и {{domxref("Element.onerror")}}
-
{{domxref("HTMLMediaElement.onerror")}}
-
События отсылаются в {{domxref("HTMLMediaElement")}}, включая {{HTMLElement("audio")}} и {{HTMLElement("video")}}
-
{{domxref("MediaRecorder.onerror")}}
-
События отсылаются в {{domxref("MediaRecorder.onerror")}}, типа {{domxref("MediaRecorderErrorEvent")}}
-
diff --git a/files/ru/web/events/focusin/index.html b/files/ru/web/events/focusin/index.html deleted file mode 100644 index 02f27b66fb..0000000000 --- a/files/ru/web/events/focusin/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: focusin -slug: Web/Events/focusin -translation_of: Web/API/Element/focusin_event ---- -

Событие focusin срабатывает, когда элемент получает фокус. Главное отличие от focus в том, что последний не всплывает.

- -

Общая информация

- -
-
Specification
-
DOM L3
-
Interface
-
{{domxref("FocusEvent")}}
-
Bubbles
-
Yes
-
Cancelable
-
No
-
Target
-
Element
-
Default Action
-
None.
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target losing focus.
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)Event target receiving focus.
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatNo}}[1]{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatNo}}[1]{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
-
- -

[1] Событие пока что не поддерживается в Firefox, см. {{Bug("687787")}}. Вместо него можно использовать событие focus, которое совместимо с делегированием событий.

- - - -
    -
  • {{event("focus")}}
  • -
  • {{event("blur")}}
  • -
  • {{event("focusin")}}
  • -
  • {{event("focusout")}}
  • -
diff --git a/files/ru/web/events/focusout/index.html b/files/ru/web/events/focusout/index.html deleted file mode 100644 index 742f52af03..0000000000 --- a/files/ru/web/events/focusout/index.html +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: focusout -slug: Web/Events/focusout -translation_of: Web/API/Element/focusout_event ---- -

Событие focusout вызывается перед потерей элементом фокуса. Главное отличие между этим событием и blur в том, что у последнего нет фазы всплытия.

- -

 

- -

Основная информация

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
{{domxref("FocusEvent")}}
-
Всплытие
-
Да
-
Отменяемый
-
Нет
-
Цель
-
Элемент
-
Действие по умолчанию
-
Нет.
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}Цель события, теряющая фокус.
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Всплывает ли событие при нормальных условиях.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM-элемент)Цель события, получающая фокус.
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoDesktop(52)}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile(52)}}{{CompatVersionUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
-
- - - -
    -
  • {{event("focus")}}
  • -
  • {{event("blur")}}
  • -
  • {{event("focusin")}}
  • -
diff --git a/files/ru/web/events/load/index.html b/files/ru/web/events/load/index.html deleted file mode 100644 index a8d456806d..0000000000 --- a/files/ru/web/events/load/index.html +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: load -slug: Web/Events/load -translation_of: Web/API/Window/load_event ---- -

Событие load происходит когда ресурс и его зависимые ресурсы закончили загружаться.

- -

General info

- -
-
Спецификация
-
DOM L3
-
Интерфейс
-
UIEvent
-
Всплывает
-
Да
-
Отменяемое
-
Нет
-
Цель
-
Window
-
Default Action
-
Нет.
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}EventTargetThe event target (the topmost target in the DOM tree).
type {{readonlyInline}}DOMStringThe type of event.
bubbles {{readonlyInline}}BooleanWhether the event normally bubbles or not.
cancelable {{readonlyInline}}BooleanWhether the event is cancellable or not.
view {{readonlyInline}}WindowProxydocument.defaultView (window of the document)
detail {{readonlyInline}}long (float)0.
- -

Пример

- -
<script>
-  window.addEventListener("load", function(event) {
-    console.log("All resources finished loading!");
-  });
-</script>
-
- -

 

- -

Связанные события

- -
    -
  • {{event("DOMContentLoaded")}}
  • -
  • {{event("readystatechange")}}
  • -
  • {{event("load")}}
  • -
  • {{event("beforeunload")}}
  • -
  • {{event("unload")}}
  • -
diff --git a/files/ru/web/events/loadstart/index.html b/files/ru/web/events/loadstart/index.html deleted file mode 100644 index b725b05b30..0000000000 --- a/files/ru/web/events/loadstart/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: loadstart -slug: Web/Events/loadstart -translation_of: Web/API/XMLHttpRequest/loadstart_event ---- -

Событие loadstart происходит, когда начинается загрузка.

- -

Общая информация

- -
-
Спецификация
-
Progress
-
Интерфейс
-
ProgressEvent
-
Распространяется
-
Нет
-
Отменяемое
-
Нет
-
Цель
-
Element
-
Действие по умолчанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
lengthComputable {{readonlyInline}}{{jsxref("Boolean")}}Specifies whether or not the total size of the transfer is known. Read only.
loaded {{readonlyInline}}unsigned long (long)The number of bytes transferred since the beginning of the operation. This doesn't include headers and other overhead, but only the content itself. Read only.
total {{readonlyInline}}unsigned long (long)The total number of bytes of content that will be transferred during the operation. If the total size is unknown, this value is zero. Read only.
- -

Связанные свойства

- -
    -
  • {{event("loadstart")}}
  • -
  • {{event("progress")}}
  • -
  • {{event("error")}}
  • -
  • {{event("abort")}}
  • -
  • {{event("load")}}
  • -
  • {{event("loadend")}}
  • -
- -

См. также

- - diff --git a/files/ru/web/events/readystatechange/index.html b/files/ru/web/events/readystatechange/index.html deleted file mode 100644 index 5a268b033f..0000000000 --- a/files/ru/web/events/readystatechange/index.html +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: readystatechange -slug: Web/Events/readystatechange -tags: - - события -translation_of: Web/API/Document/readystatechange_event ---- -

{{ApiRef}}

- -

Событие readystatechange срабатывает, когда изменяется атрибут документа readyState.

- -

Основная информация

- -
-
Спецификация
-
HTML5
-
 
-
Интерфейс
-
Event
-
Всплывает
-
Нет
-
Отменяемое
-
Нет
-
Цель
-
Document
-
Действие по умолчаанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СвойствоТипОписание
target {{readonlyInline}}{{domxref("EventTarget")}}Цель события (Самая верхняя цель в дереве DOM).
type {{readonlyInline}}{{domxref("DOMString")}}Тип события.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Всплывает ли событие.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Возможно ли отменить событие.
- -

Примеры

- -
document.readyState === "complete";
-// true
-
-
-// Альтернатива DOMContentLoaded
-document.onreadystatechange = function () {
-    if (document.readyState === "interactive") {
-        initApplication();
-    }
-}
-
- -

Поддержка браузерами

- -

Данное событие давно поддерживается Internet Explorer и может быть использовано в качестве альтернативы событию DOMContentLoaded (см. примечание [2] в разделе  Поддержка браузерами).

- -

Связанные события

- -
    -
  • {{event("DOMContentLoaded")}}
  • -
  • {{event("readystatechange")}}
  • -
  • {{event("load")}}
  • -
  • {{event("beforeunload")}}
  • -
  • {{event("unload")}}
  • -
diff --git a/files/ru/web/events/transitionend/index.html b/files/ru/web/events/transitionend/index.html deleted file mode 100644 index dfb8542da6..0000000000 --- a/files/ru/web/events/transitionend/index.html +++ /dev/null @@ -1,165 +0,0 @@ ---- -title: transitionend -slug: Web/Events/transitionend -tags: - - CSS -translation_of: Web/API/HTMLElement/transitionend_event ---- -

Событие transitionend срабатывает, когда CSS transition закончил свое выполнение. В случае, когда анимация удаляется до ее завершения(например, если transition-property [en-US] удаляется), то событие не срабатывает.

- -

Общая информация

- -
-
Интерфейс
-
{{domxref("TransitionEvent")}}
-
Всплывает
-
Да
-
Отменяемое
-
Да
-
Элемент
-
{{domxref("document")}}, {{domxref("element")}}
-
Действие по умолчанию
-
Нет
-
- -

Свойства

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
propertyName {{readonlyInline}}{{domxref("DOMString")}}The name of the CSS property associated with the transition.
elapsedTime {{readonlyInline}}FloatThe amount of time the transition has been running, in seconds, as of the time the event was generated. This value is not affected by the value of transition-delay.
pseudoElement {{readonlyInline}}{{domxref("DOMString")}}The name (beginning with two colons) of the CSS pseudo-element on which the transition occured (in which case the target of the event is that pseudo-element's corresponding element), or the empty string if the transition occurred on an element (which means the target of the event is that element).
- -

Пример

- -
/*
- * Прослушивать событие transitionend на определенном элементе, т.е. #slidingMenu
- * Затем, вызвать определенную функцию, т.е. showMessage()
- */
-function showMessage() {
-    alert('Transition закончил свое выполнение');
-}
-
-var element = document.getElementById("slidingMenu");
-element.addEventListener("transitionend", showMessage, false);
-
- -

Спецификация

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("CSS3 Transitions", "#transition-events", "transitionend")}}{{ Spec2('CSS3 Transitions') }}Initial definition.
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support1.0 as webkitTransitionEnd{{ CompatGeckoDesktop("2.0") }}1010.5 as oTransitionEnd
- 12 as otransitionend
- 12.10 as transitionend
3.2 as webkitTransitionEnd
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support2.1 as webkitTransitionEnd{{ CompatGeckoMobile("2.0") }}{{ CompatUnknown() }}10 as oTransitionEnd
- 12 as otransitionend
- 12.10 as transitionend
3.2 as webkitTransitionEnd
-
- -

Также

- -
    -
  • The {{ domxref("TransitionEvent") }} interface and the transitionend event.
  • -
diff --git a/files/ru/web/events/unhandledrejection/index.html b/files/ru/web/events/unhandledrejection/index.html deleted file mode 100644 index 5248e75748..0000000000 --- a/files/ru/web/events/unhandledrejection/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: unhandledrejection -slug: Web/Events/unhandledrejection -translation_of: Web/API/Window/unhandledrejection_event ---- -

Событие unhandledrejection происходит, когда {{jsxref("Promise")}} завершен с ошибкой, но на данную ошибку не установлен обработчик.

- - - - - - - - - - - - - - - - - - - - -
ВсплытиеНет
Возможность отменыНет
Target objectsdefaultView
Интерфейс{{domxref("PromiseRejectionEvent")}}
- -

Пример

- -
window.addEventListener("unhandledrejection", function (event) {
-  console.warn("Внимание: Необработанная ошибка Promise. Позор вам! Причина: "
-               + event.reason);
-});
-
- -

Inheritance

- -

Событие unhandledrejection реализует {{domxref("PromiseRejectionEvent")}} интерфейс, который наследуется от {{domxref("Event")}}. Вы можете использовать свойства и методы, определенные в данных интерфейсах.

- -

{{InheritanceDiagram('','','', 'PromiseRejectionEvent')}}

- -

Смотрите также

- -
    -
  • {{Event("rejectionhandled")}}
  • -
  • {{domxref("PromiseRejectionEvent")}}
  • -
  • {{domxref("Promise")}}
  • -
diff --git a/files/ru/web/guide/ajax/getting_started/index.html b/files/ru/web/guide/ajax/getting_started/index.html new file mode 100644 index 0000000000..e06b408228 --- /dev/null +++ b/files/ru/web/guide/ajax/getting_started/index.html @@ -0,0 +1,258 @@ +--- +title: С чего начать +slug: Web/Guide/AJAX/С_чего_начать +tags: + - AJAX +translation_of: Web/Guide/AJAX/Getting_Started +--- +

 

+ +

В этой статье рассмотрены основные принципы работы AJAX и даны два простых примера, использующих эту технологию.

+ +

Что такое AJAX?

+ +

Ajax означает Асинхронный JavaScript и XML. В основе технологии лежит использование нестандартного объекта XMLHttpRequest, необходимого для взаимодействия со скриптами на стороне сервера. Объект может как отправлять, так и получать информацию в различных форматах включая XML, HTML и даже текстовые файлы. Самое привлекательное в Ajax — это его асинхронный принцип работы. С помощью этой технологии можно осуществлять взаимодействие с сервером без необходимости перезагрузки страницы. Это позволяет обновлять содержимое страницы частично, в зависимости от действий пользователя.

+ +

Две особенности, которые мы рассмотрим:

+ +
    +
  • Отправление запросов серверу без перезагрузки страницы
  • +
  • Работа с XML документами
  • +
+ +

Шаг 1 — Как послать HTTP запрос

+ +

Для того, чтобы послать HTTP запрос на сервер используя JavaScript, вам необходим экземпляр класса, который позволит это сделать. Такой класс впервые был введен в Internet Explorer как объект ActiveX, называемый XMLHTTP. Позже в Mozilla, Safari и другие браузеры был введен класс XMLHttpRequest, который поддерживал методы и свойства изначального объекта ActiveX от Microsoft.

+ +

В результате, чтобы создать кросс-браузерный объект требуемого класса, вы можете сделать следующее:

+ +
var httpRequest;
+if (window.XMLHttpRequest) { // Mozilla, Safari, ...
+    httpRequest = new XMLHttpRequest();
+} else if (window.ActiveXObject) { // IE
+    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
+}
+
+ +

(В целях наглядности, код выше является немного упрощенным. Более жизненный пример будет рассмотрен в шаге 3 этой статьи)

+ +

Некоторые версии некоторых броузеров Mozilla не будут корректно работать, если ответ сервера не содержит заголовка XML mime-type. Чтобы решить эту проблему, вы можете использовать вызовы дополнительных методов для переопределения заголовка полученного от сервера, если он отличен от text/xml.

+ +
httpRequest = new XMLHttpRequest();
+httpRequest.overrideMimeType('text/xml');
+
+ +

Далее вам необходимо решить, что вы будете делать после получения ответа сервера. На этом этапе вам необходимо указать объекту, какая JavaScript функция будет обрабатывать ответ. Это делается путем присваивания свойству onreadystatechange имени JavaScript функции, которую вы собираетесь использовать:

+ +

httpRequest.onreadystatechange = nameOfTheFunction;

+ +

Заметьте, что после названия функции нет скобок и не указано параметров, потому что вы просто присваиваете ссылку на функцию, а не вызываете ее. К тому же, вместо указания имени функции, вы можете использовать возможность JavaScript объявлять функции на лету (так называемые «анонимные функции») и указывать действия, которые тотчас же будут обрабатывать ответ:

+ +
httpRequest.onreadystatechange = function(){
+    // какой-нибудь код
+};
+
+ +

Далее, после того как вы объявили что будет происходить после получения ответа, вам необходимо сделать запрос. Вы должны вызвать методы класса open() и send():

+ +
httpRequest.open('GET', 'http://www.example.org/some.file', true);
+httpRequest.send(null);
+
+ +
    +
  • Первый параметр вызова функции open() — метод HTTP запроса (GET, POST, HEAD или любой другой метод, который вы хотите использовать). Используйте методы в соответствии с HTTP стандартами, иначе некоторые браузеры (такие как Firefox) могут не обработать запрос. Информация о допустимых HTTP запросах доступна по адресу спецификации W3C
  • +
  • Второй параметр — URL запрашиваемой страницы. Из соображений безопасности возможность запрашивать страницы сторонних доменов недоступна. Убедитесь, что вы используете одинаковое доменное имя на всех страницах, иначе вы получите ошибку 'доступ запрещен' при вызове функции open(). Типичной ошибкой при доступе к сайту через site.ru является отправка запроса на www.site.ru.
  • +
  • Третий параметр указывает, является ли запрос асинхронным. Если он TRUE, то выполнение JavaScript продолжится во время ожидания ответа сервера. В этом и заключается асинхронность технологии.
  • +
+ +

Параметром метода send() могут быть любые данные, которые вы хотите послать на сервер. Данные должны быть сформированы в строку запроса:

+ +

name=value&anothername=othervalue&so=on

+ +

Заметьте, что если вы хотите отправить данные методом POST, вы должны изменить MIME-тип запроса с помощью следующей строки:

+ +
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+ +

Иначе сервер проигнорирует данные отправленные методом POST.

+ +

Шаг 2 — Обрабатываем ответ сервера

+ +

Отправляя запрос, вы указали имя функции JavaScript, обрабатывающей ответ.

+ +

httpRequest.onreadystatechange = nameOfTheFunction;

+ +

Давайте посмотрим, что эта функция должна делать. Во-первых, функция должна проверять статус запроса. Если значение переменной статуса 4, то это означает, что ответ от сервера получен и его можно обрабатывать.

+ +
if (httpRequest.readyState == 4) {
+    // все в порядке, ответ получен
+} else {
+    // все еще не готово
+}
+
+ +

Полный список значений кодов readyState такой:

+ +
    +
  • 0 (uninitialized)
  • +
  • 1 (loading)
  • +
  • 2 (loaded)
  • +
  • 3 (interactive)
  • +
  • 4 (complete)
  • +
+ +

(Источник)

+ +

Следующее, что нужно проверить — это статус HTTP-ответа. Все возможные коды можно посмотреть на сайте W3C. Для наших целей нам интересен только код ответа 200 OK.

+ +
if (httpRequest.status == 200) {
+    // великолепно!
+} else {
+    // с запросом возникли проблемы,
+    // например, ответ может быть 404 (Не найдено)
+    // или 500 (Внутренняя ошибка сервера)
+}
+
+ +

Теперь, после проверки состояния запроса и статуса HTTP-ответа, вы можете делать с данными, полученными от сервера, все что угодно. Есть два способа получить доступ к данным:

+ +
    +
  • httpRequest.responseText – возвращает ответ сервера в виде строки текста.
  • +
  • httpRequest.responseXML – возвращает ответ сервера в виде объекта XMLDocument, который вы можете обходить используя функции JavaScript DOM
  • +
+ +

Шаг 3 — Простой пример

+ +

Давайте соберем все вместе и сделаем простой пример HTTP-запроса. Наш JavaScript запросит HTML документ test.html, который содержит текст "I'm a test." и выведет содержимое файла в диалоговом окне.

+ +
<script type="text/javascript" language="javascript">
+    function makeRequest(url) {
+        var httpRequest = false;
+
+        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
+            httpRequest = new XMLHttpRequest();
+            if (httpRequest.overrideMimeType) {
+                httpRequest.overrideMimeType('text/xml');
+                // Читайте ниже об этой строке
+            }
+        } else if (window.ActiveXObject) { // IE
+            try {
+                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
+            } catch (e) {
+                try {
+                    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
+                } catch (e) {}
+            }
+        }
+
+        if (!httpRequest) {
+            alert('Не вышло :( Невозможно создать экземпляр класса XMLHTTP ');
+            return false;
+        }
+        httpRequest.onreadystatechange = function() { alertContents(httpRequest); };
+        httpRequest.open('GET', url, true);
+        httpRequest.send(null);
+
+    }
+
+    function alertContents(httpRequest) {
+
+        if (httpRequest.readyState == 4) {
+            if (httpRequest.status == 200) {
+                alert(httpRequest.responseText);
+            } else {
+                alert('С запросом возникла проблема.');
+            }
+        }
+
+    }
+</script>
+<span
+    style="cursor: pointer; text-decoration: underline"
+    onclick="makeRequest('test.html')">
+        Сделать запрос
+</span>
+
+ +


+ В этом примере:

+ +
    +
  • Пользователь нажимает на ссылку "Сделать запрос" в броузере;
  • +
  • Это вызывает функцию makeRequest() с параметром test.html — именем HTML файла;
  • +
  • Посылается запрос, после чего (onreadystatechange) выполнение передается alertContents();
  • +
  • alertContents() проверяет получен ли ответ и все ли с ним в порядке, после чего содержимое файла test.html выводится в диалоговом окне.
  • +
+ +

Вы можете попробовать пример в действии здесь, а сам тестовый файл можно посмотреть здесь.

+ +

Замечание: Строка httpRequest.overrideMimeType('text/xml'); вызовет ошибки в консоли JavaScript в Firefox 1.5 или более позднем, как описано в https://bugzilla.mozilla.org/show_bug.cgi?id=311724, если страница вызванная с помощью XMLHttpRequest не является правильным XML (например, если это обычный текст). На самом деле это корректное поведение.

+ +

Замечание 2: Если вы посылаете запрос не на статический XML-файл, а на серверный скрипт, возвращающий XML, то нужно установить некоторые заголовки ответа, если вы планируете сделать вашу страницу работоспособной в Internet Explorer помимо Mozilla. Если вы не установите заголовок Content-Type: application/xml, IE будет сообщать об ошибке JavaScript, 'Object Expected', после строки, где вы пытаетесь получить доступ к XML элементу. Если вы не установите заголовок Cache-Control: no-cache броузер будет кэшировать ответ и никогда не будет повторно отправлять запрос, что сделает отладку весьма «забавной».

+ +

Замечание 3: Если переменная httpRequest используется глобально, то конкурирующие функции, вызывающие makeRequest() могут конкурировать друг с другом, вызывая состязания. Объявление переменной httpRequest локально в функции и передача ее в alertContent() предотвращает состязания.

+ +

Замечание 4: При привязывании функции обратного вызова к onreadystatechange нельзя указывать аргументов. По этой причине не работает следующий код:

+ +
httpRequest.onreadystatechange = alertContents(httpRequest); // (не работает)
+
+ +

Таким образом, для успешной регистрации функции, вы должны передать ей аргументы косвенно через анонимную функцию или используя httpRequest как глобальную переменную. Вот пример:

+ +
httpRequest.onreadystatechange = function() { alertContents(httpRequest); };  //1 (одновременный запрос)
+httpRequest.onreadystatechange = alertContents;  //2 (глобальная переменная)
+
+ +

Первый способ позволяет делать несколько запросов одновременно, а второй используется, когда переменная httpRequest является глобальной.

+ +

Замечание 5: В случае ошибки взаимодействия (например, если сервер упал), при попытке доступа к переменной .status метода onreadystatechange будет сгенерировано исключение. Убедитесь, что if...then заключено в try...catch. (См. https://bugzilla.mozilla.org/show_bug.cgi?id=238559).

+ +
function alertContents(httpRequest) {
+
+        try {
+            if (httpRequest.readyState == 4) {
+                if (httpRequest.status == 200) {
+                    alert(httpRequest.responseText);
+                } else {
+                    alert('С запросом возникла проблема.');
+                }
+            }
+        }
+        catch( e ) {
+            alert('Произошло исключение: ' + e.description);
+        }
+
+    }
+
+ +

Шаг 4 — Работа с XML ответом

+ +

В предыдущем примере, после того как был получен ответ на HTTP-запрос мы использовали responseText запрашиваемого объекта, который содержал данные файла test.html. Теперь давайте попробуем использовать свойство responseXML.

+ +

Прежде всего, давайте создадим правильный XML документ, который мы будем запрашивать. Документ (test.xml) содержит следующее:

+ +
<?xml version="1.0" ?>
+<root>
+    I'm a test.
+</root>
+
+ +

В скрипте нам всего лишь необходимо заменить строку запроса на:

+ +
...
+onclick="makeRequest('test.xml')">
+...
+
+ +

Далее в alertContents() нам нужно заменить строку alert(httpRequest.responseText); на:

+ +
var xmldoc = httpRequest.responseXML;
+var root_node = xmldoc.getElementsByTagName('root').item(0);
+alert(root_node.firstChild.data);
+
+ +

Этот код берет объект XMLDocument, возвращаемый responseXML и использует методы DOM для доступа к данным, содержащимся в документе XML. Посмотреть test.xml можно здесь, а обновленный скрипт здесь.

+ +

Чтобы узнать больше о методах DOM, посмотрите реализация DOM в Mozilla.

+ +

{{ languages( { "ca": "ca/AJAX/Primers_passos", "de": "de/AJAX/Getting_Started", "en": "en/AJAX/Getting_Started", "es": "es/AJAX/Primeros_Pasos", "fr": "fr/AJAX/Premiers_pas", "it": "it/AJAX/Iniziare", "ja": "ja/AJAX/Getting_Started", "ko": "ko/AJAX/Getting_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt/AJAX/Como_come\u00e7ar", "zh-cn": "cn/AJAX/\u5f00\u59cb" } ) }}

diff --git "a/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214/index.html" "b/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214/index.html" deleted file mode 100644 index e06b408228..0000000000 --- "a/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214/index.html" +++ /dev/null @@ -1,258 +0,0 @@ ---- -title: С чего начать -slug: Web/Guide/AJAX/С_чего_начать -tags: - - AJAX -translation_of: Web/Guide/AJAX/Getting_Started ---- -

 

- -

В этой статье рассмотрены основные принципы работы AJAX и даны два простых примера, использующих эту технологию.

- -

Что такое AJAX?

- -

Ajax означает Асинхронный JavaScript и XML. В основе технологии лежит использование нестандартного объекта XMLHttpRequest, необходимого для взаимодействия со скриптами на стороне сервера. Объект может как отправлять, так и получать информацию в различных форматах включая XML, HTML и даже текстовые файлы. Самое привлекательное в Ajax — это его асинхронный принцип работы. С помощью этой технологии можно осуществлять взаимодействие с сервером без необходимости перезагрузки страницы. Это позволяет обновлять содержимое страницы частично, в зависимости от действий пользователя.

- -

Две особенности, которые мы рассмотрим:

- -
    -
  • Отправление запросов серверу без перезагрузки страницы
  • -
  • Работа с XML документами
  • -
- -

Шаг 1 — Как послать HTTP запрос

- -

Для того, чтобы послать HTTP запрос на сервер используя JavaScript, вам необходим экземпляр класса, который позволит это сделать. Такой класс впервые был введен в Internet Explorer как объект ActiveX, называемый XMLHTTP. Позже в Mozilla, Safari и другие браузеры был введен класс XMLHttpRequest, который поддерживал методы и свойства изначального объекта ActiveX от Microsoft.

- -

В результате, чтобы создать кросс-браузерный объект требуемого класса, вы можете сделать следующее:

- -
var httpRequest;
-if (window.XMLHttpRequest) { // Mozilla, Safari, ...
-    httpRequest = new XMLHttpRequest();
-} else if (window.ActiveXObject) { // IE
-    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
-}
-
- -

(В целях наглядности, код выше является немного упрощенным. Более жизненный пример будет рассмотрен в шаге 3 этой статьи)

- -

Некоторые версии некоторых броузеров Mozilla не будут корректно работать, если ответ сервера не содержит заголовка XML mime-type. Чтобы решить эту проблему, вы можете использовать вызовы дополнительных методов для переопределения заголовка полученного от сервера, если он отличен от text/xml.

- -
httpRequest = new XMLHttpRequest();
-httpRequest.overrideMimeType('text/xml');
-
- -

Далее вам необходимо решить, что вы будете делать после получения ответа сервера. На этом этапе вам необходимо указать объекту, какая JavaScript функция будет обрабатывать ответ. Это делается путем присваивания свойству onreadystatechange имени JavaScript функции, которую вы собираетесь использовать:

- -

httpRequest.onreadystatechange = nameOfTheFunction;

- -

Заметьте, что после названия функции нет скобок и не указано параметров, потому что вы просто присваиваете ссылку на функцию, а не вызываете ее. К тому же, вместо указания имени функции, вы можете использовать возможность JavaScript объявлять функции на лету (так называемые «анонимные функции») и указывать действия, которые тотчас же будут обрабатывать ответ:

- -
httpRequest.onreadystatechange = function(){
-    // какой-нибудь код
-};
-
- -

Далее, после того как вы объявили что будет происходить после получения ответа, вам необходимо сделать запрос. Вы должны вызвать методы класса open() и send():

- -
httpRequest.open('GET', 'http://www.example.org/some.file', true);
-httpRequest.send(null);
-
- -
    -
  • Первый параметр вызова функции open() — метод HTTP запроса (GET, POST, HEAD или любой другой метод, который вы хотите использовать). Используйте методы в соответствии с HTTP стандартами, иначе некоторые браузеры (такие как Firefox) могут не обработать запрос. Информация о допустимых HTTP запросах доступна по адресу спецификации W3C
  • -
  • Второй параметр — URL запрашиваемой страницы. Из соображений безопасности возможность запрашивать страницы сторонних доменов недоступна. Убедитесь, что вы используете одинаковое доменное имя на всех страницах, иначе вы получите ошибку 'доступ запрещен' при вызове функции open(). Типичной ошибкой при доступе к сайту через site.ru является отправка запроса на www.site.ru.
  • -
  • Третий параметр указывает, является ли запрос асинхронным. Если он TRUE, то выполнение JavaScript продолжится во время ожидания ответа сервера. В этом и заключается асинхронность технологии.
  • -
- -

Параметром метода send() могут быть любые данные, которые вы хотите послать на сервер. Данные должны быть сформированы в строку запроса:

- -

name=value&anothername=othervalue&so=on

- -

Заметьте, что если вы хотите отправить данные методом POST, вы должны изменить MIME-тип запроса с помощью следующей строки:

- -
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-
- -

Иначе сервер проигнорирует данные отправленные методом POST.

- -

Шаг 2 — Обрабатываем ответ сервера

- -

Отправляя запрос, вы указали имя функции JavaScript, обрабатывающей ответ.

- -

httpRequest.onreadystatechange = nameOfTheFunction;

- -

Давайте посмотрим, что эта функция должна делать. Во-первых, функция должна проверять статус запроса. Если значение переменной статуса 4, то это означает, что ответ от сервера получен и его можно обрабатывать.

- -
if (httpRequest.readyState == 4) {
-    // все в порядке, ответ получен
-} else {
-    // все еще не готово
-}
-
- -

Полный список значений кодов readyState такой:

- -
    -
  • 0 (uninitialized)
  • -
  • 1 (loading)
  • -
  • 2 (loaded)
  • -
  • 3 (interactive)
  • -
  • 4 (complete)
  • -
- -

(Источник)

- -

Следующее, что нужно проверить — это статус HTTP-ответа. Все возможные коды можно посмотреть на сайте W3C. Для наших целей нам интересен только код ответа 200 OK.

- -
if (httpRequest.status == 200) {
-    // великолепно!
-} else {
-    // с запросом возникли проблемы,
-    // например, ответ может быть 404 (Не найдено)
-    // или 500 (Внутренняя ошибка сервера)
-}
-
- -

Теперь, после проверки состояния запроса и статуса HTTP-ответа, вы можете делать с данными, полученными от сервера, все что угодно. Есть два способа получить доступ к данным:

- -
    -
  • httpRequest.responseText – возвращает ответ сервера в виде строки текста.
  • -
  • httpRequest.responseXML – возвращает ответ сервера в виде объекта XMLDocument, который вы можете обходить используя функции JavaScript DOM
  • -
- -

Шаг 3 — Простой пример

- -

Давайте соберем все вместе и сделаем простой пример HTTP-запроса. Наш JavaScript запросит HTML документ test.html, который содержит текст "I'm a test." и выведет содержимое файла в диалоговом окне.

- -
<script type="text/javascript" language="javascript">
-    function makeRequest(url) {
-        var httpRequest = false;
-
-        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
-            httpRequest = new XMLHttpRequest();
-            if (httpRequest.overrideMimeType) {
-                httpRequest.overrideMimeType('text/xml');
-                // Читайте ниже об этой строке
-            }
-        } else if (window.ActiveXObject) { // IE
-            try {
-                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
-            } catch (e) {
-                try {
-                    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
-                } catch (e) {}
-            }
-        }
-
-        if (!httpRequest) {
-            alert('Не вышло :( Невозможно создать экземпляр класса XMLHTTP ');
-            return false;
-        }
-        httpRequest.onreadystatechange = function() { alertContents(httpRequest); };
-        httpRequest.open('GET', url, true);
-        httpRequest.send(null);
-
-    }
-
-    function alertContents(httpRequest) {
-
-        if (httpRequest.readyState == 4) {
-            if (httpRequest.status == 200) {
-                alert(httpRequest.responseText);
-            } else {
-                alert('С запросом возникла проблема.');
-            }
-        }
-
-    }
-</script>
-<span
-    style="cursor: pointer; text-decoration: underline"
-    onclick="makeRequest('test.html')">
-        Сделать запрос
-</span>
-
- -


- В этом примере:

- -
    -
  • Пользователь нажимает на ссылку "Сделать запрос" в броузере;
  • -
  • Это вызывает функцию makeRequest() с параметром test.html — именем HTML файла;
  • -
  • Посылается запрос, после чего (onreadystatechange) выполнение передается alertContents();
  • -
  • alertContents() проверяет получен ли ответ и все ли с ним в порядке, после чего содержимое файла test.html выводится в диалоговом окне.
  • -
- -

Вы можете попробовать пример в действии здесь, а сам тестовый файл можно посмотреть здесь.

- -

Замечание: Строка httpRequest.overrideMimeType('text/xml'); вызовет ошибки в консоли JavaScript в Firefox 1.5 или более позднем, как описано в https://bugzilla.mozilla.org/show_bug.cgi?id=311724, если страница вызванная с помощью XMLHttpRequest не является правильным XML (например, если это обычный текст). На самом деле это корректное поведение.

- -

Замечание 2: Если вы посылаете запрос не на статический XML-файл, а на серверный скрипт, возвращающий XML, то нужно установить некоторые заголовки ответа, если вы планируете сделать вашу страницу работоспособной в Internet Explorer помимо Mozilla. Если вы не установите заголовок Content-Type: application/xml, IE будет сообщать об ошибке JavaScript, 'Object Expected', после строки, где вы пытаетесь получить доступ к XML элементу. Если вы не установите заголовок Cache-Control: no-cache броузер будет кэшировать ответ и никогда не будет повторно отправлять запрос, что сделает отладку весьма «забавной».

- -

Замечание 3: Если переменная httpRequest используется глобально, то конкурирующие функции, вызывающие makeRequest() могут конкурировать друг с другом, вызывая состязания. Объявление переменной httpRequest локально в функции и передача ее в alertContent() предотвращает состязания.

- -

Замечание 4: При привязывании функции обратного вызова к onreadystatechange нельзя указывать аргументов. По этой причине не работает следующий код:

- -
httpRequest.onreadystatechange = alertContents(httpRequest); // (не работает)
-
- -

Таким образом, для успешной регистрации функции, вы должны передать ей аргументы косвенно через анонимную функцию или используя httpRequest как глобальную переменную. Вот пример:

- -
httpRequest.onreadystatechange = function() { alertContents(httpRequest); };  //1 (одновременный запрос)
-httpRequest.onreadystatechange = alertContents;  //2 (глобальная переменная)
-
- -

Первый способ позволяет делать несколько запросов одновременно, а второй используется, когда переменная httpRequest является глобальной.

- -

Замечание 5: В случае ошибки взаимодействия (например, если сервер упал), при попытке доступа к переменной .status метода onreadystatechange будет сгенерировано исключение. Убедитесь, что if...then заключено в try...catch. (См. https://bugzilla.mozilla.org/show_bug.cgi?id=238559).

- -
function alertContents(httpRequest) {
-
-        try {
-            if (httpRequest.readyState == 4) {
-                if (httpRequest.status == 200) {
-                    alert(httpRequest.responseText);
-                } else {
-                    alert('С запросом возникла проблема.');
-                }
-            }
-        }
-        catch( e ) {
-            alert('Произошло исключение: ' + e.description);
-        }
-
-    }
-
- -

Шаг 4 — Работа с XML ответом

- -

В предыдущем примере, после того как был получен ответ на HTTP-запрос мы использовали responseText запрашиваемого объекта, который содержал данные файла test.html. Теперь давайте попробуем использовать свойство responseXML.

- -

Прежде всего, давайте создадим правильный XML документ, который мы будем запрашивать. Документ (test.xml) содержит следующее:

- -
<?xml version="1.0" ?>
-<root>
-    I'm a test.
-</root>
-
- -

В скрипте нам всего лишь необходимо заменить строку запроса на:

- -
...
-onclick="makeRequest('test.xml')">
-...
-
- -

Далее в alertContents() нам нужно заменить строку alert(httpRequest.responseText); на:

- -
var xmldoc = httpRequest.responseXML;
-var root_node = xmldoc.getElementsByTagName('root').item(0);
-alert(root_node.firstChild.data);
-
- -

Этот код берет объект XMLDocument, возвращаемый responseXML и использует методы DOM для доступа к данным, содержащимся в документе XML. Посмотреть test.xml можно здесь, а обновленный скрипт здесь.

- -

Чтобы узнать больше о методах DOM, посмотрите реализация DOM в Mozilla.

- -

{{ languages( { "ca": "ca/AJAX/Primers_passos", "de": "de/AJAX/Getting_Started", "en": "en/AJAX/Getting_Started", "es": "es/AJAX/Primeros_Pasos", "fr": "fr/AJAX/Premiers_pas", "it": "it/AJAX/Iniziare", "ja": "ja/AJAX/Getting_Started", "ko": "ko/AJAX/Getting_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt/AJAX/Como_come\u00e7ar", "zh-cn": "cn/AJAX/\u5f00\u59cb" } ) }}

diff --git "a/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" "b/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" deleted file mode 100644 index f66d6b1dbf..0000000000 --- "a/files/ru/web/guide/ajax/\321\201_\321\207\320\265\320\263\320\276_\320\275\320\260\321\207\320\260\321\202\321\214_question_/index.html" +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: С чего начать? -slug: Web/Guide/AJAX/С_чего_начать? ---- -

IKFIA -

diff --git a/files/ru/web/guide/api/dom/index.html b/files/ru/web/guide/api/dom/index.html deleted file mode 100644 index 1671813170..0000000000 --- a/files/ru/web/guide/api/dom/index.html +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: DOM developer guide -slug: Web/Guide/API/DOM -tags: - - API - - DOM - - Guide - - NeedsContent - - NeedsTranslation - - TopicStub -translation_of: Web/API/Document_Object_Model -translation_of_original: Web/Guide/API/DOM ---- -

{{draft}}

- -

Объектная модель документа - это API для документов HTML и XML. Она обеспечивает структурное представление документа, позволяя разработчику изменять его содержание и визуальное представление. По сути, она соединяет веб-страницы со скриптами или языками программирования.

- -

Все свойства, методы и события, доступные веб-разработчику для манипулирования и создания веб-страниц, организованы в объекты (например, объект документа, представляющий сам документ, объект таблицы, представляющий элемент таблицы HTML и т. Д.) , Эти объекты доступны через скриптовые языки в самых последних веб-браузерах.

- -

DOM чаще всего используется в сочетании с JavaScript. Тем не менее, DOM был разработан, чтобы быть независимым от какого-либо конкретного языка программирования, делая структурное представление документа доступным из единого, согласованного API. Хотя мы,на этом сайте, сосредоточены на JavaScript реализации DOM могут быть построены для любого языка.

- -

Консорциум World Wide Web устанавливает стандарт для DOM, называемый W3C DOM. Теперь, когда наиболее важные браузеры правильно его реализуют, следует включить мощные кросс-браузерные приложения.

- -

Почему так важен DOM?

- -

"Dynamic HTML" (DHTML) это термин, используемый некоторыми поставщиками для описания комбинации HTML, таблиц стилей и сценариев, позволяющих анимировать документы. Рабочая группа W3C DOM усердно работает над тем, чтобы согласовать совместимые и не зависящие от языка решения (см. также W3C FAQ).

- -

Поскольку Mozilla претендует на звание «Платформа веб-приложений», поддержка DOM является одной из наиболее востребованных функций и необходимой, если Mozilla хочет стать жизнеспособной альтернативой другим браузерам. Пользовательский интерфейс Mozilla (также Firefox и Thunderbird) построен с использованием XUL, используя DOM для управления собственным пользовательским  интерфейсом UI.

- -

More about the DOM

- -

{{LandingPageListSubpages}}

- - - -

«Динамический HTML» (DHTML) - это термин, используемый некоторыми поставщиками для описания комбинации HTML, таблиц стилей и сценариев, позволяющих анимировать документы. Рабочая группа W3C DOM усердно работает над тем, чтобы согласовать совместимые и не зависящие от языка решения (см. Также FAQ по W3C).

- -

Поскольку Mozilla претендует на звание «Платформа веб-приложений», поддержка DOM является одной из наиболее востребованных функций и необходимой, если Mozilla хочет стать жизнеспособной альтернативой другим браузерам. Пользовательский интерфейс Mozilla (также Firefox и Thunderbird) построен с использованием XUL, используя DOM для управления собственным пользовательским интерфейсом.

diff --git a/files/ru/web/guide/api/dom/storage/index.html b/files/ru/web/guide/api/dom/storage/index.html deleted file mode 100644 index b63a374c8c..0000000000 --- a/files/ru/web/guide/api/dom/storage/index.html +++ /dev/null @@ -1,368 +0,0 @@ ---- -title: DOM Storage guide -slug: Web/Guide/API/DOM/Storage -translation_of: Web/API/Web_Storage_API -translation_of_original: Web/Guide/API/DOM/Storage ---- -

 

- -

DOM хранилище (DOM Storage) - это название для набора инструментов, относящихся к хранилищам, впервые представленных в спецификации Web Applications 1.0,  и выделенных теперь в отдельную специкацию W3C Web Storage. DOM хранилище было разработано с целью предоставления альтернативы хранению информации в кукисах. Предполагается, что DOM хранилище предоставляет больше объема, оно более защищено и легче в использовании. Впервые оно было представлено  в браузерах Firefox 2 и Safari 4.

- -
Заметка: DOM хранилище - это не то же самое, что mozStorage (Mozilla's XPCOM interfaces to SQLite) или Session store API (утилита XPCOM - хранилище для использования в расширениях).
- -
-

Заметка: Эта статья скоро будет сильно переработана. Вместо того, чтобы хранить всю информацию на одной странице, она будет разбита на несколько статей, каждая из которых будет описывать разные API хранилища. Отдельная статья, помогающая разобраться в разных API, будет также добавлена.

-
- -

Описание

- -

Механизм DOM хранилища - средство, благодаря которому можно безопасно хранить и позже извлекать пары "ключ / значение". Целью этого является обеспечение комплексного средства, с помощью которого можно разрабатывать интерактивные приложения(включая приложения с продвинутыми возможностями, такими как возможность работать "автономно"("offline") в течение длительных периодов времени).

- -

Браузеры на основе Mozilla, Internet Explorer 8 +, Safari 4 + и Chrome обеспечивают рабочую реализацию спецификации DOM хранилища. (В случае, если нужна кросс-браузерная поддержка функциональности, включая более старые версии IE, будет полезно отметить, что IE также имеет подобную легаси функциональность под названием "USERDATA поведение", которая дополненяет DOM хранилище IE в IE8.)

- -

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

- -

Одним из первых известных приложений,  использующих новые функциональные возможности DOM хранилища(в дополнение к USERDATA поведения в Internet Explorer) было halfnote (приложение для заметок), написанное Аароном Будменом. В своем приложении, Аарон одновременно сохранял заметки на сервере (когда/если Интернет-подключение  был доступно) и локального хранилища данных(в обратном случае). Это дало возможность пользователю смело писать резервные копии заметок даже при нерегулярном подключении к Интернету.

- -

Хотя идея и реализация halfnote были сравнительно простыми, создание halfnote показывает возможность для нового поколения веб-приложений, которые можно использовать как в онлайн-, так и оффлайн- режиме.

- -

Связь

- -

Ниже приведены глобальные объекты, которые существуют как свойства каждого объекта  window. Это означает, что они могут быть доступны как sessionStorage или window.sessionStorage. (Это важно, потому что вы можете использовать фреймы(IFrames) для хранения или доступа, дополнительные данные кроме того, что сразу же включено на странице.)

- -

Storage

- -

Это конструктор(Storageдля всех экземпляров Storage (sessionStorage и globalStorage[location.hostname]).

- -

Сохранение Storage.prototype.removeKey = function(key){ this.removeItem(this.key(key)) } будет доступно через localStorage.removeKey и sessionStorage.removeKey.

- -

Единицы globalStorage являются экземплярами StorageObsolete, а не Storage.

- -

Storage определен в WhatWG Storage Interface следующим образом:

- -
interface Storage {
-  readonly attribute unsigned long length;
-  [IndexGetter] DOMString key(in unsigned long index);
-  [NameGetter] DOMString getItem(in DOMString key);
-  [NameSetter] void setItem(in DOMString key, in DOMString data);
-  [NameDeleter] void removeItem(in DOMString key);
-  void clear();
-};
-
- -
Заметка: Несмотря на то, что значения доступны для чтения и записи через стандартные способы Javascript, рекомендуется использование getItem и setItem.
- -
Заметка: Обратите внимание, что любые данные, которые хранятся в любом из хранилищ, описанных на этой странице, преобразуются в строку, используя метод.toString. перед тем, как сохранить значение. Попытка сохранить объект приведет к сохранению строки "[object Object]"  вместо объекта или его JSON представления. Самым лучшим и распространенным способом сохранения объектов в формате строки является использование предоставляемых браузером методов JSON для парсинга и сериализации объектов.
- -

sessionStorage

- -

Это глобальный объект (sessionStorage), который сохраняет значения, которые доступны в течение периода текущей сессии. Сессия страницы длится, пока браузер открыт, и восстанавливает свои значения после перегрузки страницы. Открытие страницы в новой вкладке или окне приведет к созданию новой сессии для этой страницы.

- -
// Сохранить данные в текущем хранилизе сессий
-sessionStorage.setItem("username", "John");
-
-// Получить значения сохраненного значения
-alert( "username = " + sessionStorage.getItem("username"));
-
- -

Объект sessionStorage наиболее полезен для хранения временных данных, которые должны быть восстановлены, если страница браузер была случайно перегружена.

- -

Примеры:

- -

Автоматическое сохранение содержимого тестового поля, и если страница была случайно перегружена, то данные не будут потеряны.

- -
 // Получить значение текстового поля, которое мы собираемся отслеживать
- var field = document.getElementById("field");
-
- // Проверяем, что значение поля autosave существует
- // (это будет происходить при случайной перезагрузке страницы)
- if (sessionStorage.getItem("autosave")) {
-    // Восстановить значение тестового поля
-    field.value = sessionStorage.getItem("autosave");
- }
-
- // Прослушивать изменения значения текстового поля
- field.addEventListener("change", function() {
-    // И сохранить результаты в объект хранилища сессий
-    sessionStorage.setItem("autosave", field.value);
- });
-
- -

Больше информации:

- - - -

localStorage

- -

localStorage - это то же самое, что и {{ Anch("sessionStorage") }}, поддерживает правила единого происхождения(same-origin rules), но хранение данных постоянно. localStorage был представлен в Firefox 3.5.

- -
Заметка: Когда браузер переходит в частный режим браузера(private browsing mode), то новая, временная база данных создается для хранения данных локального хранилища; эта база данных очищается и удаляется, как только частный режим браузера выключается.
- -

Совместимость

- -

Объекты Storage - относительно недавнее дополнение стандарта. Это означает, что они не обязательно должны быть реализованы во всех браузерах. Проблему можно решить с помощью включения следующего куска кода в начале вашего скрипта, позволяя использовать объект localStorage в реализациях, которые нативно не поддерживают его.

- -

Следующий алгоритм - это точная имитация объекта localStorage, но использует куки.

- -
if (!window.localStorage) {
-  Object.defineProperty(window, "localStorage", new (function () {
-    var aKeys = [], oStorage = {};
-    Object.defineProperty(oStorage, "getItem", {
-      value: function (sKey) { return sKey ? this[sKey] : null; },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "key", {
-      value: function (nKeyId) { return aKeys[nKeyId]; },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "setItem", {
-      value: function (sKey, sValue) {
-        if(!sKey) { return; }
-        document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
-      },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "length", {
-      get: function () { return aKeys.length; },
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "removeItem", {
-      value: function (sKey) {
-        if(!sKey) { return; }
-        document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
-      },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    this.get = function () {
-      var iThisIndx;
-      for (var sKey in oStorage) {
-        iThisIndx = aKeys.indexOf(sKey);
-        if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
-        else { aKeys.splice(iThisIndx, 1); }
-        delete oStorage[sKey];
-      }
-      for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
-      for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx < aCouples.length; nIdx++) {
-        aCouple = aCouples[nIdx].split(/\s*=\s*/);
-        if (aCouple.length > 1) {
-          oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]);
-          aKeys.push(iKey);
-        }
-      }
-      return oStorage;
-    };
-    this.configurable = false;
-    this.enumerable = true;
-  })());
-}
-
- -
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.setItem() and localStorage.removeItem() to add, change, or remove a key. The use of methods localStorage.yourKey = yourValue; and delete localStorage.yourKey; to set or delete a key is not a secure way with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
- -
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.
- -

Here is another, less exact, imitation of the localStorage object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8 (tested and working even in Internet Explorer 6). It also makes use of cookies.

- -
if (!window.localStorage) {
-  window.localStorage = {
-    getItem: function (sKey) {
-      if (!sKey || !this.hasOwnProperty(sKey)) { return null; }
-      return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
-    },
-    key: function (nKeyId) {
-      return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]);
-    },
-    setItem: function (sKey, sValue) {
-      if(!sKey) { return; }
-      document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
-      this.length = document.cookie.match(/\=/g).length;
-    },
-    length: 0,
-    removeItem: function (sKey) {
-      if (!sKey || !this.hasOwnProperty(sKey)) { return; }
-      document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
-      this.length--;
-    },
-    hasOwnProperty: function (sKey) {
-      return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
-    }
-  };
-  window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length;
-}
-
- -
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.getItem(), localStorage.setItem(), and localStorage.removeItem() to get, add, change, or remove a key. The use of method localStorage.yourKey in order to get, set, or delete a key is not permitted with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
- -
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.
- -

Compatibility and relation with globalStorage

- -

localStorage is also the same as globalStorage[location.hostname], with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and localStorage being an instance of Storage as opposed to globalStorage[location.hostname] being an instance of StorageObsolete which is covered below. For example, http://example.com is not able to access the same localStorage object as https://example.com but they can access the same globalStorage item. localStorage is a standard interface while globalStorage is non-standard so you shouldn't rely on these.

- -

Please note that setting a property on globalStorage[location.hostname] does not set it on localStorage and extending Storage.prototype does not affect globalStorage items; only extending StorageObsolete.prototype does.

- -

globalStorage

- -
{{ Non-standard_header }}{{ obsolete_header("13.0") }}
- -

globalStorage is obsolete since Gecko 1.9.1 (Firefox 3.5) and unsupported since Gecko 13 (Firefox 13). Just use {{ Anch("localStorage") }} instead. This proposed addition to HTML5 has been removed from the HTML5 specification in favor of {{ Anch("localStorage") }}, which is implemented in Firefox 3.5. This is a global object (globalStorage) that maintains multiple private storage areas that can be used to hold data over a long period of time (e.g., over multiple pages and browser sessions).

- -
Note: globalStorage is not a Storage instance, but a StorageList instance containing StorageObsolete instances.
- -
// Save data that only scripts on the mozilla.org domain can access
-globalStorage['mozilla.org'].setItem("snippet", "<b>Hello</b>, how are you?");
-
- -

Specifically, the globalStorage object provides access to a number of different storage objects into which data can be stored. For example, if we were to build a web page that used globalStorage on this domain (developer.mozilla.org) we'd have the following storage object available to us:

- -
    -
  • globalStorage{{ mediawiki.external('\'developer.mozilla.org\'') }} - All web pages within the developer.mozilla.org sub-domain can both read and write data to this storage object.
  • -
- -

Examples:

- -

All of these examples require that you have a script inserted (with each of the following code) in every page that you want to see the result on.

- -

Remember a user's username for the particular sub-domain that is being visited:

- -
 globalStorage['developer.mozilla.org'].setItem("username", "John");
-
- -

Keep track of the number of times that a user visits all pages of your domain:

- -
 // parseInt must be used since all data is stored as a string
- globalStorage['mozilla.org'].setItem("visits", parseInt(globalStorage['mozilla.org'].getItem("visits") || 0 ) + 1);
-
- -

Расположение хранилища и очищение данных

- -

In Firefox the DOM storage data is stored in the webappsstore.sqlite file in the profile folder (there's also chromeappsstore.sqlite file used to store browser's own data, notably for the start page - about:home, but potentially for other internal pages with "about:" URLs).

- -
    -
  • DOM Storage can be cleared via "Tools -> Clear Recent History -> Cookies" when Time range is "Everything" (via nsICookieManager::removeAll) -
      -
    • But not when another time range is specified: (bug 527667)
    • -
    • Does not show up in Tools -> Options -> Privacy -> Remove individual cookies (bug 506692)
    • -
    -
  • -
  • DOM Storage is not cleared via Tools -> Options -> Advanced -> Network -> Offline data -> Clear Now.
  • -
  • Doesn't show up in the "Tools -> Options -> Advanced -> Network -> Offline data" list, unless the site also uses the offline cache. If the site does appear in that list, its DOM storage data is removed along with the offline cache when clicking the Remove button.
  • -
- -

See also clearing offline resources cache.

- -

Больше информации

- - - -

Примеры

- -
    -
  • JavaScript Web Storage Tutorial: Creating an Address Book Application - Hands-on tutorial describing how to use the Web Storage API by creating a simple address book application.
  • -
  • offline web applications at hacks.mozilla.org - Showcases an offline app demo and explains how it works.
  • -
  • Noteboard - Note writing application that stores all data locally.
  • -
  • jData - A shared localStorage object interface that can be accessed by any website on the internet and works on Firefox 3+, Webkit 3.1.2+ nightlies, and IE8. Think of it as pseudo-globalStorage[""] but write access needs user confirmation.
  • -
  • HTML5 localStorage example - Very simple and easy to understand example of localStorage. Saves and retrieves texts and shows a list of saved items. Tested in Firefox 3 or higher.
  • -
  • HTML5 Session Storage - A very simple example of session storage. Also includes a example on local storage. Tested in Firefox 3.6 or higher.
  • -
  • Basic DOMStorage Examples - Broken in Firefox 3 and up due to use of globalStorage on one domain level up from the current domain which is not allowed in Firefox 3.
  • -
  • halfnote - (displaying broken in Firefox 3) Note writing application that uses DOM Storage.
  • -
- -

Совместимость с браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
localStorage43.5810.504
sessionStorage52810.504
globalStorage{{ CompatNo }}2-13{{ CompatNo }}{{ CompatNo }}{{ CompatNo }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support2.1{{ CompatUnknown }}811iOS 3.2
-
- -

All browsers have varying capacity levels for both localStorage and sessionStorage. Here is a detailed rundown of all the storage capacities for various browsers.

- -
-

Note: since iOS 5.1, Safari Mobile stores localStorage data in the cache folder, which is subject to occasional clean up, at the behest of the OS, typically if space is short.

-
- -

Полезные ссылки

- - - -
{{ HTML5ArticleTOC }}
diff --git a/files/ru/web/guide/api/webrtc/index.html b/files/ru/web/guide/api/webrtc/index.html deleted file mode 100644 index d8fbf01983..0000000000 --- a/files/ru/web/guide/api/webrtc/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: WebRTC -slug: Web/Guide/API/WebRTC -translation_of: Web/API/WebRTC_API -translation_of_original: Web/Guide/API/WebRTC ---- -

WebRTC (где RTC расшифровывается как Real-Time Communications) - это технология, которая позволяет передавать данные и потоковое аудио/видео между браузерами. Как набор стандартов в целом, WebRTC предоставляет любым поддерживающим этот стандарт, браузерам обмениваться данными и устраивать сеансы телеконференций в режиме точка-точка, без необходимости устанавливать какие-либо плагины и стороннее програмное обеспечение.

- -

Компоненты WebRTC доступны через API JavaScript: Network Stream API, который представляет собой поток аудио и видео данных, PeerConnection API, который позволяет двум и более пользователям общаться браузер-браузер напрямую, DataChannel API, который позволяет обмениваться данными других типов, например в играх в режиме реального времени, текстовые чаты, обмен файлами и так далее.

- -
-

На заметку: Эта документация находится в процессе переезда в свой новый дом.

-
- -

Руководства

- -
-
Обмен данными в режиме точка-точка с WebRTC
-
О том, как наладить обмен данными в режиме точка-точка используя API WebRTC.
-
Введение в архитектуру WebRTC
-
(AKA "WebRTC and the Ocean of Acronyms") WebRTC состоит из множества частей и это может быть причиной сложностей для новичков. Эта статья рассказывает обо всех частях и объясняет то как они между собой связаны.
-
Основы WebRTC
-
Теперь, когда вы уже знаете архитектуру WebRTC, вы можете перейти к этой статье, которая проведет вас через путь создания кросс-браузерного RTC-приложения
-
- -

Ссылки

- -
-
MediaDevices.getUserMedia
-
API захвата медиа (видео/аудио)
-
RTCPeerConnection
-
Интерфейс обработки потоковых данных между двуми пирами.
-
RTCDataChannel
-
Интерфейс передачи произвольных данных через соединение точка-точка.
-
diff --git a/files/ru/web/guide/css/getting_started/cascading_and_inheritance/index.html b/files/ru/web/guide/css/getting_started/cascading_and_inheritance/index.html deleted file mode 100644 index a192eb1d28..0000000000 --- a/files/ru/web/guide/css/getting_started/cascading_and_inheritance/index.html +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: Каскадность и наследование -slug: Web/Guide/CSS/Getting_started/Cascading_and_inheritance -tags: - - Beginner - - CSS - - 'CSS:Getting_Started' - - Guide - - Web - - Веб - - Новичку -translation_of: Learn/CSS/Building_blocks/Cascade_and_inheritance -translation_of_original: Web/Guide/CSS/Getting_started/Cascading_and_inheritance ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/How_CSS_works", "Как работает CSS")}} Это четвертый раздел руководства CSS для начинающих. Он описывает, как таблицы стилей взаимодействуют в каскаде, и как дочерние элементы наследуют стиль от родительских. Используя наследование, в приведённой ниже задаче вы измените стиль некоторых элементов за один шаг.

- -

Информация: Каскадность и наследование

- -

Окончательный стиль элемента можно указать во многих местах, которые комплексно взаимодействуют между собой. Эти комплексные взаимодействия делают CSS мощным, но в то же время, иногда сбивают с толку и порождают сложности при отладке. 

- -

Три основных источника информации о стилях образовывают каскад. К ним относятся следующие:

- -
    -
  • Стили разметки браузера по умолчанию.
  • -
  • Стили, указанные пользователем при чтении документа.
  • -
  • Стили, связанные с документом их автором. Их можно указывать в трех местах:
  • -
- -
    -
  1. Во внешнем файле: в этом учебном руководстве обсуждается преимущественно этот метод указания стилей.
  2. -
  3. В начале документа (раздел заголовок документа): используйте этот метод только для стилей в пределах этой страницы.
  4. -
  5. Для конкретного элемента в теле документа: это наименее поддерживаемый метод, но может быть использован для тестирования.
  6. -
- -

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

- -
-
Пример
- -

Когда вы читаете этот документ в браузере, часть стилей происходит от стилей для HTML по умолчанию вашего браузера.

- -

Часть стиля может происходить от измененных настроек браузера или измененного файла определения стиля. В Firefox настройки можно изменить в диалоге Предпочтения или же указать стили в файле userContent.css в профиле браузера.

- -

Часть стиля приходит из таблиц стилей, связываемых с документом вики-сервером.

-
- -

Когда вы открываете шаблон документа в браузере, элементы {{ HTMLElement("strong") }} имеют более жирный шрифт по сравнению с остальным текстом. Это следует из настроек HTML стилей браузера по умолчанию.

- -

Элемент {{ HTMLElement("strong") }} красного цвета. Это следует из настроек вашего шаблона таблиц стилей.

- -

Элементы {{ HTMLElement("strong") }} также наследуют большую часть стилей элемента {{ HTMLElement("p") }} поскольку они являются дочерними. Таким же образом элемент {{ HTMLElement("p") }} наследует большую часть стиля элемента {{ HTMLElement("body") }}.

- -

Для стилей в каскаде, авторские таблицы стилей имеют приоритет перед стилями для режимов чтения браузера. Последние, в свою очередь, имеют приоритет перед настройками браузера по умолчанию.

- -

Для наследуемых стилей, собственный стиль дочернего узла имеет приоритет над стилем, унаследованным от родительского узла.

- -

These are not the only priorities that apply. A later page in this tutorial will explain more.

- -
-
Подробнее
- -

CSS также предоставляет способ переопределения стиля в авторском документе для читателя с помощью ключевого слова !important.

- -

Это означает, что как автор документа, вы не всегда можете точно предсказать, что ваши читатели будут видеть в своём браузере.

- -

Если вы хотите знать все детали каскадирования и наследования, ознакомьтесь с документом Assigning property values, Cascading, and Inheritance в спецификации CSS.

-
- -

К действию: Использование наследования

- -
    -
  1. Откройте CSS-файл примера.
  2. -
  3. Добавьте в файл строку кода, представленную ниже. Не имеет особого значения, в какой части CSS-документа вы расположите эту строку. Тем не менее, добавить его в самом верху будет логично, поскольку в документе элемент {{ HTMLElement("p") }} является родительским по отношению к элементу {{ HTMLElement("strong") }} : -
    p {color: blue; text-decoration: underline;}
    -
    -
  4. -
  5. Теперь сохраните документ и обновите страницу в браузере, чтобы увидеть изменения. Весь текст в абзаце будет подчеркнут, в том числе и начальные буквы. Элемент {{ HTMLElement("strong") }} унаследовал подчеркнутый стиль от родительского элемента {{ HTMLElement("p") }} .
    - -

    Обратите внимание, что элементы {{ HTMLElement("strong") }} всё ещё красные. Красный цвет является их собственным стилем, поэтому имеет приоритет перед синим цветом, заданным для родительского элемента {{ HTMLElement("p") }} . 

    -
  6. -
- -

До

- -

HTML

- -
<p>
-<strong>C</strong>ascading
-<strong>S</strong>tyle
-<strong>S</strong>heets
-</p>
-
- -

CSS

- -
strong {color:red}
-
- -

{{ EmbedLiveSample('Before') }}

- -

После

- -

HTML

- -
<p>
-<strong>C</strong>ascading
-<strong>S</strong>tyle
-<strong>S</strong>heets
-</p>
-
- -

CSS

- -
p {color:blue; text-decoration:underline}
-strong {color:red}
- -

{{ EmbedLiveSample('After') }}

- -

 

- -
-
Задание
-Измените таблицу стилей таким образом, чтобы были подчеркнуты только красные буквы: - - - - - - - -
Cascading Style Sheets
- -
-
Возможное решение
- -

Переместите объявление подчеркивания из правила для {{ HTMLElement("p") }} в правило для {{ HTMLElement("strong") }}. В результате файл будет выглядеть следующим образом:

- -
p {color: blue; }
-strong {color: red; text-decoration: underline;}
-
- -

 

-Hide solution
-Посмотреть вариант решения.
- -

 

- -

Что дальше?

- -

{{ nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Selectors", "Селекторы")}}Ваш пример таблицы стилей определяет стили для тегов <p> и <STRONG>, изменяя стиль соответствующих элементов по всему документу. В следующем разделе описывается, как задать стиль более избирательными методами.

diff --git a/files/ru/web/guide/css/getting_started/color/index.html b/files/ru/web/guide/css/getting_started/color/index.html deleted file mode 100644 index 911a8010b6..0000000000 --- a/files/ru/web/guide/css/getting_started/color/index.html +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: Color -slug: Web/Guide/CSS/Getting_started/Color -translation_of: Learn/CSS/Introduction_to_CSS/Values_and_units#Colors -translation_of_original: Web/Guide/CSS/Getting_started/Color ---- -

{{ CSSTutorialTOC() }}

- -

{{previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Text_styles", "Text styles")}}This is the 8th section of the CSS Getting Started tutorial; it explains how you can specify color in CSS. In your sample stylesheet, you introduce background colors.

- -

Information: Color

- -

In this tutorial so far, you have used a limited number of named colors. CSS2 supports 17 named colors in all. Some of the names might not be what you expect:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 black gray silver white 
primariesred lime blue 
secondariesyellow aqua fuchsia 
 maroon orange olive purple green navy teal 
- -

 

- -
-
Details
- -

Your browser might support many more named colors, like:

- - - - - - - - - - - - - - - - -
dodgerblue peachpuff tan firebrick aquamarine 
- -

For details of this extended list, see: SVG color keywords in the CSS 3 Color Module. Beware of using color names that your reader's browsers might not support.

-
- -

For a larger palette, specify the red, green and blue components of the color you want by using a number sign (hash) and three hexadecimal digits in the range 0 – 9, a – f. The letters a – f represent the values 10 – 15:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
black #000
pure red #f00
pure green #0f0
pure blue #00f
white #fff
- -


- For the full palette, specify two hexadecimal digits for each component:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
black #000000
pure red #ff0000
pure green #00ff00
pure blue #0000ff
white #ffffff
- -

You can usually get these six-digit hexadecimal codes from your graphics program or some other tool.

- -
-
Example
- -

With a little practice, you can adjust the three-digit colors manually for most purposes:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Start with pure red: #f00
To make it paler, add some green and blue: #f77
To make it more orange, add a little extra green: #fa7
To darken it, reduce all its components: #c74
To reduce its saturation, make its components more equal: #c98
If you make them exactly equal, you get gray: #ccc
- -

For a pastel shade like pale blue:

- - - - - - - - - - - - - - -
Start with pure white: #fff
Reduce the other components a little: #eef
-
- -
-
More details
- -

You can also specify a color using decimal RGB values in the range 0 – 255, or percentages.

- -

For example, this is maroon (dark red):

- -
rgb(128, 0, 0)
-
- -

For full details of how to specify colors, see: Colors in the CSS Specification.

- -

For information on matching system colors like Menu and ThreeDFace, see: CSS2 System Colors in the CSS Specification.

-
- -

Color properties

- -

You have already used the {{ cssxref("color") }} property on text.

- -

You can also use the {{ cssxref("background-color") }} property to change elements' backgrounds.

- -

Backgrounds can be set to transparent to explicitly remove any color, revealing the parent element's background.

- -
-
Example
- -

The Example boxes in this tutorial use this pale yellow background:

- -
background-color: #fffff4;
-
- -

The More details boxes use this pale gray:

- -
background-color: #f4f4f4;
-
-
- -

 

- -

Action: Using color codes

- -

Color page

- -
    -
  1. Edit your CSS file.
  2. -
  3. Make the change shown down here, to give the initial letters a pale blue background. (The layout and comments in your file probably differ from the file shown here. Keep the layout and comments the way you prefer them.)
  4. -
  5. -

    HTML Content

    - -
    <p id = "first"> <strong>C</strong>ascading <strong class="spinach">S</strong>tyle <strong class="spinach">S</strong>heets</p>
    -<p> <strong>C</strong>ascading <strong>S</strong>tyle <strong>S</strong>heets</p>
    -
    - -

    CSS Content

    - -
    /*** CSS Tutorial: Color page ***/
    -
    -/* page font */
    -body {
    -  font: 16px "Comic Sans MS", cursive;
    -}
    -
    -/* paragraphs */
    -p {
    -  color: blue;
    -}
    -#first {
    -  font-style: italic;
    -}
    -
    -/* initial letters */
    -strong {
    -  background-color: #ddf;
    -  color: red;
    -  font: 200% serif;
    -}
    -
    -.spinach {
    -  color: green;
    -  background-color: #ddf;
    -}
    -
    -
    -
  6. -
  7. Save the file and refresh your browser to see the result.
  8. -
  9. The result should be like this:
  10. -
- -

{{ EmbedLiveSample('Color_page', '', '', '', 'Web/Guide/CSS/Getting_started/Color') }}

- -
-
Challenge
- -

In your CSS file, change all the color names to 3-digit color codes without affecting the result.

- -

(This cannot be done exactly, but you can get close. To do it exactly you need 6-digit codes, and you need to look up the CSS Specification or use a graphics tool to match the colors.)

- -
-
Possible solution
- -

The following values are reasonable approximations of the named colors:

- -
strong {
-  color: #f00; /* red */
-  background-color: #ddf; /* pale blue */
-  font: 200% serif;
-}
-
-.carrot {
-  color: #fa0; /* orange */
-}
-
-.spinach {
-  color: #080; /* dark green */
-}
-
-p {
-  color: #00f; /* blue */
-}
-
- -

 

-Hide solution
-See a solution for the challenge.
- -

What next?

- -

{{nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Content", "Content")}}Your sample document and your sample stylesheet strictly separate content from style. The next section explains how you can make exceptions to this strict separation.

diff --git a/files/ru/web/guide/css/getting_started/how_css_works/index.html b/files/ru/web/guide/css/getting_started/how_css_works/index.html deleted file mode 100644 index 9edeb9fe1f..0000000000 --- a/files/ru/web/guide/css/getting_started/how_css_works/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Как работает CSS -slug: Web/Guide/CSS/Getting_started/How_CSS_works -translation_of: Learn/CSS/First_steps/How_CSS_works -translation_of_original: Web/Guide/CSS/Getting_started/How_CSS_works ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/Why_use_CSS", "Зачем нужен CSS?") }} Это третья статья руководства по CSS для начинающих, объясняет, как работает CSS в вашем браузере, а также назначение Объектной Модели Документа (Document Object Model или DOM). Вы также узнаете, как сделать анализ документа.

- -

Информация: Как работает CSS

- -

Когда браузер отображает документ, он должен совместить содержимое документа с информацией о стилях для него. Браузер обрабатывает документ в два этапа:

- -
    -
  1. Браузер преобразует язык разметки и CSS в DOM (Document Object Model). DOM представляет собой документ в памяти компьютера. Он сочетает в себе содержание документа с его стилем.
  2. -
  3. Браузер отображает содержимое DOM.
  4. -
- -

Язык разметки использует элементы для определения структуры документа. Элемент обозначается с использованием тегов, которые представляют собой строки, начинающиеся с символа '<' и заканчивающиеся '>'. Большинство элементов имеет парные теги: открывающий тег и закрывающий тег. Для открывающего тега, поместите имя элемента между '<' и '>'. Для закрывающего тега, поместите '/'  между '<', и именем элемента.

- -

В зависимости от языка разметки, некоторые элементы имеют только начальный тег, или тег, где '/' располагается после имени элемента. Элемент так же может быть контейнером, включающим в себя другие элементы. В этом случае они располагаются между открывающим и закрывающим тегами. Не забывайте всегда закрывать теги внутри контейнера.

- -

DOM имеет древовидную структуру. Каждый элемент, атрибут и запуск текста на языке разметки становится узлом в древовидной структуре. Узлы определяются их взаимодействием с другими узлами DOM. Некоторые элементы становятся родительскими по отношению к другим, дочерним узлам (или узлам-потомкам). В свою очередь, дочерние узлы имеют "братьев" (siblings).

- -

Понимание DOM поможет вам при разработке, отладке и поддержке CSS, поскольку DOM это место, где встречаются CSS и содержимое документа.

- -
-
Пример
- -
 
-В данном примере, тег <p> и его закрывающий тег </p> создают контейнер: - -
<p>
-  <strong>C</strong>ascading
-  <strong>S</strong>tyle
-  <strong>S</strong>heets
-</p>
-
- -

Живой пример

- -

{{ EmbedLiveSample('Информация_Как_работает_CSS', '', '', '', 'Web/Guide/CSS/Getting_started/How_CSS_works') }}

- -

В DOM соответствующий узел P является родительским. Его дочерние узлы - это теги STRONG  и узлы текста. Теги STRONG,  в свою очередь, являются родительскими по отношению к текстовым узлам, которые являются их дочерними узлами:

- -
P
-├─STRONG
-│ └─"C"
-├─"ascading"
-├─STRONG
-│ └─"S"
-├─"tyle"
-├─STRONG
-│ └─"S"
-└─"heets"
-
- -

К действию: Анализ DOM

- -

Использование DOM Inspector

- -

Для анализа DOM, вам потребуется специальная программа. Вы можете использовать расширение DOM Inspector (DOMi) от Mozilla для анализа DOM. Вам просто нужно установить это расширение в браузере (подробнее см. ниже).

- -
    -
  1. Используйте браузер Mozilla, чтобы открыть свой HTML-документ.
  2. -
  3. Из строки меню браузера выберите Инструменты > DOM инспектор, или Инструменты > Веб-разработка > Инспектор. -
    -
    Подробнее
    - -

    Если в вашем браузере Mozilla не установлен DOMi, вы можете установить его с сайта дополнений и перезапустить браузер. Затем возвращайтесь к этому руководству.

    - -

    Если вы не хотите устанавливать DOMi (или вы используете браузер не от Mozilla), то можете воспользоваться Рентген-очками, как описано в секции ниже. Или вы можете пропустить эту секцию и перейти к прямо к следующей странице. Если вы пропустите данный раздел, это не помешает вам в дальнейшем освоении руководства.

    -
    -
  4. -
  5. В DOMi разверните узлы вашего документа, нажав на их стрелки. -

    Замечание:  Пустые места в вашем HTML файле DOMi может отображать как пустые текстовые узлы, которые можно игнорировать.

    - -

    Часть результата может выглядеть следующим образом, в зависимости от того, какие узлы вы развернули:

    - -
    │ ▼╴P
    -│ │ │ ▼╴STRONG
    -│ │ └#text
    -│ ├╴#text
    -│ ►╴STRONG
    -│ │
    - -

    При выборе любого узла, вы можете использовать правую панель DOMi's для поиска информации об узле. Например, когда вы выбираете текстовый узел, DOMi показывает вам текст в соответствующей панели.

    - -

    При выборе узла элемента, DOMi анализирует его и предоставляет огромное количество информации, которая содержится в правой панели. Информация о стилях - лишь часть информации, которую там можно просмотреть.

    -
  6. -
- -
-
Задача
- -

В DOMi, кликните на узле STRONG.

- -

Используйте правую панель ДОМи, чтобы выяснить, где цвет для этого узла установлен на красный, и где его внешний вид сделан толще, чем обычный текст.

- -
-
Possible solution
- -

In the menu above the right-hand pane, choose CSS Rules. You see two items listed, one that references an internal resource and one that references your stylesheet file. The internal resource defines the font-weight property as bolder; your stylesheet defines the color property as red.

-Hide solution
-Посмотреть решение задачи.
- -

Использование Рентген-очков

- -

Рентген-очки показывают меньше информации, чем DOM Инспектор, но проще в установке и использовании.

- -
    -
  1. Перейдите на домашнюю страницу X-Ray Goggles.
  2. -
  3. Перетащите ссылку X-Ray Googles с этой страницы на панель закладок.
  4. -
  5. Откройте HTML-документ.
  6. -
  7. Запустите Рентген-очки, кликнув по появившейся закладке.
  8. -
  9. Передвигайте курсор мыши по документу для просмотра элементов в документе.
  10. -
- -

Что дальше?

- -

{{ nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Cascading_and_inheritance", "Каскадность и наследование") }}Если вы решили задачу, то увидели, что информация о стиле из более чем одного места взаимодействует для создания окончательного стиля для элемента. На следующей странице объясняется больше об этих взаимодействиях.

diff --git a/files/ru/web/guide/css/getting_started/index.html b/files/ru/web/guide/css/getting_started/index.html deleted file mode 100644 index b2f6ebed77..0000000000 --- a/files/ru/web/guide/css/getting_started/index.html +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: CSS для начинающих -slug: Web/Guide/CSS/Getting_started -tags: - - Beginner - - CSS - - 'CSS:Getting_Started' - - Guide - - Needs - - NeedsBeginnerUpdate - - NeedsTranslation - - NeedsUpdate - - TopicStub - - Web - - Новичку - - Руководство -translation_of: Learn/CSS/First_steps -translation_of_original: Web/Guide/CSS/Getting_started ---- -

Это руководство (самоучитель) познакомит вас с базовыми возможностями и языком (синтаксом) Каскадных таблиц стилей (CSS). CSS используется для изменения внешнего вида структурированного документа, такого как веб-страница. Руководство также включает простые упражнения, которые вы сможете выполнить на своем компьютере и увидеть, как работает CSS, а также его возможности в современных браузерах.

- -

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

- - - -

Что вам нужно для того, чтобы начать

- -
    -
  • Текстовый редактор
  • -
  • Современный браузер
  • -
  • Опыт работы с текстовым редактором и браузером
  • -
- -

В данном руководстве вам будут встречаться упражнения, которые вам предлагается выполнить для лучшего понимания материала. Их выполнение не является обязательным: вы можете просто читать материал и смотреть на иллюстрации.

- -

Важно: Руководство включает в себя материалы по работе с цветом в CSS. Эти материалы будет легче пройти, если у вас цветной монитор и нормальное цветовое зрение.

- -

Как пользоваться руководством

- -

Наилучшим вариантом будет внимательное и постепенное чтение разделов в строгой последовательности. Если вы пропустите какой-то раздел, вам может оказаться что-то непонятно в следующих главах.

- -

Часть I: Основы CSS

- -

На каждой странице, используйте секцию Информация, чтобы понять, как работает CSS. Используйте секцию К действию, чтобы попробовать использовать CSS на вашем компьютере.

- -

Чтобы проверить усвоенные знания, вам будет полезно решить задачу в конце каждой страницы. Верные решения задач вы всегда можете найти под их описанием в виде ссылки - таким образом, вы не сможете увидеть их случайно.

- -

Чтобы добиться более глубокого понимания CSS, читайте информацию в блоках с заголовком Подробнее. А также не забудьте посетить приведенные там ссылки.

- -

Часть II: Возможности CSS

- -

Вторая часть руководства содержит примеры, которые продемонстрируют вам возможности CSS применительно к другим web-технологиям и технологиям Mozilla. 

- -
    -
  1. JavaScript
  2. -
  3. SVG графика
  4. -
  5. XML данные
  6. -
  7. XBL байдинг bindings
  8. -
  9. Пользовательские интерфейсы XUL
  10. -
diff --git a/files/ru/web/guide/css/getting_started/readable_css/index.html b/files/ru/web/guide/css/getting_started/readable_css/index.html deleted file mode 100644 index 9e9a4231a9..0000000000 --- a/files/ru/web/guide/css/getting_started/readable_css/index.html +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: Чистый СSS код -slug: Web/Guide/CSS/Getting_started/Readable_CSS -translation_of: Learn/CSS/Introduction_to_CSS/Syntax#Beyond_syntax_make_CSS_readable -translation_of_original: Web/Guide/CSS/Getting_started/Readable_CSS ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors", "Selectors")}}Это 6-я статья руководства CSS для начинающих; здесь обсуждается стиль и грамматика самого языка CSS. Вы можете изменить пусть к вашему файлу CSS на более удобный для чтения.

- -

Информация: Чистый код CSS

- -

Вы можете добавлять пустое пространство и комментарии к вашим стилям, чтобы сделать их более читабельными. Также вы можете группировать селекторы вместе, в случае если те же самые правила стиля применяются к разным элементам.

- -

Пустое пространство

- -

Пустое пространство означает фактические пробелы, табуляцию, а также новые строки. Вы можете использовать их, чтобы сделать ваш код более читабельным.

- -

В макете страницы, данное пространство — это та часть, которая остается без опознавательных знаков: отступы от других элементов (margin) и пространство между колонками и строками.

- -

Ваш пример файла CSS в настоящее время имеет правила в одной строке, и почти минимум пробелов. В комплексе стилей эта схема будет усложнять читаемость, а значит в нее будет трудно вносить изменения.

- -

Стиль написания который вы выбираете, как правило, зависит от личных предпочтений, но если ваши css являются частью общих проектов, могут возникнуть трудности с понимаем вашего написания кода.

- -
-
Примеры
- -

Некоторые люди пытаются написать код максимально компактно и пишут код в одну строку, даже если он достаточно долгий:

- -
.carrot {color: orange; text-decoration: underline; font-style: italic;}
-
- -

Некоторые люди предпочитают писать каждое свойство-значение в отдельной строке:

- -
.carrot
-{
-color: orange;
-text-decoration: underline;
-font-style: italic;
-}
-
- -

Некоторые используют отступы — 2 или 4 пробела или табы:

- -
.carrot {
-  color: orange;
-  text-decoration: underline;
-  font-style: italic;
-}
-
- -

Некоторые люди все выстраивают вертикально (но такое расположение не лучший вариант для поддержки):

- -
.carrot
-    {
-    color           : orange;
-    text-decoration : underline;
-    font-style      : italic;
-    }
-
- -

Некоторые люди используют смешанный пробелы для повышения читаемости.

- -
.vegetable         { color: green; min-height:  5px; min-width:  5px }
-.vegetable.carrot  { color: orange;    height: 90px;     width: 10px }
-.vegetable.spinach { color: darkgreen; height: 30px;     width: 30px }
-
-
- -

Некоторые используют вкладки для компоновки элементов, а другие только пробелы.

- -

Комментарии

- -

Комментарии в CSS имеют следующий вид: /* комментарий */.

- -

Вы можете использовать комментарии, чтобы сделать фактические комментарии в css, а также чтобы закомментировать временно часть кода с целью тестирования.

- -

Часть стилей, которая будет закомментирована, не будет отображатся браузером. Будьте осторожны при комментировании кода, поскольку важно сохранить правильный синтаксис остального кода.

- -
-
Пример
- -
/* стиль для начальной буквой C в первом пункте*/
-.carrot {
-  color:            orange;
-  text-decoration:  underline;
-  font-style:       italic;
-  }
-
-
- -

Группировка селекторов

- -

Когда многие элементы имеют один и тот же стиль, вы можете указывать группу селекторов, разделяя их запятыми. Декларация применится для всех выбранных элементов.

- -

В другом месте в таблице стилей можно указать те же селекторы уже индивидуально, чтобы применить индивидуальные правила стилей для них.

- -
-
Пример
- -

Это правило делает элементы {{HTMLElement ("h1")}}, {{HTMLElement ("h2")}}, и {{HTMLElement ("h3")}} одного цвета.

- -

Удобно определить цвет только в одном месте, в случае, если возможны изменения.

- -
/* цвет для заголовков */
-h1, h2, h3 {color: navy;}
-
-
- -

Действуем: добавление комментариев и улучшения формата

- -
    -
  1. Редактируя ваш CSS-файл убедитесь, что он применяет эти правила (в любом порядке): -
    strong {color: red;}
    -.carrot {color: orange;}
    -.spinach {color: green;}
    -#first {font-style: italic;}
    -p {color: blue;}
    -
    -
  2. -
  3. Сделайте его более читабельным, перестраивая его таким образом, какой будете считать более логичным и применяя пробелы и комментарии на свое усмотрение.
  4. -
  5. Сохраните файл и обновите экран браузера, чтобы убедиться, что ваши изменения не повлияли на роботу стилей: - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  6. -
- -
-
Задание
- -

Закомментируйте часть стиля не меняя остальное, чтобы сделать первую букву вашего документа красной:

- - - - - - - - - - -
Cascading Style Sheets
Cascading Style Sheets
- -

(Существует более чем один способ сделать это).

- -
-
Possible solution
-One way to do this is to put comment delimiters around the rule for .carrot: - -
/*.carrot {
-  color: orange;
-}*/
-Hide solution
-Посмотреть решение задания.
- -

Что дальше?

- -

{{ nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Text_styles", "Text styles") }}Ваш образец таблицы стилей использовал курсивный текст и подчеркнутый текст. На следующей странице описаны несколько способов, чтобы указать внешний вид текста в вашем документе.

diff --git a/files/ru/web/guide/css/getting_started/selectors/index.html b/files/ru/web/guide/css/getting_started/selectors/index.html deleted file mode 100644 index 797aefefa3..0000000000 --- a/files/ru/web/guide/css/getting_started/selectors/index.html +++ /dev/null @@ -1,434 +0,0 @@ ---- -title: Selectors -slug: Web/Guide/CSS/Getting_started/Selectors -translation_of: Learn/CSS/Building_blocks/Selectors -translation_of_original: Web/Guide/CSS/Getting_started/Selectors ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Cascading_and_inheritance", "Cascading & inheritance")}}Это пятый раздел руководства CSS для начинающих. В нем объясняется, как можно выборочно применять стили и каким образом различные типы селекторов имеют разные приоритеты.  

- -

Некоторые атрибуты добавляются к тегам в шаблоне документа, и эти атрибуты используются в шаблоне таблицы стилей.

- -

Информация: Селекторы

- -

Ранее мы уже встречались с селекторами. Мы создали строку в файле стилей следующего вида:

- -
strong {
-  color: red;
-}
-
- -

В терминологии CSS эта строка полностью является правилом CSS. Это правило начинается со strong, что и называется селектором CSS. Селектор выбирает, к каким элементам DOM применяется правило.

- -
-
Подробности
- -

Часть внутри фигурных скобок называется объявлением.

- -

Ключевое слово colorсвойство, а red - значение.

- -

Точка с запятой после пары "свойство-значение" отделяет её от других пар "свойство-значение" в том же объявлении.

- -

Этот учебник ссылается на селектор типа strong как на селектор тега. Спецификация CSS ссылается на него как на селектор типа.

-
- -

На этой странице учебника объясняются дополнительные сведения о селекторах, которые можно использовать в правилах CSS.

- -

В дополнение к именам тегов, вы можете использовать в селекторах значения атрибутов. Это позволит вашим правилам быть более избирательными.

- -

Два атрибута имеют особый статус в CSS. Это class и id.

- -

Селекторы классов

- -

Используйте атрибут class в элементе, чтобы назначить элемент именованному классу. Выбор имени класса целиком за вами. Множество элементов в документе может иметь одно и то же значение класса.

- -

В вашей таблице стилей используйте точку перед именем класса для использования его в качестве селектора.

- -

Селекторы ID

- -

Используйте атрибут id в элементе, чтобы назначить идентификатор элементу. Это зависит от вас, какое имя вы выберете для ID. Идентификационное имя должно быть уникальным в документе.

- -

В таблице стилей введите знак решетки перед идентификатором, когда вы используете его в селекторе.

- -
-
Пример
-Этот HTML тэг имеет оба элемента, атрибут class и id: - -
<p class="key" id="principal">
-
- -

Значение идентификатора id, principal, должно быть уникально в документе, но разные тэги в документе, могут иметь одинаковое имя class со значением key.

- -

Это правило делает все классы(class) со значениемkey зелёными. (Они даже не должны быть все элементами {{ HTMLElement("p") }}.)

- -
.key {
-  color: green;
-}
-
- -

Это правило делает один элемент с идентификатором (id) и значением principal полужирным:

- -
#principal {
-  font-weight: bolder;
-}
-
-
- -

Селекторы Атрибутов

- -

Вы не ограничены двумя специальными атрибутами, class и id. Вы можете определить другие атрибуты используя квадратные скобки. Внутри скобок вы задаёте имя атрибута, так же можно указать оператор соответствия и значение. Дополнительно, соответствие может быть установлено как чувствительное к регистру если дописать " i" после значения, но пока не все браузеры это поддерживают. Примеры:

- -
-
[disabled]
-
Выбирает все элементы с атрибутом "disabled".
-
[type='button']
-
Выбирает элементы с типом "button".
-
[class~=key]
-
Выбирает элементы со значением класса(class) "key" (но не такие как например "keyed", "monkey", "buckeye"). По сути эквивалентно .key.
-
[lang|=es]
-
Выбирает элементы определённые как Spanish. Это включает "es" и "es-MX" но не включает "eu-ES" (что является языком Basque).
-
[title*="example" i]
-
Выбирает элементы в состав которых входит "example", игнорируя регистр. В браузерах, которые не поддерживают флаг "i", этот селектор возможно не найдет ни один элемент.
-
a[href^="https://"]
-
Выбирает все защищённые ссылки.
-
img[src$=".png"]
-
Косвенно выбирает изображения PNG; любые изображения которые являются изображениями PNG но, чей адрес URL не заканчивается на ".png" (такие как в строке запроса) не будут выбраны.
-
- -

Селекторы псевдокласса

- -

Псевдокласс класса CSS - это ключевое слово, добавленное в селектор, который задает особое состояние выбранного элемента. Например {{Cssxref (": hover")}} применит стиль, когда пользователь наводит на элемент, указанный селектором.

- -

Псевдо-классы вместе с псевдоэлементами позволяют применять стиль к элементу не только по отношению к содержанию дерева документов, но и по отношению к внешним факторам, таким как история навигатора ({{ cssxref(":visited") }}, для примера), статус его содержимого (наподобии {{ cssxref(":checked") }} на некоторых элементах формы) или положение мыши (наподобии {{ cssxref(":hover") }} который позволяет узнать, находится ли мышь над элементом или нет). Чтобы просмотреть полный список селекторов, посетите CSS3 Спецификация работы селекторов.

- -
-
Синтаксис
- -
selector:pseudo-class {
-  property: value;
-}
-
-
- -

Список псевдоклассов

- -
    -
  • {{ Cssxref(":link") }}
  • -
  • {{ Cssxref(":visited") }}
  • -
  • {{ Cssxref(":active") }}
  • -
  • {{ Cssxref(":hover") }}
  • -
  • {{ Cssxref(":focus") }}
  • -
  • {{ Cssxref(":first-child") }}
  • -
  • {{ Cssxref(":last-child") }}
  • -
  • {{ Cssxref(":nth-child") }}
  • -
  • {{ Cssxref(":nth-last-child") }}
  • -
  • {{ Cssxref(":nth-of-type") }}
  • -
  • {{ Cssxref(":first-of-type") }}
  • -
  • {{ Cssxref(":last-of-type") }}
  • -
  • {{ Cssxref(":empty") }}
  • -
  • {{ Cssxref(":target") }}
  • -
  • {{ Cssxref(":checked") }}
  • -
  • {{ Cssxref(":enabled") }}
  • -
  • {{ Cssxref(":disabled") }}
  • -
- -

Информация: Специфичность

- -

Несколько правил могут иметь селектор, каждый из которых соответствует одному и тому же элементу. Если свойство задано только одним правилом, конфликт не возникает, и свойство устанавливается в элементе. Если к элементу применяется более одного правила и устанавливает одно и то же свойство, тогда CSS дает приоритет правилу, которое имеет более конкретный селектор. Селектор ID более специфичен, чем селектор класса, псевдокласса или атрибута, который, в свою очередь, более специфичен, чем селектор тегов или псевдоэлементов.

- -
-
Подробнее
- -

Вы также можете комбинировать селектор, создавая более конкретный селектор. Например, селектор .key выбирает все элементы, с ключом имени класса key. Селектор p.key отбирает только {{ HTMLElement("p") }} элементы, которые имеют имя класса key.

-
- -

Если таблица стилей имеет противоречивые правила, и они одинаково специфичны, тогда CSS дает приоритет правилу, которое позже находится в таблице стилей.

- -

Если у вас возникла проблема с конфликтующими правилами, попробуйте разрешить это, сделав одно из правил более конкретным, чтобы оно имело приоритет. Если вы не можете этого сделать, попробуйте переместить одно из правил ближе к концу таблицы стилей, чтобы оно имело приоритет.

- -

Информация: Селекторы на основе отношений

- -

CSS имеет несколько способов выбора элементов на основе отношений между элементами. Вы можете использовать их, чтобы сделать селектора более конкретными.

- - - - - - - - - - - - - - - - - - - - - - - - - -
Общие селекторы, основанные на отношениях
СелекторВыбрано
A EЛюбой E элемент, что является потомком одного из A элемента (то есть: дочерний, или один из дочернего, т.д.)
A > EЛюбой E элемент, что явлется  дочерним (т.е. прямой потомок)  A элемента.
E:first-childЛюбой E элемент, что является первым дочерним элементом родительского элемента.
B + EЛюбой E элемент, что является следующим "братом" B элемента (то есть: следующий ребенок того же родителя)
- -

Вы можете комбинировать их для выражения сложных отношений.

- -

Вы можете так же использовать символ * (звездочка), что подразумевает "любой элемент".

- -
-
Пример
- -

Таблица HTML имеет аттрибут id , но строки и ячейки не имеют отдельных идентификаторов:

- -
<table id="data-table-1">
-...
-<tr>
-<td>Prefix</td>
-<td>0001</td>
-<td>default</td>
-</tr>
-...
-
- -

Эти правила делают первую ячейку в каждой строке подчеркнутой, а "брат" первой ячейки каждой строки зачеркнутой (в примере 2-я ячейка) . Они влияют только на одну конкретную таблицу в документе::

- -
#data-table-1 td:first-child {text-decoration: underline;}
-#data-table-1 td:first-child + td {text-decoration: line-through;}
-
- -

Резульат  выглядит  наподобии:

- - - - - - - -
- - - - - - - - -
Prefix0001default
-
-
- -
-
Подробно
- -

Обычным способом, если вы делаете селектор более конкретным, вы увеличиваете его приоритет.

- -

Если вы используете эти методы, вы избегаете необходимость указывать в атрибутах class или id на множестве тегов в вашем документе. Вместо этого, CSS выполнит эту работу.

- -

В больших конструкциях, где скорость важна, вы можете сделать свои таблицы стилей более эффективными, избегая сложных правил, которые зависят от отношений между элементами.

- -

Дополнительные примеры о таблицах, смотрите Tables на странице ссылок CSS.

-
- -

Действие: Использование селекторов class и ID

- -
    -
  1. Измените свой HTML-файл и продублируйте абзац, скопировав его и вставив в него.
  2. -
  3. Затем добавьте аттрибуты id и class  в первую копию, а аттрибут id во вторую копию, как показано ниже. Кроме того, скопируйте и вставьте весь файл снова: -
    <!doctype html>
    -<html>
    -  <head>
    -  <meta charset="UTF-8">
    -  <title>Sample document</title>
    -  <link rel="stylesheet" href="style1.css">
    -  </head>
    -  <body>
    -    <p id="first">
    -      <strong class="carrot">C</strong>ascading
    -      <strong class="spinach">S</strong>tyle
    -      <strong class="spinach">S</strong>heets
    -    </p>
    -    <p id="second">
    -      <strong>C</strong>ascading
    -      <strong>S</strong>tyle
    -      <strong>S</strong>heets
    -    </p>
    -  </body>
    -</html>
    -
    -
  4. -
  5. Теперь отредактируйте свой файл CSS. Замените все содержимое на: -
    strong { color: red; }
    -.carrot { color: orange; }
    -.spinach { color: green; }
    -#first { font-style: italic; }
    -
    -
  6. -
  7. Сохраните файлы и обновите свой браузер, чтобы увидеть результат: - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    - -

    Вы можете попробовать перестроить строки в вашем файле CSS, чтобы показать, что порядок не имеет никакого эффекта.

    - -

    Селекторы классов .carrot и .spinach имеют приоритет над селектором тега strong.

    - -

    Селектор ID #first имеет приоритет над селекторами класс и тег.

    -
  8. -
- -
-
Вызовы
- -
    -
  1. Не изменяя свой HTML-файл, добавьте в свой CSS-файл одно правило, которое сохраняет все начальные буквы того же цвета, что и сейчас, но делает весь текст во втором абзаце синим: - - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  2. -
  3. Теперь измените правило, которое вы только что добавили (не изменяя ничего другого), чтобы сделать первый абзац синим: - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  4. -
- -
-
Possible solution
- -
    -
  1. Add a rule with an ID selector of #second and a declaration color: blue;, as shown below: - -
    #second { color: blue; }
    -
    - A more specific selector, p#second also works.
  2. -
  3. Change the selector of the new rule to be a tag selector using p: -
    p { color: blue; }
    -
    -
  4. -
-Hide solution
-See a solution for the challenge.
- -

Действие: Использование селекторов псевдокласса

- -
    -
  1. Создайте HTML-файл со следующим содержимым: - -
    <!doctype html>
    -<html>
    -  <head>
    -  <meta charset="UTF-8">
    -  <title>Sample document</title>
    -  <link rel="stylesheet" href="style1.css">
    -  </head>
    -  <body>
    -    <p>Go to our <a class="homepage" href="http://www.example.com/" title="Home page">Home page</a>.</p>
    -  </body>
    -</html>
    -
    -
  2. -
  3. Теперь отредактируйте свой файл CSS. Замените все содержимое на: -
    a.homepage:link, a.homepage:visited {
    -  padding: 1px 10px 1px 10px;
    -  color: #fff;
    -  background: #555;
    -  border-radius: 3px;
    -  border: 1px outset rgba(50,50,50,.5);
    -  font-family: georgia, serif;
    -  font-size: 14px;
    -  font-style: italic;
    -  text-decoration: none;
    -}
    -
    -a.homepage:hover, a.homepage:focus, a.homepage:active {
    -  background-color: #666;
    -}
    -
    -
  4. -
  5. Сохраните файлы и обновите свой браузер, чтобы увидеть результат (наведите указатель мыши на следующую ссылку, чтобы увидеть эффект): - - - - - - -
    Перейдите к нашей Домашняя страница 
    -
  6. -
- -

Действие: Использование селекторов на основе отношений и псевдоклассов

- -

С помощью селекторов, основанных на связях и псевдоклассах, вы можете создавать сложные каскадные алгоритмы. Это обычная техника, используемая, например, для создания чисто-CSS выпадающее меню ( это только CSS, без использования JavaScript). Суть этого метода заключается в создании правила следующего вида:

- -
div.menu-bar ul ul {
-  display: none;
-}
-
-div.menu-bar li:hover > ul {
-  display: block;
-}
- -

для применения к структуре HTML, наподобии следующей:

- -
<div class="menu-bar">
-  <ul>
-    <li>
-      <a href="example.html">Menu</a>
-      <ul>
-        <li>
-          <a href="example.html">Link</a>
-        </li>
-        <li>
-          <a class="menu-nav" href="example.html">Submenu</a>
-          <ul>
-            <li>
-              <a class="menu-nav" href="example.html">Submenu</a>
-              <ul>
-                <li><a href="example.html">Link</a></li>
-                <li><a href="example.html">Link</a></li>
-                <li><a href="example.html">Link</a></li>
-                <li><a href="example.html">Link</a></li>
-              </ul>
-            </li>
-            <li><a href="example.html">Link</a></li>
-          </ul>
-        </li>
-      </ul>
-    </li>
-  </ul>
-</div>
-
- -

Смотрите наш полный Пример CSS-основанного выпадающего меню для возможной реплики.

- -

Что дальше?

- -

Ваша таблица стилей начинает выглядеть плотной и сложной. Следующая секция описывает пути CSS легкого чтения. {{nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Readable_CSS", "Readable CSS")}}

diff --git "a/files/ru/web/guide/css/getting_started/svg_\320\270_css/index.html" "b/files/ru/web/guide/css/getting_started/svg_\320\270_css/index.html" deleted file mode 100644 index a69c4281af..0000000000 --- "a/files/ru/web/guide/css/getting_started/svg_\320\270_css/index.html" +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: SVG и CSS -slug: Web/Guide/CSS/Getting_started/SVG_и_CSS -translation_of: Web/SVG/Tutorial/SVG_and_CSS ---- -
{{CSSTutorialTOC}}
- -

На этой странице показано, как использовать CSS со специальным языком для создания графики: SVG.

- -

Вы сделаете небольшой пример, которые можно будет запустить в любом браузере с поддержкой SVG.

- -

Это вторая секция Части II Руководство по CSS.
- Предыдущая секция: JavaScript
- Следующая секция: Данные XML

- -

Общая информация: SVG

- -

SVG (Scalable Vector Graphics) является подмножеством языка XML и предназначен для создания графики.

- -

SVG можно использовать для статических изображений, а также для анимаций и создания пользовательских интерфейсов.

- -

Как и прочие языки, основанные на XML, SVG поддерживает использование таблиц стилей CSS, что позволяет отделить различные варианты визуального отображения от структуры данных.

- -

Кроме того, таблицы стилей, которые вы используете в других языках разметки документов, могут содержать ссылку на SVG графику, в тех местах, где необходимо изображение. Например, в таблице стилей, для вашего HTML документа, можно указать ссылку (URL) на SVG графику в свойстве background.

- - - - - - - - -
Немного подробностей
-

На момент написания статьи (середина 2011года), большинство современных браузеров имеет базовую поддержку SVG, в том числе Internet Explorer 9 и выше. Некоторые дополнительные возможности SVG не поддерживаются, либо поддерживаются лишь частично, в определенных браузерах. Для более подробной информации о текущей поддержке SVG, см. SVG tables on caniuse.com, либо в таблицах совместимости SVG element reference, для информации о поддержке отдельных элементов.

- -

В остальные версии можно добавить поддержку SVG, установив дополнительный плагин, например, предоставленный компанией Adobe.

- -

Более подробная информация о SVG в Mozilla, представлена на станице SVG в этой wiki.

-
- -

За дело: Демонстрация SVG

- -

Создайте новый документ SVG, как обычный текстовый файл, doc8.svg. Скопируйте и вставьте содержимое блока ниже, убедитесь, что пролистали его полностью, чтобы скопировать все:

- -
<?xml version="1.0" standalone="no"?>
-
-<?xml-stylesheet type="text/css" href="style8.css"?>
-
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
-  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-
-<svg width="600px" height="600px" viewBox="-300 -300 600 600"
-  xmlns="http://www.w3.org/2000/svg" version="1.1"
-  xmlns:xlink="http://www.w3.org/1999/xlink">
-
-<title>SVG demonstration</title>
-<desc>Mozilla CSS Getting Started - SVG demonstration</desc>
-
-<defs>
-  <g id="segment" class="segment">
-    <path class="segment-fill" d="M0,0 v-200 a40,40 0 0,0 -62,10 z"/>
-    <path class="segment-edge" d="M0,-200 a40,40 0 0,0 -62,10"/>
-    </g>
-  <g id="quadrant">
-    <use xlink:href="#segment"/>
-    <use xlink:href="#segment" transform="rotate(18)"/>
-    <use xlink:href="#segment" transform="rotate(36)"/>
-    <use xlink:href="#segment" transform="rotate(54)"/>
-    <use xlink:href="#segment" transform="rotate(72)"/>
-    </g>
-  <g id="petals">
-    <use xlink:href="#quadrant"/>
-    <use xlink:href="#quadrant" transform="rotate(90)"/>
-    <use xlink:href="#quadrant" transform="rotate(180)"/>
-    <use xlink:href="#quadrant" transform="rotate(270)"/>
-    </g>
-  <radialGradient id="fade" cx="0" cy="0" r="200"
-      gradientUnits="userSpaceOnUse">
-    <stop id="fade-stop-1" offset="33%"/>
-    <stop id="fade-stop-2" offset="95%"/>
-    </radialGradient>
-  </defs>
-
-<text id="heading" x="-280" y="-270">
-  SVG demonstration</text>
-<text  id="caption" x="-280" y="-250">
-  Move your mouse pointer over the flower.</text>
-
-<g id="flower">
-  <circle id="overlay" cx="0" cy="0" r="200"
-    stroke="none" fill="url(#fade)"/>
-  <use id="outer-petals" xlink:href="#petals"/>
-  <use id="inner-petals" xlink:href="#petals"
-    transform="rotate(9) scale(0.33)"/>
-  </g>
-
-</svg>
-
- -

Создайте новый файл CSS, style8.css. копируйте и вставьте содержимое блока ниже, убедитесь, что пролистали его полностью, чтобы скопировать все:

- -
/*** SVG demonstration ***/
-
-/* page */
-svg {
-  background-color: beige;
-  }
-
-#heading {
-  font-size: 24px;
-  font-weight: bold;
-  }
-
-#caption {
-  font-size: 12px;
-  }
-
-/* flower */
-#flower:hover {
-  cursor: crosshair;
-  }
-
-/* gradient */
-#fade-stop-1 {
-  stop-color: blue;
-  }
-
-#fade-stop-2 {
-  stop-color: white;
-  }
-
-/* outer petals */
-#outer-petals {
-  opacity: .75;
-  }
-
-#outer-petals .segment-fill {
-  fill: azure;
-  stroke: lightsteelblue;
-  stroke-width: 1;
-  }
-
-#outer-petals .segment-edge {
-  fill: none;
-  stroke: deepskyblue;
-  stroke-width: 3;
-  }
-
-#outer-petals .segment:hover > .segment-fill {
-  fill: plum;
-  stroke: none;
-  }
-
-#outer-petals .segment:hover > .segment-edge {
-  stroke: slateblue;
-  }
-
-/* inner petals */
-#inner-petals .segment-fill {
-  fill: yellow;
-  stroke: yellowgreen;
-  stroke-width: 1;
-  }
-
-#inner-petals .segment-edge {
-  fill: none;
-  stroke: yellowgreen;
-  stroke-width: 9;
-  }
-
-#inner-petals .segment:hover > .segment-fill {
-  fill: darkseagreen;
-  stroke: none;
-  }
-
-#inner-petals .segment:hover > .segment-edge {
-  stroke: green;
-  }
-
- -

Откройте документ в вашем браузере с поддержкой SVG. Переместите указатель мыши на изображение.

- -

Эта wiki не поддерживает вставку SVG в страницы, поэтому мы не имеем возможности продемонстрировать это здесь. Изображение будет выглядеть так:

- - - - - - - -
SVG demonstration
- -

Примечания к демонстрации:

- -
    -
  • Документ SVG привязывается к таблице стилей общепринятым способом.
  • -
  • SVG содержит собственные свойства CSS и их значения. Некоторые из них похожи на значения CSS для HTML.
  • -
- - - - - - - - -
Задание
Измение таблицу стилей так, чтобы все внутренние лепестки становились розовыми, по наведению курсора на одного из них, при этом нельзя менять принцип работы других лепестков.
- -

Посмотреть решение к этому заданию.

- -

Что дальше?

- -

В этой демонстрации, ваш браузер с поддержкой SVG уже знает, как отображать элементы  SVG. Таблица стилей всего лишь некоторым образом меняет отображение. То же самое происходит с документами HTML и XUL. Однако CSS можно использовать для любых документов XML, в которых нет предусмотренного по умолчанию способа отображения элементов. Данный пример продемонстрирован на следующей странице: Данные XML

diff --git a/files/ru/web/guide/css/getting_started/text_styles/index.html b/files/ru/web/guide/css/getting_started/text_styles/index.html deleted file mode 100644 index a25565cf79..0000000000 --- a/files/ru/web/guide/css/getting_started/text_styles/index.html +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: Text styles -slug: Web/Guide/CSS/Getting_started/Text_styles -translation_of: Learn/CSS/Styling_text/Fundamentals -translation_of_original: Web/Guide/CSS/Getting_started/Text_styles ---- -

{{ CSSTutorialTOC() }}

- -

{{previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Readable_CSS", "Readable CSS")}}This is the 7th section of the CSS Getting Started tutorial; it gives more examples of text styles. You modify your sample stylesheet to use different fonts.

- -

Information: Text styles

- -

CSS имеет несколько свойств для стилизации текста.

- -

There is a convenient shorthand property, {{ cssxref("font") }}, which you can use to specify several aspects at once—for example:

- -
    -
  • Bold, italic, and small-caps (small capitals)
  • -
  • Size
  • -
  • Line height
  • -
  • Font typeface
  • -
- -
-
Example
- -
p {
-font: italic 75%/125% "Comic Sans MS", cursive;
-}
-
- -

This rule sets various font properties, making all paragraphs italic.

- -

The font size is set to three-quarters of the size in each paragraph's parent element, and the line height is set to 125% (a little more spaced than normal).

- -

The font typeface is set to Comic Sans MS, but if this typeface is not available then the browser will use its default cursive (hand-written) typeface.

- -

The rule has the side-effect of turning off bold and small-caps (setting them to normal).

-
- -

Font faces

- -

You cannot predict what typefaces the readers of your document will have. When you specify font typefaces, it is a good idea to give a list of alternatives in order of preference.

- -

End the list with one of the built-in default typefaces: serif, sans-serif, cursive, fantasy or monospace.

- -

If the typeface does not support some features in the document, then the browser can substitute a different typeface. For example, the document might contain special characters that the typeface does not support. If the browser can find another typeface that has those characters, then it will use the other typeface.

- -

To specify a typeface on its own, use the {{ cssxref("font-family") }} property.

- -

Font sizes

- -

Browser users can override the default font sizes or change the text size while they read a page, so it makes good sense for you to use relative sizes wherever you can.

- -

You can use some built-in values for font sizes, like small, medium and large. You can also use values relative to the font size of the parent element like: smaller, larger, 150% or 1.5em. An "em" is equivalent to the width of the letter "m" (for the font size of the parent element); thus 1.5em is one-and-a-half times the size of the font of the parent element.

- -

If necessary you can specify an actual size like: 14px (14 pixels) for a display device or 14pt (14 points) for a printer. This is not accessible for visually impaired users because it does not allow them to change the size. A more accessible strategy is to set a built-in value like medium on a top-level element of the document, and then set relative sizes for all its descendent elements.

- -

To specify a font size on its own, use the {{ cssxref("font-size") }} property.

- -

Line height

- -

The line height specifies the spacing between lines. If your document has long paragraphs with many lines, a larger-than-normal spacing makes it easier to read, especially if the font size is small.

- -

To specify a line height on its own, use the {{ cssxref("line-height") }} property.

- -

Decoration

- -

The separate {{ cssxref("text-decoration") }} property can specify other styles, like underline or line-through. You can set it to none to explicitly remove any decoration.

- -

Other properties

- -

To specify italic on its own, use {{ cssxref("font-style") }}: italic;
- To specify bold on its own, use {{ cssxref("font-weight") }}: bold;
- To specify small capitals on its own, use {{ cssxref("font-variant") }}: small-caps;

- -

To turn any of these off individually, you can specify the value normal or inherit.

- -
-
More details
- -

You can specify text styles in a variety of other ways.

- -

For example, some of the properties mentioned here have other values that you can use.

- -

In a complex stylesheet, avoid using the shorthand font property because of its side-effects (resetting other individual properties).

- -

For full details of the properties that relate to fonts, see Fonts in the CSS Specification. For full details of text decoration, see Text.

- -

If you don't want to depend on the typefaces installed on users' systems, you can use {{ cssxref("@font-face") }} to specify an online font. However, this requires that the users have a browser that supports this rule.

-
- -

Action: Specifying fonts

- -

For a simple document, you can set the font of the {{ HTMLElement("body") }} element and the rest of the document inherits the settings.

- -
    -
  1. Edit your CSS file.
  2. -
  3. Add the following rule to change the font throughout the document. The top of the CSS file is a logical place for it, but it has the same effect wherever you put it: -
    body {
    -font: 16px "Comic Sans MS", cursive;
    -}
    -
    -
  4. -
  5. Add a comment explaining the rule, and add white space to make it match your preferred layout.
  6. -
  7. Save the file and refresh your browser to see the effect. If your system has Comic Sans MS, or another cursive font that does not support italic, then your browser chooses a different font face for the italic text in the first line: - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  8. -
  9. From your browser's menu bar, choose View > Text Size > Increase (or View > Zoom > Zoom In). Even though you specified 16 pixels in the style, a user reading the document can change the size.
  10. -
- -
-
Challenge
- -

Without changing anything else, make all six initial letters twice the size in the browser's default serif font:

- - - - - - - - - - -
Cascading Style Sheets
Cascading Style Sheets
- -
-
Possible solution
- -

Add the following style declaration to the strong rule:

- -
  font: 200% serif;
-
-If you use separate declarations for font-size and font-family, then the font-style setting on the first paragraph is not overridden. - -

 

-Hide solution
-See a solution for the challenge.
- -

What next?

- -

{{nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Color", "Color")}}Your sample document already uses several named colors. The next section lists the names of standard colors and explains how you can specify others.

diff --git a/files/ru/web/guide/css/getting_started/what_is_css/index.html b/files/ru/web/guide/css/getting_started/what_is_css/index.html deleted file mode 100644 index 95df2fe915..0000000000 --- a/files/ru/web/guide/css/getting_started/what_is_css/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: Что такое CSS? -slug: Web/Guide/CSS/Getting_started/What_is_CSS -tags: - - Beginner - - CSS - - 'CSS:Getting_Started' - - Example - - Guide - - Веб - - Новичку -translation_of: Learn/CSS/First_steps/How_CSS_works -translation_of_original: Web/Guide/CSS/Getting_started/What_is_CSS ---- -
{{ CSSTutorialTOC() }}
- -

{{previousPage("/ru/docs/Web/Guide/CSS/Getting_Started", "CSS для начинающих")}} Эта первая статья руководства по CSS для начинающих кратко объясняет, что такое Cascading Style Sheets (CSS). С её помощью вы сможете создать простой документ, который будете использовать в дальнейших разделах.

- -

Информация: Что такое CSS

- -

Каскадные таблицы стилей (Cascading Style Sheets = CSS) — это язык, который отвечает за визуальное представление документов пользователю.

- -

Под документом мы будем понимать набор информации о структуре страницы, описываемый языком разметки.

- -

А представление документа пользователю, в свою очередь, означает его преобразование в удобную для восприятия форму. Браузеры, такие как Firefox, Chrome или Internet Explorer, были созданы для визуального отображения документов, например, на экране компьютера, проекторе или вывода через принтер.

- -
-

Примеры

- -
    -
  • Страница сайта, которую вы сейчас читаете — это документ. Структура информации, которую вы видите на странице, обычно описывается при помощи языка разметки HTML (HyperText Markup Language — Язык ГиперТекстовой Разметки)
  • -
  • Диалоговые окна в компьютерных программах, также называемые модальными окнами, как правило, также являются документами. Такие окна могут также быть описаны с помощью языка разметки, такого как XUL (XML User Interface Language — XML’ный Язык Пользовательского Интерфейса), которые можно найти, например, в некоторых приложениях от Mozilla.
  • -
-
- -

В этом руководстве блоки с заголовком Подробнее, как нижеследующий, содержат дополнительную информацию и ссылки на ресурсы, позволяющие более глубоко изучить вопрос, которому посвящен тот или иной раздел. Вы можете сразу же воспользоваться этими материалами или же пропустить эти блоки и вернуться к ним позже.

- -
-
Подробнее
- -

Документ это не то же самое, что файл. Но, тем не менее, документ может храниться в одном файле.

- -

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

- -

Больше информации о документах и языках разметки вы найдете в других разделах этого сайта:

- - - - - - - - - - - - - - - - - - - - -
HTMLо веб-страницах
XMLо структуре документов в общем
SVGо графике
XULо пользовательских интерфейсах в Mozilla
- -

Во второй части данного руководства вы встретите примеры этих языков разметки.

-
- -
-
Подробнее
- -

В терминах CSS программа, которая выводит документ пользователю, так называемому user agent (UA). Браузер — один из видов UA. CSS, таким образом, не предназначен только для браузеров или визуального представления, но в первой части данного руководства вы будете работать с CSS только в браузере.

- -

Прочие определения и термины, имеющие отношение к CSS, вы можете найти в Определениях спецификации CSS, созданной World Wide Web Consortium (W3C), международным сообществом которое установило открытые стандарты web.

-
- -

К действию: Создание документа

- -
    -
  1. Создайте новую папку на вашем компьютере для упражнений.
  2. -
  3. Откройте текстовый редактор и создайте новый текстовый файл. Этот файл будет содержать документ для нескольких следующих упражнений.
  4. -
  5. Скопируйте и вставьте HTML, приведенный ниже, а затем сохраните ваш файл под именем doc1.html. -
    <!DOCTYPE html>
    -<html>
    -  <head>
    -  <meta charset="UTF-8">
    -  <title>Sample document</title>
    -  </head>
    -
    -  <body>
    -    <p>
    -      <strong>C</strong>ascading
    -      <strong>S</strong>tyle
    -      <strong>S</strong>heets
    -    </p>
    -  </body>
    -</html>
    - -

    {{ LiveSampleLink('Action.3A_Creating_a_document', 'Посмотреть демо') }}

    -
  6. -
  7. Откройте новую вкладку или новое окно в вашем браузере и откройте только что созданный файл. -

    Вы должны увидеть строку, в которой заглавные буквы выделены полужирным начертанием:

    - - - - - - - -
    Cascading Style Sheets
    - -

    То, что вы увидите на самом деле, может немного отличаться потому, что настройки по умолчанию вашего браузера и данной энциклопедии наверняка будут отличаться: небольшие различия в шрифте, пробелах и цветах не очень-то и важны.

    -
  8. -
- -

Что дальше?

- -

{{nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Why_use_CSS", "Зачем нужен CSS?")}}В документе, который вы создали, CSS пока что не использовался. В следующем разделе вы научитесь использовать CSS для стилизации документа.

diff --git a/files/ru/web/guide/css/getting_started/why_use_css/index.html b/files/ru/web/guide/css/getting_started/why_use_css/index.html deleted file mode 100644 index 3041d28920..0000000000 --- a/files/ru/web/guide/css/getting_started/why_use_css/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Зачем нужен CSS? -slug: Web/Guide/CSS/Getting_started/Why_use_CSS -tags: - - Beginner - - CSS - - 'CSS:Getting_Started' - - Example - - Guide - - Web - - Веб - - Новичку - - Руководство -translation_of: Learn/CSS/First_steps/How_CSS_works -translation_of_original: Web/Guide/CSS/Getting_started/Why_use_CSS ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/What_is_CSS", "Что такое CSS?") }}Это вторая статья руководства по CSS для начинающих, объясняющая взаимосвязь между CSS и документами. В ней вы узнаете, как добавить CSS стили для документа, который вы создали в процессе изучения первой статьи.

- -

Информация: Зачем нужен CSS?

- -

CSS используется для определения стилей ваших документов, в том числе дизайна, верстки и вариаций макета для различных устройств и размеров экрана. Вы можете разместить стили CSS внутри тега <HEAD> документа с встроенной таблицей стилей, или приложить отдельный CSS-файл, который будет определять ваши стили извне. Чтобы привязать внешнюю таблицу стилей к документу, просто добавьте ссылку на таблицу стилей в заголовке <HEAD> документа.

- -

У внешней таблицы стилей есть множество преимуществ. Сохранение стилей отдельно от содержания HTML:

- -
    -
  • Помогает избежать дублирования
  • -
  • Облегчает обслуживание
  • -
  • Позволяет делать изменения для всего сайта в одном месте
  • -
- -
-
Пример
- -

Используя CSS, вы храните информацию о стилях в общих файлах, которые доступны всем страницам. Например, когда документы ссылаются на те таблицы стилей, которые определяют цвет заголовков h2, вы можете применить стиль для тегов заголовков h2 на глобальном уровне путем изменения одного атрибута CSS.

- -

Когда пользователь открывает веб-страницу, браузер загружает информацию стиля вместе с содержанием страницы.

- -

Когда пользователь открывает веб-страницу в режиме печати, вы можете предоставить различную информацию о стилях которая сделает страницу более лёгкой для чтения.

-
- -

Как заставить HTML и CSS работать вместе? В целом, HTML используется для описания содержимого документа, а не его стиля. CSS же используется, чтобы указать стиль документа, но не содержание. Позже в руководстве вы увидите некоторые исключения из этого правила.

- -
-
Подробнее
- -

Язык разметки, типа HTML также обеспечивает некоторые способы задания стилей.

- -

Например, в HTML вы можете использовать тег <B>, чтобы сделать текст жирным, либо указать цвет фона страницы в теге <BODY>.

- -

При использовании CSS, задание стилей средствами языка разметки обычно не используется, поскольку вся информация о стилях легко доступна для чтения и изменения в CSS-файле.

-
- -

Действие: Создание таблицы стилей

- -
    -
  1. Создайте новый текстовый файл в том же каталоге, что и doc1.html, созданный в первой статье.
  2. -
  3. Сохраните его как style1.css. Этот файл будет вашей таблицей стилей.
  4. -
  5. Скопируйте и вставьте в CSS-файл приведённую ниже строку, после чего сохраните файл: -
    strong {color: red;}
    -
    -
  6. -
- -

Привязка таблицы стилей к документу

- -
    -
  1. Для привязки вашего документа к таблице стилей, необходимо внести в HTML-файл некоторые исправления. Добавьте строки, приведённые ниже: -
    <!DOCTYPE html>
    -<html>
    -  <head>
    -  <meta charset="UTF-8">
    -  <title>Sample document</title>
    -  <link rel="stylesheet" href="style1.css">
    -  </head>
    -  <body>
    -    <p>
    -      <strong>C</strong>ascading
    -      <strong>S</strong>tyle
    -      <strong>S</strong>heets
    -    </p>
    -  </body>
    -</html>
    -
    -
  2. -
  3. Сохраните файл, и откройте его в браузере. Таблица стилей сделает заглавные буквы красными:
  4. -
- -

{{ EmbedLiveSample('Действие_Создание_таблицы_стилей', '', '', '', 'Web/Guide/CSS/Getting_started/Why_use_CSS') }}

- -

{{ LiveSampleLink('Action.3A_Creating_a_stylesheet', 'Просмотреть демо') }}

- -
-
Задание
- -

В дополнение к красному, в CSS имеются и другие названия цветов.

- -

Не открывая подсказку, подберите ещё пять цветовых имён, которые будут работать в CSS.

- -
-
Возможное решение
- -

CSS поддерживает общие названия цветов, например orange, yellow, blue, green, или black. Он также поддерживает некоторые более экзотические названия типа chartreuse, fuschia, или burlywood. Посмотрите значения цвета CSS, чтобы ознакомится с полным списком поддерживаемых цветов, а так же методов их задания.

-Скрыть решение
-Посмотреть решение задания.
- -

Что дальше?

- -

{{nextPage("/ru/docs/Web/Guide/CSS/Getting_started/How_CSS_works", "Как работает CSS.")}}  Теперь, когда у вас есть образец документа, связанный с отдельной таблицей стилей, вы готовы узнать больше о том, как ваш браузер объединяет их при отображении документа.

diff --git "a/files/ru/web/guide/css/getting_started/\321\202\320\260\320\261\320\273\320\270\321\206\321\213/index.html" "b/files/ru/web/guide/css/getting_started/\321\202\320\260\320\261\320\273\320\270\321\206\321\213/index.html" deleted file mode 100644 index 82b7edae60..0000000000 --- "a/files/ru/web/guide/css/getting_started/\321\202\320\260\320\261\320\273\320\270\321\206\321\213/index.html" +++ /dev/null @@ -1,525 +0,0 @@ ---- -title: Таблицы -slug: Web/Guide/CSS/Getting_started/Таблицы -tags: - - CSS - - Веб - - Руководство -translation_of: Learn/CSS/Building_blocks/Styling_tables -translation_of_original: Web/Guide/CSS/Getting_started/Tables ---- -

{{CSSTutorialTOC}}{{previousPage("/ru/docs/Web/Guide/CSS/Getting_Started/Layout", "Layout")}}

- -

Это 13-я секция руководства CSS Начало работы; оно описывает более продвинутые селекторы и некоторые специфичные способы, которыми вы можете стилизовать таблицу. Вы создаете новый пример документа, содержащий таблицу и таблицу стилей для неё.

- -

Информация: Таблицы

- -

Таблица распологает информацию в прямоугольной сетке. Некоторые таблицы могут быть сложными, и для сложных таблиц разные браузеры выдают разный результат.

- -

Когда вы проектируете ваш документ, используйте таблицы для выражения отношений между кусочками информации. Поэтому это не важно, если различные браузеры отображают информацию слегка различными способами, потому что значение остается ясным.

- -

Не используйте таблицы необычным способом для создания особенной визуальной разметки. Техники на предыдущей странице руководства (Разметка) предпочтительнее для этой цели.

- -

Структура таблицы

- -

В таблице, каждый кусок информации отображается в ячейке (cell).

- -

Ячейки, лежащие на одной линии, составляют строку (row).

- -

В некоторыех таблицах, строки могут быть сгруппирированы. Специальная группа строк в начале таблицы - заголовок (header), в конце - нижний колонтитул (footer). Главные строки таблицы - тело (body), и они могут быть также сгруппирированы.

- -

Ячейки в линии сверху вниз, составляют столбец (column), но столбцы имеют ограниченное приминение в таблицах CSS.

- -
-
Пример
- -

Таблица Селекторов, основанных на отношении в Селекторы имеет десять ячеек в пяти строках.

- -

Первая строка - заголовок. Остальные четыре строки - тело таблицы. Нижнего колонтитула нет.

- -

У неё два столбца.

-
- -

Это руководство охватывает только простые таблицы, где результат довольно предсказуемый. В простой таблице, каждая ячейка занимает только одну ячейку в строке и в столбце. Вы можете использовать CSS для сложных таблиц, где ячейки занимают диапазон ячеек более чем одна в строке или столбце, но таблицы, подобно этим находятся вне пределов этого руководства.

- -

Рамки

- -

Ячейки не имеют границ.

- -

У ячеек нет рамок и наполнений. По умолчанию, рамки разделены значениями таблицы, свойство {{cssxref("border-spacing")}}. Вы можете также полностью удалить пространство, установив свойство таблицы {{cssxref("border-collapse")}} в collapse.

- -
-
Пример
- -

Здесь три таблицы.

- -

У таблицы слева интервал рамки 0.5 em. У таблицы по центру он составляет ноль. Таблица справа имеет сжатые границы:

- - - - - - - - - -
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
-
- -

Заголовок

- -

{{HTMLElement("caption")}} элемент - это метка, которая применяется ко всей таблице. По умолчанию, она отображается вверху таблицы.

- -

Чтобы переместить её вниз, установите её свойство {{cssxref("caption-side")}} в bottom. Это свойство наследуется, поэтому, в качестве альтернативы вы можете установить это свойство у таблицы или у другого элемента предка.

- -

Чтобы стилизовать заголовок текста, используйте любое из обычных свойств для текста.

- -
-
Пример
- -

У этой таблицы заголовок внизу

- -
#demo-table > caption {
-  caption-side: bottom;
-  font-style: italic;
-  text-align: right;
-}
-
- - - - - - - -
- - - - - - - -
Подходит
- - - - - - - - - - - -
КлубыСердца
АлмазыЛопаты
-
-
-
- -

Пустые ячейки

- -

Вы можете отобразить пустые ячейки (т.е. их рамки и фон) указывав {{cssxref("empty-cells")}}: show; для элемента таблицы.

- -

Вы можете скрыть их, указав empty-cells: hide;. Тогда, если у элемента родителя ячейки есть фон, он будет отображен через пустую ячейку.

- -
-
Пример
- -

Эти таблицы имеют бледно-зелёный фон. Их ячейки имеют бледно-серый фон и тёмно-серые рамки.

- -

В таблице слева пустая таблица отображается. В таблице справа, она скрыта:

- - - - - - - - -
- - - - - - - - - - - -
 Сердца
АлмазыЛопаты
-
- - - - - - - - - - - -
 Сердца
АлмазыЛопаты
-
-
- -
-
Детали
- -

Для подбробной информации о таблицах, смотрите Таблицы в Спецификации CSS.

- -

Информации там больше, чем в этом руководстве, но она не покрывает различия между браузерами, которые могут влиять на сложные таблицы.

-
- -

Действие: Стилизация таблицы

- -
    -
  1. Создайте новый HTML документ, doc3.html. Скопируйте и вставьте содержимое отсюда: - -
    -
    <!DOCTYPE html>
    -<html>
    -  <head>
    -    <title>Документ примера 3</title>
    -    <link rel="stylesheet" href="style3.css">
    -  </head>
    -  <body>
    -    <table id="demo-table">
    -      <caption>Океаны</caption>
    -      <thead>
    -        <tr>
    -          <th></th>
    -          <th>Площадь</th>
    -          <th>Средняя глубина</th>
    -        </tr>
    -        <tr>
    -          <th></th>
    -          <th>млн. км<sup>2</sup></th>
    -          <th>м</th>
    -        </tr>
    -      </thead>
    -      <tbody>
    -        <tr>
    -          <th>Северный Ледовитый</th>
    -          <td>13,000</td>
    -          <td>1,200</td>
    -        </tr>
    -        <tr>
    -          <th>Атлантический</th>
    -          <td>87,000</td>
    -          <td>3,900</td>
    -        </tr>
    -        <tr>
    -          <th>Тихий</th>
    -          <td>180,000</td>
    -          <td>4,000</td>
    -        </tr>
    -        <tr>
    -          <th>Индийский</th>
    -          <td>75,000</td>
    -          <td>3,900</td>
    -        </tr>
    -        <tr>
    -          <th>Южный</th>
    -          <td>20,000</td>
    -          <td>4,500</td>
    -        </tr>
    -      </tbody>
    -      <tfoot>
    -        <tr>
    -          <th>Общая</th>
    -          <td>361,000</td>
    -          <td></td>
    -        </tr>
    -        <tr>
    -          <th>Средняя</th>
    -          <td>72,000</td>
    -          <td>3,800</td>
    -        </tr>
    -      </tfoot>
    -    </table>
    -  </body>
    -</html>
    -
    -
    -
  2. -
  3. Создайте новую таблицу стилей, style3.css. Скопируйте и вставьте содержимое отсюда: -
    /*** Style for doc3.html (Tables) ***/
    -
    -#demo-table {
    -  font: 100% sans-serif;
    -  background-color: #efe;
    -  border-collapse: collapse;
    -  empty-cells: show;
    -  border: 1px solid #7a7;
    -}
    -
    -#demo-table > caption {
    -  text-align: left;
    -  font-weight: bold;
    -  font-size: 200%;
    -  border-bottom: .2em solid #4ca;
    -  margin-bottom: .5em;
    -}
    -
    -
    -/* basic shared rules */
    -#demo-table th,
    -#demo-table td {
    -  text-align: right;
    -  padding-right: .5em;
    -}
    -
    -#demo-table th {
    -  font-weight: bold;
    -  padding-left: .5em;
    -}
    -
    -
    -/* header */
    -#demo-table > thead > tr:first-child > th {
    -  text-align: center;
    -  color: blue;
    -}
    -
    -#demo-table > thead > tr + tr > th {
    -  font-style: italic;
    -  color: gray;
    -}
    -
    -/* fix size of superscript */
    -#demo-table sup {
    -  font-size: 75%;
    -}
    -
    -/* body */
    -#demo-table td {
    -  background-color: #cef;
    -  padding:.5em .5em .5em 3em;
    -}
    -
    -#demo-table tbody th:after {
    -  content: ":";
    -}
    -
    -
    -/* footer */
    -#demo-table tfoot {
    -  font-weight: bold;
    -}
    -
    -#demo-table tfoot th {
    -  color: blue;
    -}
    -
    -#demo-table tfoot th:after {
    -  content: ":";
    -}
    -
    -#demo-table > tfoot td {
    -  background-color: #cee;
    -}
    -
    -#demo-table > tfoot > tr:first-child td {
    -  border-top: .2em solid #7a7;
    -}
    -
    -
  4. -
  5. Откройте документ в вашем браузере. Он должен выглядеть наподобие этого: - - - - - - -
    -

    Океаны

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     ПлощадьСредняя глубина
     млн. км2м
    Северный Ледовитый:13,0001,200
    Атлантический:87,0003,900
    Тихий:180,0004,000
    Индийский:75,0003,900
    Южный:20,0004,500
    Общая:361,000 
    Средняя:72,0003,800
    -
    -
    -
  6. -
  7. Сравните правила в таблице стилей с отображенной таблицей, чтобы гарантировать, что вы понимаете действие для каждого правила. Если вы найдете правило, значение которого вы не понимаете, то закомментируйте его и обновите страницу, чтобы посмотреть, что изменилось. Вот несколько заметок об этой таблице: -
      -
    • Заголовок находится снаружи рамки таблицы.
    • -
    • Если у вас установлен минимальный размер точки в Опциях, это может повлиять на верхний индекс в km2.
    • -
    • Три пустые ячейки. Через две из них  позволено показывать фон таблицы. У третьей есть фон и верхняя рамка.
    • -
    • Двоеточия добавлены с помощью таблицы стилей.
    • -
    -
  8. -
- -
-
Вызов
- -

Измените таблицу стилей, чтобы она выглядела, как эта:

- - - - - - - -
-
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 ПлощадьСредняя глубина
 млн. км2м
Северный Ледовитый:13,0001,200
Атлантический:87,0003,900
Тихий:180,0004,000
Индийский:75,0003,900
Южный:20,0004,500
Общая:361,000 
Средняя:72,0003,800
-
-
- -

Океаны

-
-
- -

Посмотреть решение для этой задачи.

- -

Что дальше?

- -

{{nextPage("/ru/docs/Web/Guide/CSS/Getting_Started/Media", "Media")}}Это последняя страница в этом руководстве, которая фокусируется на CSS свойствах и значениях. Для полного обзора свойств и значений, смотрите все свойства таблиц в CSS Спецификациях.

- -

Следующая страница тоже рассматривает цель и структуру CSS таблиц.

diff --git a/files/ru/web/guide/css/index.html b/files/ru/web/guide/css/index.html deleted file mode 100644 index 7529234ef5..0000000000 --- a/files/ru/web/guide/css/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Руководство разработчика CSS -slug: Web/Guide/CSS -tags: - - CSS - - Landing - - NeedsTranslation - - TopicStub -translation_of: Learn/CSS -translation_of_original: Web/Guide/CSS ---- -prepare for redirect diff --git a/files/ru/web/guide/css/understanding_z_index/adding_z-index/index.html b/files/ru/web/guide/css/understanding_z_index/adding_z-index/index.html deleted file mode 100644 index 2fff1726d3..0000000000 --- a/files/ru/web/guide/css/understanding_z_index/adding_z-index/index.html +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: Using z-index -slug: Web/Guide/CSS/Understanding_z_index/Adding_z-index -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index ---- -
{{cssref}}
- -

The first part of this article, Stacking without the z-index property, explains how stacking is arranged by default. If you want to create a custom stacking order, you can use the {{cssxref("z-index")}} property on a positioned element.

- -

Свойство z-index может иметь значение в целых числах (положительные, ноль, или отрицательные), что представляет собой позицию єлемента вдоль оси z. Если вы не знакомы с осью z, представьте себе страницу как стопку слоев, имеющих собственое порядковое число. Слои представлены в числовом порядке, with larger numbers above smaller numbers.

- -
    -
  • bottom layer (farthest from the observer)
  • -
  • ...
  • -
  • Layer -3
  • -
  • Layer -2
  • -
  • Layer -1
  • -
  • Layer 0 (default rendering layer)
  • -
  • Layer 1
  • -
  • Layer 2
  • -
  • Layer 3
  • -
  • ...
  • -
  • top layer (closest to the observer)
  • -
- -
-

Notes:

- -
    -
  • When no z-index property is specified, elements are rendered on the default rendering layer 0 (zero).
  • -
  • If several elements share the same z-index value (i.e., they are placed on the same layer), stacking rules explained in the section Stacking without z-index apply.
  • -
-
- -

In the following example, the layers' stacking order is rearranged using z-index. The z-index of element #5 has no effect since it is not a positioned element.

- -

{{EmbedLiveSample("Source_code_for_the_example", 600, 400)}}

- -

Source code for the example

- -

HTML

- -
<div id="abs1">
-  <b>DIV #1</b>
-  <br />position: absolute;
-  <br />z-index: 5;
-</div>
-
-<div id="rel1">
-  <b>DIV #2</b>
-  <br />position: relative;
-  <br />z-index: 3;
-</div>
-
-<div id="rel2">
-  <b>DIV #3</b>
-  <br />position: relative;
-  <br />z-index: 2;
-</div>
-
-<div id="abs2">
-  <b>DIV #4</b>
-  <br />position: absolute;
-  <br />z-index: 1;
-</div>
-
-<div id="sta1">
-  <b>DIV #5</b>
-  <br />no positioning
-  <br />z-index: 8;
-</div>
-
- -

CSS

- -
div {
-  padding: 10px;
-  opacity: 0.7;
-  text-align: center;
-}
-
-b {
-  font-family: sans-serif;
-}
-
-#abs1 {
-  z-index: 5;
-  position: absolute;
-  width: 150px;
-  height: 350px;
-  top: 10px;
-  left: 10px;
-  border: 1px dashed #900;
-  background-color: #fdd;
-}
-
-#rel1 {
-  z-index: 3;
-  height: 100px;
-  position: relative;
-  top: 30px;
-  border: 1px dashed #696;
-  background-color: #cfc;
-  margin: 0px 50px 0px 50px;
-}
-
-#rel2 {
-  z-index: 2;
-  height: 100px;
-  position: relative;
-  top: 15px;
-  left: 20px;
-  border: 1px dashed #696;
-  background-color: #cfc;
-  margin: 0px 50px 0px 50px;
-}
-
-#abs2 {
-  z-index: 1;
-  position: absolute;
-  width: 150px;
-  height: 350px;
-  top: 10px;
-  right: 10px;
-  border: 1px dashed #900;
-  background-color: #fdd;
-}
-
-#sta1 {
-  z-index: 8;
-  height: 70px;
-  border: 1px dashed #996;
-  background-color: #ffc;
-  margin: 0px 50px 0px 50px;
-}
-
- -

See also

- - - -
-

Original Document Information

- - -
diff --git a/files/ru/web/guide/css/understanding_z_index/index.html b/files/ru/web/guide/css/understanding_z_index/index.html deleted file mode 100644 index 0074ff2577..0000000000 --- a/files/ru/web/guide/css/understanding_z_index/index.html +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Понимание CSS z-index -slug: Web/Guide/CSS/Understanding_z_index -tags: - - Advanced - - CSS - - Guide - - NeedsTranslation - - TopicStub - - Understanding_CSS_z-index - - Web - - z-index -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index ---- -

Обычно HTML страницы можно считать двухмерными, потому что текст, картинки и другие элементы расположены на странице без перекрытия. Существует единый нормальный поток отрисовки (rendering flow) и элементы избегают пространства, занятого другими.{{cssxref("z-index")}} атрибут позволяет регулировать порядок наложения объектов друг на друга в процессе отрисовки контента (rendering content).

- -
-

В CSS 2.1, позиция каждого блока была в трех измерениях. В дополнении к их горизонтальной и вертикальной позиции блоки лежали вдоль оси "z" и распологались один поверх другого. Позиция относительно оси "z" особенно актуальна, когда блоки визуально накладываются друг на друга. 

-
- -

(from CSS 2.1 Section 9.9.1 - Layered presentation)

- -

Это означает, что правила стиля CSS позволяют вам позиционировать блоки на слоях в дополнение к обычному слою рендеринга (слой 0). Положение Z каждого слоя выражается как целое число, представляющее порядок наложения для рендеринга. Большие числа означают ближе к наблюдателю. Положение Z можно контролировать с помощью свойства CSS z-index.

- -

Использование z-index кажется чрезвычайно простым: одно свойство, которому присваивается одно целое число, с простым для понимания поведением. Однако, когда z-index применяется к сложным иерархиям элементов HTML, его поведение может быть трудно понять или предсказать. Это обьясняется целым комплексом правил "укладки" элементов. Фактически в спецификации  CSS-2.1 Appendix E (CSS-2.1 Приложение Е) зарезервирован целый раздел, подробно обьясняющий эти правила.

- -

Данная статья попытается объяснить эти правила, с некоторым упрощением и несколькими примерами.

- -
    -
  1. Позиционирование без z-индекса : правила по умолчанию
  2. -
  3. Позиционирование и float : как себя поводят float элементы c позиционированием
  4. -
  5. Использование z-index : Using z-index to change default stacking
  6. -
  7. The stacking context : Notes on the stacking context
  8. -
  9. Stacking context example 1 : 2-level HTML hierarchy, z-index on the last level
  10. -
  11. Stacking context example 2 : 2-level HTML hierarchy, z-index on all levels
  12. -
  13. Stacking context example 3 : 3-level HTML hierarchy, z-index on the second level
  14. -
- -
-

Информация о документе

- -
    -
  • Автор: Paolo Lombardi
  • -
  • Эта статья - английский перевод статьи, которую я написал на итальянском для YappY. Я даю право делиться всем контентом: Creative Commons: Attribution-Sharealike license
  • -
  • Дата последнего обновления: 9 июля 2005 г.
  • -
- -

Примечание автора: спасибо Владимиру Паланту и Роду Уайтли за обзор.

- -
-
diff --git a/files/ru/web/guide/css/understanding_z_index/stacking_without_z-index/index.html b/files/ru/web/guide/css/understanding_z_index/stacking_without_z-index/index.html deleted file mode 100644 index 7f4eb09133..0000000000 --- a/files/ru/web/guide/css/understanding_z_index/stacking_without_z-index/index.html +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Stacking without z-index -slug: Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index -tags: - - CSS - - z-index -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index ---- -

« CSS « Понимание CSS z-index

- -

Наложения без Z-индекса

- -

Когда элементы не имеют z-индека, они накладываються в таком порядке(снизу вверх):

- -

1. Фон и границы корневого элемента.

- -

2. Дочерние блоки в нормальном потоке в порядке размещения(в HTML порядке).

- -

3. Дочерние позиционированные элементы, в порядке размещения (в HTML порядке).

- -

В следующем примере, абсолютно и относительно спозиционированным блокам определена величина  и позиция таким образом, чтобы продемонстировать правила наложения.

- -
-

Заметки:

- -
    -
  • Given a homogeneous group of elements without any z-index property, such as the positioned blocks (DIV #1 to #4) in the example, the element's stacking order is their order in the HTML hierarchy, regardless of their position.
  • -
  • -

    Standard blocks (DIV #5) in the normal flow, without any positioning property, are always rendered before positioned elements, and appear below them, even if they come later in the HTML hierarchy. 

    -
  • -
-
- -

understanding_zindex_01.png

- -

Пример

- -

HTML

- -
<div id="absdiv1">
-    <br /><span class="bold">DIV #1</span>
-    <br />position: absolute; </div>
-<div id="reldiv1">
-    <br /><span class="bold">DIV #2</span>
-    <br />position: relative; </div>
-<div id="reldiv2">
-    <br /><span class="bold">DIV #3</span>
-    <br />position: relative; </div>
-<div id="absdiv2">
-    <br /><span class="bold">DIV #4</span>
-    <br />position: absolute; </div>
-<div id="normdiv">
-    <br /><span class="bold">DIV #5</span>
-    <br />no positioning </div>
-
- -

CSS

- -
 .bold {
-     font-weight: bold;
-     font: 12px Arial;
- }
- #normdiv {
-     height: 70px;
-     border: 1px dashed #999966;
-     background-color: #ffffcc;
-     margin: 0px 50px 0px 50px;
-     text-align: center;
- }
- #reldiv1 {
-     opacity: 0.7;
-     height: 100px;
-     position: relative;
-     top: 30px;
-     border: 1px dashed #669966;
-     background-color: #ccffcc;
-     margin: 0px 50px 0px 50px;
-     text-align: center;
- }
- #reldiv2 {
-     opacity: 0.7;
-     height: 100px;
-     position: relative;
-     top: 15px;
-     left: 20px;
-     border: 1px dashed #669966;
-     background-color: #ccffcc;
-     margin: 0px 50px 0px 50px;
-     text-align: center;
- }
- #absdiv1 {
-     opacity: 0.7;
-     position: absolute;
-     width: 150px;
-     height: 350px;
-     top: 10px;
-     left: 10px;
-     border: 1px dashed #990000;
-     background-color: #ffdddd;
-     text-align: center;
- }
- #absdiv2 {
-     opacity: 0.7;
-     position: absolute;
-     width: 150px;
-     height: 350px;
-     top: 10px;
-     right: 10px;
-     border: 1px dashed #990000;
-     background-color: #ffdddd;
-     text-align: center;
- }
-
- -

Результат

- -

(If the image does not display in CodePen, click the Tidy button in the CSS section)

- -

{{ EmbedLiveSample('Example', '', '', '', 'Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index') }}

- -

Так же посмотрите

- - - -
-

Original Document Information

- - -
diff --git a/files/ru/web/guide/css/using_multi-column_layouts/index.html b/files/ru/web/guide/css/using_multi-column_layouts/index.html deleted file mode 100644 index 65e96fcdcf..0000000000 --- a/files/ru/web/guide/css/using_multi-column_layouts/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: Использование CSS разметки для многих колонок -slug: Web/Guide/CSS/Using_multi-column_layouts -translation_of: Web/CSS/CSS_Columns/Using_multi-column_layouts ---- -

{{CSSRef("CSS Multi-columns")}}

- -

CSS разметка для многих колонок расширяет способ блочной разметки, чтобы позволить легкое описание нескольких колонок текста. Людям сложно читать текст, если строки слишком длинные; это занимает слишком много времени для глаз, чтобы перемещать взгляд с конца одной на начало следующей строки, и они забывают на какой строке находились. Поэтому, чтобы использовать большие дисплеи по максимуму, авторам следует ограничить ширину колонок текст расположенных бок о бок, как в газетах.

- -

К несчастью, это невозможно сделать с CSS и HTML без принудительного разбиения колонки в фиксированных позициях, или строго ограничить допустимую разметку в тексте, или использовать экстраординарный скрипт. Это ограничение снимается с помощью добавления новых CSS свойств, чтобы расширить традиционный блочный способ разметки.

- -

Использование колонок

- -

Количество колонок и ширина

- -

Два свойства CSS контролируют появятся ли колонки и как много их будет: {{ Cssxref("column-count") }} and {{ Cssxref("column-width") }}.

- -

Свойство column-count устанавливает количество колонок определённым числом. Пример,

- -
<div style="column-count:2;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

отобразит содержимое в двух колонках (если вы используете многоколоночно совместимый браузер):

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Свойство column-width устанавливает минимальную желаемую ширину колонки. Если column-count также не установлено, тогда браузер автоматически сделает столько колонок, сколько нужно, чтобы заполнить  доступную ширину.

- -
<div style="column-width:20em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

становится:

- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Подробные детали описаны в CSS3 спецификации.

- -

В многоколончатом блоке, содержимое автоматически перетекает из одной колонки в следующую, как это необходимо. Вся HTML, CSS и DOM функциональность поддерживается внутри колонок, как например редактирование и печать.

- -

Краткая запись columns

- -

В большинстве случаев веб-разработчики используют одно из двух свойств CSS: {{ cssxref("column-count") }} или {{ cssxref("column-width") }}. Так как значения для этих свойств не пересекаются, то часто удобно использовать короткую запись {{ cssxref("columns") }}. Пример:

- -

CSS объявление  column-width:12em может быть заменено:

- -
<div style="columns:12em">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

CSS объявление column-count:4 может быть заменено:

- -
<div style="columns:4">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Два CSS объявления column-width:8em и column-count:12 могут быть заменены:

- -
<div style="columns:12 8em">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Выравнивание высоты

- -

CSS3-спецификация колонок требует, чтобы высота колонки была выровнена, т.е. браузер автоматически устанавливает максимальную высоту колонки, для того, чтобы высота содержимого в каждой из них была приблизительно одинаковая. Firefox так и делает.

- -

Однако, в некоторых ситуациях полезно установить максимальную высоту колонок явно, тогда расположение содержимого, начиная с первой колонки и последующих созданных, как необходимо, возможно, перекроют правую границу. Поэтому, если высота ограничена, с помощью CSS {{ cssxref("height") }} или {{ cssxref("max-height") }} свойств на многоколончатом блоке, каждой колонке разрешено расти до этой высоты, но не более, пока не добавится новая колонка. Этот режим также более эффективен для разметки.

- -

Промежутки между колонками

- -

Существует промежуток между колонками. По умолчанию рекомендовано значение 1em. Это значение можно изменить, применяя свойство {{ Cssxref("column-gap") }} на многоколончатом блоке:

- -
<div style="column-width:20em; column-gap:2em;">Lorem ipsum dolor sit amet, consectetur adipisicing elit,
-sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
-nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
-qui officia deserunt mollit anim id est laborum</div>
-
- -

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

- -

Постепенное ухудшение

- -

Свойства колонки будут просто проигнорированы браузерами, которые не поддерживают многоколончатый режим. Поэтому соответственно легче создать разметку, которая отобразит содержимое в одной колонке и будет использовать несколько колонок в тех браузерах, которые поддерживают многоколончатый режим.

- -

Обратите внимание, что не все браузеры поддерживают эти свойства без префикса. Чтобы использовать эти свойства в большинстве современных браузеров, каждое свойство должно быть написано трижды: одно с префиксом {{ property_prefix("-moz") }} , одно с префиксом {{ property_prefix("-webkit") }} и третье без префикса.

- -

Заключение

- -

CSS3 колонки - примитивная разметка, которая поможет Веб-разработчикам лучше воспользоваться реальным участком экрана. Разработчики с воображением могут найти много способов для их использования, особенно с автоматическим выравниванием высоты.

- -

Смотрите также

- - diff --git a/files/ru/web/guide/css/visual_formatting_model/index.html b/files/ru/web/guide/css/visual_formatting_model/index.html deleted file mode 100644 index 7a5de35909..0000000000 --- a/files/ru/web/guide/css/visual_formatting_model/index.html +++ /dev/null @@ -1,209 +0,0 @@ ---- -title: Модель визуального форматирования -slug: Web/Guide/CSS/Visual_formatting_model -translation_of: Web/CSS/Visual_formatting_model ---- -

{{CSSRef}}

- -

Модель визуального форматирования CSS  - это алгоритм, используемый для обработки документа и его визуального отображения. Это базовая концепция CSS. Модель визуального форматирования задаёт трансформацию каждого элемента в документе и создаёт ноль, одну или несколько боксов, согласно боксовой модели CSS. Расположение (layout) каждого бокса определяется:

- -
    -
  • размерами бокса: точно заданными или заданными ограничениями. Если размеры не заданы, это правило игнорируется;
  • -
  • типом бокса: inline, inline-level, atomic inline-level, block box;
  • -
  • схемой позиционирования: normal flow, float или absolute;
  • -
  • другими элементами дерева: дочерними и соседними;
  • -
  • размерами и расположением окна просмотра ({{glossary("viewport")}});
  • -
  • внутренними размерами содержащихся изображений;
  • -
  • другой внешней информацией.
  • -
- -

Бокс отображается относительно краев содержащего его блока. Как правило, бокс определяет родительский блок для своих потомков. Однако, стоит заметить, что бокс не ограничен содержащим его блоком. Такое поведение слоев, выходящих за пределы своих содержащих блоков, называется переполенинем (overflow).

- -

Генерация бокса

- -

Генерация бокса - часть алгоритма модели визуального форматирования, процедура, генерирующая блоки из элементов. Различные типы боксов определяют различное поведение в контексте форматирования. Тип бокса зависит от свойства CSS {{ cssxref("display") }}.

- -

Блочные эклементы и блок-боксы

- -

Говорят, что элемент является блочным, когда вычисленное значение его CSS свойства {{ cssxref("display") }} равно: blocklist-item, или table. Блочный элемент визуально форматируется как блок (например, параграф), предназначенный для вертикальной компоновки (в столбик).

- -

Каждый элемент блочного уровня участвует в контексте блочного форматирования. Каждый элемент блочного уровня генерирует как миниум один блок-бокс, названный главным блок-боксом. Некоторые элементы, например, такие как list-item, создают дополнительные боксы для хранения маркеров и других типографических элементов, содержащихся в list item. Большинство блочных элементов генерирует только один, главный блок-бокс.

- -

Главный блок-бокс содержит сгенериованные боксы-потомки и сгенериованный контекст. Он так же будет боксом, участвующем в схеме позиционирования.

- -

venn_blocks.pngЭлемент блочного уровня так же может быть блоком-контейнером. Блок-контейнер - это блок, который содержит либо только другие элементы блочного уровня, либо создаёт контекст инлайнового форматирования и, таким образом, содержит только инлайновые элементы.

- -

Важно понимать, что понятие блочного элемента и понятие блочного контейнера - это разные вещи. Первое описывает, как блок будет себя вести по отношению к своему родителю и своим соседям/братьям. А второе - описывает, как блок будет взаимодействовать со своими потомками. Некоторые элементы блочного уровня, например, таблицы, не являются содержащими блоками. И наоборот, некоторые блоки-контейнеры, например, ячейки таблицы, не являются элементами блочного уровня.

- -

Элементы блочного уровня, которые так же являются контейнерами, называются блок-боксами.

- -

Анонимные блок-боксы

- -

В некоторых случаях алгоритм визуального форматирования  вынужден добавлять дополнительные боксы. Так как эти боксы невозможно как-то проименовать и к ним невозможно применить css-селекторы, поэтому эти боксы называют анонимными.

- -

Из-за того, что к анонимным боксам невозможно применить селекторы, их невозможно изменить с помощью таблицы стилей. Это значит, что все наследуемые CSS свойства для них будут иметь значение inherit, а все ненаследуемые свойства будут иметь значение initial.

- -

Блоки-контейнеры содержат либо только инлайн-боксы, либо только элементы блочного уровня. Но, как правило, документ содержит и те и другие. В этом случае анонимные блок-боксы создаются вокруг примыкающих к ним инлайн-боксов.

- -

Пример

- -

Возьмём следующий HTML код (со стилями по умолчанию, то есть элементы {{ HTMLElement("div") }} и {{ HTMLElement("p") }} имеют значение display:block :

- -
<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>
- -

Здесь создались два анонимных блока: один для текста перед параграфом (Some inline text), и второй для текста после параграфа (followed by more inline text.). И у нас получилась вот такая структура:

- -

anonymous_block-level_boxes.png

- -

Выглядеть это будет так:

- -
Some inline text
-followed by a paragraph
-followed by more inline text.
- -

В отличие от параграфа {{ HTMLElement("p") }}, Web разработчик не может напрямую контролировать стили этих двух анонимных боксов. Те свойства, которые наследуются, берут своё значение от элемента {{ HTMLElement("div") }}, например {{ cssxref("color") }}, определяющий цвет текста. А другие значения, ненаследуемые, устанавливаются в значение initial. Например, у них не будет своего свойства {{ cssxref("background-color") }}, он всегда будет в состоянии "прозрачный" (transparent), значении по умолчанию для этого свойства, и поэтому будет видно тот background, который установлен у элемента <div>. А вот для параграфа <p> можно установить своё свойство цвета фона. Таким образом, эти два анонимных бокса будут иметь один и тот же цвет текста.

- -

Ещё один случай, который приводит к созданию анонимных блок-боксов, это случай, когда инлайн-бокс содержит один или несколько блок-боксов. В этом случае элемент, содержащий блок-боксы, делится на два инлайн-бокса - один перед, а второй после блок-бокса. И потом инлайн-элементы перед и после блок-бокса дополнительно заключаются в анонимные блок-боксы. Таким образом блок-бокс становится соседом для анонимных блок-боксов, содержащих инлайн-элементы.

- -

Если есть несколько блок-боксов, идущих подряд, без инлайн-элементов между ними, то анонимные блок-боксы создаются только перед и после такого набора блок-боксов.

- -

Пример

- -

Возьмём следующий HTML код, где установим для элемента {{ HTMLElement("p") }} значение display:inline и для элемента {{ HTMLElement("span") }} значение display:block :

- -
<p>Some <em>inline</em> text <span>followed by a paragraph</span> followed by more inline text.</p>
- -

Создадутся два анонимных блок-бокса, один для текста перед элементом span (Some inline text) и один для текста после него (followed by more inline text), и у нас получится вот такая структура:

- -

- -

Выглядеть она будет так:

- -
Some inline text
-followed by a paragraph
-followed by more inline text.
- -

Элементы инлайн-уровня и инлайн-боксы

- -

Элементы, которые называются элементами инлайн-уровня - это элементы, у которых вычисленное значение CSS свойства {{ cssxref("display") }} установлено в : inline, inline-block или inline-table. Визуально они не представляют собой какие-то отдельные блоки, но они они распологаются в одну линию с другим контентом инлайн-уровня. Например, содержание параграфа, с различным форматированием, таким как подчёркивание или картинка, состоит из элементов инлайн-уровня.

- -

venn_inlines.png

- -
-

Эта диаграмма использует устаревшую терминологию; см. примечания ниже. К тому же она некорректна, потому что жёлтый эллипс справа по определению должен быть изображён одинаковым по размеру с эллипсом слева или больше него  (it could be a mathematical superset), потому что в спецификации сказано: "Элементв инлайн-уровня генерируют боксы инлайн-уровня, участвующие в форматировании инлайн-уровня", см. CSS 2.2, глава 9.2.2

-
- -

Элементы инлайн-уровня создают боксы инлайн-уровня, которые определены как боксы, участвующие в контексте форматирования инлайн-уровня. Inline boxes are both inline-level boxes and boxes, whose contents participate in their container's inline formatting context. This is the case, for example, for all non-replaced boxes with display:inline. Inline-level boxes, whose contents do not participate in an inline formatting context, are called atomic inline-level boxes. These boxes, generated by replaced inline-level elements or by elements with a calculated {{ cssxref("display") }} value of inline-block or inline-table, are never split into several boxes, as is possible with inline boxes.

- -
Note: Initially, atomic inline-level boxes were called atomic inline boxes. This was unfortunate, as they are not inline boxes. This was corrected in an erratum to the spec. Nevertheless, you can harmlessly read atomic inline-level box each time you meet atomic inline box in the literature, as this is only a name change.
- -
Atomic inline boxes cannot be split into several lines in an inline formatting context. -
-
<style>
-  span {
-    display:inline; /* default value*/
-  }
-</style>
-<div style="width:20em;">
-   The text in the span <span>can be split in several
-   lines as it</span> is an inline box.
-</div>
-
-
- -

which leads to:

- -
The text in the span can be split into several lines as it is an inline box.
- -
<style>
-  span {
-    display:inline-block;
-  }
-</style>
-<div style="width:20em;">
-   The text in the span <span>cannot be split in several
-   lines as it</span> is an inline-block box.
-</div>
- -
-
-

which leads to:

- -
The text in the span cannot be split into several lines as it is an inline-block box.
-
-
- -

Anonymous inline boxes

- -

As for block boxes, there are a few cases where inline boxes are created automatically by the CSS engine. These inline boxes are also anonymous as they cannot be named by selectors; they inherit the value of all inheritable properties, setting it to initial for all others.

- -

The most common case where an anonymous inline box is created, is when some text is found as a direct child of a block box creating an inline formatting context. In that case, this text is included in the largest possible anonymous inline box. Also, space content, which would be removed by the behavior set in the {{ cssxref("white-space") }} CSS property, does not generate anonymous inline boxes because they would end empty.

- -
Example TBD
- -

Other types of boxes

- -

Line boxes

- -

Line boxes are generated by the inline formatting context to represent a line of text. Inside a block box, a line box extends from one border of the box to the other. When there are floats, the line box starts at the rightmost border of the left floats and ends at the leftmost border of the right floats.

- -

These boxes are technical, and Web authors do not usually have to bother with them.

- -

Run-in boxes

- -

Run-in boxes, defined using display:run-in, are boxes that are either block boxes or inline boxes, depending on the type of the following box. They can be used to create a title that runs inside its first paragraph when possible.

- -
Note: Run-in boxes were removed from the CSS 2.1 standard, as they were insufficiently specified to allow for interoperable implementation. They may reappear in CSS3, but meanwhile, are considered experimental. They should not be used in production.
- -

Model-induced boxes

- -

Besides the inline and block formatting contexts, CSS specifies several additional content models that may be applied to elements. These additional models, used to describe specific layouts, may define additional box types:

- -
    -
  • The table content model may create a table wrapper box and a table box, but also specific boxes like caption boxes.
  • -
  • The multi-column content model may create column boxes between the container box and the content.
  • -
  • The experimental grid, or flex-box content models, also create additional types of boxes.
  • -
- -

Positioning schemes

- -

Once boxes are generated, the CSS engine needs to position them on the layout. To do that, it uses one of the following algorithms:

- -
    -
  • The normal flow - positions each box one after the other.
  • -
  • The floats algorithm - extracts the box from the normal flow and put it to the side of the containing box.
  • -
  • The absolute positioning scheme - positions a box within an absolute coordinate system that is established by its containing element. An absolutely positioned element can cover other elements.
  • -
- -

Normal flow

- -

In the normal flow, boxes are laid out one after the other. In a block formatting context, they are laid out vertically; in an inline formatting context, they are laid out horizontally. The normal flow is triggered when the CSS {{ cssxref("position") }} is set to the value static or relative, and if the CSS {{ cssxref("float") }} is set to the value none.

- -

Example

- -
When in the normal flow, in a block formatting context, boxes are laid vertically one after the other out.
-
-When in the normal flow, in an inline formatting context, boxes are laid horizontally one after the other out.
- -
-

There are two sub-cases of the normal flow: static positioning and relative positioning:

- -
    -
  • In static positioning, triggered by the value static of the {{ cssxref("position") }} property, the boxes are drawn at the exact position defined by the normal flow layout.
  • -
  • In relative positioning, triggered by the value relative of the {{ cssxref("position") }} property, the boxes are drawn with an offset defined by the {{ cssxref("top") }}, {{ cssxref("bottom") }}, {{ cssxref("left") }} and {{ cssxref("right") }} CSS properties.
  • -
-
- -

Floats

- -

In the float positioning scheme, specific boxes (called floating boxes or simply floats) are positioned at the beginning, or end of the current line. This leads to the property that text (and more generally anything within the normal flow) flows along the edge of the floating boxes, except if told differently by the {{ cssxref("clear") }} CSS property.

- -

The float positioning scheme for a box is selected, by setting the {{ cssxref("float") }} CSS property on that box to a value different than none and {{ cssxref("position") }} to static or relative. If {{ cssxref("float") }} is set to left, the float is positioned at the beginning of the line box. If set to right, the float is positioned at the end of the line box. In either case, the line box is shrunk to fit alongside the float.

- -

Absolute positioning

- -

In the absolute positioning scheme, boxes are entirely removed from the flow and don't interact with it at all. They are positioned relative to their containing block using the {{ cssxref("top") }}, {{ cssxref("bottom") }}, {{ cssxref("left") }} and {{ cssxref("right") }} CSS properties.

- -

An element is absolutely positioned if the {{ cssxref("position") }} is set to absolute or fixed.

- -

With a fixed positioned element, the containing block is the viewport. The position of the element is absolute within the viewport. Scrolling does not change the position of the element.

diff --git a/files/ru/web/guide/events/creating_and_triggering_events/index.html b/files/ru/web/guide/events/creating_and_triggering_events/index.html new file mode 100644 index 0000000000..9e7a8f099b --- /dev/null +++ b/files/ru/web/guide/events/creating_and_triggering_events/index.html @@ -0,0 +1,92 @@ +--- +title: Создание и вызов событий +slug: Web/Guide/Events/Создание_и_вызов_событий +tags: + - DOM + - JavaScript + - events + - события +translation_of: Web/Guide/Events/Creating_and_triggering_events +--- +

Эта статья демонстрирует, как создавать и вызывать пользовательские DOM-события. Такие события часто называют исскуственными событиями, по отношению к событиям, производимым браузером.

+ +

Создание собственных событий

+ +

События могут быть созданы с помощью  конструктора Event:

+ +
var event = new Event('build');
+
+// Подписываемся на событие
+elem.addEventListener('build', function (e) { ... }, false);
+
+// Вызываем событие
+elem.dispatchEvent(event);
+ +

Этот конструктор поддерживается во всех современных браузерах (кроме Internet Explorer). Более подробную информацию смотрите ниже "Старомодный способ".

+ +

Добавление пользовательских данных – CustomEvent()

+ +

Чтобы добавить больше данных к объекту event, существует интерфейс CustomEvent, и вы можете использовать свойство detail, чтобы передать собственные данные. Например, событие может быть создано так:

+ +
var event = new CustomEvent('build', { 'detail': elem.dataset.time });
+ +

Это позволит вам получить доступ к дополнительным данным в обработчике:

+ +
function eventHandler(e) {
+  log('The time is: ' + e.detail);
+}
+
+ +

Старомодный способ

+ +

Старый способ создать событие использует API в стиле Java. Пример:

+ +
// Создание события
+var event = document.createEvent('Event');
+
+// Назначить имя событию
+event.initEvent('build', true, true);
+
+// Слушаем событие
+document.addEventListener('build', function (e) {
+  // e.target соотетствует объекту document
+}, false);
+
+// target события может быть любой элемент
+document.dispatchEvent(event);
+
+
+ +

Вызов встроенных событий

+ +

Этот пример показывает симуляцию клика (программно сгенерированное событие клика) по галочке чекбокса, используя DOM-методы. Просмотр действующих примеров.

+ +
function simulateClick() {
+  var event = new MouseEvent('click', {
+    'view': window,
+    'bubbles': true,
+    'cancelable': true
+  });
+  var cb = document.getElementById('checkbox');
+  var canceled = !cb.dispatchEvent(event);
+  if (canceled) {
+    // A handler called preventDefault.
+    alert("canceled");
+  } else {
+    // None of the handlers called preventDefault.
+    alert("not canceled");
+  }
+}
+ +

Совместимость с браузерами

+ +

{{Compat("api.Event.Event")}}

+ +

Смотрите также

+ +
    +
  • {{domxref("document.createEvent()")}}
  • +
  • {{domxref("Event.initEvent()")}}
  • +
  • {{domxref("EventTarget.dispatchEvent()")}}
  • +
  • {{domxref("EventTarget.addEventListener()")}}
  • +
diff --git "a/files/ru/web/guide/events/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\320\262\321\213\320\267\320\276\320\262_\321\201\320\276\320\261\321\213\321\202\320\270\320\271/index.html" "b/files/ru/web/guide/events/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\320\262\321\213\320\267\320\276\320\262_\321\201\320\276\320\261\321\213\321\202\320\270\320\271/index.html" deleted file mode 100644 index 9e7a8f099b..0000000000 --- "a/files/ru/web/guide/events/\321\201\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\320\262\321\213\320\267\320\276\320\262_\321\201\320\276\320\261\321\213\321\202\320\270\320\271/index.html" +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Создание и вызов событий -slug: Web/Guide/Events/Создание_и_вызов_событий -tags: - - DOM - - JavaScript - - events - - события -translation_of: Web/Guide/Events/Creating_and_triggering_events ---- -

Эта статья демонстрирует, как создавать и вызывать пользовательские DOM-события. Такие события часто называют исскуственными событиями, по отношению к событиям, производимым браузером.

- -

Создание собственных событий

- -

События могут быть созданы с помощью  конструктора Event:

- -
var event = new Event('build');
-
-// Подписываемся на событие
-elem.addEventListener('build', function (e) { ... }, false);
-
-// Вызываем событие
-elem.dispatchEvent(event);
- -

Этот конструктор поддерживается во всех современных браузерах (кроме Internet Explorer). Более подробную информацию смотрите ниже "Старомодный способ".

- -

Добавление пользовательских данных – CustomEvent()

- -

Чтобы добавить больше данных к объекту event, существует интерфейс CustomEvent, и вы можете использовать свойство detail, чтобы передать собственные данные. Например, событие может быть создано так:

- -
var event = new CustomEvent('build', { 'detail': elem.dataset.time });
- -

Это позволит вам получить доступ к дополнительным данным в обработчике:

- -
function eventHandler(e) {
-  log('The time is: ' + e.detail);
-}
-
- -

Старомодный способ

- -

Старый способ создать событие использует API в стиле Java. Пример:

- -
// Создание события
-var event = document.createEvent('Event');
-
-// Назначить имя событию
-event.initEvent('build', true, true);
-
-// Слушаем событие
-document.addEventListener('build', function (e) {
-  // e.target соотетствует объекту document
-}, false);
-
-// target события может быть любой элемент
-document.dispatchEvent(event);
-
-
- -

Вызов встроенных событий

- -

Этот пример показывает симуляцию клика (программно сгенерированное событие клика) по галочке чекбокса, используя DOM-методы. Просмотр действующих примеров.

- -
function simulateClick() {
-  var event = new MouseEvent('click', {
-    'view': window,
-    'bubbles': true,
-    'cancelable': true
-  });
-  var cb = document.getElementById('checkbox');
-  var canceled = !cb.dispatchEvent(event);
-  if (canceled) {
-    // A handler called preventDefault.
-    alert("canceled");
-  } else {
-    // None of the handlers called preventDefault.
-    alert("not canceled");
-  }
-}
- -

Совместимость с браузерами

- -

{{Compat("api.Event.Event")}}

- -

Смотрите также

- -
    -
  • {{domxref("document.createEvent()")}}
  • -
  • {{domxref("Event.initEvent()")}}
  • -
  • {{domxref("EventTarget.dispatchEvent()")}}
  • -
  • {{domxref("EventTarget.addEventListener()")}}
  • -
diff --git a/files/ru/web/guide/graphics/index.html b/files/ru/web/guide/graphics/index.html new file mode 100644 index 0000000000..57dd4238e1 --- /dev/null +++ b/files/ru/web/guide/graphics/index.html @@ -0,0 +1,41 @@ +--- +title: Графика для Web +slug: Web/Guide/Графика +translation_of: Web/Guide/Graphics +--- +

Современным веб-сайтам и веб-приложениям часто требуется отображать графику. Статические изображения легко отобразить с помощью элемента {{HTMLElement("img")}}, или с помощью CSS свойства  {{cssxref("background-image")}}. Часто требуется создавать графику на лету, или модифицировать ее каким-либо образом после. Как это проделать можно узнать в следующих статьях.

+ +
+
+

2D графика

+ +
+
Канвас
+
Элемент {{HTMLElement("canvas")}} представляет удобный API для рисования 2D графики с помощью JavaScript.
+
SVG
+
Масштабируемая Векторная Графика (Scalable Vector Graphics) позволяет рисовать линии, кривые, и другие геометрические фигуры. С их помощью можно создавать масштабируемые изображения, которые не теряют в качестве при изменении размера в отличии от растровой графики.
+
+ +

View All...

+
+ +
+

3D графика

+ +
+
WebGL
+
Руководство по быстрому старту с WebGL. WebGL предоставляет API для работы с 3D графиками в веб. Эта технология позволяет Вам использовать стандартный OpenGL ES в веб контексте.
+
+ +

Видео

+ +
+
Использование HTML5 видео и аудио
+
Встраивание видео и аудио в HTML документ и управление проигрыванием.
+
WebRTC
+
RTC в WebRTC означает Real-Time Communications, технология которая позволяет стримить аудио/видео и данные между клиентами браузера (пирами).
+
+
+
+ +

 

diff --git a/files/ru/web/guide/html/drag_and_drop/drag_operations/index.html b/files/ru/web/guide/html/drag_and_drop/drag_operations/index.html deleted file mode 100644 index 2dcdb6babb..0000000000 --- a/files/ru/web/guide/html/drag_and_drop/drag_operations/index.html +++ /dev/null @@ -1,314 +0,0 @@ ---- -title: Drag Operations -slug: Web/Guide/HTML/Drag_and_drop/Drag_operations -translation_of: Web/API/HTML_Drag_and_Drop_API/Drag_operations ---- -

{{DefaultAPISidebar("HTML Drag and Drop API")}}

- -

Ниже описаны шаги, которые происходят при drag and drop операции.

- -

Drag операции описываются в документе, используя {{domxref("DataTransfer")}} интерфейс. Этот документ не использует не{{domxref("DataTransferItem")}} интерфейс, не{{domxref("DataTransferItemList")}} интерфейс.

- -

draggable атрибуты

- -

На веб-странице, в некоторых случаях используется поведение drag (перетаскивания) по умолчанию. Включая выделенный текст, изображения и ссылки. Когда изображение иои ссылка переносятся, URL изображения или ссылки устанавливается в качестве данных drag и перетаскивание начинается. Для других элементов, они должны быть частью выделения для выполнения перетаскивания по умолчанию. Чтобы увидеть это в действии, выделите область веб-страницы, а затем нажмите и удерживайте кнопку мыши и перетащите выделение. Появится специфичный для ОС рендеринг выделенного фрагмента и будет следовать за указателем мыши при перетаскивании. Однако это поведение является только drag поведением по умолчанию, если нет слушателей, определяющих данные для перетаскивания.

- -

В HTML, кроме поведения по умолчанию изображений, ссылок и выделенных областей, ноикакие другие элементы по умолчанию не переносятся.

- -

Для перетаскивания других HTML-элементов, должны быть выполнены три пункта :

- -
    -
  1. Установить {{htmlattrxref("draggable")}}="true" на элемент, который вы хотите сделать перетаскиваемым.
  2. -
  3. Добавить слушатель события {{event("dragstart")}}.
  4. -
  5. Установить данные перетаскивания в слушатель выше.
  6. -
- -

Вот пример, который позволяет перетаскивать часть содержимого.

- -
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
-  This text <strong>may</strong> be dragged.
-</p>
-
- -

Атрибут {{htmlattrxref("draggable")}} установлен в  "true", т.о. этот элемент становится перетаскиваемым. Если этот атрибут был опущен или установлен в "false", то элемент не может быть перенесен, и вместо этого будет выбран текст.

- -

Атрибут {{htmlattrxref("draggable")}} может быть использован для любого элемента, включаяизображения и ссылки. Однако, для последних двух, значение по умолчанию - true, т.о. вы можете только использвать атрибут  {{htmlattrxref("draggable")}} со значением false для отключение перетаскивания этих элементов.

- -
-

Примечание: Когда элемент становится перетаскиваемыми, tтекст или другие элементы в нем больше не могут быть выбраны обычным способом, щелкая и перетаскивая мышью. Вместо этого пользователь должен удерживать клавишу Alt  чтобы выбрать текст с помощью мыши или клавиатуры.

-
- -

Начало операции перетаскивания

- -

В примере, слушатель добавлен для события {{event("dragstart")}} с использованием атрибута{{domxref("GlobalEventHandlers.ondragstart","ondragstart")}}.

- -
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
-  This text <strong>may</strong> be dragged.
-</p>
-
- -

Когда пользователь начинает перетаскивание, запускается событиеdrag, the {{event("dragstart")}}.

- -

В этом примере слушатель {{event("dragstart")}} добавлен к самому перемещаемом элементу. Однако, вы можете слушать более высокого предка, так как событие перетаскивание высплывает вверх как и большинство событий.

- -

Внутри события {{event("dragstart")}}, вы можете указать drag данные, изображжение отклика, drag-эффекты, все это описано ниже. Однако, обязательны только drag данные. (Изображение и drag-эффекты по умолчанию, подходят в большинстве ситуаций)

- -

Drag-данные

- -

Все {{domxref("DragEvent","drag events")}} имеют свойство, называемое{{domxref("DragEvent.dataTransfer","dataTransfer")}}, которое содержит drag-данные (dataTransfer это {{domxref("DataTransfer")}} object).

- -

Когда происходит перетаскивание, данные должны быть связаны с перетаскиванием, которое определяет, что перетаскивается. Например, при перетаскивании выделенного текста в текстовое поле данные, связанные с элементом данных перетаскивания, являются самим текстом. Аналогично, при перетаскивании ссылки на веб-странице элемент данных перетаскивания является URL-адресом ссылки.

- -

{{domxref("DataTransfer","drag data")}} содержит два параметра, тип (или формат) данных, и значение данных. Формат это строковый тип (такой как text/plain текстовых данных), значение - строка текста. Когда начинается перетаскивание, вы добавляете данные, предоставляя тип и данные. Во время перетаскивания в слушателе события для событий {{event("dragenter")}} и {{event("dragover")}} , вы используете типы данных перетаскиваемых данных, чтобы проверить, разрешено ли удаление. Например, цель drop, которая принимает ссылки, будет проверять тип text/uri-list. В течение события drop, слушатель будет получать данные тащат и вставить его на место.

- -

Свойство {{domxref("DataTransfer","drag data's")}} {{domxref("DataTransfer.types","types")}} возвращает список MIME-типов {{domxref("DOMString")}}, таких как text/plain или image/jpeg. Вы также можете создавать свои собственные типы. Большинство основные используемых типов описаны в  Recommended Drag Types.

- -

Перетаскивание может включать элементы данных нескольких различных типов. Это позволяет предоставлять данные в более специфических типах, часто пользовательских, но по предоставляет резервные данные для drop, которые не поддерживают более специфические типы. Как правило, наименее специфичным типом будут обычные текстовые данные, использующие тип text/plain. Эти данные будут простым текстовым представлением.

- -

Установка элементов drag-данных {{domxref("DragEvent.dataTransfer","dataTransfer")}}, используя метод {{domxref("DataTransfer.setData","setData()")}}. Требуется два аргумента: тип данных и значение данных. Например:

- -
event.dataTransfer.setData("text/plain", "Text to drag");
-
- -

Здесь, значение -  "Text to drag", формат -  text/plain.

- -

Вы можете предусмотреть данные в нескольких форматах. Сделаем это, вызовем метод  {{domxref("DataTransfer.setData","setData()")}} несколько раз с различными форматами. Вы должны вызывать его с форматами от большей специфичности к меньшей.

- -
const dt = event.dataTransfer;
-dt.setData("application/x.bookmark", bookmarkString);
-dt.setData("text/uri-list", "https://www.mozilla.org");
-dt.setData("text/plain", "https://www.mozilla.org");
-
- -

Добавлены данные трех различных форматов. Первый тип - application/x.bookmark, пользовательский тип.Другие приложения не поддерживают данный тип, но вы можете использовать пользовательский тип для перетаскивания между областями в одном приложениее или на одной странице.

- -

Предоставляя данные и в других типах, мы также можем поддерживать перетаскивание в другие приложения в менее специфичных формах. Тип application/x.bookmark может предоставлять данные с  более подробной информацией для использования в приложении, в то время как другие типы могут включать только один URL-адрес или текстовую версию.

- -

Обратите внимание, что и text/uri-list и text/plain cодержат одни и те же данные в этом примере.  Это часто бывает так, но это не обязательно.

- -

Если вы попытаетесь добавить данные дважды с тем же форматом, новые данные заменят старые данные, но в той же позиции в списке типов, что и старые данные.

- -

Вы можете очистить данные, используя метод {{domxref("DataTransfer.clearData","clearData()")}}, который принимает один аргумент: тип данных для удаления.

- -
event.dataTransfer.clearData("text/uri-list");
-
- -

Аргумент type в методе {{domxref("DataTransfer.clearData","clearData()")}} опционален. Если type не указан, данные, связанные со всеми типами, удаляются. Если перетаскивание не содержит элементов данных перетаскивания или все элементы были впоследствии очищены, то перетаскивание не произойдет.

- -

Настройка изображения отклика drag

- -

Когда происходит перетаскивание, полупрозрачное изображение генерируется из цели перетаскивания (событие "{{event("dragstart")}}" элемента срабатывает), и следует за указателем пользователя во время перетаскивания. Это изображение создается автоматически, поэтому вам не нужно создавать его самостоятельно. Однако вы можете использовать {{domxref("DataTransfer.setDragImage","setDragImage()")}} для задания пользовательского изображения отклика перетаскивания.

- -
event.dataTransfer.setDragImage(image, xOffset, yOffset);
-
- -

Необходимы три аргумента. Первый - это ссылка на изображение. Эта ссылка обычно относится к элементу <img>, но также может относиться к элементу <canvas> или любому другому элементу. Изображение отклика будет генерироваться из того, как изображение выглядит на экране, для изображений они будут нарисованы в их первоначальном размере. Второй и третий аргументы метода {{domxref("DataTransfer.setDragImage","setDragImage()")}} - это смещения, в которых изображение должно появляться относительно указателя мыши.

- -

Также можно использовать изображения и canvas, которых нет в документе. Этот метод полезен при рисовании пользовательских изображений перетаскивания с помощью элемента canvas, как показано в следующем примере:

- -
function dragWithCustomImage(event) {
-  const canvas = document.createElement("canvas");
-  canvas.width = canvas.height = 50;
-
-  const ctx = canvas.getContext("2d");
-  ctx.lineWidth = 4;
-  ctx.moveTo(0, 0);
-  ctx.lineTo(50, 50);
-  ctx.moveTo(0, 50);
-  ctx.lineTo(50, 0);
-  ctx.stroke();
-
-  const dt = event.dataTransfer;
-  dt.setData('text/plain', 'Data to Drag');
-  dt.setDragImage(canvas, 25, 25);
-}
-
- -

В этом примере мы делаем один canvas перетаскивания. Поскольку размер холста составляет 50×50 пикселей, мы используем смещение половины этого (25), чтобы изображение было центрировано на указателе мыши.

- -

Drag эффекты

- -

При перетаскивании можно выполнить несколько операций. Операция  copy используется для указания на то, что перетаскиваемые данные будут скопированы из текущего местоположения в место перетаскивания. Операция move используется для указания на то, что перетаскиваемые данные будут перемещены, а операция link используется для указания на то, что между исходным и удаляемым местоположениями будет создана некоторая форма связи или соединения.

- -

Вы можете указать, какая из трех операций разрешена для источника перетаскивания, установив свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}} в слушателе событий{{event("dragstart")}}.

- -
event.dataTransfer.effectAllowed = "copy";
-
- -

В этом примере разрешена только копия.

- -

Вы можете комбинировать значения различными способами:

- -
-
none
-
никакая операция не разрешена
-
copy
-
только copy
-
move
-
только move
-
link
-
только link
-
copyMove
-
только copy или move
-
copyLink
-
только copy или link
-
linkMove
-
только link или move
-
all
-
только copy, move, или link
-
uninitialized
-
Значение по умолчанию all.
-
- -

Обратите внимание, что эти значения должны использоваться так, как указано выше. Например, установка свойства {{domxref("DataTransfer.effectAllowed","effectAllowed")}} на copyMove позволяет выполнять операцию копирования или перемещения, но не позволяет пользователю выполнять операцию связывания. Если вы не измените свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}},  то любая операция разрешена, как и со значением 'all'. Поэтому вам не нужно настраивать это свойство, если вы не хотите исключить определенные типы.

- -

Во время операции перетаскивания, слушатель для событий {{event("dragenter")}} или {{event("dragover")}} может проверить свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}} , какие операции разрешены. Связанное свойство,  {{domxref("DataTransfer.dropEffect","dropEffect")}}, должно быть установлено в пределах одного из этих событий, чтобы указать, какая единственная операция должна быть выполнена. Допустимые значения для {{domxref("DataTransfer.dropEffect","dropEffect")}} - none, copy, move, или link. Комбинированные значения для этого свойства не используются.

- -

С событиями {{event("dragenter")}} и {{event("dragover")}}, свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} инициализируется в соответствии с запросом пользователя. Пользователь может изменить желаемый эффект, нажав клавиши-модификаторы. Хотя точные используемые клавиши различаются в зависимости от платформы, обычно клавиши  Shift и Control используются для переключения между копированием, перемещением и связыванием. Указатель мыши изменится, чтобы указать, какая операция требуется. Например, для copy курсор может появиться со знаком плюс рядом с ним.

- -

Вы можете изменять свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} во время событий {{event("dragenter")}} или {{event("dragover")}}, например, определенная drop-цель поддерживает только определенные операции. Вы можете изменить свойство {{domxref("DataTransfer.dropEffect","dropEffect")}}, чтобы переопределить действие пользователя, и обеспечить выполнение специфичной  операции перетаскивания при ее наступлении. Обратите внимание, что этот эффект должен быть указан в списке свойств {{domxref("DataTransfer.effectAllowed","effectAllowed")}}. В противном случае ему будет присвоено другое допустимое значение.

- -
event.dataTransfer.dropEffect = "copy";
-
- -

В этом примере выполняется эффект копирования.

- -

Вы можете использовать значение none, чтобы указать, что в этом месте не допускается удаление, хотя в этом случае лучше не отменять событие.

- -

В событиях {{event("drop")}} и {{event("dragend")}}, yвы можете проверить свойства {{domxref("DataTransfer.dropEffect","dropEffect")}} для определения того, какой эффект был в конечном итоге выбран.  Если выбран эффект "move",то исходные данные должны быть удалены из источника перетаскивания в событии{{event("dragend")}}.

- -

Указание drop-целей

- -

Слушатель для событий {{event("dragenter")}} и {{event("dragover")}} используются для указания допустимых drop-целей, то есть мест, где могут быть сброшены перетаскиваемые элементы. Большинство областей веб-страницы или приложения не являются допустимыми местами для сброса данных. Таким образом, обработка этих событий по умолчанию не допускает сброса перетаскиваемых данных.

- -

Если вы хотите разрешить сброс переносимых данных, вы должны предотвратить обработку по умолчанию, отменив оба события dragenter и dragover.  Это можно сделать, либо вернув false из определенных атрибутом слушателя событий, либо вызвав метод {{domxref("Event.preventDefault","preventDefault()")}} событие. Последнее может быть более осуществимо в функции, определенной в отдельном скрипте.

- -
<div ondragover="return false">
-<div ondragover="event.preventDefault()">
-
- -

Вызывая метод {{domxref("Event.preventDefault","preventDefault()")}} во время обоих событий {{event("dragenter")}} и {{event("dragover")}} укажите, что падение разрешено в этом месте. Однако обычно вы захотите вызвать метод  {{domxref("Event.preventDefault","preventDefault()")}} события только в определенных ситуациях (например, только при перетаскивании ссылки).

- -

Для этого вызовите функцию, которая проверяет условие и отменяет событие только при его выполнении. Если условие не выполнено, не отменяйте событие, и сброс перетаскиваемых данных не произойдет, если пользователь отпустит кнопку мыши.

- -

Наиболее распространенным является принятие или отклонение сброса в зависимости от типа данных перетаскивания при передаче данных — например, разрешение для изображений, ссылок или и того, и другого. Для этого вы можете проверить свойство {{domxref("DataTransfer.types","types")}} события {{domxref("DragEvent.dataTransfer","dataTransfer")}} (свойство). Свойство {{domxref("DataTransfer.types","types")}} возвращает массив из строк, добавленных при начале перетаскивания, в порядке от наиболее значимого к наименее значимому.

- -
function doDragOver(event) {
-  const isLink = event.dataTransfer.types.includes("text/uri-list");
-  if (isLink) {
-    event.preventDefault();
-  }
-}
- -

В этом примере мы используем метод includes  чтобы проверить, присутствует ли тип text/uri-list в списке типов. Если это так, мы отменим событие, так что сброс становится разрешен. Если перетаскиваемые данные не содержат ссылки, событие не будет отменено, и сброс не может произойти в этом месте.

- -

Вы также можете установить либо свойство {{domxref("DataTransfer.effectAllowed","effectAllowed")}}, либо свойство{{domxref("DataTransfer.dropEffect","dropEffect")}}, либо оба одновременно, если вы хотите указать более конкретные сведения о типе операции, которая будет выполнена. Естественно, изменение любого свойства не будет иметь никакого эффекта, если вы не отмените событие.

- -

Drop Feedback

- -

There are several ways in which you can indicate to the user that a drop is allowed at a certain location. The mouse pointer will update as necessary depending on the value of the {{domxref("DataTransfer.dropEffect","dropEffect")}} property.

- -

Although the exact appearance depends on the user's platform, typically a plus sign icon will appear for a 'copy' for example, and a 'cannot drop here' icon will appear when a drop is not allowed. This mouse pointer feedback is sufficient in many cases.

- -

However, you can also update the user interface with an insertion point or highlight as needed. For simple highlighting, you can use the :-moz-drag-over CSS pseudoclass on a drop target.

- -
.droparea:-moz-drag-over {
-  outline: 1px solid black;
-}
-
- -

In this example, the element with the class droparea will receive a 1 pixel black outline while it is a valid drop target, that is, if the {{domxref("Event.preventDefault","preventDefault()")}} method was called during the {{event("dragenter")}} event.

- -
-

Note: You must cancel the {{event("dragenter")}} event for this pseudoclass to apply, as this state is not checked for the {{event("dragover")}} event.

-
- -

For more complex visual effects, you can also perform other operations during the {{event("dragenter")}} event. For example, by inserting an element at the location where the drop will occur. This might be an insertion marker, or an element that represents the dragged element in its new location. To do this, you could create an image or separator element and simply insert it into the document during the {{event("dragenter")}} event.

- -

The {{event("dragover")}} event will fire at the element the mouse is pointing at. Naturally, you may need to move the insertion marker around a {{event("dragover")}} event as well. You can use the event's {{domxref("MouseEvent.clientX","clientX")}} and {{domxref("MouseEvent.clientY","clientY")}} properties as with other mouse events to determine the location of the mouse pointer.

- -

Finally, the {{event("dragleave")}} event will fire at an element when the drag leaves the element. This is the time when you should remove any insertion markers or highlighting. You do not need to cancel this event. Any highlighting or other visual effects specified using the :-moz-drag-over pseudoclass will be removed automatically. The {{event("dragleave")}} event will always fire, even if the drag is cancelled, so you can always ensure that any insertion point cleanup can be done during this event.

- -

Performing a Drop

- -

When the user releases the mouse, the drag and drop operation ends.

- -

If the mouse is released over an element that is a valid drop target, that is, one that cancelled the last {{event("dragenter")}} or {{event("dragover")}} event, then the drop will be successful, and a {{event("drop")}} event will fire at the target. Otherwise, the drag operation is cancelled, and no {{event("drop")}} event is fired.

- -

During the {{event("drop")}} event, you should retrieve that data that was dropped from the event and insert it at the drop location. You can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine which drag operation was desired.

- -

As with all drag-related events, the event's {{domxref("DataTransfer","dataTransfer")}} property will hold the data that is being dragged. The {{domxref("DataTransfer.getData","getData()")}} method may be used to retrieve the data again.

- -
function onDrop(event) {
-  const data = event.dataTransfer.getData("text/plain");
-  event.target.textContent = data;
-  event.preventDefault();
-}
-
- -

The {{domxref("DataTransfer.getData","getData()")}} method takes one argument, the type of data to retrieve. It will return the string value that was set when {{domxref("DataTransfer.setData","setData()")}} was called at the beginning of the drag operation. An empty string will be returned if data of that type does not exist. (Naturally, though, you would likely know that the right type of data was available, as it was previously checked during a {{event("dragover")}} event.)

- -

In the example here, once the data has been retrieved, we insert the string as the textual content of the target. This has the effect of inserting the dragged text where it was dropped, assuming that the drop target is an area of text such as a p or div element.

- -

In a web page, you should call the {{domxref("Event.preventDefault","preventDefault()")}} method of the event if you have accepted the drop, so that the browser's default handling is not triggered by the dropped data as well. For example, when a link is dragged to a web page, Firefox will open the link. By cancelling the event, this behavior will be prevented.

- -

You can retrieve other types of data as well. If the data is a link, it should have the type text/uri-list. You could then insert a link into the content.

- -
function doDrop(event) {
-  const lines = event.dataTransfer.getData("text/uri-list").split("\n");
-  lines.filter(line => !line.startsWith("#"))
-    .forEach(line => {
-      const link = document.createElement("a");
-      link.href = line;
-      link.textContent = line;
-      event.target.appendChild(link);
-    })
-  event.preventDefault();
-}
-
- -

This example inserts a link from the dragged data. As the name implies, the text/uri-list type actually may contain a list of URLs, each on a separate line. The above code uses split to break the string into lines, then iterates over the list of lines, and inserts each as a link into the document. (Note also that links starting with a number sign (#) are skipped, as these are comments.)

- -

For simple cases, you can use the special type URL just to retrieve the first valid URL in the list. For example:

- -
const link = event.dataTransfer.getData("URL");
-
- -

This eliminates the need to check for comments or iterate through lines yourself. However, it is limited to only the first URL in the list.

- -

The URL type is a special type. It is used only as a shorthand, and it does not appear within the list of types specified in the {{domxref("DataTransfer.types","types")}} property.

- -

Sometimes you may support some different formats, and you want to retrieve the data that is most specific that is supported. In the following example, three formats are supported by a drop target.

- -

The following example returns the data associated with the best-supported format:

- -
function doDrop(event) {
-  const supportedTypes = ["application/x-moz-file", "text/uri-list", "text/plain"];
-  const types = event.dataTransfer.types.filter(type => supportedTypes.includes(type));
-  if (types.length) {
-    const data = event.dataTransfer.getData(types[0]);
-  }
-  event.preventDefault();
-}
-
- -

Окончание перетаскивания

- -

Как только перетаскивание завершено, событие {{event("dragend")}} запускается в источнике перетаскивания (тот же элемент, который получил событие {{event("dragstart")}}). Это событие сработает, если перетаскивание было успешным[1] или если оно было отменено. Однако вы можете использовать свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} для определения, какая операция удаления произошла.

- -

Если свойство {{domxref("DataTransfer.dropEffect","dropEffect")}} имеет значение none во время события {{event("dragend")}}, то перетаскивание было отменено. В противном случае эффект указывает, какая операция была выполнена. Источник может использовать эту информацию после операции перемещения для удаления перетаскиваемого элемента из старого расположения. Свойство {{domxref("DataTransfer.mozUserCancelled","mozUserCancelled")}} будет присвоено значение true, если пользователь отменил перетаскивание (нажав Escape), и false если перетаскивание было отменено по другим причинам, таким как недопустимая цель перетаскивания, или если оно было успешным.

- -

Сброс может произойти внутри того же окна или над другим приложением. Событие{{event("dragend")}}будет срабатывать всегда, независимо от этого. Свойство события {{domxref("MouseEvent.screenX","screenX")}} и {{domxref("MouseEvent.screenY","screenY")}} будут установлены в координаты экрана, где произошел сброс.

- -

Когда событие {{event("dragend")}} завершило распространение, операция перетаскивания завершена.

- -

[1]: В Gecko, {{event("dragend")}} не отправляется, если исходный узел движется или удаляется во время перетаскивания (например, при сбрасывании или {{event("dragover")}}). Bug 460801

- -

Смотрите также

- - diff --git a/files/ru/web/guide/html/drag_and_drop/index.html b/files/ru/web/guide/html/drag_and_drop/index.html deleted file mode 100644 index 86467501fd..0000000000 --- a/files/ru/web/guide/html/drag_and_drop/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Drag and drop -slug: Web/Guide/HTML/Drag_and_drop -translation_of: Web/API/HTML_Drag_and_Drop_API ---- -

Firefox и прочие приложения компании Mozilla имеют ряд возможностей для управления drag и drop. Это позволяет пользователю нажать и удерживая зажатой кнопку мыши над элементом, переместить его на другую позицию, отпустив кнопку мыши пользователь может оставить элемент на новой позиции. На протяжении всей операции перемещения полупрозрачное представление элемента следует за курсором мыши. Новая позиция элемента может располагаться в совершенно другом приложении. Веб сайты, и XUL приложения могут использовать эту функциональность для того, чтобы определить какие элементы страницы могут быть перемещены, а также определить элементы куда первые могут быть перемещены.

- -
Эта часть покрывает функциональность drag и drop в Firefox 3.5 (Gecko 1.9.1) а также последующие версии. Для старого API для Firefox 3.0 и ранее, в котором нет соответствующей поддержки данной функциональности, смотрите older API documentation.
- -

Основы Drag и Drop

- -

Использование функциональности drag и drop подразумевает выполнения следующих шагов:

- -
    -
  • Определить переносимый элемент. Присвоить true атрибуту draggable элемента, который мы хотим перенести. Для детальной информации смотрите The Draggable Attribute.
  • -
  • Определить данные, которые могут быть перемещены, они могут быть разного формата. К примеру, текстовые данные, содержащие строку текста который может быть перемещен. Для детальной информации смотрите Drag Data.
  • -
  • (Необязательно) Определить изображение которое будет рядом с указателем мыши на протяжении всей операции перетаскивания.  Если пользовательское изображение не будет определено, будет сгенерирована картинка по умолчанию, в зависимости от элемента, на котором была зажата кнопка мыши (что будет означать, что элемент переносят). Ознакомиться детально с установкой изображения перетаскивания можно по ссылке Setting the Drag Feedback Image.
  • -
  • Определить возможные эффекты переноса. Возможны три таких эффекта: copy показывает, что перемещаемые данные копируются из прежнего места расположения в новое, move показывает, что перемещаемые данные полностью переносятся на новое место, и link показывает, что создается некая форма взаимодействия или связи между исходной точкой и точкой назначения. На протяжении операции перемещения, картинка которая следует за курсором мыши может меняться в зависимости от того, может ли элемент быть перемещен в область под курсором. Если перенос разрешен, перемещение может быть произведено. Смотрите Drag Effects для детальной информации.
  • -
  • Определить область назначения. По умолчанию браузер не позволяет перемещать что-либо на HTML элемент. Однако, чтобы сделать элемент активным для перемещения других элементов на него, просто отмените действие по умолчанию. То есть, подпишитесь на события "ondragenter" или "ondragover". Для детальной информации смотрите Specifying Drop Targets.
  • -
  • Обработать завершение переноса. Вы можете получить данные из переносимого элемента и произвести над ними необходимые операции. Для детальной информации, пожалуйста, смотрите Performing a Drop.
  • -
- -

Mozilla и Firefox поддерживают ряд возможностей, которые выходят за рамку стандартной модели спецификации. Они позволяют пользователю перемещать несколько элементов и перемещать нестроковые данные. Для детальной информации смотрите Dragging and Dropping Multiple Items.

- -

Для того, чтобы ознакомиться с общим списком данных поддерживаемых операцией drag and drop смотрите Recommended Drag Types.

- -

Также доступны примеры с лучшей практикой использования операции drag and drop для перемещения данных разных типов:

- - - -

Смотри DataTransfer для ссылки на объект DataTransfer.

- -

События Drag

- -

Ряд событий срабатывают на протяжении всей процедуры drag and drop. Запомните, что только drag-события срабатывают на протяжении операции перемещения; события мыши, такие как mousemove - нет. Также запомните, что события dragstart и dragend не срабатывают при попытке перенести файл из операционной системы в браузер.

- -

Свойство dataTransfer всех событий перемещения содержит данные про все drag и drop операции.

- -
-
dragstart
-
Срабатывает когда элeмент начал перемещаться. В момент срабатывания события dragstart пользователь начинает перетаскивание элемента. Обработчик данного события может быть использован для сохранения информации о перемещаемом объекте, а также для изменения изображения, которое будет ассоциировано с перемещением. Дaнное событие не срабатывает, когда некоторый файл будет переноситься из операционной системы в браузер. Для детальной информации Starting a Drag Operation.
-
dragenter
-
Срабатывает, когда перемещаемый элемент попадает на элемент-назначение. Обработчик этого события показывает, что элемент находится над объектом на который он может быть перенесен. Если же обработчика нет, либо он не совершает никаких действий перемещение по умолчанию запрещено. Это событие также используется для того, чтобы подсветить либо промаркировать объект над которым происходит перемещения в случае, если перемещение на данный элемент разрешено. Для детальной информации смотрите Specifying Drop Targets.
-
dragover
-
Данное событие срабатывает каждые несколько сотен милисекунд, когда перемещаемый элемент оказывается над зоной, принимающей перетаскиваемые элементы. Для детальной информации смотрите Specifying Drop Targets.
-
dragleave
-
Это событие запускается в момент перетаскивания, когда курсор мыши выходит за пределы элемента. Обработчикам следует убрать любую подсветку или иные индикаторы, указывавшие на присутствие курсора, чтобы тем самым обозначить реакцию на прекращение перетаскивания.
-
drag
-
Запускается при перемещении элемента или выделенного текста.
-
drop
-
Событие drop вызывается для элемента, над которым произошло "сбрасывание" перемещаемого элемента. Событие отвечает за извлечение "сброшенных" данных и их вставку. Событие будет срабатывать только при завершении операции перетаскивания, например, событие не сработает, если пользователь отменит перетаскивание нажатием Esc, или не донесет элемент, до цели. Для детальной информации смотрите Performing a Drop.
-
dragend
-
Источник перетаскивания получит событие dragend, когда перетаскивание завершится, было оно удачным или нет. Это событие не вызывается при перетаскивании файла в браузер из ОС.   Для детальной информации смотрите Finishing a Drag.
-
- -

Смотрите также

- - diff --git a/files/ru/web/guide/html/html5/constraint_validation/index.html b/files/ru/web/guide/html/html5/constraint_validation/index.html new file mode 100644 index 0000000000..5a5fccec8c --- /dev/null +++ b/files/ru/web/guide/html/html5/constraint_validation/index.html @@ -0,0 +1,343 @@ +--- +title: Constraint validation +slug: HTML/HTML5/Constraint_validation +tags: + - Селекторы +translation_of: Web/Guide/HTML/HTML5/Constraint_validation +--- +

Создание веб форм всегда было комплексной задачей. В то время как сама по себе разметка формы - задача не сложная, проверка каждого поля на валидность - сложнее, а информирование юзера о проблеме - может стать головной болью. Стандарт HTML5 предоставил новые механизмы для форм: были добавлены новые семантические типы для элемента {{ HTMLElement("input") }} и обязательная валидация, чтобы облегчить работу по проверке содержимого формы на стороне браузера. Проще говоря, обычная проверка может быть выполнена без JavaScript, простой установкой новых аттрибутов; более сложные ограничения могут быть реализованы через HTML5 Constraint Validation API.

+ +
Внимание: HTML5 Constraint validation не отменяет валидацию на стороне сервера. Несмотря на то что на сервер будет отправляться меньше запросов с невалидными данными, такие запросы всё ещё могут быть отправлены менее "сговорчивыми" браузерами (например, браузерами без поддержки HTML5 и без JavaScript) или плохими парнями, пытающимися взломать ваше веб-приложение. Следовательно, как и в случае с HTML4, вам всё ещё нужно проверять ввод на стороне сервера, таким образом, чтобы это было согласовано с валидацией на стороне клиента.
+ +

Внутренние и базовые ограничения

+ +

В HTML5, базовые ограничения описываются двумя способами:

+ +
    +
  • Использованием наиболее семантически подходящего значения для {{ htmlattrxref("type", "input") }} аттрибута элемента {{ HTMLElement("input") }}, например, выбор типа email автоматически создаёт ограничение, которое проверяет, является ли значение e-mail адресом.
  • +
  • Установкой значений для аттрибутов, связанных с валидацией, описывая базовые ограничения без использования JavaScript.
  • +
+ +

Семантические типы input-ов

+ +

Аттрибуты, присущие элементам {{ htmlattrxref("type", "input") }}:

+ + + + + + + + + + + + + + + + + + + + + +
Input typeОпределение ограниченияСвязанное с этим нарушение
<input type="URL">Значение должно быть абсолютным URL, одним из: +
    +
  • валидным URI (как описано в RFC 3986)
  • +
  • валидным IRI, без query сомпонента (как описано в RFC 3987)
  • +
  • валидным IRI, без query сомпонента и без неэкранированных не-ASCII символов (как описано в RFC 3987)
  • +
  • валидным IRI, при условии, что кодировка документа UTF-8 или UTF-16 (как описано в RFC 3987)
  • +
+
Type mismatch constraint violation
 <input type="email">Значение должно следовать ABNF: 1*( atext / "." ) "@" ldh-str 1*( "." ldh-str ) где: +
    +
  • atext (описан в RFC 5322) - US-ASCII символ (A to Z and a-z), цифра (от 0 до 9) или один из следующих: 
    + ! # $ % & ' * + - / = ? ` { } | ~ специальных символов,
  • +
  • ldh-str (описан в RFC 1034) - US-ASCII символы, цифры и "-", сгруппированы по словам и разделённые точкой (.).
  • +
+ +
Внимание: если установлен аттрибут {{ htmlattrxref("multiple", "input") }}, в поле могут быть вписаны несколько e-mail адресов, разделённых запятыми. Если любое из этих условий не выполнено, будет вызвано Type mismatch constraint violation.
+
Type mismatch constraint violation
+ +

Следует учесть, что большинство типов input не имеют "нативных" ограничений, а некоторые из них просто лишены валидации или имеют автоматическую корректировку невалидных значений по умолчанию. 

+ +

Аттрибуты валидации

+ +

Ниже перечислены аттрибуты, которые описывают базовые ограничения:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
АттрибутТипы input с поддержкой аттрибутаВозможные значенияОписание ограниченияСвязанное нарушение
{{ htmlattrxref("pattern", "input") }}text, search, url, tel, email, passwordРегулярное выражение JavaScript (по стандарту ECMAScript 5, флаги global, ignoreCase, и multiline отключены)Значение должно подходить под паттернPattern mismatch constraint violation
{{ htmlattrxref("min", "input") }}range, numberВалидное числоЗначение поля должно быть больше или равно значению аттрибутаUnderflow constraint violation
date, month, weekВалидная дата
datetime, datetime-local, timeВалидная дата и время
{{ htmlattrxref("max", "input") }}range, numberВалидное числоЗначение поля должно быть меньше или равно значению аттрибутаOverflow constraint violation
date, month, weekВалидная дата
datetime, datetime-local, timeВалидная дата и время
{{ htmlattrxref("required", "input") }}text, search, url, tel, email, password, date, datetime, datetime-local, month, week, time, number, checkbox, radio, file; also on the {{ HTMLElement("select") }} and {{ HTMLElement("textarea") }} elementsникакое так как это Boolean аттрибут: его присутствие означает true, а отсутствие - falseЗначение должно быть не пустым (если установлено).Missing constraint violation
{{ htmlattrxref("step", "input") }}dateЦелое число днейПока в аттрибут step не установлен любой литерал, значение может быть min + любое число, крастное шагу.Step mismatch constraint violation
monthЦелое число месяцев
weekЦелое число недель
datetime, datetime-local, timeЦелое число секунд
range, numberЦелое число
{{ htmlattrxref("maxlength", "input") }}text, search, url, tel, email, password; также на элементе {{ HTMLElement("textarea") }}Длина (целое число)Количество символов (знаков) не должно превышать значение аттрибута.Too long constraint violation
+ +

Процесс валидации ограничений

+ +

Constraint validation is done through the Constraint Validation API either on a single form element or at the form level, on the {{ HTMLElement("form") }} element itself. The constraint validation is done in the following ways:

+ +
    +
  • By a call to the checkValidity() method of a form-related DOM interface (HTMLInputElement, HTMLSelectElement, HTMLButtonElement or HTMLTextAreaElement), which evaluates the constraints only on this element, allowing a script to get this information. (This is typically done by the user-agent when determining which of the CSS pseudo-classes, {{ Cssxref(":valid") }} or {{ Cssxref(":invalid") }}, applies.)
  • +
  • By a call to the checkValidity() function on the HTMLFormElement interface, which is called statically validating the constraints.
  • +
  • By submitting the form itself, which is called interactively validating the constraints.
  • +
+ +
Note: + +
    +
  • If the {{ htmlattrxref("novalidate", "form") }} attribute is set on the {{ HTMLElement("form") }} element, interactive validation of the constraints doesn't happen.
  • +
  • Calling the send() method on the HTMLFormElement interface doesn't trigger a constraint validation. In other words, this method sends the form data to the server even if doesn't satisfy the constraints.
  • +
+
+ +

Complex constraints using HTML5 Constraint API

+ +

Using JavaScript and the Constraint API, it is possible to implement more complex constraints, for example, constraints combining several fields, or constraints involving complex calculations.

+ +

Basically, the idea is to trigger JavaScript on some form field event (like onchange) to calculate whether the constraint is violated, and then to use the method field.setCustomValidity() to set the result of the validation: an empty string means the constraint is satisfied, and any other string means there is an error and this string is the error message to display to the user.

+ +

Constraint combining several fields: Postal code validation

+ +

The postal code format varies from one country to another. Not only do most countries allow an optional prefix with the country code (like D- in Germany, F- in France or Switzerland), but some countries have postal codes with only a fixed number of digits; others, like the UK, have more complex structures, allowing letters at some specific positions.

+ +
+

Note: This is not a comprehensive postal code validation library, but rather a demonstration of the key concepts. 

+
+ +

As an example, we will add a script checking the constraint validation for this simple form:

+ +
<form>
+    <label for="ZIP">ZIP : </label>
+    <input type="text" id="ZIP">
+    <label for="Country">Country : </label>
+    <select id="Country">
+      <option value="ch">Switzerland</option>
+      <option value="fr">France</option>
+      <option value="de">Germany</option>
+      <option value="nl">The Netherlands</option>
+    </select>
+    <input type="submit" value="Validate">
+</form>
+ +

This displays the following form: 

+ +

+ +

First, we write a function checking the constraint itself:

+ +
function checkZIP() {
+  // For each country, defines the pattern that the ZIP has to follow
+  var constraints = {
+    ch : [ '^(CH-)?\\d{4}$', "Switzerland ZIPs must have exactly 4 digits: e.g. CH-1950 or 1950" ],
+    fr : [ '^(F-)?\\d{5}$' , "France ZIPs must have exactly 5 digits: e.g. F-75012 or 75012" ],
+    de : [ '^(D-)?\\d{5}$' , "Germany ZIPs must have exactly 5 digits: e.g. D-12345 or 12345" ],
+    nl : [ '^(NL-)?\\d{4}\\s*([A-RT-Z][A-Z]|S[BCE-RT-Z])$',
+                    "Nederland ZIPs must have exactly 4 digits, followed by 2 letters except SA, SD and SS" ]
+  };
+
+  // Read the country id
+  var country = document.getElementById("Country").value;
+
+  // Get the NPA field
+  var ZIPField = document.getElementById("ZIP");
+
+  // Build the constraint checker
+  var constraint = new RegExp(constraints[country][0], "");
+    console.log(constraint);
+
+
+  // Check it!
+  if (constraint.test(ZIPField.value)) {
+    // The ZIP follows the constraint, we use the ConstraintAPI to tell it
+    ZIPField.setCustomValidity("");
+  }
+  else {
+    // The ZIP doesn't follow the constraint, we use the ConstraintAPI to
+    // give a message about the format required for this country
+    ZIPField.setCustomValidity(constraints[country][1]);
+  }
+}
+
+ +

Then we link it to the onchange event for the {{ HTMLElement("select") }} and the oninput event for the {{ HTMLElement("input") }}:

+ +
window.onload = function () {
+    document.getElementById("Country").onchange = checkZIP;
+    document.getElementById("ZIP").oninput = checkZIP;
+}
+ +

You can see a live example of the postal code validation.  

+ +

Limiting the size of a file before its upload

+ +

Another common constraint is to limit the size of a file to be uploaded. Checking this on the client side before the file is transmitted to the server requires combining the Constraint API, and especially the field.setCustomValidity() method, with another JavaScript API, here the HTML5 File API.

+ +

Here is the HTML part:

+ +
<label for="FS">Select a file smaller than 75 kB : </label>
+<input type="file" id="FS">
+ +

This displays:

+ +

+ +

 

+ +

The JavaScript reads the file selected, uses the File.size() method to get its size, compares it to the (hard coded) limit, and calls the Constraint API to inform the browser if there is a violation:

+ +
function checkFileSize() {
+  var FS = document.getElementById("FS");
+  var files = FS.files;
+
+  // If there is (at least) one file selected
+  if (files.length > 0) {
+     if (files[0].size > 75 * 1024) { // Check the constraint
+       FS.setCustomValidity("The selected file must not be larger than 75 kB");
+       return;
+     }
+  }
+  // No custom constraint violation
+  FS.setCustomValidity("");
+}
+ +

 

+ +

Finally we hook the method with the correct event:

+ +
window.onload = function () {
+  document.getElementById("FS").onchange = checkFileSize;
+}
+ +

You can see a live example of the File size constraint validation.

+ +

Visual styling of constraint validation

+ +

Apart from setting constraints, web developers want to control what messages are displayed to the users and how they are styled.

+ +

Controlling the look of elements

+ +

The look of elements can be controlled via CSS pseudo-classes.

+ +

:required and :optional CSS pseudo-classes

+ +

The :required and :optional pseudo-classes allow writing selectors that match form elements that have the {{ htmlattrxref("required") }} attribute, or that don't have it.

+ + +

:-moz-placeholder CSS pseudo-class

+ +

See :-moz-placeholder.

+ +

:valid :invalid CSS pseudo-classes

+ +

The :valid and :invalid pseudo-classes are used to represent <input> elements whose content validates and fails to validate respectively according to the input's type setting. These classes allow the user to style valid or invalid form elements to make it easier to identify elements that are either formatted correctly or incorrectly.

+ +

Default styles

+ +

Controlling the text of constraints violation

+ +

The x-moz-errormessage attribute

+ +

The x-moz-errormessage attribute is a Mozilla extension that allows you to specify the error message to display when a field does not successfully validate.

+ +
+

Note: This extension is non-standard.

+
+ +

Constraint API's element.setCustomValidity()

+ +

The element.setCustomValidity(error) method is used to set a custom error message to be displayed when a form is submitted. The method works by taking a string parameter error. If error is a non-empty string, the method assumes validation was unsuccessful and displays error as an error message. If error is an empty string, the element is considered validated and resets the error message.

+ +

Constraint API's ValidityState object

+ +

The DOM ValidityState interface represents the validity states that an element can be in, with respect to constraint validation. Together, they help explain why an element's value fails to validate, if it's not valid.

+ +

Examples of personalized styling

+ +

HTML4 fallback

+ +

Trivial fallback

+ +

JS fallback

+ +

Conclusion

diff --git a/files/ru/web/guide/html/html5/index.html b/files/ru/web/guide/html/html5/index.html new file mode 100644 index 0000000000..dca2e39993 --- /dev/null +++ b/files/ru/web/guide/html/html5/index.html @@ -0,0 +1,171 @@ +--- +title: HTML5 +slug: HTML/HTML5 +tags: + - HTML5 +translation_of: Web/Guide/HTML/HTML5 +--- +

HTML5 — последняя версия стандарта HTML. Термин имеет два определения:

+ +
    +
  • Новая версия языка HTML, с новыми элементами, атрибутами и новым поведением.
  • +
  • Набор технологий, позволяющий создавать разнообразные сайты и Web-приложения.
  • +
+ +

Эта страница создана в помощь всем разработчикам Open Web и ссылается на множество материалов, сгруппированных по функциям:

+ +
    +
  • Семантика: позволяет точнее описывать, что из себя представляет ваш контент;
  • +
  • Связь: новые способы общения с сервером;
  • +
  • Оффлайн и Хранилище: методы, позволяющие сохранять информацию локально на стороне клиента;
  • +
  • Мультимедиа:создание и взаимодействие с видео и звуком;
  • +
  • 2D/3D Графика и эффекты: способы значительно разнообразить  представление;
  • +
  • Доступ к устройствам: использование разных устройств для ввода и вывода информации;
  • +
  • Стилизация: создание изощренных и совершенных тем.
  • +
+ + + + + + + + +
+

СЕМАНТИКА

+ +
+
Секции и контуры в HTML5
+
Контурные и секционные элементы в HTML5: {{ HTMLElement("section") }}, {{ HTMLElement("article") }}, {{ HTMLElement("nav") }}, {{ HTMLElement("header") }}, {{ HTMLElement("footer") }}, {{ HTMLElement("aside") }} and {{ HTMLElement("hgroup") }}.
+
Использование HTML5 audio и video
+
{{ HTMLElement("audio") }} и {{ HTMLElement("video") }} элементы вставляют и позволяют управлять мультимедиа контентом.
+
Формы в HTML5
+
Взгляд на улучшение форм в HTML5: API валидации, несколько новых атрибутов, новые значения для аттрибута {{ htmlattrxref("type", "input") }} тега {{ HTMLElement("input") }} и новый элемент {{ HTMLElement("output") }}.
+
Новые семантические элементы
+
Кроме секций, медиа и форм, множество новых тегов, такие как {{ HTMLElement("mark") }}, {{ HTMLElement("figure") }}, {{ HTMLElement("figcaption") }}, {{ HTMLElement("data") }}, {{ HTMLElement("time") }}, {{ HTMLElement("output") }}, {{ HTMLElement("progress") }} и {{ HTMLElement("meter") }}, увеличено количество валидных HTML5 элементов.
+
Улучшение {{HTMLElement("iframe")}}
+
Использование атрубутов {{htmlattrxref("sandbox", "iframe")}}, {{htmlattrxref("seamless", "iframe")}}, and {{htmlattrxref("srcdoc", "iframe") }}, разработчики могут задать нужный уровень безопасности и осуществивить рендеринг тега {{HTMLElement("iframe")}}.
+
MathML
+
Позволяет вставлять математические формулы.
+
Введение в HTML5
+
Эта статья знакомит вас с тем, как указать на то, что вы используете HTML5 в вашем веб-дизайне или веб-приложении.
+
HTML5-совместимый парсер
+
Анализатор, который превращает байты HTML документа в DOM, был расширен и точно определяет поведение, чтобы даже в случае неверного HTML, исход был предсказуемым и одинаков во всех HTML5-совместимых браузерах.
+
+
+ +

СВЯЗЬ

+ +
+
Web Sockets
+
Позволяет создать постоянное соединение между страницей и сервером и обмениваться данными через него.
+
Server-sent события
+
Позволяет серверу отправлять события клиенту, а не по классической парадигме, где сервер может передавать данные только в ответ на запрос клиента.
+
WebRTC
+
Эта технология, где RTC создает возможость общения в реальном времени, позволяет подключаться к другим людям и контролировать видеоконференции непосредственно в браузере, без необходимости плагинов и внешний приложений.
+
+ +

ОФФЛАЙН И ХРАНИЛИЩЕ

+ +
+
Оффлайн ресурсы: кеш приложения
+
Firefox полностью поддерживает спецификацию HTML5 по оффлайн ресурсам. Другие браузеры также имеют поддержку спецификации на должном уровне
+
Online and offline events
+
Firefox 3 поддерживает WHATWG online и offline события, которые позволяют приложениям и расширениям обнаружить есть ли активное подключение к Интернет, а также определить, когда соединение портится или улучшается.
+
WHATWG сессионное или постоянное хранилище (aka DOM Storage)
+
Постоянное или сессионое храилище позволяет веб-приложениям хранить структурированны данные на стороне клиента.
+
IndexedDB
+
Веб-стандарт для хранения значительных количеств структурированных данных в браузере и для быстрого их поиска, используя индексы.
+
Using files from web applications
+
Поддержка HTML5 File API была добавлена в Gecko, сделав возможным веб-приложениям иметь доступ к файлам, выбираемых пользователем. Это включает поддержку множества файлов, используя {{ HTMLElement("input") }} с типом file, имеющих атрибут multiple. Ещё это FileReader.
+
+ +

МУЛЬТИМЕДИА

+ +
+
Использование HTML5 audio и video
+
{{ HTMLElement("audio") }} и {{ HTMLElement("video") }} элементы вставляют и позволяют управлять мультимедиа контентом.
+
WebRTC
+
Эта технология, где RTC создает возможость общения в реальном времени, позволяет подключаться к другим людям и контролировать видеоконференции непосредственно в браузере, без необходимости плагинов и внешний приложений.
+
Использование Camera API
+
Позволяет контролировать, манипулировать и хранить изображения с камеры устройства.
+
+ +

ГРАФИКА И ЭФФЕКТЫ

+ +
+
Canvas Tutorial
+
Узнайте о элементе {{ HTMLElement("canvas") }} и узнайте, как рисовать графику и другие элементы в Firefox.
+
HTML5 text API для <canvas>
+
HTML5 text API сейчас поддерживается в {{ HTMLElement("canvas") }}.
+
WebGL
+
WebGL приносит 3D в веб, соответстсвует OpenGL ES 2.0, может использоваться в HTML5 через {{ HTMLElement("canvas") }}.
+
SVG
+
Основанный на XML формат векторных изображений, который может быть непосредственно вставлен в HTML.
+
+ +
+
+
+
+

производительность и интеграция

+ +
+
Web Workers
+
Позволяет делегировать выполнение JavaScript в фоновые потоки, это позволит предотвратить замедление интерактивных событий.
+
XMLHttpRequest Level 2
+
Позволяет извлечь асинхронно некоторые части страницы, что позволяет отобразить динамический контент, изменяющейся время от времени или от действий пользователя. Это технология, лежащая в основе AJAX.
+
JIT-компилирование движков JavaScript
+
Новое поколение движков JavaScript гораздо более мощных, приводящих к большей производительности.
+
History API
+
Позволяет управлять историей браузера. Это особенно полезно страниц, интерактивно загружающих новую информацию.
+
contentEditable атрибут: трансформируйте свой сайт в википедию!
+
HTML5 стандартизировал атрибут contentEditable. Узнайте больше об этой фиче.
+
Drag and drop
+
HTML5 drag and drop API позволяет перетаскивать элементы по сайту или на него. Также простейшее API для использования расширениями или иными приложениями.
+
Управление фокусом в HTML
+
Поддержка новый атрибутов HTML5 activeElement and hasFocus.
+
Обработчики протоколов для Web
+
Вы можете зарегистровать веб-приложения, как обработчики протоколов, используя метод navigator.registerProtocolHandler().
+
requestAnimationFrame
+
Контролирует анимации для обеспечения оптимальной производительности.
+
Fullscreen API
+
Позволяет использовать весь экран для веб-приложения, без отображения UI браузера.
+
Pointer Lock API
+
Позволяет блокировать курсор, так чтобы игры и подобные приложения не теряли фокус, когда указатель достигает предела окна.
+
Online and offline events
+
Для того, чтобы построить хорошую оффлайн-совместимые веб-приложения, вы должны знать, когда ваше приложение без сети. Также, вы должны знать, когда ваше приложение снова вернется в сеть.
+
+ +

доступ к устройствам

+ +
+
Использование Camera API
+
Позволяет контролировать, манипулировать и хранить изображения с камеры устройства.
+
Touch события
+
Обрабатывает события, создаваемые нажатиями пользователя по тач скрину.
+
Геолокация
+
Позволяет браузерам получать местоположение пользователя.
+
Определение ориентации устройства
+
Позволяет среагировать, когда устройство, на котором работает браузер, меняет ориентацию. Это может быть использовано в качестве устройства ввода (например, чтобы сделать игры, которые реагируют на положение устройства) или адаптировать компоновку страницы с ориентацией экрана (вертикальная или горизонтальная).
+
Pointer Lock API
+
Позволяет блокировать курсор, так чтобы игры и подобные приложения не теряли фокус, когда указатель достигает предела окна.
+
+ +

стилизация

+ +

CSS был расширен, чтобы дать возможность стилизировать элементы наиболее оптимальным способом. Его часто называют CSS3, хотя CSS больше не является монолитной спецификацией и различные модули, не все на уровне 3: некоторые на уровне 1, а некоторые на уровне 4, с промежуточными уровнями.

+ +
+
Новые способы стилизирования фона
+
Новая возможность задать тень элемента, используя {{ cssxref("box-shadow") }} или установление множественных фонов.
+
Лучшие границы
+
Не только изображения можно использовать для стилизирования границы, используя {{ cssxref("border-image") }} или его длинные формы записи, а скруглить уголки можно свойством {{ cssxref("border-radius") }}.
+
Анимируйте свой стиль
+
Используйте CSS Переходы, чтобы анимировать изменение состояния элемента или CSS Анимации для анимации частей страницы без запуска событий, вы теперь можете контролировать мобильные элементы на вашей странице.
+
Улучшение типографии
+
Авторы могут лучше контролировать типографию. Например, они могут контролировать {{ cssxref("text-overflow") }} и перенос слов, а также тень текста и его декорированиe. Могут загрузить и применить другой шрифт правилом {{ cssxref("@font-face") }}.
+
Новые презентационные макеты
+
Для того, чтобы улучшить гибкость дизайна, добавили: CSS мульти-колоночный макет и CSS отзывчивый блочный макет.
+
+
diff --git a/files/ru/web/guide/html/html5/introduction_to_html5/index.html b/files/ru/web/guide/html/html5/introduction_to_html5/index.html new file mode 100644 index 0000000000..28b8138f0e --- /dev/null +++ b/files/ru/web/guide/html/html5/introduction_to_html5/index.html @@ -0,0 +1,26 @@ +--- +title: Введение в HTML5 +slug: HTML/HTML5/Введение_в_HTML5 +tags: + - DOCTYPE + - HTML5 + - HTML5 парсер +translation_of: Web/Guide/HTML/HTML5/Introduction_to_HTML5 +--- +

HTML5 - пятая редакция и самая новая версия стандарта HTML. Она предлагает новые возможности, которые предоставляют не только богатую поддержку медиа, но и также расширяет возможности для создания веб-приложений, которые могут взаимодействовать с пользователем, его локальными данными, и серверами проще и эффективнее, чем это было раньше.

+

Because HTML5 is still being developed, changes to the specifications are inevitable. Therefore, not all of its features are supported by all browsers yet. However, Gecko, and by extension, Firefox, has very good initial support for HTML5, and work continues toward supporting more of its features. Gecko began supporting some HTML5 features in version 1.8.1. You can find a list of all of the HTML5 features that Gecko currently supports on the main HTML5 page. For detailed information about multiple browsers' support of HTML5 features, refer to the CanIUse website.

+

Declaring that the document contains HTML5 mark-up with the HTML5 doctype

+

The doctype for HTML5 is very simple. To indicate that your HTML content uses HTML5, simply use:

+
<!DOCTYPE html>
+
+

Doing so will cause even browsers that don't presently support HTML5 to enter into standards mode, which means that they'll interpret the long-established parts of HTML in an HTML5-compliant way while ignoring the new features of HTML5 they don't support.

+

This is much simpler than the former doctypes, and shorter, making it easier to remember and reducing the amount of bytes that must be downloaded.

+

Декларация кодировки с помощью <meta charset>

+

The first thing done on a page is usually indicating the character set that is used. In previous versions of HTML, it was done using a very complex {{HTMLElement("meta")}} element. Now, it is very simple:

+
<meta charset="UTF-8">
+

Place this right after your {{HTMLElement("head") }}, as some browsers restart the parsing of an HTML document if the declared charset is different from what they had anticipated. Also, if you are not currently using UTF-8, it's recommended that you switch to it in your Web pages, as it simplifies character handling in documents using different scripts.

+

Note that HTML5 restricts the valid charset to that compatible with ASCII and using at least 8 bits. This was done to tighten security and prevent some types of attacks.

+

Использование нового HTML5 парсера

+

The parsing rule of HTML5, which analyzes the meaning of mark-up, has been more precisely defined in HTML5. Until the introduction of HTML5, only the meaning of valid mark-up was defined, meaning that as soon as one small error was made in the mark-up (most Web sites have at least one), the behavior was undefined. Essentially, it meant that all browsers behaved differently, which is no longer the case. Now, faced with errors in the mark-up, all compliant browsers must behave exactly in the same way.

+

This requirement helps Web developers quite a bit. While it is true that all modern browsers now use these HTML5 parsing rules, non-HTML5-compliant browsers are still used by some. Keep in mind that it's still highly recommended that one write valid mark-up, as such code is easier to read and maintain, and it greatly decreases the prominence of incompatibilities that exists in various older browsers.

+

Не волнуйтесь - вам не придется ничего менять на вашем веб-сайте - разработчики веб-браузерах сделали все для вас!

diff --git a/files/ru/web/guide/html/sections_and_outlines_of_an_html5_document/index.html b/files/ru/web/guide/html/sections_and_outlines_of_an_html5_document/index.html deleted file mode 100644 index a6236d9c24..0000000000 --- a/files/ru/web/guide/html/sections_and_outlines_of_an_html5_document/index.html +++ /dev/null @@ -1,375 +0,0 @@ ---- -title: Использование разделов и создание структуры HTML документа -slug: Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document -tags: - - HTML5 - - Веб - - Для опытных разработчиков - - Обзор - - Пример - - Разделы - - Руководство - - Структура -translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines ---- -
-

Важно: В настоящее время нет известных реализаций алгоритма построения структуры документа в графических браузерах или пользовательских приложениях, использующих реабилитационные технологии, хотя такой алгоритм внедрен в другие приложения, например, в средствах проверки соответствия спецификации. Поэтому алгоритм построения структуры нельзя использовать для передачи структуры документа пользователям. Авторы рекомендуют использовать для этой цели степень важности заголовков (h1-h6).

-
- -

Спецификация HTML5 предлагает разработчикам несколько новых элементов, позволяющих описывать структуру веб-документа с помощью стандартной семантики. В настоящей статье описываются эти элементы и способы их использования для создания требуемой структуры любого документа.

- -

Структура документа в HTML 4

- -

Структура документа, т. е. семантическая структура контента, заключенного в теги  <body> и </body>, является основой для представления страницы пользователю. HTML4 использует для описания структуры страницы разделы и подразделы. Раздел определяется элементом ({{HTMLElement("div")}}) с включенными в него элементами заголовка ({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}} или {{HTMLElement("h6")}}), содержащими его название. Структура документа определяется отношениями между этими элементами.

- -

Так, следующая разметка:

- -
-
<div class="section" id="forest-elephants" >
-  <h1>Лесные слоны</h1>
-  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <div class="subsection" id="forest-habitat" >
-    <h2>Среда обитания</h2>
-    <p>Лесные слоны живут не на деревьях, а под ними.
-     ...продолжение данного подраздела...
-  </div>
-</div>
-
-
- -

обеспечивает следующую структуру:

- -
1. Лесные слоны
-   1.1 Среда обитания
-
- -

Для задания нового раздела не обязательно использовать элементы {{HTMLElement("div")}}. Для этого достаточно наличия элемента заголовка. Поэтому, разметка

- -
<h1>Лесные слоны</h1>
- <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <h2>Среда обитания</h2>
-  <p>Лесные слоны живут не на деревьях, а под ними.
-    ...продолжение данного подраздела...
-  <h2>Рацион</h2>
-<h1>Монгольская песчанка</h1>
-
- -

обеспечивает следующую структуру:

- -
1. Лесные слоны
-   1.1 Среда обитания
-   1.2 Рацион
-2. Монгольская песчанка
-
- -

Какие проблемы решает HTML5

- -

Определение структуры документа и неявный алгоритм создания структуры в HTML 4 не отличаются четкостью, что порождает множество проблем:

- -
    -
  1. Использование {{HTMLElement("div")}} для задания семантических разделов, без задания специальных значений для атрибутов class не позволяет автоматизировать алгоритм создания структуры («Является ли данный {{HTMLElement("div")}} частью структуры страницы, определяющим раздел или подраздел, или он используется исключительно для управления стилем?»). Другими словами, спецификация HTML4 не дает точного определения разделу и четких правил его определения. Автоматическое создание структуры имеет большое значение, особенно в случае с реабилитационными технологиями, представляющими информацию пользователю в соответствии со структурой документа. HTML5 позволяет больше не использовать элементы {{HTMLElement("div")}} в алгоритме построения структуры благодаря добавлению нового элемента {{HTMLElement("section")}}.
  2. -
  3. Объединить несколько документов в один непросто: включение подчиненного документа в основной документ требует изменения уровня элементов заголовков для сохранения правильной структуры. В HTML5 эта проблема решена благодаря новым элементам задания разделов ({{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("nav")}} и {{HTMLElement("aside")}}), которые всегда являются подразделами ближайшего родительского раздела, независимо от того, какие разделы создаются внутренними заголовками.
  4. -
  5. В HTML4 каждый раздел является частью структуры документа. Однако часто документы отличаются сложной, нелинейной структурой. Документ может включать специальные разделы, информация в которых не является частью основного контента, хотя и связана с ним, например, рекламный блок или поясняющая заметка. HTML5 добавляет элемент {{HTMLElement("aside")}}, позволяющий исключить такие разделы из основной структуры.
  6. -
  7. Опять же, поскольку в HTML4 каждый раздел является частью структуры документа, как быть с разделами, содержащими информацию, касающуюся не конкретного документа, а всего сайта, например, логотипы, оглавления или информация об авторских правах и правовые положения. В HTML5 для этих целей добавлено три новых элемента: {{HTMLElement("nav")}} для наборов ссылок, например, оглавления, {{HTMLElement("footer")}} и {{HTMLElement("header")}} для информации, касающейся всего сайта. Обратите внимание, что {{HTMLElement("header")}} и {{HTMLElement("footer")}} не создают разделы как {{HTMLElement("section")}}, а, скорее, обеспечивают семантическую разметку частей раздела.
  8. -
- -

В общем, HTML5 обеспечивает большую точность при задании разделов и оглавлений, позволяя строить более предсказуемую структуру документа, что дает браузерам возможность более качественно обслуживать пользователей.

- -

Алгоритм создания структуры HTML5

- -

Задание разделов в HTML5

- -

Весь контент, находящийся внутри {{HTMLElement("body")}}, является частью раздела. Разделы в HTML5 могут быть вложенными. Помимо основного раздела, определяемого элементом {{HTMLElement("body")}}, границы разделов определяются явным или неявным образом. Явным образом заданные разделы – это контент внутри тегов {{HTMLElement("body")}},  {{HTMLElement("section")}},  {{HTMLElement("article")}},  {{HTMLElement("aside")}} и {{HTMLElement("nav")}}. 

- -
Note: Каждый раздел может иметь собственную иерархию заголовков. Следовательно, даже вложенный раздел может иметь {{HTMLElement("h1")}}. См. «Задание заголовков в HTML5».
- -

Например:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <section>
-    <h1>Введение</h1>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
-  </section>
-  <section>
-    <h1>Среда обитания</h1>
-    <p>Лесные слоны живут не на деревьях, а под ними.</p>
-  </section>
-  <aside>
-    <p>рекламный блок</p>
-  </aside>
-</section>
-<footer>
-  <p>(c) 2010 The Example company</p>
-</footer>
- -

Данный фрагмент HTML задает раздел верхнего уровня:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <section>
-    <h1>Введение</h1>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
-  </section>
-  <section>
-    <h1>Среда обитания</h1>
-    <p>Лесные слоны живут не на деревьях, а под ними.</p>
-  </section>
-  <aside>
-    <p>рекламный блок</p>
-  </aside>
-</section>
-<footer>
-  <p>(c) 2010 The Example company</p>
-</footer>
- -

Данный раздел имеет три подраздела:

- -
<section>
-  <h1>Лесные слоны</h1>
-
-  <section>
-    <h1>Введение</h1>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
-  </section>
-
-  <section>
-    <h1>Среда обитания</h1>
-    <p>Лесные слоны живут не на деревьях, а под ними.</p>
-  </section>
-
-  <aside>
-    <p>рекламный блок</p>
-  </aside>
-</section>
-
-<footer>
-  <p>(c) 2010 The Example company</p>
-</footer>
- -

В результате получаем следующую структуру:

- -
1. Лесные слоны
-   1.1 Введение
-   1.2 Среда обитания
-
- -

Задание заголовков в HTML5

- -

Хотя структура определяется элементами задания структуры, она будет практически бесполезна без заголовка. Основное правило очень простой: первый элемент заголовка (это может быть {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}}) задает заголовок текущего раздела.

- -

Элемент заголовка имеет определенную степень важности, определяемую цифрой в его названии, таким образом, {{HTMLElement("h1")}} имеет максимальную степень важности, а {{HTMLElement("h6")}} минимальную. Соотношение степеней важности имеет смысл только внутри раздела; структура документа определяется структурами разделов, а не степенью важности заголовков разделов. Например, данный код:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <section>
-    <h2>Среда обитания</h2>
-    <p>Лесные слоны живут не на деревьях, а под ними.
-        ...продолжение данного подраздела...
-  </section>
-</section>
-<section>
-  <h3>Монгольская песчанка</h3>
-  <p>В данном разделе мы расскажем о монгольской песчанке.
-     ...продолжение данного раздела...
-</section>
- -

приводит к следующей структуре:

- -
1. Лесные слоны
-   1.1 Среда обитания
-2. Монгольская песчанка
- -

Обратите внимание, что степень важности элемента заголовка (в данном примере {{HTMLElement("h1")}} для первого раздела верхнего уровня, {{HTMLElement("h2")}} для подраздела {{HTMLElement("h3")}} для второго раздела верхнего уровня) роли не играет. (В качестве заголовка явно заданного раздела может использоваться заголовок с любой степенью важности, хотя такая практика и не рекомендуется.)

- -

Неявное задание разделов

- -

Поскольку элементы задания разделов HTML5 Sectioning Elements не являются обязательными для задания структуры, можно задавать разделы и не используя их, чтобы обеспечить совместимость с веб-сайтами, созданными на HTML4. Это называется неявным заданием разделов.

- -

Элементы заголовков ({{HTMLElement("h1")}} — {{HTMLElement("h6")}}) задают новый, неявный раздел, когда не являются первым заголовком своего родительского, явно заданного раздела. То, как этот неявно заданный раздел располагается в структуре документа, определяется отношением важности его заголовка в важности предыдущего заголовка в родительском разделе. Если его степень важности ниже, чем у предыдущего заголовка, он открывает неявно заданный подраздел раздела. Следующий код:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <h3 class="implicit subsection">Среда обитания</h3>
-  <p>Лесные слоны живут не на деревьях, а под ними.
-    ...продолжение данного подраздела...
-</section>
- -

приводит к следующей структуре:

- -
1. Лесные слоны
-   1.1 Среда обитания (неявно задано элементом h3)
-
- -

Если степень важности такого заголовка совпадает со степенью важности предыдущего заголовка, он закрывает предыдущий раздел (который мог быть задан неявно!) и открывает новый неявно заданный раздел на том же уровне: 

- -
<section>
-  <h1>Лесные слоны</h1>
-  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-  <h1 class="implicit section">Монгольская песчанка</h1>
-  <p>Монгольская песчанка – это небольшое симпатичное млекопитающее.
-    ...продолжение данного раздела...
-</section>
- -

приводит к следующей структуре:

- -
1. Лесные слоны
-2. Монгольская песчанка (неявно задано элементом h1, который одновременно закрывает предыдущий раздел)
-
- -

Если степень важности такого заголовка выше, чем у предыдущего заголовка, он закрывает предыдущий раздел и открывает новый неявно заданный раздел на более высоком уровне:

- -
<body>
-  <h1>Млекопитающие</h1>
-  <h2>Киты</h2>
-  <p>В данном разделе мы поговорим о китах.
-    ...продолжение данного раздела...
-  <section>
-    <h3>Лесные слоны</h3>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
-    ...продолжение данного раздела...
-    <h3>Монгольская песчанка</h3>
-      <p>Песчанки распространились далеко за пределы Монголии.
-         ...продолжение данного подраздела...
-    <h2>Рептилии</h2>
-      <p>Рептилии – это холоднокровные животные.
-          ...продолжение данного раздела...
-  </section>
-</body>
- -

приводит к следующей структуре:

- -
1. Млекопитающие
-   1.1 Киты (неявно задается элементом h2)
-   1.2 Лесные слоны (явным образом задается элементом раздела)
-   1.3 Монгольская песчанка (неявно задается элементом h3, который одновременно закрывает предыдущий раздел)
-2. Рептилии (неявно задается элементом h2, который одновременно закрывает предыдущий раздел)
-
- -

Эта не та структура, которую можно было бы ожидать, бегло просмотрев теги заголовков. Чтобы разметка стала понятна человеку, а также чтобы степень важности заголовка соответствовала уровню вложенности раздела, рекомендуется использовать наглядные теги для открытия и закрытия разделов. Однако спецификация HTML5 этого не требует. Поэтому, если браузеры отображают структуру документа не так, как ожидалось, проверьте, нет ли в документе разделов, не явно закрытых элементами заголовков.

- -

Исключение из общего правила соответствия степени важности тега уровню вложенности раздела делается для разделов, которые могут использоваться в нескольких документах. Например, раздел может храниться в системе управления контентом и добавляться в документы при их генерировании. В этом случае рекомендуется начинать с {{HTMLElement("h1")}} в качестве главного заголовка многократно используемого раздела. Уровень вложенности многократно используемого раздела будет определяться иерархией разделов документа, в который он добавляется. Теги для явного задания разделов по-прежнему останутся полезными и в этом конкретном случае.

- -

Корни задания разделов

- -

 Корень задания разделов – это элемент HTML, который может иметь собственную структуру, однако входящие в нее разделы и заголовки, не входят в структуру его родительского элемента. Помимо {{HTMLElement("body")}}, который является логическим корнем задания разделов документа, такими элементами часто являются элементы, добавляющие внешний контент на страницу: {{HTMLElement("blockquote")}}, {{HTMLElement("details")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}} и {{HTMLElement("td")}}.

- -

Например:

- -
<section>
-  <h1>Лесные слоны</h1>
-  <section>
-    <h2>Введение</h2>
-    <p>В данном разделе мы поговорим о малоизвестных лесных слонах</p>
-  </section>
-  <section>
-    <h2>Среда обитания</h2>
-    <p>Лесные слоны живут не на деревьях, а под ними. Давайте рассмотрим, что говорят ученые в «<cite>Лесной слон на Борнео</cite>»:</p>
-    <blockquote>
-       <h1>Борнео</h1>
-       <p>Лесной слон живет на Борнео...</p>
-    </blockquote>
-  </section>
-</section>
-
- -

Данный пример приводит к следующей структуре:

- -
1. Лесные слоны
-   1.1 Введение
-   1.2 Среда обитания
- -

Данная структура не включает внутреннюю структуру элемента {{HTMLElement("blockquote")}}, который, будучи внешней цитатой, является корнем задания разделов и изолирует свою внутреннюю структуру.

- -

Разделы, не входящие в структуру

- -

 HTML5 вводит два новых элемента, позволяющих задавать разделы, не входящие в основную структуру веб-документа:

- -
    -
  1. Элемент вспомогательного раздела {{HTMLElement("aside")}} задает раздел, который, хотя и связан с основным элементом, не принадлежит к основной структуре, например, поясняющая заметка или реклама. Он имеет собственную структуру, однако не входит в основную структуру страницы.
  2. -
  3. Элемент навигационного раздела {{HTMLElement("nav")}} задает раздел, содержащий навигационные ссылки. Таких элементов в документе может быть несколько, например, один со внутренними ссылками на страницу, например, оглавление, а другой – с ссылками для навигации по сайту. Такие ссылки не являются частью основной структуры документа и как правило пропускаются экранными дикторами.
  4. -
- -

Шапки и подвалы

- -

HTML5 также добавляет два новых элемента, которые могут использоваться для разметки верхнего и нижнего колонтитулов страниц:

- -
    -
  1. Элемент шапки {{HTMLElement("header")}} задает шапку страницы (как правило, логотип и название сайта, а также горизонтальное меню, если имеется) или раздела (которая может включать заголовок раздела, имя автора и т.д.).{{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}}, и {{HTMLElement("nav")}} могут иметь собственный {{HTMLElement("header")}}. Несмотря на название, этот элемент не обязательно располагается в начале страницы или раздела.
  2. -
  3. Элемент подвала ({{HTMLElement("footer")}}) задает нижний колонтитул страницы (как правило включающий уведомления об авторских правах и другую правовую информацию, а иногда также содержащий какие-либо ссылки) или раздела (может включать дату публикации, информацию о лицензии и т.п. {{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}} и {{HTMLElement("nav")}} могут иметь собственный {{HTMLElement("footer")}}. Несмотря на название, этот элемент не обязательно располагается в конце страницы или раздела.
  4. -
- -

Эти элементы не создают новые разделы в структуре, а скорее используются для разметки контента внутри разделов страницы.

- -

Адреса в элементах задания разделов

- -

Автор документа часто хочет опубликовать свою контактную информацию, например, имя и адрес. HTML4 позволял сделать это с помощью элемента {{HTMLElement("address")}}, расширенного в HTML5.

- -

Документ может включать несколько разделов, принадлежащих разным авторам. Если раздел создается не автором основной страницы, для задания используется элемент {{HTMLElement("article")}}. В результате элемент {{HTMLElement("address")}} теперь связан с ближайшим родительским {{HTMLElement("body")}} или {{HTMLElement("article")}}.

- -

Использование элементов HTML5 в браузерах, не поддерживающих HTML5

- -

Элементы разделов и заголовков должны работать в большинстве браузеров, не поддерживающих HTML5. Хотя они и не поддерживаются, они не требуют специального интерфейса DOM, им требуется лишь особый стиль CSS, поскольку к неизвестным элементам по умолчанию применяется стиль display:inline:

- -
section, article, aside, footer, header, nav, hgroup {
-  display:block;
-}
-
- -

Конечно, веб-разработчик может применить к ним любой другой стиль, однако следует помнить в браузерах, не поддерживающих HTML5, по умолчанию используется не тот стиль, который требуется для таких элементов. Также обратите внимание на отсутствие в перечне элемента {{HTMLElement("time")}}, поскольку по умолчанию к нему применяется одинаковый стиль как в браузерах, не поддерживающих HTML5, так и в браузерах, совместимых с HTML5.

- -

Данный способ не универсален, поскольку некоторые браузеры не позволяют применять стили к неподдерживаемым элементам. Например, Internet Explorer (версии 8 и более ранней), для которого требуется специальный скрипт:

- -
<!--[if lt IE 9]>
-  <script>
-    document.createElement("header" );
-    document.createElement("footer" );
-    document.createElement("section");
-    document.createElement("aside"  );
-    document.createElement("nav"    );
-    document.createElement("article");
-    document.createElement("hgroup" );
-    document.createElement("time"   );
-  </script>
-<![endif]-->
- -

Этот скрипт запускается в Internet Explorer (8 и более ранней версии), однако требует включенной поддержки скриптов для правильного отображения элементов задания разделов и заголовок HTML5. Если поддержа скриптов выключена, это может стать проблемой, поскольку данные элементы, скорее всего, определяют структуру всей страницы. Поэтому необходимо добавить элемент {{HTMLElement("noscript")}}:

- -
<noscript>
-   <strong>Внимание!</strong>
-   Поскольку ваш браузер не поддерживает HTML5, некоторые элементы воспроизводятся с помощью JScript.
-   Однако в вашем браузере скрипты отключены, пожалуйста, включите их, чтобы браузер смог отобразить данную страницу.
-</noscript>
- -

This leads to the following code to allow the support of the HTML5 sections and headings elements in non-HTML5 browsers, even for Internet Explorer (8 and older), with a proper fallback for the case where this latter browser is configured not to use scripting:

- -
<!--[if lt IE 9]>
-  <script>
-    document.createElement("header" );
-    document.createElement("footer" );
-    document.createElement("section");
-    document.createElement("aside"  );
-    document.createElement("nav"    );
-    document.createElement("article");
-    document.createElement("hgroup" );
-    document.createElement("time"   );
-  </script>
-  <noscript>
-     <strong>Внимание!</strong>
-     Поскольку ваш браузер не поддерживает HTML5, некоторые элементы воспроизводятся с помощью JScript.
-     Однако в вашем браузере скрипты отключены, пожалуйста, включите их, чтобы браузер смог отобразить данную страницу.
-  </noscript>
-<![endif]-->
- -

Заключение

- -

Новые семантические элементы, добавленные в HTML5, обеспечивают стандартизацию описания структуры веб-документа. Они облегчают жизнь пользователям с ограниченными возможностями, просты в использовании, могут без особых проблем поддерживаться в старых браузерах и поэтому настоятельно рекомендуются к применению.

- -
{{HTML5ArticleTOC()}}
diff --git a/files/ru/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html b/files/ru/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html deleted file mode 100644 index f34fe049f5..0000000000 --- a/files/ru/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: Tips for authoring fast-loading HTML pages -slug: Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages -translation_of: Learn/HTML/Howto/Author_fast-loading_HTML_pages ---- -

Эти советы основаны на общих знаниях и экспериментах.

- -

Оптимизированная веб-страница не только обеспечивает более отзывчивый сайт для ваших посетителей, но также снижает нагрузку на ваши веб-серверы и интернет-соединения. Это может иметь решающее значение для сайтов с большим объемом или сайтов, которые имеют всплеск трафика из-за необычных обстоятельств, таких как последние новости

- -

Оптимизация производительности загрузки страницы нужна не только для контента, который будет просматриваться узкополосным модемом или посетителями мобильных устройств. Это так же важно для широкополосного контента и может привести к значительным улучшениям даже для ваших посетителей с самыми быстрыми подключениями.

- -

Советы

- -

Уменьшайте вес страницы

- -

Веб-страницы - безусловно, самый важный фактор в производительности загрузки страницы.

- -

Уменьшение веса страницы за счет устранения ненужных пробелов и комментариев, широко известна как минимизация, и перемещая встроенный скрипт и CSS во внешние файлы, можно улучшить производительность загрузки с минимальными потребностями в других изменениях в структуре страницы.

- -

Такие инструменты, как HTML Tidy , могут автоматически убирать начальные пробелы и лишние пустые строки из допустимого источника HTML. Другие инструменты могут «сжимать» JavaScript, переформатируя источник или запутывая источник и заменяя длинные идентификаторы на более короткие версии

- -

Минимизируйте количество файлов

- -

Уменьшение количества файлов, на которые есть ссылки на веб-странице, уменьшает количество HTTP-соединений, необходимых для загрузки страницы, тем самым сокращая время отправки этих запросов и получения их ответов.

- -

В зависимости от настроек кэша браузера он может отправить запрос с заголовком If-Modified-Since для каждого ссылочного файла, спрашивая, был ли файл изменен с момента последней загрузки. Слишком много времени, затрачиваемое на запрос времени последнего изменения указанных файлов, может задержать первоначальное отображение веб-страницы, так как браузер должен проверить время изменения каждого из этих файлов перед отображением страницы.

- -

Если вы часто используете фоновые изображения в своем CSS, вы можете уменьшить количество запросов на поиск HTTP, объединив изображения в одно, называемое спрайтом изображения. Затем вы просто применяете одно и то же изображение каждый раз, когда вам это нужно для фона, и соответственно корректируете координаты x / y. Этот метод лучше всего работает с элементами, которые будут иметь ограниченные размеры, и не будет работать для каждого использования фонового изображения. Тем не менее, меньшее количество HTTP-запросов и кэширование одного изображения может помочь сократить время загрузки страницы.

- -

Используйте сеть доставки (и дистрибуции) содержимого (Content Delivery Network (CDN))

- -

Для целей этой статьи CDN - это средство уменьшения физического расстояния между вашим сервером и вашим посетителем. По мере увеличения расстояния между вашим сервером и посетителем время загрузки будет увеличиваться. Предположим, ваш сервер веб-сайта находится в Соединенных Штатах и имеет посетителя из Индии; время загрузки страницы будет намного выше для индийского посетителя по сравнению с посетителем из США.

- -

CDN - это географически распределенная сеть серверов, которые работают вместе, чтобы сократить расстояние между пользователем и вашим сайтом. CDN хранят кэшированные версии вашего веб-сайта и предоставляют их посетителям через ближайший к пользователю сетевой узел, тем самым снижая задержку

- -

Дальнейшее чтение:

- - - -

Сократите поиск доменов

- -

Поскольку каждый отдельный домен требует времени для поиска DNS, время загрузки страницы будет расти вместе с количеством отдельных доменов, отображаемых в ссылках CSS, а также в JavaScript и изображениях.

- -

Это не всегда может быть практичным; однако вы всегда должны позаботиться об использовании только минимально необходимого количества разных доменов на своих страницах.

- -

Кэшируйте повторно использованный контент

- -

Убедитесь, что любой контент, который может быть кэширован, кэширован и имеет подходящее время истечения.

- -

В частности, обратите внимание на  заголовок Last-Modified. Это позволяет эффективно кэшировать страницы; с помощью этого заголовка агенту пользователя передается информация о файле, который он хочет загрузить, например, когда он был последний раз изменен. Большинство веб-серверов автоматически добавляют заголовок Last-Modified к статическим страницам (напр. .html, .css), на основе даты последнего изменения, хранящейся в файловой системе. С динамическими страницами (напр. .php, .aspx), это, конечно, не может быть сделано, и заголовок не отправляется.

- -

Так, в частности, для страниц, которые генерируются динамически, небольшое исследование по этой теме полезно. Это может быть несколько сложным, но это сэкономит много запросов страниц на страницах, которые обычно не могут быть кэшированы.

- -

Больше информации:

- -
    -
  1. HTTP Conditional Get for RSS Hackers
  2. -
  3. HTTP 304: Not Modified
  4. -
  5. On HTTP Last-Modified and ETag
  6. -
- -

Оптимально размещайте компоненты на странице

- -

Сначала загрузите содержимое страницы вместе с любым CSS или JavaScript, которые могут потребоваться для его первоначального отображения, чтобы пользователь получил самый быстрый очевидный ответ во время загрузки страницы. Этот контент, как правило, представляет собой текст, и поэтому может получить выгоду от сжатия текста при передаче, что обеспечивает еще более быстрый отклик для пользователя.

- -

Любые динамические функции, требующие полной загрузки страницы перед использованием, должны быть изначально отключены, а затем включены только после загрузки страницы. Это приведет к загрузке JavaScript после содержимого страницы, что улучшит общий вид загрузки страницы.

- -

Уменьшайте количество встроенных скриптов

- -

Встроенные сценарии могут быть дорогими для загрузки страницы, так как синтаксический анализатор должен предполагать, что встроенный сценарий может изменить структуру страницы во время анализа. Сокращение использования встроенных сценариев в целом и сокращение использования document.write() для вывода контента, в частности, может улучшить общую загрузку страницы. Используйте современные методы AJAX для управления содержимым страницы, а не устаревшие подходы, которые основаны на  document.write().

- -

Используйте современный CSS и корректную разметку

- -

Использование современного CSS уменьшает количество текста, может уменьшить потребность в (разделительных) изображениях с точки зрения макета и очень часто может заменить изображения стилизованного текста - это «стоит» намного дороже, чем эквивалентный текст и CSS.

- -

Использование корректной разметки имеет следующие преимущества. Во-первых, браузерам не нужно выполнять исправление ошибок при разборе HTML (это помимо философской проблемы: разрешить ли изменение формата при вводе пользователем, а затем программно «исправить» или нормализовать его; или вместо этого обеспечить строгий формат ввода без допусков).

- -

Кроме того, корректная разметка позволяет спокойно использовать другие инструменты, которые могут предварительно обрабатывать ваши веб-страницы. Например, HTML Tidy может удалить пробелы и необязательные конечные теги; однако он откажется запускать страницу с серьезными ошибками разметки

- -

Разделяйте ваш контент

- -

Использование таблиц для вёрстки макетов устаревший метод, который не должен больше использоваться. Вместо этого для создания макетов нужно использовать <a href="/en-US/docs/Learn/CSS/CSS_layout/Floats">floats</a>, <a href="/en-US/docs/Learn/CSS/CSS_layout/Positioning">positioning</a>, <a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox">flexbox</a>, или <a href="/en-US/docs/Learn/CSS/CSS_layout/Grids">grids</a>.

- -

Таблицы по-прежнему считаются допустимой разметкой, но их следует использовать для отображения табличных данных. Чтобы браузер быстрее отображал вашу страницу, вам следует избегать вложения таблиц.

- -

Вместо глубоко вложенных таблиц, как в:

- -
<TABLE>
-  <TABLE>
-    <TABLE>
-          ...
-    </TABLE>
-  </TABLE>
-</TABLE>
- -

используйте невложенные таблицы как показано (или div'ы)

- -
<TABLE>...</TABLE>
-<TABLE>...</TABLE>
-<TABLE>...</TABLE>
-
- -

Смотри также: CSS3 Multi-column Layout Spec и CSS3 Flexible Box Layout

- -

Сокращайте и сжимайте активы SVG

- -

SVG, создаваемый большинством графических приложений, часто содержит ненужные метаданные, которые можно удалить. Настройте свои сервера, примените сжатие gzip для ресурсов SVG

- -

Сокращайте и сжимайте ваши изображения

- -

Большие изображения приводят к тому, что загрузка страницы занимает больше времени. Рассмотрите возможность сжатия ваших изображений перед добавлением их на свою страницу.  Есть онлайн-инструменты, такие как <a href="https://compressjpeg.com/">Compress Jpeg</a>, <a href="https://tinypng.com">Tiny PNG</a> и многие другие, доступны онлайн. Вы можете использовать офлайн-инструменты, такие как фотошоп и другие.

- -

Указывайте размеры для изображений и таблиц 

- -

Если браузер может немедленно определить высоту и/или ширину ваших изображений и таблиц, он сможет отображать веб-страницу без необходимости переформатировать содержимое. Это не только ускоряет отображение страницы, но и предотвращает раздражающие изменения в макете страницы после завершения загрузки страницы. По этой причине height и width  должны быть указаны для изображений всегда, когда это возможно.

- -

Таблицы должны использовать CSS селектор: комбинация свойств

- -
  table-layout: fixed;
-
- -

и должны указывать ширину колонок используя HTML теги COL и COLGROUP

- -

Мудро выбирайте требования к пользовательскому агенту

- -

Чтобы добиться наибольших улучшений в дизайне страниц, убедитесь, что для проектов указаны разумные требования к пользовательским агентам. Не требуйте, чтобы ваш контент казался идеальным во всех браузерах, особенно в устаревших.

- -

В идеале ваши базовые минимальные требования должны основываться на рассмотрении современных браузеров, поддерживающих соответствующие стандарты.Это может включать: Firefox 3.6+ на любой платформе, Internet Explorer 8.0+ на Windows, Opera 10+ на Windows, и Safari 4 на Mac OS X.

- -

Примечание. Несмотря на то, что эти атрибуты очень помогают при первой загрузке страницы, вы должны использовать их, но не предполагать, что они будут работать во всех браузерах. Если вы уже следуете всем рекомендациям JavaScript, вам не нужно менять код.

- -

Используйте async и defer, если это возможно

- -

Сделайте сценарии JavaScript такими, чтобы они были совместимы как с async, так и с defer, и по возможности используйте async, особенно если у вас есть несколько тегов script.

- -

При этом страница может перестать отображаться, пока JavaScript все еще загружается. В противном случае браузер не будет отображать ничего после тегов сценария, которые не имеют этих атрибутов.

- -

Примечание. Несмотря на то, что эти атрибуты очень помогают при первой загрузке страницы, вы должны использовать их, но не предполагать, что они будут работать во всех браузерах. Если вы уже следуете всем рекомендациям JavaScript, вам не нужно менять код.

- -

Пример структуры страницы

- -

· HTML

- -
-
· HEAD
-
- -
-
-
-
· LINK ...
- CSS файлы необходимы для отображения веб-страницы. Минимизируйте количество файлов для производительности, сохраняя несвязанные CSS в отдельных файлах для обслуживания.
-
-
-
- -
-
-
-
· SCRIPT ...
- Файлы JavaScript для функций, необходимых при загрузке страницы, но не для любого DHTML, который может работать только после загрузки страницы
-
Минимизируйте количество файлов для повышения производительности, сохраняя несвязанный JavaScript в отдельных файлах для обслуживания.
-
-
-
- -
-
· BODY
-
· Видимое пользователем содержимое страницы небольшими порциями (tables / divs) что можно отобразить, не дожидаясь загрузки полной страницы.
-
- -
-
-
-
· SCRIPT ...
- Любые сценарии, которые будут использоваться для выполнения DHTML. Сценарий DHTML обычно может запускаться только после полной загрузки страницы и инициализации всех необходимых объектов. Нет необходимости загружать эти скрипты перед содержимым страницы. Это только замедляет первоначальный вид загрузки страницы.
-
Минимизируйте количество файлов для повышения производительности, сохраняя несвязанный JavaScript в отдельных файлах для обслуживания
-
Если какие-либо изображения используются для эффектов ролловера, вам следует предварительно загрузить их здесь после загрузки содержимого страницы.
-
-
-
- - - - - -
-

Original Document Information

- -
    -
  • Author(s): Bob Clary, Technology Evangelist, Netscape Communications
  • -
  • Last Updated Date: Published 04 Apr 2003
  • -
  • Copyright Information: Copyright © 2001-2003 Netscape. All rights reserved.
  • -
  • Note: This reprinted article was originally part of the DevEdge site.
  • -
-
- -

 

diff --git a/files/ru/web/guide/html/using_data_attributes/index.html b/files/ru/web/guide/html/using_data_attributes/index.html deleted file mode 100644 index cef001e25a..0000000000 --- a/files/ru/web/guide/html/using_data_attributes/index.html +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: Использование data-* атрибутов -slug: Web/Guide/HTML/Using_data_attributes -tags: - - Guide - - HTML -translation_of: Learn/HTML/Howto/Use_data_attributes ---- -

HTML5 спроектирован с возможностью расширения данных ассоциированных с каким-либо элементом, но в то же время не обязательно имеющих определённое значение. data-* атрибуты позволяют хранить дополнительную информацию в стандартных элементах HTML, без хаков вроде нестандартных атрибутов, лишних DOM-свойств или {{domxref("Node.setUserData()")}}.

- -

Синтаксис HTML

- -

Синтаксис прост — любой атрибут, чьё имя начинается с data-, является data-* атрибутом. Предположим у нас имеется статья и мы хотим сохранить дополнительную информацию без визуального представления. Для этого можно использовать data-атрибуты:

- -
<article
-  id="electriccars"
-  data-columns="3"
-  data-index-number="12314"
-  data-parent="cars">
-...
-</article>
- -

Доступ в JavaScript

- -

Чтение data-атрибутов в JavaScript осуществляется также просто. Для этого можно использовать метод {{domxref("Element.getAttribute", "getAttribute()")}} с параметром, равным полному имени атрибута. Но есть и более простой способ, используя объект {{domxref("HTMLElement.dataset", "dataset")}}.

- -

Чтобы получить data-атрибут можно взять свойство объекта dataset с именем, равным части имени атрибута после data- (обратите внимание, что дефисы в имени преобразуются в camelCase).

- -
var article = document.getElementById('electriccars');
-
-article.dataset.columns // "3"
-article.dataset.indexNumber // "12314"
-article.dataset.parent // "cars"
- -

Каждое свойство является строкой и может быть прочитано и записано. В приведённом выше примере выполнение кода article.dataset.columns = 5 приведёт к тому, что новое значение атрибута станет равным "5".

- -

Доступ в CSS

- -

Заметим, что data-атрибуты являются обычными HTML-аттрибутами, к которым можно получить доступ в CSS. Например, чтобы показать родительские данные о статье можно использовать генерируемый контент и CSS функцию {{cssxref("attr")}}:

- -
article::before {
-  content: attr(data-parent);
-}
- -

Также можно использовать селекторы атрибутов в CSS для изменения стилей в соответствии с данным:

- -
article[data-columns='3']{
-  width: 400px;
-}
-article[data-columns='4']{
-  width: 600px;
-}
- -

Увидеть как это работает можно в примере на JSBin.

- -

Data-аттрибуты также могут использоваться для хранения информации, которая постоянно изменяется, например, счёт в игре. Используя CSS селекторы и возможности JavaScript можно создавать некоторые изящные эффекты, без необходимости писать свои функции отображения. Посмотрите скринкаст чтобы увидеть больше примеров использующих сгенерированный контент и переходы на CSS. Пример кода из скринкаста можно также посмотреть на JSBin.

- -

Проблемы

- -

Не храните данные, которые должны быть видимы и доступны в data-атрибутах. Дело в том, что вспомогательная техника (assistive technology) может не получить к ним доступ. В дополнение, поисковые роботы не индексируют данные, содержащиеся в data-атрибутах.

- -

Печально, что всё простое и полезное в этой жизни не достаётся бесплатно. Internet Explorer 11+ поддерживает этот стандарт, но все более ранние версии не поддерживают dataset. Для поддержки IE 10 и более ранних версий получение доступа к data-атрибутам необходимо осуществлять через {{domxref("Element.getAttribute", "getAttribute()")}}. Также, производительность чтения data-атрибутов по сравнению с хранением этих данных в хранилище данных JS значительно хуже. Использование dataset ещё медленнее, чем чтение данных с getAttribute().

- -

Тем не менее, для пользовательских метаданных, связанных с элементами, data-атрибуты являются отличным решением.

- -

Поддержка в браузерах

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
caniuse
-

IE

-
-

Edge

-
-

Firefox

-
-

Chrome

-
-

Safari

-
-

Opera

-
-

iOS Safari

-
-

Opera Mini*

-
-

Android Browser

-
-

Chrome for Android

-
11+14+52+49+10.1+46+9.3+all4.4+59+
- -

 

- -

Тем не менее, для содержимого, которое не надо показывать это является отличным решением.

- -

См. также

- - diff --git a/files/ru/web/guide/html/using_html_sections_and_outlines/index.html b/files/ru/web/guide/html/using_html_sections_and_outlines/index.html new file mode 100644 index 0000000000..a6236d9c24 --- /dev/null +++ b/files/ru/web/guide/html/using_html_sections_and_outlines/index.html @@ -0,0 +1,375 @@ +--- +title: Использование разделов и создание структуры HTML документа +slug: Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document +tags: + - HTML5 + - Веб + - Для опытных разработчиков + - Обзор + - Пример + - Разделы + - Руководство + - Структура +translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines +--- +
+

Важно: В настоящее время нет известных реализаций алгоритма построения структуры документа в графических браузерах или пользовательских приложениях, использующих реабилитационные технологии, хотя такой алгоритм внедрен в другие приложения, например, в средствах проверки соответствия спецификации. Поэтому алгоритм построения структуры нельзя использовать для передачи структуры документа пользователям. Авторы рекомендуют использовать для этой цели степень важности заголовков (h1-h6).

+
+ +

Спецификация HTML5 предлагает разработчикам несколько новых элементов, позволяющих описывать структуру веб-документа с помощью стандартной семантики. В настоящей статье описываются эти элементы и способы их использования для создания требуемой структуры любого документа.

+ +

Структура документа в HTML 4

+ +

Структура документа, т. е. семантическая структура контента, заключенного в теги  <body> и </body>, является основой для представления страницы пользователю. HTML4 использует для описания структуры страницы разделы и подразделы. Раздел определяется элементом ({{HTMLElement("div")}}) с включенными в него элементами заголовка ({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}} или {{HTMLElement("h6")}}), содержащими его название. Структура документа определяется отношениями между этими элементами.

+ +

Так, следующая разметка:

+ +
+
<div class="section" id="forest-elephants" >
+  <h1>Лесные слоны</h1>
+  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <div class="subsection" id="forest-habitat" >
+    <h2>Среда обитания</h2>
+    <p>Лесные слоны живут не на деревьях, а под ними.
+     ...продолжение данного подраздела...
+  </div>
+</div>
+
+
+ +

обеспечивает следующую структуру:

+ +
1. Лесные слоны
+   1.1 Среда обитания
+
+ +

Для задания нового раздела не обязательно использовать элементы {{HTMLElement("div")}}. Для этого достаточно наличия элемента заголовка. Поэтому, разметка

+ +
<h1>Лесные слоны</h1>
+ <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <h2>Среда обитания</h2>
+  <p>Лесные слоны живут не на деревьях, а под ними.
+    ...продолжение данного подраздела...
+  <h2>Рацион</h2>
+<h1>Монгольская песчанка</h1>
+
+ +

обеспечивает следующую структуру:

+ +
1. Лесные слоны
+   1.1 Среда обитания
+   1.2 Рацион
+2. Монгольская песчанка
+
+ +

Какие проблемы решает HTML5

+ +

Определение структуры документа и неявный алгоритм создания структуры в HTML 4 не отличаются четкостью, что порождает множество проблем:

+ +
    +
  1. Использование {{HTMLElement("div")}} для задания семантических разделов, без задания специальных значений для атрибутов class не позволяет автоматизировать алгоритм создания структуры («Является ли данный {{HTMLElement("div")}} частью структуры страницы, определяющим раздел или подраздел, или он используется исключительно для управления стилем?»). Другими словами, спецификация HTML4 не дает точного определения разделу и четких правил его определения. Автоматическое создание структуры имеет большое значение, особенно в случае с реабилитационными технологиями, представляющими информацию пользователю в соответствии со структурой документа. HTML5 позволяет больше не использовать элементы {{HTMLElement("div")}} в алгоритме построения структуры благодаря добавлению нового элемента {{HTMLElement("section")}}.
  2. +
  3. Объединить несколько документов в один непросто: включение подчиненного документа в основной документ требует изменения уровня элементов заголовков для сохранения правильной структуры. В HTML5 эта проблема решена благодаря новым элементам задания разделов ({{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("nav")}} и {{HTMLElement("aside")}}), которые всегда являются подразделами ближайшего родительского раздела, независимо от того, какие разделы создаются внутренними заголовками.
  4. +
  5. В HTML4 каждый раздел является частью структуры документа. Однако часто документы отличаются сложной, нелинейной структурой. Документ может включать специальные разделы, информация в которых не является частью основного контента, хотя и связана с ним, например, рекламный блок или поясняющая заметка. HTML5 добавляет элемент {{HTMLElement("aside")}}, позволяющий исключить такие разделы из основной структуры.
  6. +
  7. Опять же, поскольку в HTML4 каждый раздел является частью структуры документа, как быть с разделами, содержащими информацию, касающуюся не конкретного документа, а всего сайта, например, логотипы, оглавления или информация об авторских правах и правовые положения. В HTML5 для этих целей добавлено три новых элемента: {{HTMLElement("nav")}} для наборов ссылок, например, оглавления, {{HTMLElement("footer")}} и {{HTMLElement("header")}} для информации, касающейся всего сайта. Обратите внимание, что {{HTMLElement("header")}} и {{HTMLElement("footer")}} не создают разделы как {{HTMLElement("section")}}, а, скорее, обеспечивают семантическую разметку частей раздела.
  8. +
+ +

В общем, HTML5 обеспечивает большую точность при задании разделов и оглавлений, позволяя строить более предсказуемую структуру документа, что дает браузерам возможность более качественно обслуживать пользователей.

+ +

Алгоритм создания структуры HTML5

+ +

Задание разделов в HTML5

+ +

Весь контент, находящийся внутри {{HTMLElement("body")}}, является частью раздела. Разделы в HTML5 могут быть вложенными. Помимо основного раздела, определяемого элементом {{HTMLElement("body")}}, границы разделов определяются явным или неявным образом. Явным образом заданные разделы – это контент внутри тегов {{HTMLElement("body")}},  {{HTMLElement("section")}},  {{HTMLElement("article")}},  {{HTMLElement("aside")}} и {{HTMLElement("nav")}}. 

+ +
Note: Каждый раздел может иметь собственную иерархию заголовков. Следовательно, даже вложенный раздел может иметь {{HTMLElement("h1")}}. См. «Задание заголовков в HTML5».
+ +

Например:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <section>
+    <h1>Введение</h1>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
+  </section>
+  <section>
+    <h1>Среда обитания</h1>
+    <p>Лесные слоны живут не на деревьях, а под ними.</p>
+  </section>
+  <aside>
+    <p>рекламный блок</p>
+  </aside>
+</section>
+<footer>
+  <p>(c) 2010 The Example company</p>
+</footer>
+ +

Данный фрагмент HTML задает раздел верхнего уровня:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <section>
+    <h1>Введение</h1>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
+  </section>
+  <section>
+    <h1>Среда обитания</h1>
+    <p>Лесные слоны живут не на деревьях, а под ними.</p>
+  </section>
+  <aside>
+    <p>рекламный блок</p>
+  </aside>
+</section>
+<footer>
+  <p>(c) 2010 The Example company</p>
+</footer>
+ +

Данный раздел имеет три подраздела:

+ +
<section>
+  <h1>Лесные слоны</h1>
+
+  <section>
+    <h1>Введение</h1>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.</p>
+  </section>
+
+  <section>
+    <h1>Среда обитания</h1>
+    <p>Лесные слоны живут не на деревьях, а под ними.</p>
+  </section>
+
+  <aside>
+    <p>рекламный блок</p>
+  </aside>
+</section>
+
+<footer>
+  <p>(c) 2010 The Example company</p>
+</footer>
+ +

В результате получаем следующую структуру:

+ +
1. Лесные слоны
+   1.1 Введение
+   1.2 Среда обитания
+
+ +

Задание заголовков в HTML5

+ +

Хотя структура определяется элементами задания структуры, она будет практически бесполезна без заголовка. Основное правило очень простой: первый элемент заголовка (это может быть {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}}) задает заголовок текущего раздела.

+ +

Элемент заголовка имеет определенную степень важности, определяемую цифрой в его названии, таким образом, {{HTMLElement("h1")}} имеет максимальную степень важности, а {{HTMLElement("h6")}} минимальную. Соотношение степеней важности имеет смысл только внутри раздела; структура документа определяется структурами разделов, а не степенью важности заголовков разделов. Например, данный код:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <section>
+    <h2>Среда обитания</h2>
+    <p>Лесные слоны живут не на деревьях, а под ними.
+        ...продолжение данного подраздела...
+  </section>
+</section>
+<section>
+  <h3>Монгольская песчанка</h3>
+  <p>В данном разделе мы расскажем о монгольской песчанке.
+     ...продолжение данного раздела...
+</section>
+ +

приводит к следующей структуре:

+ +
1. Лесные слоны
+   1.1 Среда обитания
+2. Монгольская песчанка
+ +

Обратите внимание, что степень важности элемента заголовка (в данном примере {{HTMLElement("h1")}} для первого раздела верхнего уровня, {{HTMLElement("h2")}} для подраздела {{HTMLElement("h3")}} для второго раздела верхнего уровня) роли не играет. (В качестве заголовка явно заданного раздела может использоваться заголовок с любой степенью важности, хотя такая практика и не рекомендуется.)

+ +

Неявное задание разделов

+ +

Поскольку элементы задания разделов HTML5 Sectioning Elements не являются обязательными для задания структуры, можно задавать разделы и не используя их, чтобы обеспечить совместимость с веб-сайтами, созданными на HTML4. Это называется неявным заданием разделов.

+ +

Элементы заголовков ({{HTMLElement("h1")}} — {{HTMLElement("h6")}}) задают новый, неявный раздел, когда не являются первым заголовком своего родительского, явно заданного раздела. То, как этот неявно заданный раздел располагается в структуре документа, определяется отношением важности его заголовка в важности предыдущего заголовка в родительском разделе. Если его степень важности ниже, чем у предыдущего заголовка, он открывает неявно заданный подраздел раздела. Следующий код:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <h3 class="implicit subsection">Среда обитания</h3>
+  <p>Лесные слоны живут не на деревьях, а под ними.
+    ...продолжение данного подраздела...
+</section>
+ +

приводит к следующей структуре:

+ +
1. Лесные слоны
+   1.1 Среда обитания (неявно задано элементом h3)
+
+ +

Если степень важности такого заголовка совпадает со степенью важности предыдущего заголовка, он закрывает предыдущий раздел (который мог быть задан неявно!) и открывает новый неявно заданный раздел на том же уровне: 

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+  <h1 class="implicit section">Монгольская песчанка</h1>
+  <p>Монгольская песчанка – это небольшое симпатичное млекопитающее.
+    ...продолжение данного раздела...
+</section>
+ +

приводит к следующей структуре:

+ +
1. Лесные слоны
+2. Монгольская песчанка (неявно задано элементом h1, который одновременно закрывает предыдущий раздел)
+
+ +

Если степень важности такого заголовка выше, чем у предыдущего заголовка, он закрывает предыдущий раздел и открывает новый неявно заданный раздел на более высоком уровне:

+ +
<body>
+  <h1>Млекопитающие</h1>
+  <h2>Киты</h2>
+  <p>В данном разделе мы поговорим о китах.
+    ...продолжение данного раздела...
+  <section>
+    <h3>Лесные слоны</h3>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах.
+    ...продолжение данного раздела...
+    <h3>Монгольская песчанка</h3>
+      <p>Песчанки распространились далеко за пределы Монголии.
+         ...продолжение данного подраздела...
+    <h2>Рептилии</h2>
+      <p>Рептилии – это холоднокровные животные.
+          ...продолжение данного раздела...
+  </section>
+</body>
+ +

приводит к следующей структуре:

+ +
1. Млекопитающие
+   1.1 Киты (неявно задается элементом h2)
+   1.2 Лесные слоны (явным образом задается элементом раздела)
+   1.3 Монгольская песчанка (неявно задается элементом h3, который одновременно закрывает предыдущий раздел)
+2. Рептилии (неявно задается элементом h2, который одновременно закрывает предыдущий раздел)
+
+ +

Эта не та структура, которую можно было бы ожидать, бегло просмотрев теги заголовков. Чтобы разметка стала понятна человеку, а также чтобы степень важности заголовка соответствовала уровню вложенности раздела, рекомендуется использовать наглядные теги для открытия и закрытия разделов. Однако спецификация HTML5 этого не требует. Поэтому, если браузеры отображают структуру документа не так, как ожидалось, проверьте, нет ли в документе разделов, не явно закрытых элементами заголовков.

+ +

Исключение из общего правила соответствия степени важности тега уровню вложенности раздела делается для разделов, которые могут использоваться в нескольких документах. Например, раздел может храниться в системе управления контентом и добавляться в документы при их генерировании. В этом случае рекомендуется начинать с {{HTMLElement("h1")}} в качестве главного заголовка многократно используемого раздела. Уровень вложенности многократно используемого раздела будет определяться иерархией разделов документа, в который он добавляется. Теги для явного задания разделов по-прежнему останутся полезными и в этом конкретном случае.

+ +

Корни задания разделов

+ +

 Корень задания разделов – это элемент HTML, который может иметь собственную структуру, однако входящие в нее разделы и заголовки, не входят в структуру его родительского элемента. Помимо {{HTMLElement("body")}}, который является логическим корнем задания разделов документа, такими элементами часто являются элементы, добавляющие внешний контент на страницу: {{HTMLElement("blockquote")}}, {{HTMLElement("details")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}} и {{HTMLElement("td")}}.

+ +

Например:

+ +
<section>
+  <h1>Лесные слоны</h1>
+  <section>
+    <h2>Введение</h2>
+    <p>В данном разделе мы поговорим о малоизвестных лесных слонах</p>
+  </section>
+  <section>
+    <h2>Среда обитания</h2>
+    <p>Лесные слоны живут не на деревьях, а под ними. Давайте рассмотрим, что говорят ученые в «<cite>Лесной слон на Борнео</cite>»:</p>
+    <blockquote>
+       <h1>Борнео</h1>
+       <p>Лесной слон живет на Борнео...</p>
+    </blockquote>
+  </section>
+</section>
+
+ +

Данный пример приводит к следующей структуре:

+ +
1. Лесные слоны
+   1.1 Введение
+   1.2 Среда обитания
+ +

Данная структура не включает внутреннюю структуру элемента {{HTMLElement("blockquote")}}, который, будучи внешней цитатой, является корнем задания разделов и изолирует свою внутреннюю структуру.

+ +

Разделы, не входящие в структуру

+ +

 HTML5 вводит два новых элемента, позволяющих задавать разделы, не входящие в основную структуру веб-документа:

+ +
    +
  1. Элемент вспомогательного раздела {{HTMLElement("aside")}} задает раздел, который, хотя и связан с основным элементом, не принадлежит к основной структуре, например, поясняющая заметка или реклама. Он имеет собственную структуру, однако не входит в основную структуру страницы.
  2. +
  3. Элемент навигационного раздела {{HTMLElement("nav")}} задает раздел, содержащий навигационные ссылки. Таких элементов в документе может быть несколько, например, один со внутренними ссылками на страницу, например, оглавление, а другой – с ссылками для навигации по сайту. Такие ссылки не являются частью основной структуры документа и как правило пропускаются экранными дикторами.
  4. +
+ +

Шапки и подвалы

+ +

HTML5 также добавляет два новых элемента, которые могут использоваться для разметки верхнего и нижнего колонтитулов страниц:

+ +
    +
  1. Элемент шапки {{HTMLElement("header")}} задает шапку страницы (как правило, логотип и название сайта, а также горизонтальное меню, если имеется) или раздела (которая может включать заголовок раздела, имя автора и т.д.).{{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}}, и {{HTMLElement("nav")}} могут иметь собственный {{HTMLElement("header")}}. Несмотря на название, этот элемент не обязательно располагается в начале страницы или раздела.
  2. +
  3. Элемент подвала ({{HTMLElement("footer")}}) задает нижний колонтитул страницы (как правило включающий уведомления об авторских правах и другую правовую информацию, а иногда также содержащий какие-либо ссылки) или раздела (может включать дату публикации, информацию о лицензии и т.п. {{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}} и {{HTMLElement("nav")}} могут иметь собственный {{HTMLElement("footer")}}. Несмотря на название, этот элемент не обязательно располагается в конце страницы или раздела.
  4. +
+ +

Эти элементы не создают новые разделы в структуре, а скорее используются для разметки контента внутри разделов страницы.

+ +

Адреса в элементах задания разделов

+ +

Автор документа часто хочет опубликовать свою контактную информацию, например, имя и адрес. HTML4 позволял сделать это с помощью элемента {{HTMLElement("address")}}, расширенного в HTML5.

+ +

Документ может включать несколько разделов, принадлежащих разным авторам. Если раздел создается не автором основной страницы, для задания используется элемент {{HTMLElement("article")}}. В результате элемент {{HTMLElement("address")}} теперь связан с ближайшим родительским {{HTMLElement("body")}} или {{HTMLElement("article")}}.

+ +

Использование элементов HTML5 в браузерах, не поддерживающих HTML5

+ +

Элементы разделов и заголовков должны работать в большинстве браузеров, не поддерживающих HTML5. Хотя они и не поддерживаются, они не требуют специального интерфейса DOM, им требуется лишь особый стиль CSS, поскольку к неизвестным элементам по умолчанию применяется стиль display:inline:

+ +
section, article, aside, footer, header, nav, hgroup {
+  display:block;
+}
+
+ +

Конечно, веб-разработчик может применить к ним любой другой стиль, однако следует помнить в браузерах, не поддерживающих HTML5, по умолчанию используется не тот стиль, который требуется для таких элементов. Также обратите внимание на отсутствие в перечне элемента {{HTMLElement("time")}}, поскольку по умолчанию к нему применяется одинаковый стиль как в браузерах, не поддерживающих HTML5, так и в браузерах, совместимых с HTML5.

+ +

Данный способ не универсален, поскольку некоторые браузеры не позволяют применять стили к неподдерживаемым элементам. Например, Internet Explorer (версии 8 и более ранней), для которого требуется специальный скрипт:

+ +
<!--[if lt IE 9]>
+  <script>
+    document.createElement("header" );
+    document.createElement("footer" );
+    document.createElement("section");
+    document.createElement("aside"  );
+    document.createElement("nav"    );
+    document.createElement("article");
+    document.createElement("hgroup" );
+    document.createElement("time"   );
+  </script>
+<![endif]-->
+ +

Этот скрипт запускается в Internet Explorer (8 и более ранней версии), однако требует включенной поддержки скриптов для правильного отображения элементов задания разделов и заголовок HTML5. Если поддержа скриптов выключена, это может стать проблемой, поскольку данные элементы, скорее всего, определяют структуру всей страницы. Поэтому необходимо добавить элемент {{HTMLElement("noscript")}}:

+ +
<noscript>
+   <strong>Внимание!</strong>
+   Поскольку ваш браузер не поддерживает HTML5, некоторые элементы воспроизводятся с помощью JScript.
+   Однако в вашем браузере скрипты отключены, пожалуйста, включите их, чтобы браузер смог отобразить данную страницу.
+</noscript>
+ +

This leads to the following code to allow the support of the HTML5 sections and headings elements in non-HTML5 browsers, even for Internet Explorer (8 and older), with a proper fallback for the case where this latter browser is configured not to use scripting:

+ +
<!--[if lt IE 9]>
+  <script>
+    document.createElement("header" );
+    document.createElement("footer" );
+    document.createElement("section");
+    document.createElement("aside"  );
+    document.createElement("nav"    );
+    document.createElement("article");
+    document.createElement("hgroup" );
+    document.createElement("time"   );
+  </script>
+  <noscript>
+     <strong>Внимание!</strong>
+     Поскольку ваш браузер не поддерживает HTML5, некоторые элементы воспроизводятся с помощью JScript.
+     Однако в вашем браузере скрипты отключены, пожалуйста, включите их, чтобы браузер смог отобразить данную страницу.
+  </noscript>
+<![endif]-->
+ +

Заключение

+ +

Новые семантические элементы, добавленные в HTML5, обеспечивают стандартизацию описания структуры веб-документа. Они облегчают жизнь пользователям с ограниченными возможностями, просты в использовании, могут без особых проблем поддерживаться в старых браузерах и поэтому настоятельно рекомендуются к применению.

+ +
{{HTML5ArticleTOC()}}
diff --git "a/files/ru/web/guide/html/\321\204\320\276\321\200\320\274\321\213_\320\262_html/index.html" "b/files/ru/web/guide/html/\321\204\320\276\321\200\320\274\321\213_\320\262_html/index.html" deleted file mode 100644 index ad5a8bc7e6..0000000000 --- "a/files/ru/web/guide/html/\321\204\320\276\321\200\320\274\321\213_\320\262_html/index.html" +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: Формы в HTML -slug: Web/Guide/HTML/Формы_в_HTML -tags: - - HTML - - HTML5 - - Введение - - Интернет - - Любитель - - Новичок - - Обзор - - Руководство - - Формы -translation_of: Learn/HTML/Forms/HTML5_updates ---- -

Элементы и атрибуты форм в HTML5 предоставляют большие возможности семантической верстки, чем HTML4, а также позволяет отказаться от использования JavaScript и CSS, которое было ранее необходимо для HTML4. Большие возможности в формах HTML5 делают удобным для пользователей отправление информации с различных веб-сайтов. Они также предоставляют эти возможности для тех пользователей, у которых отключена поддержка JavaScript.

- -

Эта статья описывает изменения в HTML-формах, представленных в HTML5. Для более подробного руководства по использованию формами, просмотрите наше обширное руководство по HTML-формам.

- -

Элемент <input>

- -

В элементе {{HTMLElement("input")}} появились новые значения для атрибута {{htmlattrxref("type", "input")}}. (Просмотрите справочник {{HTMLElement("input")}} для получения полного списка атрибутов, значений и их использования для этого элемента.)

- -
    -
  • search: Элемент представляет из себя поле для поиска. Переходы строк автоматически удаляются из значения value.
  • -
  • tel: Элемент представляет из себя поле для редактирования номера телефона. Переходы строк автоматически удаляются из значения value. Вы можете использовать атрибуты, такие как: {{htmlattrxref("pattern", "input")}} и {{htmlattrxref("maxlength", "input")}}, чтобы запретить ввод неподходящих символов.
  • -
  • url: Элемент представляет из себя поле для редактирования URL. Переходы строк и пробелы автоматически удаляются из значения value.
  • -
  • -

    email: Элемент представляет из себя поле для ввода одного адреса электронной почты. Переходы строк автоматически удаляются из значения value. Может быть предоставлен недействительный адрес эл. почты, но поле ввода запретит отправку формы, если эл. адрес почты не будет соответствовать нормам ABNF.

    - -
    Заметьте: Если установлен атрибут {{htmlattrxref("multiple", "input")}}, то может быть введено несколько адресов электронной почты, разделенных запятой, но, в данный момент, такая возможность не реализована в Firefox.
    -
  • -
- -

Также, элемент {{HTMLElement("input")}} получил новые атрибуты:

- -
    -
  • {{htmlattrxref("list", "input")}}: ID элемента {{HTMLElement("datalist")}}, в котором элементы {{HTMLElement("option")}} используются как подсказки для текстового поля.
  • -
  • {{htmlattrxref("pattern", "input")}}: Регулярное выражение, по которому поверяются вводимые данные. Может использоваться в элементе {{htmlattrxref("type", "input")}} со значениями text, tel, search, url, и email.
  • -
  • {{htmlattrxref("form", "input")}}: Строка, указывающая, к какому элементу {{HTMLElement("form")}} принадлежит элемент. Элемент может быть частью только одной формы.
  • -
  • {{htmlattrxref("formmethod", "input")}}: Строка, указывающая метод передачи данных  (GET or POST), когда форма отправляется на сервер. Он перекрывает значение атрибута {{htmlattrxref("method", "form")}} элемента {{HTMLElement("form")}}, если установлен. Работает только, если {{htmlattrxref("type", "input")}} является image или submit, и если установлен атрибут {{htmlattrxref("form", "input")}}.
  • -
  • {{htmlattrxref("x-moz-errormessage", "input")}} {{non-standard_inline}}: Строка, указывающая на сообщение об ошибке, которое будет показано, если это поле не пройдет валидацию. Этот атрибут - расширение Mozilla и не является стандартом.
  • -
- -

Текстовое поле

- -

<input> с атрибутом type="text" определяет однострочное поле для ввода.

- -
<form>
-  Введите свое имя: <input type="text" name="name">
-</form>
- -

Флажок

- -

<input> с атрибутом type="checkbox" определяет флажок.

- -
<input type="checkbox" name="chk" value="" checked> Подписаться на рассылку
- -

Переключатель

- -

<input> с атрибутом type="radio" определяет радио кнопку.

- -
<form>
-  <input type="radio" name="animal" value="monkey">Обезьяна<br>
-  <input type="radio" name="animal" value="cat">Кот<br>
-  <input type="radio" name="animal" value="other">Другое
-</form>
- -

Элемент <form>

- -

Элемент {{HTMLElement("form")}} получил новый атрибут:

- -
    -
  • {{htmlattrxref("novalidate", "form")}}: Этот атрибут предотвращает валидацию формы перед отправкой.
  • -
- -

Элемент <datalist>

- -

Элемент {{HTMLElement("datalist")}} представляет собой список элементов {{HTMLElement("option")}}, который необходимо предложить при вводе поля {{HTMLElement("input")}}.

- -

Вы можете использовать атрибут {{htmlattrxref("list", "input")}} в элементе {{HTMLElement("input")}}, чтобы связать текстовое поле с элементом {{HTMLElement("datalist")}}.

- -

Элемент <output>

- -

Элемент {{HTMLElement("output")}} представляет собой результат каких-либо вычислений.

- -

Вы можете использовать атрибут {{htmlattrxref("for", "output")}} для указания связи между элементом {{HTMLElement("output")}} и другими элементами в документе, которые повлияли на расчет (к примеру, поля для ввода параметров). Значением атрибута {{htmlattrxref("for", "output")}} является список ID других элементов, разделенный пробелами.

- -

{{non-standard_inline}} Gecko 2.0 (but not necessarily other browser engines) supports defining custom validity constraints and error messages for {{HTMLElement("output")}} elements, and therefore applies the {{Cssxref(":invalid")}}, {{Cssxref(":valid")}}, {{Cssxref(":-moz-ui-invalid")}}, and {{Cssxref(":-moz-ui-valid")}} CSS pseudo-classes to them. This can be helpful in situations where the calculated result violates a business rule, but no specific input value does (for example, "The total of percentages must not exceed 100").

- -

Атрибут placeholder

- -

Атрибут {{htmlattrxref("placeholder", "input")}} в элементах {{HTMLElement("input")}} и {{HTMLElement("textarea")}} отображает подсказки для пользователей, которые показывают, что можно ввести в эти поля. Текст в placeholder не должен содержать символов перевода строки или возврата каретки.

- -

Атрибут autofocus

- -

Атрибут {{htmlattrxref("autofocus", "input")}} позволяет указать для элемента формы автоматическое получение фокуса после полной загрузки страницы, если пользователь сам не переместит фокус на другой элемент, например, этот атрибут можно указать для различных полей ввода. Только один элемент в документе должен иметь этот атрибут, который содержит Boolean значение. Этот атрибут может быть установлен в {{HTMLElement("input")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}} и {{HTMLElement("textarea")}} элементах.  {{htmlattrxref("autofocus", "input")}} нельзя установить в элементах input c атрибутом type установленным в значение hidden (это означает, что ты не можешь автоматически устанавливать фокус в скрытых полях).

- -

DOM свойство label.control

- -

DOM интерфейс HTMLLabelElement , помимо свойств, относящихся к HTML элементу {{HTMLElement("label")}} , предоставляет дополнительное свойство  control, возвращающее поле ввода, для которого предназначен {{HTMLElement("label")}}. Оно либо указывается в атрибуте {{htmlattrxref("for", "label")}} , либо является первым вложенным полем ввода.

- -

Constraint Validation

- -

HTML5 provides syntax and API items to support client-side validation of forms. While this functionality does not replace server-side validation, which is still necessary for security and data integrity, client-side validation can support a better user experience by giving the user immediate feedback about the input data.

- -

If the title attribute is set on the {{HTMLElement("input")}} element, its value is used as tooltip. However, if the validation fails, this tooltip text will be replaced with the associated error message. It is possible to customize this error message using the non-standard {{htmlattrxref("x-moz-errormessage")}} attribute or when calling the setCustomValidity() method.

- -
<input type="email" title="Please, provide an e-mail" x-moz-errormessage="This is not a valid e-mail">
- -
Note: Constraint validation is not supported on {{HTMLElement("button")}} elements in a form; to style a button based on the validity of the associated form, use the {{cssxref(":-moz-submit-invalid")}} pseudo-class.
- -

HTML Syntax for Constraint Validation

- -

The following items in HTML5 syntax can be used to specify constraints on form data.

- -
    -
  • The {{htmlattrxref("required", "input")}} attribute on the {{HTMLElement("input")}}, {{HTMLElement("select")}}, and {{HTMLElement("textarea")}} elements indicates that a value must be supplied. (On the {{HTMLElement("input")}} element, {{htmlattrxref("required", "input")}} applies only in conjunction with certain values of the {{htmlattrxref("type", "input")}} attribute.)
  • -
  • The {{htmlattrxref("pattern", "input")}} attribute on the {{HTMLElement("input")}} element constrains the value to match a specific regular expression.
  • -
  • The {{htmlattrxref("min", "input")}} and {{htmlattrxref("max", "input")}} attributes of the {{HTMLElement("input")}} element constrain the minimum and maximum values that can be entered.
  • -
  • The {{htmlattrxref("step", "input")}} attribute of the {{HTMLElement("input")}} element (when used in combination with the {{htmlattrxref("min", "input")}} and {{htmlattrxref("max", "input")}} attributes) constrains the granularity of values that can be entered. A value that does not correspond an allowed value step does not validate.
  • -
  • The {{htmlattrxref("maxlength", "input")}} attribute of the {{HTMLElement("input")}} and {{HTMLElement("textarea")}} elements constrains the maximum number of characters (in Unicode code points) that the user can enter.
  • -
  • The values url and email for the {{htmlattrxref("type", "input")}} constrain the value to being a valid URL or e-mail address, respectively.
  • -
- -

In addition, you can prevent constraint validation by specifying the {{htmlattrxref("novalidate", "form")}} attribute on the {{HTMLElement("form")}}, or the {{htmlattrxref("formnovalidate", "button")}} attribute on the {{HTMLElement("button")}} element and on the {{HTMLElement("input")}} element (when {{htmlattrxref("type", "input")}} is submit or image). These attributes indicate that the form is not to be validated when it is submitted.

- -

Constraint Validation API

- -

The following DOM properties and methods related to constraint validation are available to client-side scripts:

- -
    -
  • On HTMLFormElement objects, the checkValidity() method, which returns true if all of this form element's associated elements that are subject to constraint validation satisfy their constraints, and false if any do not.
  • -
  • On form-associated elements: -
      -
    • willValidate property, which is false if the element has constraints that are not satisfied.
    • -
    • validity property, which is a ValidityState object representing the validity states that the element is in (i.e., constraint failure or success conditions).
    • -
    • validationMessage property, which is a message describing any constraint failures that pertain to the element.
    • -
    • checkValidity() method, which returns false if the element fails to satisfy any of its constraints, or true otherwise.
    • -
    • setCustomValidity() method, which sets a custom validation message, allowing for constraints to be imposed and validated beyond those that are predefined.
    • -
    -
  • -
- -

See also

- - diff --git a/files/ru/web/guide/performance/index.html b/files/ru/web/guide/performance/index.html new file mode 100644 index 0000000000..8b1d2760da --- /dev/null +++ b/files/ru/web/guide/performance/index.html @@ -0,0 +1,20 @@ +--- +title: Оптимизация и производительность +slug: Web/Guide/Производительность +tags: + - Оптимизация + - Производительность +translation_of: Web/Guide/Performance +--- +

Создаваемые Вами современные веб-приложения и сайты должны иметь хорошую производительность - работать быстро и эффективно, как на персональных компьютерах (десктоп), так и на менее мощных мобильных устройствах. Существуют различные инструменты для тестирования сайтов на производительность. Самые известные из них:

+ + + +

Производительность в web - первостепенная задача для тех, кто заботится о комфорте конечного пользователя.

+ +

{{LandingPageListSubpages}}

diff --git "a/files/ru/web/guide/\320\263\321\200\320\260\321\204\320\270\320\272\320\260/index.html" "b/files/ru/web/guide/\320\263\321\200\320\260\321\204\320\270\320\272\320\260/index.html" deleted file mode 100644 index 57dd4238e1..0000000000 --- "a/files/ru/web/guide/\320\263\321\200\320\260\321\204\320\270\320\272\320\260/index.html" +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Графика для Web -slug: Web/Guide/Графика -translation_of: Web/Guide/Graphics ---- -

Современным веб-сайтам и веб-приложениям часто требуется отображать графику. Статические изображения легко отобразить с помощью элемента {{HTMLElement("img")}}, или с помощью CSS свойства  {{cssxref("background-image")}}. Часто требуется создавать графику на лету, или модифицировать ее каким-либо образом после. Как это проделать можно узнать в следующих статьях.

- -
-
-

2D графика

- -
-
Канвас
-
Элемент {{HTMLElement("canvas")}} представляет удобный API для рисования 2D графики с помощью JavaScript.
-
SVG
-
Масштабируемая Векторная Графика (Scalable Vector Graphics) позволяет рисовать линии, кривые, и другие геометрические фигуры. С их помощью можно создавать масштабируемые изображения, которые не теряют в качестве при изменении размера в отличии от растровой графики.
-
- -

View All...

-
- -
-

3D графика

- -
-
WebGL
-
Руководство по быстрому старту с WebGL. WebGL предоставляет API для работы с 3D графиками в веб. Эта технология позволяет Вам использовать стандартный OpenGL ES в веб контексте.
-
- -

Видео

- -
-
Использование HTML5 видео и аудио
-
Встраивание видео и аудио в HTML документ и управление проигрыванием.
-
WebRTC
-
RTC в WebRTC означает Real-Time Communications, технология которая позволяет стримить аудио/видео и данные между клиентами браузера (пирами).
-
-
-
- -

 

diff --git "a/files/ru/web/guide/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" "b/files/ru/web/guide/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" deleted file mode 100644 index 8b1d2760da..0000000000 --- "a/files/ru/web/guide/\320\277\321\200\320\276\320\270\320\267\320\262\320\276\320\264\320\270\321\202\320\265\320\273\321\214\320\275\320\276\321\201\321\202\321\214/index.html" +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Оптимизация и производительность -slug: Web/Guide/Производительность -tags: - - Оптимизация - - Производительность -translation_of: Web/Guide/Performance ---- -

Создаваемые Вами современные веб-приложения и сайты должны иметь хорошую производительность - работать быстро и эффективно, как на персональных компьютерах (десктоп), так и на менее мощных мобильных устройствах. Существуют различные инструменты для тестирования сайтов на производительность. Самые известные из них:

- - - -

Производительность в web - первостепенная задача для тех, кто заботится о комфорте конечного пользователя.

- -

{{LandingPageListSubpages}}

diff --git a/files/ru/web/html/attributes/crossorigin/index.html b/files/ru/web/html/attributes/crossorigin/index.html new file mode 100644 index 0000000000..686989bb0c --- /dev/null +++ b/files/ru/web/html/attributes/crossorigin/index.html @@ -0,0 +1,130 @@ +--- +title: CORS settings attributes +slug: Web/HTML/CORS_settings_attributes +translation_of: Web/HTML/Attributes/crossorigin +--- +

В HTML5 некоторые теги поддерживают CORS, например {{ HTMLElement("img") }} или {{ HTMLElement("video") }}, имеют атрибут crossorigin (crossOrigin свойство), которое позволяет настроить CORS запросы для данных получаемых элементом. Эти атрибуты могут иметь следующие значения:

+ + + + + + + + + + + + + + + + +
Ключевое словоОписание
anonymousCORS запросы от этого элемента не будут передавать учетные данные.
use-credentialsCORS запросы от этого элемента будут передавать учетные данные.
+ +

По умолчанию (если значение атрибута не задано), CORS не используется вообще. Ключевое слово "anonymous" означает что не будет обмена учетных данных(user credentials) через cookies, client-side SSL сертификаты или HTTP аутентификацию как описано в Секции Терминология CORS спецификации.

+ +

Неправильное ключевое слово или пустая строка, будет обработано как anonymous.

+ +

Пример: crossorigin с тегом script

+ +

Используя тег {{HTMLElement("script")}} вы можете указать браузеру выполнять код https://example.com/example-framework.js без передачи user-credentials.

+ +
<script src="https://example.com/example-framework.js"
+        crossorigin="anonymous"></script>
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'infrastructure.html#cors-settings-attributes', 'CORS settings attributes')}}{{Spec2('HTML WHATWG')}} 
{{SpecName('HTML WHATWG', 'embedded-content.html#attr-img-crossorigin', 'crossorigin')}}{{Spec2('HTML WHATWG')}} 
+ +

Поддержка браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка13{{ CompatGeckoDesktop("8.0") }}11{{ CompatNo() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoDesktop("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{ CompatUnknown() }}{{ CompatGeckoMobile("8.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoMobile("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/html/cors_settings_attributes/index.html b/files/ru/web/html/cors_settings_attributes/index.html deleted file mode 100644 index 686989bb0c..0000000000 --- a/files/ru/web/html/cors_settings_attributes/index.html +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: CORS settings attributes -slug: Web/HTML/CORS_settings_attributes -translation_of: Web/HTML/Attributes/crossorigin ---- -

В HTML5 некоторые теги поддерживают CORS, например {{ HTMLElement("img") }} или {{ HTMLElement("video") }}, имеют атрибут crossorigin (crossOrigin свойство), которое позволяет настроить CORS запросы для данных получаемых элементом. Эти атрибуты могут иметь следующие значения:

- - - - - - - - - - - - - - - - -
Ключевое словоОписание
anonymousCORS запросы от этого элемента не будут передавать учетные данные.
use-credentialsCORS запросы от этого элемента будут передавать учетные данные.
- -

По умолчанию (если значение атрибута не задано), CORS не используется вообще. Ключевое слово "anonymous" означает что не будет обмена учетных данных(user credentials) через cookies, client-side SSL сертификаты или HTTP аутентификацию как описано в Секции Терминология CORS спецификации.

- -

Неправильное ключевое слово или пустая строка, будет обработано как anonymous.

- -

Пример: crossorigin с тегом script

- -

Используя тег {{HTMLElement("script")}} вы можете указать браузеру выполнять код https://example.com/example-framework.js без передачи user-credentials.

- -
<script src="https://example.com/example-framework.js"
-        crossorigin="anonymous"></script>
- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', 'infrastructure.html#cors-settings-attributes', 'CORS settings attributes')}}{{Spec2('HTML WHATWG')}} 
{{SpecName('HTML WHATWG', 'embedded-content.html#attr-img-crossorigin', 'crossorigin')}}{{Spec2('HTML WHATWG')}} 
- -

Поддержка браузерами

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Базовая поддержка13{{ CompatGeckoDesktop("8.0") }}11{{ CompatNo() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoDesktop("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{ CompatUnknown() }}{{ CompatGeckoMobile("8.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoMobile("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

Смотрите также

- - diff --git a/files/ru/web/html/element/button/index.html b/files/ru/web/html/element/button/index.html new file mode 100644 index 0000000000..ec13035e29 --- /dev/null +++ b/files/ru/web/html/element/button/index.html @@ -0,0 +1,363 @@ +--- +title: