From 310fd066e91f454b990372ffa30e803cc8120975 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 12:56:40 +0100 Subject: unslug zh-cn: move --- files/zh-cn/web/css/@viewport/height/index.html | 80 - .../zh-cn/web/css/@viewport/orientation/index.html | 110 - .../web/css/@viewport/viewport-fit/index.html | 67 - files/zh-cn/web/css/@viewport/width/index.html | 133 - files/zh-cn/web/css/@viewport/zoom/index.html | 69 - .../web/css/_colon_-moz-placeholder/index.html | 67 - files/zh-cn/web/css/_colon_any/index.html | 190 -- files/zh-cn/web/css/_colon_blank/index.html | 56 + .../index.html" | 56 - .../css/_doublecolon_-moz-placeholder/index.html | 99 - .../css/all_about_the_containing_block/index.html | 268 -- .../zh-cn/web/css/common_css_questions/index.html | 183 -- files/zh-cn/web/css/containing_block/index.html | 268 ++ .../border-radius_generator/index.html | 1599 +++++++++++ .../box-shadow_generator/index.html | 2880 ++++++++++++++++++++ .../web/css/css_background_and_borders/index.html | 155 -- .../using_css_multiple_backgrounds/index.html | 60 - .../index.html" | 1599 ----------- .../resizing_background_images/index.html | 129 + .../scaling_background_images/index.html | 129 - .../index.html | 125 + .../css_box_model/box-shadow_generator/index.html | 2880 -------------------- files/zh-cn/web/css/css_colors/index.html | 120 - .../using_multi-column_layouts/index.html | 130 + .../backwards_compatibility_of_flexbox/index.html | 121 + .../index.html" | 121 - .../css/css_flexible_box_layout/mixins/index.html | 408 --- .../index.html | 123 + .../typical_use_cases_of_flexbox/index.html | 131 + .../using_css_flexible_boxes/index.html | 408 --- .../index.html | 187 -- .../index.html" | 131 - .../index.html" | 123 - .../in_flow_and_out_of_flow/index.html | 64 + .../index.html" | 64 - files/zh-cn/web/css/css_fragmentation/index.html | 46 + .../index.html | 502 ---- .../index.html | 502 ++++ .../index.html | 593 ++++ .../index.html" | 593 ---- .../implementing_image_sprites_in_css/index.html | 49 + .../css/css_images/using_css_gradients/index.html | 717 +++++ .../consistent_list_indentation/index.html | 106 + .../using_css_counters/index.html | 120 + .../basic_concepts/index.html | 71 + .../basic_conceptsjie/index.html | 71 - .../floating_and_positioning/index.html | 132 + .../index.html" | 132 - .../adding_z-index/index.html | 158 ++ .../understanding_z_index/index.html | 47 + .../stacking_and_float/index.html | 158 ++ .../stacking_context_example_1/index.html | 133 + .../stacking_context_example_2/index.html | 142 + .../stacking_context_example_3/index.html | 190 ++ .../stacking_without_z-index/index.html | 161 ++ .../the_stacking_context/index.html | 240 ++ .../css_selectors/comparison_with_xpath/index.html | 43 - .../index.html | 68 + .../css/css_\345\210\206\347\211\207/index.html" | 46 - .../css/cssom_view/coordinate_systems/index.html | 178 ++ .../index.html" | 178 -- files/zh-cn/web/css/cursor/url/index.html | 125 - files/zh-cn/web/css/float/index.html | 247 ++ files/zh-cn/web/css/grid-template-rows/index.html | 209 ++ .../zh-cn/web/css/layout_cookbook/card/index.html | 82 + .../css/layout_cookbook/media_objects/index.html | 86 + .../\345\215\241\347\211\207/index.html" | 82 - .../index.html" | 86 - files/zh-cn/web/css/media_queries/index.html | 109 + .../media_queries/testing_media_queries/index.html | 90 + .../media_queries/using_media_queries/index.html | 412 +++ files/zh-cn/web/css/offset/index.html | 97 + files/zh-cn/web/css/overflow-wrap/index.html | 147 + .../web/css/text-decoration-thickness/index.html | 119 + files/zh-cn/web/css/timing-function/index.html | 266 -- files/zh-cn/web/css/url()/index.html | 127 + files/zh-cn/web/css/url/index.html | 127 - .../web/css/visual_formatting_model/index.html | 282 ++ files/zh-cn/web/css/word-wrap/index.html | 147 - .../web/css/\345\201\217\347\247\273/index.html" | 97 - .../index.html" | 109 - .../index.html" | 119 - .../index.html" | 209 -- 83 files changed, 11444 insertions(+), 10639 deletions(-) delete mode 100644 files/zh-cn/web/css/@viewport/height/index.html delete mode 100644 files/zh-cn/web/css/@viewport/orientation/index.html delete mode 100644 files/zh-cn/web/css/@viewport/viewport-fit/index.html delete mode 100644 files/zh-cn/web/css/@viewport/width/index.html delete mode 100644 files/zh-cn/web/css/@viewport/zoom/index.html delete mode 100644 files/zh-cn/web/css/_colon_-moz-placeholder/index.html delete mode 100644 files/zh-cn/web/css/_colon_any/index.html create mode 100644 files/zh-cn/web/css/_colon_blank/index.html delete mode 100644 "files/zh-cn/web/css/_colon_blank\347\251\272\347\231\275\344\274\252\347\261\273/index.html" delete mode 100644 files/zh-cn/web/css/_doublecolon_-moz-placeholder/index.html delete mode 100644 files/zh-cn/web/css/all_about_the_containing_block/index.html delete mode 100644 files/zh-cn/web/css/common_css_questions/index.html create mode 100644 files/zh-cn/web/css/containing_block/index.html create mode 100644 files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html create mode 100644 files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html delete mode 100644 files/zh-cn/web/css/css_background_and_borders/index.html delete mode 100644 files/zh-cn/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html delete mode 100644 "files/zh-cn/web/css/css_background_and_borders/\345\234\206\350\247\222\350\276\271\346\241\206\345\217\221\347\224\237\345\231\250/index.html" create mode 100644 files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html delete mode 100644 files/zh-cn/web/css/css_backgrounds_and_borders/scaling_background_images/index.html create mode 100644 files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html delete mode 100644 files/zh-cn/web/css/css_box_model/box-shadow_generator/index.html delete mode 100644 files/zh-cn/web/css/css_colors/index.html create mode 100644 files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html create mode 100644 files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html delete mode 100644 "files/zh-cn/web/css/css_flexible_box_layout/flexbox_\347\232\204_\345\220\221\344\270\213_\346\224\257\346\214\201/index.html" delete mode 100644 files/zh-cn/web/css/css_flexible_box_layout/mixins/index.html create mode 100644 files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html create mode 100644 files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html delete mode 100644 files/zh-cn/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html delete mode 100644 files/zh-cn/web/css/css_flexible_box_layout/using_flexbox_to_lay_out_web_applications/index.html delete mode 100644 "files/zh-cn/web/css/css_flexible_box_layout/\345\205\270\345\236\213_\347\224\250\344\276\213_\347\232\204_flexbox/index.html" delete mode 100644 "files/zh-cn/web/css/css_flexible_box_layout/\345\274\271\346\200\247\347\233\222\345\255\220\344\270\216\345\205\266\344\273\226\345\270\203\345\261\200\346\226\271\346\263\225\347\232\204\350\201\224\347\263\273/index.html" create mode 100644 files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html delete mode 100644 "files/zh-cn/web/css/css_flow_layout/\345\234\250flow\344\270\255\345\222\214flow\344\271\213\345\244\226/index.html" create mode 100644 files/zh-cn/web/css/css_fragmentation/index.html delete mode 100644 files/zh-cn/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html create mode 100644 files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html create mode 100644 files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html delete mode 100644 "files/zh-cn/web/css/css_grid_layout/\345\210\251\347\224\250css\347\275\221\346\240\274\345\270\203\345\261\200\345\256\236\347\216\260\345\270\270\347\224\250\345\270\203\345\261\200/index.html" create mode 100644 files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html create mode 100644 files/zh-cn/web/css/css_images/using_css_gradients/index.html create mode 100644 files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html create mode 100644 files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html create mode 100644 files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html delete mode 100644 files/zh-cn/web/css/css_logical_properties/basic_conceptsjie/index.html create mode 100644 files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html delete mode 100644 "files/zh-cn/web/css/css_logical_properties/\346\265\256\345\212\250\345\222\214\345\256\232\344\275\215/index.html" create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html delete mode 100644 files/zh-cn/web/css/css_selectors/comparison_with_xpath/index.html create mode 100644 files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html delete mode 100644 "files/zh-cn/web/css/css_\345\210\206\347\211\207/index.html" create mode 100644 files/zh-cn/web/css/cssom_view/coordinate_systems/index.html delete mode 100644 "files/zh-cn/web/css/cssom_view/\345\235\220\346\240\207\347\263\273/index.html" delete mode 100644 files/zh-cn/web/css/cursor/url/index.html create mode 100644 files/zh-cn/web/css/float/index.html create mode 100644 files/zh-cn/web/css/grid-template-rows/index.html create mode 100644 files/zh-cn/web/css/layout_cookbook/card/index.html create mode 100644 files/zh-cn/web/css/layout_cookbook/media_objects/index.html delete mode 100644 "files/zh-cn/web/css/layout_cookbook/\345\215\241\347\211\207/index.html" delete mode 100644 "files/zh-cn/web/css/layout_cookbook/\345\252\222\344\275\223\345\257\271\350\261\241/index.html" create mode 100644 files/zh-cn/web/css/media_queries/index.html create mode 100644 files/zh-cn/web/css/media_queries/testing_media_queries/index.html create mode 100644 files/zh-cn/web/css/media_queries/using_media_queries/index.html create mode 100644 files/zh-cn/web/css/offset/index.html create mode 100644 files/zh-cn/web/css/overflow-wrap/index.html create mode 100644 files/zh-cn/web/css/text-decoration-thickness/index.html delete mode 100644 files/zh-cn/web/css/timing-function/index.html create mode 100644 files/zh-cn/web/css/url()/index.html delete mode 100644 files/zh-cn/web/css/url/index.html create mode 100644 files/zh-cn/web/css/visual_formatting_model/index.html delete mode 100644 files/zh-cn/web/css/word-wrap/index.html delete mode 100644 "files/zh-cn/web/css/\345\201\217\347\247\273/index.html" delete mode 100644 "files/zh-cn/web/css/\345\252\222\344\275\223\346\237\245\350\257\242/index.html" delete mode 100644 "files/zh-cn/web/css/\346\226\207\346\234\254\350\243\205\351\245\260\347\272\277\345\216\232\345\272\246(\347\262\227\347\273\206)/index.html" delete mode 100644 "files/zh-cn/web/css/\347\275\221\346\240\274-\346\250\241\346\235\277-\345\210\227/index.html" (limited to 'files/zh-cn/web/css') diff --git a/files/zh-cn/web/css/@viewport/height/index.html b/files/zh-cn/web/css/@viewport/height/index.html deleted file mode 100644 index 92d33a292c..0000000000 --- a/files/zh-cn/web/css/@viewport/height/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: height -slug: Web/CSS/@viewport/height -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/height ---- -
{{CSSRef}}
- -
height CSS 属性是同时设置可视区 {{cssxref("@viewport/min-height", "min-height")}} and {{cssxref("@viewport/max-height", "max-height")}} 的简写。当你设置一个值的时候,最小高度(minimum height)和最大高度(maximum height)会被同时设置。
- -

如果提供两个值,第一个值会被设置为最小高度,第二个值将会被设置为最大高度。

- -

语法

- -
/* One value */
-height: auto;
-height: 320px;
-height: 15em;
-
-/* Two values */
-height: 320px 200px;
-
- -

合法值

- -
-
auto
-
真实生效的高度值将根据其他 CSS 属性计算得出。
-
<length>
-
一个非负的绝对或相对值。
-
<percentage>
-
一个相对于缩放因子是 1.0 的初始可视区宽高的百分比值,水平和垂直方向的长度分别计算。不能是负值。
-
- -

正式定义

- -

{{cssinfo}}

- -

正式语法

- -
{{csssyntax}}
- -

示例

- -

设置最小和最大高度

- -
@viewport {
-  height: 500px;
-}
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Device', '#descdef-viewport-height', '"height" descriptor')}}{{Spec2('CSS3 Device')}}初始定义
- -

浏览器兼容性

- - - -

{{Compat("css.at-rules.viewport.height")}}

- -

同时查看

- - diff --git a/files/zh-cn/web/css/@viewport/orientation/index.html b/files/zh-cn/web/css/@viewport/orientation/index.html deleted file mode 100644 index 11519cee6e..0000000000 --- a/files/zh-cn/web/css/@viewport/orientation/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: orientation -slug: Web/CSS/@viewport/orientation -tags: - - CSS - - CSS Description -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/orientation ---- -
{{CSSRef}}
- -

摘要

- -

此 orientation CSS 描述符控制由{{cssxref("@viewport")}}定义文档的方向。

- -

通过设备的倾斜摆动情况来决定文档显示的方向,作者可以通过设置这个描述符来抑制方向的变化{{cssinfo}}

- -

语法

- -
/* Keyword values */
-orientation: auto;
-orientation: portrait;/*锁定为纵向*/
-orientation: landscape;/* 锁定为横向*/
-
- -

取值

- -
-
auto
-
用户代理将文档的方向设置为自动,通常基于设备的定位由加速度传感器 (如果设备具有这种硬件传感器),但是用户控制,OS 级别的"锁方向"往往会优先于加速度传感器的设置。
-
portrait
-
文档被锁定为纵向。
-
landscape
-
文档被锁定为横向。
-
- -

标准语法

- -
{{csssyntax}}
- -

规范

- - - - - - - - - - - - - - - - -
规范标准注释
{{SpecName('CSS3 Device', '#the-lsquoorientationrsquo-descriptor', '"orientation" descriptor')}}{{Spec2('CSS3 Device')}}Initial definition
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}10 {{property_prefix("-ms")}}{{CompatNo}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}8 {{property_prefix("-o")}}{{CompatUnknown}}
-
diff --git a/files/zh-cn/web/css/@viewport/viewport-fit/index.html b/files/zh-cn/web/css/@viewport/viewport-fit/index.html deleted file mode 100644 index 2716ef1d6f..0000000000 --- a/files/zh-cn/web/css/@viewport/viewport-fit/index.html +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: viewport-fit -slug: Web/CSS/@viewport/viewport-fit -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/viewport-fit ---- -
{{CSSRef}} {{Draft}} {{SeeCompatTable}}
- -

viewport-fit CSS {{CSSxRef("@viewport")}}  {{Glossary("Descriptor (CSS)", "descriptor")}} 是为了控制文档是如何填充满屏幕的。

- -

语法

- -
/* 关键值*/
-viewport-fit: auto;
-viewport-fit: contain;
-viewport-fit: cover;
-
- -

属性值

- -
-
auto
-
此值不影响初始布局视图端口,并且整个web页面都是可查看的。
-
contain
-
视图端口按比例缩放,以适合显示内嵌的最大矩形。
-
cover
-
视图端口被缩放以填充设备显示。强烈建议使用 safe area inset 变量,以确保重要内容不会出现在显示之外。
-
- -

形式语法

- -
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
- -

注意

- -

在使用 viewport-fit 描述符时,必须记住并不是所有的设备显示都是矩形的,因此应该使用safe area inset 变量

- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("CSS Round Display", "#viewport-fit-descriptor", '"viewport-fit" descriptor')}}{{Spec2("CSS Round Display")}}Initial definition.
- -

浏览器兼容性

- - - -

{{Compat("css.at-rules.viewport.viewport-fit")}}

- -

另请参见

- - diff --git a/files/zh-cn/web/css/@viewport/width/index.html b/files/zh-cn/web/css/@viewport/width/index.html deleted file mode 100644 index ed5c585a7e..0000000000 --- a/files/zh-cn/web/css/@viewport/width/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: width -slug: Web/CSS/@viewport/width -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/width ---- -
{{CSSRef}}
- -

The width CSS descriptor is shorthand for setting both the min-width and the max-width descriptors of the viewport. By providing one viewport length value, that value will determine both the min-width and the max-width to the value provided.

- -

If two viewport values are provided the first value will be set to the min-width and the second value will be set max-width.

- -

Syntax

- -
/* An example with one viewport value: */
-@viewport {
-    width: 320px;
-}
-
-/* An example with two viewport values: */
-@viewport {
-    width: 320px, 120px;
-}
-
-
- - - -

Values

- -
-
auto
-
The used value is calculated from the other CSS descriptors' values.
-
<length>
-
A non-negative absolute or relative length.
-
<percentage>
-
A percentage value relative to the width or height of the initial viewport at zoom factor 1.0, for horizontal and vertical lengths respectively. Must be non-negative.
-
- -

Formal syntax

- -
auto | <length> | <percentage>
- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Device', '#descdef-viewport-min-width', '"min-width" descriptor')}}{{Spec2('CSS3 Device')}}Initial definition
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support29 (behind a flag){{CompatNo}}10 {{property_prefix("-ms")}}11.10
- Removed in 15
- Reintroduced behind a flag in 16
{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support - - - - - - -
4.4
-
- - - - - - -
29
-
{{CompatNo}}10{{property_prefix("-ms")}}11.10
- Removed in 15
- Reintroduced behind a flag in 16
{{CompatNo}}
-
diff --git a/files/zh-cn/web/css/@viewport/zoom/index.html b/files/zh-cn/web/css/@viewport/zoom/index.html deleted file mode 100644 index 894e8a6c73..0000000000 --- a/files/zh-cn/web/css/@viewport/zoom/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: zoom -slug: Web/CSS/@viewport/zoom -tags: - - CSS - - CSS Descriptor -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/zoom ---- -
{{ CSSRef }}
- -

zoom CSS 属性会根据 {{cssxref("@viewport")}} 来初始化一个缩放因数。

- -

当设置1.0 或 100%时表示不缩放。更大的值放大,更小的值缩小。

- -

{{cssinfo}}

- -

语法

- -
/* Keyword value */
-zoom: auto;
-
-/* <number> values */
-zoom: 0.8;
-zoom: 2.0;
-
-/* <percentage> values */
-zoom: 150%;
-
- -

- -
-
auto
-
根据`viewport`来既定当前标签的缩放。
-
<number>
-
必须是一个非负数。1表示没有缩放,大于1表示放大的倍数,小于1亦然。
-
<percentage>
-
必须是一个非负的百分比。以100%为基础进行缩放。
-
- -

形式语法

- -
{{csssyntax}}
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Device', '#zoom-desc', '"zoom" descriptor')}}{{Spec2('CSS3 Device')}}Initial specification
- -

浏览器兼容

- - - -

{{Compat("css.at-rules.viewport.zoom")}}

diff --git a/files/zh-cn/web/css/_colon_-moz-placeholder/index.html b/files/zh-cn/web/css/_colon_-moz-placeholder/index.html deleted file mode 100644 index f7493e4757..0000000000 --- a/files/zh-cn/web/css/_colon_-moz-placeholder/index.html +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: ':-moz-placeholder' -slug: 'Web/CSS/:-moz-placeholder' -tags: - - CSS - - CSS Pseudo-class - - CSS Reference - - Non-standard -translation_of: 'Web/CSS/:placeholder-shown' -translation_of_original: 'Web/CSS/:-moz-placeholder' ---- -

 

- -
提示: 在Firefox 19+版本中 :-moz-placeholder 伪类将被 {{ cssxref('::-moz-placeholder') }} 伪元素所替代.
- -
Note: The CSSWG have decided to introduce :placeholder-shown. This functionality will be reintroduced in Gecko at some point in the future, unprefixed and under the new name.  {{bug(1069012)}}
- -

{{ CSSRef() }}{{Non-standard_header}}{{ gecko_minversion_header("2.0") }}

- -

摘要

- -

 :-moz-placeholder伪类控制元素所显示的文字占位符文字占位符. 它允许开发者/设计师改变文字占位符样式. 默认的文字占位符颜色为浅灰色,当你的表单背景色为类似的颜色时它可能效果并不是很明显,那么你就可以使用这个伪类来改变文字占位符的颜色.

- -

示例

- -

这个示例将文字占位符改变为了绿色.

- -
<!doctype html>
-<html>
-<head>
-  <title>Placeholder demo</title>
-  <style type="text/css">
-    input:-moz-placeholder {
-      color: green;
-    }
-  </style>
-</head>
-<body>
-  <input id="test" placeholder="Placeholder text!">
-</body>
-</html>
-
- -

查看这个示例.

- -

溢出

- -

在手机等设备上搜索框和表单字段经常会缩的很短,有时输入框并不能完全显示文字占位符,那么它便会被生硬的"切断".为了防止出现这种难看的效果,可以使用CSS text-overflow: ellipsis; 来省略一中间部分文字.

- -
input[placeholder] { text-overflow: ellipsis; }
-::-moz-placeholder { text-overflow: ellipsis; } /* firefox 19+ */
-input:-moz-placeholder { text-overflow: ellipsis; }
-
- -

It was David Walsh, the man on fire who introduced this to a lot of designers. Placeholders and Overflow.

- -

Bugzilla

- -

{{ Bug(457801) }}

- -

See also

- - diff --git a/files/zh-cn/web/css/_colon_any/index.html b/files/zh-cn/web/css/_colon_any/index.html deleted file mode 100644 index e9f8527a79..0000000000 --- a/files/zh-cn/web/css/_colon_any/index.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: ':any' -slug: 'Web/CSS/:any' -tags: - - CSS - - 伪类选择器 - - 实验性 -translation_of: 'Web/CSS/:is' -translation_of_original: 'Web/CSS/:any' ---- -
{{CSSRef}}{{SeeCompatTable}}
- -

概要

- -

The :any() pseudo-class lets you quickly construct sets of similar selectors by establishing groups from which any of the included items will match. This is an alternative to having to repeat the entire selector for the one item that varies.

- -

译文:any()伪类可以让您快速构建类似的选择器集合,通过建立包含所有包含项的组来匹配。这是另一种选择,它必须重复整个选择器,因为其中一个项目是不同的。

- -
Note : This pseudo-class is in progress to be standardized in CSS Selectors Level 4 under the name :matches(). It is likely that the syntax and name of :-vendor-any() will be changed to reflect it in the near future.
- -
注意:这个伪类正在CSS选择器第4级按照名称:matches()进行标准化。很可能的语法和名称:- vendor-any()将在不久的将来被更改以反映它。
- -

语法

- -
{{csssyntax}}
- -

- -
-
selector
-
选择器。这可以是由 CSS 3 简单选择器 组成的简单选择器或多重选择器,并且可以包含后代组合器。
-
- -
注意:选择器可以包含伪元素,并且仅允许的组合器是后代组合器。
- -

例子

- -

举个例子,如以下 CSS:

- -
/* 3 deep (or more) unordered lists use a 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 deep (or more) unordered lists use a 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;
-}
- -

但是,不能写成这样(详见the section on performance):

- -
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) :-moz-any(ul, menu, dir) {
-  list-style-type: square;
-}
- -

Notes

- -

译文: 这个伪类选择器会在处理 HTML5 的 sections and headings 中尤其有用。因为 {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, 和 {{HTMLElement("nav")}} 可以被嵌套,如果不使用  :any() ,为了去匹配这些标签来给予样式会变得困难。

- -

举个例子,当不使用 :any() ,给予不同的 DOM  结点层次深度下的所有的 {{HTMLElement("h1")}}  的元素样式时,将会变得特别的复杂。

- -
/* Level 0 */
-h1 {
-  font-size: 30px;
-}
-/* Level 1 */
-section h1, article h1, aside h1, nav h1 {
-  font-size: 25px;
-}
-/* Level 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;
-}
-/* Level 3 */
-/* ... don't even think about it*/
-
- -

然而,通过使用  :any() ,这将变得很简单:

- -
/* Level 0 */
-h1 {
-  font-size: 30px;
-}
-/* Level 1 */
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 25px;
-}
-/* Level 2 */
-:-moz-any(section, article, aside, nav)
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 20px;
-}
-/* Level 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, Class, 标签选择器作为最右边的选择器要来的慢。

- -

例如:

- -
.a > :-moz-any(.b, .c)
-
- -

会比下面的表达式慢

- -
.a > .b, .a > .c
-
- -

而下面的表达式将会是最快的

- -
:-moz-any(.a, .d) > .b, :-moz-any(.a, .d) > .c
-
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{CompatGeckoDesktop("2")}}{{property_prefix("-moz")}}12.0 (534.30){{property_prefix("-webkit")}}{{CompatUnknown}}{{CompatUnknown}}5
- {{property_prefix("-webkit")}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}{{property_prefix("-webkit")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}5
- {{property_prefix("-webkit")}}
-
diff --git a/files/zh-cn/web/css/_colon_blank/index.html b/files/zh-cn/web/css/_colon_blank/index.html new file mode 100644 index 0000000000..adcaa5c998 --- /dev/null +++ b/files/zh-cn/web/css/_colon_blank/index.html @@ -0,0 +1,56 @@ +--- +title: ':blank' +slug: 'Web/CSS/:blank空白伪类' +tags: + - CSS + - CSS 选择器 + - 伪类 +translation_of: 'Web/CSS/:blank' +--- +

{{CSSRef}}{{Draft}}{{SeeCompatTable}}

+ +
+

注意:使用 :blank 选择器被认为尚有一定风险,CSSWG 正在持续改进它。

+ +

详见 CSSWG issue #1967

+
+ +

:blank CSS 伪类选择器选择用户输入为空的输入框,如 {{HTMLElement("input")}} 和 {{HTMLElement("textarea")}})。

+ +

语法

+ +
{{CSSSyntax}}
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("CSS4 Selectors", "#blank-pseudo", ":blank")}}{{Spec2("CSS4 Selectors")}}Initial definition.
+ +

浏览器兼容性

+ + + + + +

{{Compat("css.selectors.blank")}}

+ +

参见

+ + diff --git "a/files/zh-cn/web/css/_colon_blank\347\251\272\347\231\275\344\274\252\347\261\273/index.html" "b/files/zh-cn/web/css/_colon_blank\347\251\272\347\231\275\344\274\252\347\261\273/index.html" deleted file mode 100644 index adcaa5c998..0000000000 --- "a/files/zh-cn/web/css/_colon_blank\347\251\272\347\231\275\344\274\252\347\261\273/index.html" +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: ':blank' -slug: 'Web/CSS/:blank空白伪类' -tags: - - CSS - - CSS 选择器 - - 伪类 -translation_of: 'Web/CSS/:blank' ---- -

{{CSSRef}}{{Draft}}{{SeeCompatTable}}

- -
-

注意:使用 :blank 选择器被认为尚有一定风险,CSSWG 正在持续改进它。

- -

详见 CSSWG issue #1967

-
- -

:blank CSS 伪类选择器选择用户输入为空的输入框,如 {{HTMLElement("input")}} 和 {{HTMLElement("textarea")}})。

- -

语法

- -
{{CSSSyntax}}
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("CSS4 Selectors", "#blank-pseudo", ":blank")}}{{Spec2("CSS4 Selectors")}}Initial definition.
- -

浏览器兼容性

- - - - - -

{{Compat("css.selectors.blank")}}

- -

参见

- - diff --git a/files/zh-cn/web/css/_doublecolon_-moz-placeholder/index.html b/files/zh-cn/web/css/_doublecolon_-moz-placeholder/index.html deleted file mode 100644 index 3c08f433c8..0000000000 --- a/files/zh-cn/web/css/_doublecolon_-moz-placeholder/index.html +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: '::-moz-placeholder' -slug: 'Web/CSS/::-moz-placeholder' -tags: - - CSS - - CSS Pseudo-class - - CSS Reference - - Non-standard -translation_of: 'Web/CSS/::placeholder' -translation_of_original: 'Web/CSS/::-moz-placeholder' ---- -
{{Non-standard_header}}{{CSSRef}}
- -
提示: {{cssxref('::-moz-placeholder')}} 伪元素在Firefox 19+替代了之前的 :-moz-placeholder 伪类.
- -
{{gecko_minversion_header("19.0")}}
- -

摘要

- -

 ::-moz-placeholder 伪元素控制元素所显示的文字占位符.它允许开发者/设计师改变文字占位符的样式.默认的文字占位符为浅灰色,当你的表单背景色为类似的颜色时它可能效果并不是很明显,那么你就可以使用这个伪类来改变文字占位符的颜色.

- -

示例

- -

HTML 内容

- -
<input id="test" placeholder="Placeholder text!">
- -

CSS 内容

- -
input::-moz-placeholder {
-  color: green;
-}
- -

{{EmbedLiveSample('%E7%A4%BA%E4%BE%8B', '100%', 100)}}

- -

 

- -

浏览器兼容性

- -

{{CompatibilityTable}}

- - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("19.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
- - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatGeckoMobile("19.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
- -

[1] Firefox 对placeholder文本默认应用{{cssxref("opacity")}}:0.54。详见{{Bug("556145")}}。大多数主流浏览器目前不会对placeholder文本伪元素或者伪类应用默认样式。

- -

Gecko 此前将本属性视为 {{cssxref(":-moz-placeholder")}}。详见 {{Bug("737786")}}.

- -

See also

- - diff --git a/files/zh-cn/web/css/all_about_the_containing_block/index.html b/files/zh-cn/web/css/all_about_the_containing_block/index.html deleted file mode 100644 index bf35aa8c04..0000000000 --- a/files/zh-cn/web/css/all_about_the_containing_block/index.html +++ /dev/null @@ -1,268 +0,0 @@ ---- -title: 布局和包含块 -slug: Web/CSS/All_About_The_Containing_Block -tags: - - CSS - - CSS Position - - Containers - - Guide - - Layout - - Position - - Style - - blocks - - containing block - - size -translation_of: Web/CSS/Containing_block ---- -

{{cssref}}

- -

一个元素的尺寸和位置经常受其包含块(containing block)的影响。大多数情况下,包含块就是这个元素最近的祖先块元素内容区,但也不是总是这样。在本文中,我们来过一遍确定包含块的所有因素。

- -

当一个客户端代理(比如说浏览器)展示一个文档的时候,对于每一个元素,它都产生了一个盒子。每一个盒子都被划分为四个区域:

- -
    -
  1. 内容区
  2. -
  3. 内边距区
  4. -
  5. 边框区
  6. -
  7. 外边距区
  8. -
- -

Diagram of the box model

- -

许多开发者认为一个元素的包含块就是他的父元素的内容区。但事实并非如此。接下来让我们来看看,确定元素包含块的因素都有哪些。

- -

包含块的影响

- -

在学习如何确定元素包含块之前,先了解一下它的重要性。

- -

元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 {{cssxref("width")}}, {{cssxref("height")}}, {{cssxref("padding")}}, {{cssxref("margin")}},绝对定位元素的偏移值 (比如 {{cssxref("position")}} 被设置为 absolute 或 fixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。

- -

确定包含块

- -

确定一个元素的包含块的过程完全依赖于这个元素的 {{cssxref("position")}} 属性:

- -
    -
  1. 如果 position 属性为 static 、 relative 或 sticky,包含块可能由它的最近的祖先块元素(比如说inline-block, block 或 list-item元素)的内容区的边缘组成,也可能会建立格式化上下文(比如说 a table container, flex container, grid container, 或者是 the block container 自身)。
  2. -
  3. 如果 position 属性为 absolute ,包含块就是由它的最近的 position 的值不是 static (也就是值为fixed, absolute, relative 或 sticky)的祖先元素的内边距区的边缘组成。
  4. -
  5. 如果 position 属性是 fixed,在连续媒体的情况下(continuous media)包含块是 {{glossary("viewport")}} ,在分页媒体(paged media)下的情况下包含块是分页区域(page area)。
  6. -
  7. 如果 position 属性是 absolutefixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的: -
      -
    1.  {{cssxref("transform")}} 或 {{cssxref("perspective")}} 的值不是 none
    2. -
    3.  {{cssxref("will-change")}} 的值是 transform 或 perspective
    4. -
    5.  {{cssxref("filter")}} 的值不是 none 或 will-change 的值是 filter(只在 Firefox 下生效).
    6. -
    7.  {{cssxref("contain")}} 的值是 paint (例如: contain: paint;)
    8. -
    -
  8. -
- -
-

注意: 根元素(<html>)所在的包含块是一个被称为初始包含块的矩形。他的尺寸是视口 viewport (for continuous media) 或分页媒体 page media (for paged media).

-
- -

根据包含块计算百分值

- -

如上所述,如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:

- -
    -
  1. 要计算 {{cssxref("height")}} {{cssxref("top")}} 及 {{cssxref("bottom")}} 中的百分值,是通过包含块的 height 的值。如果包含块的 height 值会根据它的内容变化,而且包含块的 position 属性的值被赋予 relativestatic ,那么,这些值的计算值为 auto
  2. -
  3. 要计算 {{cssxref("width")}}, {{cssxref("left")}}, {{cssxref("right")}}, {{cssxref("padding")}}, {{cssxref("margin")}} 这些属性由包含块的 width 属性的值来计算它的百分值。
  4. -
- -

示例

- -

接下来的示例,都使用如下 HTML 代码:

- -
<body>
-  <section>
-    <p>This is a paragraph!</p>
-  </section>
-</body>
- -

下面的示例,只有 CSS 不同。

- -

Example 1

- -

这个示例中,P 标签设置为静态定位,所以它的包含块为 <section> ,因为距离最近的父节点即是她的包含块。

- - - -
body {
-  background: beige;
-}
-
-section {
-  display: block;
-  width: 400px;
-  height: 160px;
-  background: lightgray;
-}
-
-p {
-  width: 50%;   /* == 400px * .5 = 200px */
-  height: 25%;  /* == 160px * .25 = 40px */
-  margin: 5%;   /* == 400px * .05 = 20px */
-  padding: 5%;  /* == 400px * .05 = 20px */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_1','100%','300')}}

- -

Example 2

- -

在这个示例中,P 标签的包含块为 <body> 元素,因为 <section> 不再是一个块容器,所以并没有形成一个格式上下文。

- - - -
body {
-  background: beige;
-}
-
-section {
-  display: inline;
-  background: lightgray;
-}
-
-p {
-  width: 50%;     /* == half the body's width */
-  height: 200px;  /* Note: a percentage would be 0 */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_2','100%','300')}}

- -

Example 3

- -

这个示例中,P 元素的包含块是 <section>,因为 <section> 的 position 为 absolute 。P 元素的百分值会受其包含块的 padding 所影响。不过,如果包含块的 {{cssxref("box-sizing")}} 值设置为 border-box ,就没有这个问题。

- - - -
body {
-  background: beige;
-}
-
-section {
-  position: absolute;
-  left: 30px;
-  top: 30px;
-  width: 400px;
-  height: 160px;
-  padding: 30px 20px;
-  background: lightgray;
-}
-
-p {
-  position: absolute;
-  width: 50%;   /* == (400px + 20px + 20px) * .5 = 220px */
-  height: 25%;  /* == (160px + 30px + 30px) * .25 = 55px */
-  margin: 5%;   /* == (400px + 20px + 20px) * .05 = 22px */
-  padding: 5%;  /* == (400px + 20px + 20px) * .05 = 22px */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_3','100%','300')}}

- -

Example 4

- -

这个示例中,P 元素的 position 为 fixed,所以它的包含块就是初始包含块(在屏幕上,也就是 viewport)。这样的话,P 元素的尺寸大小,将会随着浏览器窗框大小的变化,而变化。

- - - -
body {
-  background: beige;
-}
-
-section {
-  width: 400px;
-  height: 480px;
-  margin: 30px;
-  padding: 15px;
-  background: lightgray;
-}
-
-p {
-  position: fixed;
-  width: 50%;   /* == (50vw - (width of vertical scrollbar)) */
-  height: 50%;  /* == (50vh - (height of horizontal scrollbar)) */
-  margin: 5%;   /* == (5vw - (width of vertical scrollbar)) */
-  padding: 5%;  /* == (5vw - (width of vertical scrollbar)) */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_4','100%','300')}}

- -

Example 5

- -

这个示例中,P 元素的 position 为 absolute,所以它的包含块是 <section>,也就是距离它最近的一个 transform 值不为 none 的父元素。

- - - -
body {
-  background: beige;
-}
-
-section {
-  transform: rotate(0deg);
-  width: 400px;
-  height: 160px;
-  background: lightgray;
-}
-
-p {
-  position: absolute;
-  left: 80px;
-  top: 30px;
-  width: 50%;   /* == 200px */
-  height: 25%;  /* == 40px */
-  margin: 5%;   /* == 20px */
-  padding: 5%;  /* == 20px */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_5','100%','300')}}

- -

另见

- - diff --git a/files/zh-cn/web/css/common_css_questions/index.html b/files/zh-cn/web/css/common_css_questions/index.html deleted file mode 100644 index 0e0593054b..0000000000 --- a/files/zh-cn/web/css/common_css_questions/index.html +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: CSS 常见问题 -slug: Web/CSS/Common_CSS_Questions -translation_of: Learn/CSS/Howto/CSS_FAQ ---- -

为什么我有效的CSS没有正确的渲染?

- -

浏览器使用DOCTYPE声明来选择是否使用更符合Web标准或兼容旧浏览器的bug的模式。在你的HTML的开始使用一个正确的和现代的DOCTYPE声明将改善浏览器标准执行。

- -

现代浏览器主要有两种渲染模式:

- - - -

基于Gecko的浏览器, 有三分之一 Almost Standards Mode, 只有一些小怪癖。

- -

这是最常用的触发标准模式或准标准模式的DOCTYPE声明列表:

- -
<!DOCTYPE html> /* 这一行是 HTML5 的 doctype 声明。,使用该声明会使现代浏览器使用
-                   HTML5 解析器处理页面,这是推荐的 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">
-
- -

为什么我有效的css完全没有被渲染? 

- -

为了使浏览器渲染样式文件,CSS样式表必须用text/css的MIME。如果Web服务器不服务于这种类型,则CSS也不会被应用。

- -

id和class有什么不同?

- -

HTML元素可以拥有一个id/或class属性。 id属性为元素指定应用一个有效名称,只能有一个具有该名称的元素。class属性指定一个类名的元素,而这个名称可以被页面内的许多元素被使用。 CSS允许你可以对特定的id和/或类名的元素应用样式。
-
- 当你想给一个特定元素或块应用样式规则时就使用ID选择符。此样式将只用于与该特定id匹配的元素。

- -


- 当你想要将样式规则应用于多个块和元素时,你应该使用class选择符。

- -

较少样式的样式表通常性能更高。因此建议尽可能多地使用类, 保留id作为特定用途 (比如链接label标签和form元素或者为语义上唯一的元素应用样式)。

- -

查看 CSS selectors

- -

我如何还原属性的默认值?

- -

最初CSS没有提供“defaule”关键字和还原默认属性的值,唯一途径是显式地重新声明该属性。

- -

与CSS2相比,已经发生了改变。 关键字 initial 现在是一个有效的CSS属性。它将给定的CSS属性值重置为默认值。

- -

我如何才可以从一个样式中衍生出另一种样式?

- -

CSS 不允许这样做。(See Eric Meyer's note about the Working Group's stance). 但是,将多个类分配给单个元素,可以提供相同的效果。

- -

我该如何给一个元素分配多个类?

- -

HTML元素可以通过列出的类属性,用空格分开它们。

- -
<style type="text/css">
-.news { background: black; color: white; }
-.today { font-weight: bold; }
-</style>
-
-<div class="news today">
-... content of today's news ...
-</div>
-
- -

如果相同的属性中声明的规则,解决冲突首先通过特异性,然后根据CSS声明的顺序。在class属性类的顺序是不相关的。

- -

为什么我的样式规则不能正确地工作?

- -

在语法上正确的样式规则可能在某些情况下不适用。你可以使用 DOM Inspector's CSS Style Rules 调试这类问题。 下面列出了最常见的忽略样式规则的实例:

- -

HTML元素层次结构

- -

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.

- -

显式重定义样式规则

- -

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.

- -

使用便捷属性

- -

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

使用 * 选择器

- -

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.

- -

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

- -

 -moz-*, -ms-*, -webkit-*, -o-* 以及 -khtml-* 属性有什么用?

- -

These  properties, called prefixed properties, are extension 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 evolve.

- -

Please see the Mozilla CSS Extensions page for more information on the Mozilla-prefixed CSS properties.

- -

z-index 属性与定位有什么关系?

- -

z-index属性指定了元素的栈序。

- -

有较高z-index/栈序的元素总是在有着较低z-index/栈序的元素之前。

- -

z-index只会在有着指定position (position:absolute, position:relative, or position:fixed)的元素上工作。

diff --git a/files/zh-cn/web/css/containing_block/index.html b/files/zh-cn/web/css/containing_block/index.html new file mode 100644 index 0000000000..bf35aa8c04 --- /dev/null +++ b/files/zh-cn/web/css/containing_block/index.html @@ -0,0 +1,268 @@ +--- +title: 布局和包含块 +slug: Web/CSS/All_About_The_Containing_Block +tags: + - CSS + - CSS Position + - Containers + - Guide + - Layout + - Position + - Style + - blocks + - containing block + - size +translation_of: Web/CSS/Containing_block +--- +

{{cssref}}

+ +

一个元素的尺寸和位置经常受其包含块(containing block)的影响。大多数情况下,包含块就是这个元素最近的祖先块元素内容区,但也不是总是这样。在本文中,我们来过一遍确定包含块的所有因素。

+ +

当一个客户端代理(比如说浏览器)展示一个文档的时候,对于每一个元素,它都产生了一个盒子。每一个盒子都被划分为四个区域:

+ +
    +
  1. 内容区
  2. +
  3. 内边距区
  4. +
  5. 边框区
  6. +
  7. 外边距区
  8. +
+ +

Diagram of the box model

+ +

许多开发者认为一个元素的包含块就是他的父元素的内容区。但事实并非如此。接下来让我们来看看,确定元素包含块的因素都有哪些。

+ +

包含块的影响

+ +

在学习如何确定元素包含块之前,先了解一下它的重要性。

+ +

元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 {{cssxref("width")}}, {{cssxref("height")}}, {{cssxref("padding")}}, {{cssxref("margin")}},绝对定位元素的偏移值 (比如 {{cssxref("position")}} 被设置为 absolute 或 fixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。

+ +

确定包含块

+ +

确定一个元素的包含块的过程完全依赖于这个元素的 {{cssxref("position")}} 属性:

+ +
    +
  1. 如果 position 属性为 static 、 relative 或 sticky,包含块可能由它的最近的祖先块元素(比如说inline-block, block 或 list-item元素)的内容区的边缘组成,也可能会建立格式化上下文(比如说 a table container, flex container, grid container, 或者是 the block container 自身)。
  2. +
  3. 如果 position 属性为 absolute ,包含块就是由它的最近的 position 的值不是 static (也就是值为fixed, absolute, relative 或 sticky)的祖先元素的内边距区的边缘组成。
  4. +
  5. 如果 position 属性是 fixed,在连续媒体的情况下(continuous media)包含块是 {{glossary("viewport")}} ,在分页媒体(paged media)下的情况下包含块是分页区域(page area)。
  6. +
  7. 如果 position 属性是 absolutefixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的: +
      +
    1.  {{cssxref("transform")}} 或 {{cssxref("perspective")}} 的值不是 none
    2. +
    3.  {{cssxref("will-change")}} 的值是 transform 或 perspective
    4. +
    5.  {{cssxref("filter")}} 的值不是 none 或 will-change 的值是 filter(只在 Firefox 下生效).
    6. +
    7.  {{cssxref("contain")}} 的值是 paint (例如: contain: paint;)
    8. +
    +
  8. +
+ +
+

注意: 根元素(<html>)所在的包含块是一个被称为初始包含块的矩形。他的尺寸是视口 viewport (for continuous media) 或分页媒体 page media (for paged media).

+
+ +

根据包含块计算百分值

+ +

如上所述,如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:

+ +
    +
  1. 要计算 {{cssxref("height")}} {{cssxref("top")}} 及 {{cssxref("bottom")}} 中的百分值,是通过包含块的 height 的值。如果包含块的 height 值会根据它的内容变化,而且包含块的 position 属性的值被赋予 relativestatic ,那么,这些值的计算值为 auto
  2. +
  3. 要计算 {{cssxref("width")}}, {{cssxref("left")}}, {{cssxref("right")}}, {{cssxref("padding")}}, {{cssxref("margin")}} 这些属性由包含块的 width 属性的值来计算它的百分值。
  4. +
+ +

示例

+ +

接下来的示例,都使用如下 HTML 代码:

+ +
<body>
+  <section>
+    <p>This is a paragraph!</p>
+  </section>
+</body>
+ +

下面的示例,只有 CSS 不同。

+ +

Example 1

+ +

这个示例中,P 标签设置为静态定位,所以它的包含块为 <section> ,因为距离最近的父节点即是她的包含块。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  display: block;
+  width: 400px;
+  height: 160px;
+  background: lightgray;
+}
+
+p {
+  width: 50%;   /* == 400px * .5 = 200px */
+  height: 25%;  /* == 160px * .25 = 40px */
+  margin: 5%;   /* == 400px * .05 = 20px */
+  padding: 5%;  /* == 400px * .05 = 20px */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_1','100%','300')}}

+ +

Example 2

+ +

在这个示例中,P 标签的包含块为 <body> 元素,因为 <section> 不再是一个块容器,所以并没有形成一个格式上下文。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  display: inline;
+  background: lightgray;
+}
+
+p {
+  width: 50%;     /* == half the body's width */
+  height: 200px;  /* Note: a percentage would be 0 */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_2','100%','300')}}

+ +

Example 3

+ +

这个示例中,P 元素的包含块是 <section>,因为 <section> 的 position 为 absolute 。P 元素的百分值会受其包含块的 padding 所影响。不过,如果包含块的 {{cssxref("box-sizing")}} 值设置为 border-box ,就没有这个问题。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  position: absolute;
+  left: 30px;
+  top: 30px;
+  width: 400px;
+  height: 160px;
+  padding: 30px 20px;
+  background: lightgray;
+}
+
+p {
+  position: absolute;
+  width: 50%;   /* == (400px + 20px + 20px) * .5 = 220px */
+  height: 25%;  /* == (160px + 30px + 30px) * .25 = 55px */
+  margin: 5%;   /* == (400px + 20px + 20px) * .05 = 22px */
+  padding: 5%;  /* == (400px + 20px + 20px) * .05 = 22px */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_3','100%','300')}}

+ +

Example 4

+ +

这个示例中,P 元素的 position 为 fixed,所以它的包含块就是初始包含块(在屏幕上,也就是 viewport)。这样的话,P 元素的尺寸大小,将会随着浏览器窗框大小的变化,而变化。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  width: 400px;
+  height: 480px;
+  margin: 30px;
+  padding: 15px;
+  background: lightgray;
+}
+
+p {
+  position: fixed;
+  width: 50%;   /* == (50vw - (width of vertical scrollbar)) */
+  height: 50%;  /* == (50vh - (height of horizontal scrollbar)) */
+  margin: 5%;   /* == (5vw - (width of vertical scrollbar)) */
+  padding: 5%;  /* == (5vw - (width of vertical scrollbar)) */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_4','100%','300')}}

+ +

Example 5

+ +

这个示例中,P 元素的 position 为 absolute,所以它的包含块是 <section>,也就是距离它最近的一个 transform 值不为 none 的父元素。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  transform: rotate(0deg);
+  width: 400px;
+  height: 160px;
+  background: lightgray;
+}
+
+p {
+  position: absolute;
+  left: 80px;
+  top: 30px;
+  width: 50%;   /* == 200px */
+  height: 25%;  /* == 40px */
+  margin: 5%;   /* == 20px */
+  padding: 5%;  /* == 20px */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_5','100%','300')}}

+ +

另见

+ + diff --git a/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html b/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html new file mode 100644 index 0000000000..b9f50d5332 --- /dev/null +++ b/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html @@ -0,0 +1,1599 @@ +--- +title: 圆角边框生成器 +slug: Web/CSS/CSS_Background_and_Borders/圆角边框发生器 +translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator +--- +

使用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/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html b/files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html new file mode 100644 index 0000000000..3fb264bc40 --- /dev/null +++ b/files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html @@ -0,0 +1,2880 @@ +--- +title: Box-shadow generator +slug: Web/CSS/CSS_Box_Model/Box-shadow_generator +translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator +--- +

这个可视化工具可以帮助你生成一个元素的CSS{{cssxref("box-shadow")}}相关代码,添加box shadow效果到你的CSS对象上。

+ +
+

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"> 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"> Class element properties </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 Code </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 = 'shadow ' + 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', '') }}
+ +

Related Tool: Box Shadow CSS Generator

diff --git a/files/zh-cn/web/css/css_background_and_borders/index.html b/files/zh-cn/web/css/css_background_and_borders/index.html deleted file mode 100644 index 96d540eedd..0000000000 --- a/files/zh-cn/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 背景与边框 是 CSS中描述元素背景与边框的组件。边框的实现方式包含直线、图片。盒模型可以具有单个或多个背景、圆角以及阴影。

- -

参考

- -

CSS 属性

- -
- -
- -

导航

- -
-
应用CSS多重背景
-
阐述设置元素背景方法以及背景、元素之间的交互方式
-
缩放背景图片
-
阐述如何通过拉伸、重复使背景图片覆盖或不全部覆盖元素的背景区域,更改背景图片的呈现方式。
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('CSS3 Backgrounds') }}{{ Spec2('CSS3 Backgrounds') }} 
{{SpecName('CSS2.1', 'box.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1', '#border')}}{{Spec2('CSS1')}} 
- -

浏览器支持

- -

{{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/zh-cn/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html b/files/zh-cn/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html deleted file mode 100644 index 66cd1921d5..0000000000 --- a/files/zh-cn/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: 使用CSS的多背景 -slug: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds -tags: - - CSS - - CSS Background - - Example - - Guide - - Intermediate -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") }}。

- -

示例

- -

该例中,三个背景进行堆叠:火狐标志,一个线性渐变, 和一张带有花的图片:

- -
.multi_bg_example {
-  background: url(http://demos.hacks.mozilla.org/openweb/resources/images/logos/firefox-48.png),
-        linear-gradient(to right, rgba(255, 255, 255, 0),  rgba(255, 255, 255, 1)),
-        url(http://demos.hacks.mozilla.org/openweb/resources/images/patterns/flowers-pattern.jpg);
-  background-repeat: no-repeat, no-repeat, repeat;
-  background-position: bottom right, left, right;
-}
-
- - - - - - - - - - -
结果
css_multibg.png
- -

如你所见,火狐标志(列表第一项)在最上面,紧接着是放在图片上面的线性渐变。每个子属性 ({{ cssxref("background-repeat") }} 和 {{ cssxref("background-position") }}) 应用于对应的背景。因此属性 {{ cssxref("background-repeat") }} 的第一个值应用于第一个(最前面)的背景,依次可推。

- -

其它

- - - -
 
- -
 
diff --git "a/files/zh-cn/web/css/css_background_and_borders/\345\234\206\350\247\222\350\276\271\346\241\206\345\217\221\347\224\237\345\231\250/index.html" "b/files/zh-cn/web/css/css_background_and_borders/\345\234\206\350\247\222\350\276\271\346\241\206\345\217\221\347\224\237\345\231\250/index.html" deleted file mode 100644 index b9f50d5332..0000000000 --- "a/files/zh-cn/web/css/css_background_and_borders/\345\234\206\350\247\222\350\276\271\346\241\206\345\217\221\347\224\237\345\231\250/index.html" +++ /dev/null @@ -1,1599 +0,0 @@ ---- -title: 圆角边框生成器 -slug: Web/CSS/CSS_Background_and_Borders/圆角边框发生器 -translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator ---- -

使用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/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html b/files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html new file mode 100644 index 0000000000..2873b2878c --- /dev/null +++ b/files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html @@ -0,0 +1,129 @@ +--- +title: Scaling background images +slug: Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images +translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images +--- +
{{cssref}}
+ +

CSS属性{{ cssxref("background-size") }} 可以用于调整背景图片的宽和高,因背景图片布局的默认行为是根据其原尺寸平铺,所以{{ cssxref("background-size") }}可修改其默认行为。你可以根据需要放大或缩小图片。

+ +

Tiling a large image

+ +

Let's consider a large image, a 2982x2808 Firefox logo image. We want (for some reason likely involving horrifyingly bad site design) to tile four copies of this image into a 300x300-pixel element. To do this, we can use a fixed background-size value of 150 pixels.

+ +

HTML

+ +
<div class="tiledBackground">
+</div>
+ +

CSS

+ +
.tiledBackground {
+  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
+  background-size: 150px;
+  width: 300px;
+  height: 300px;
+  border: 2px solid;
+  color: pink;
+}
+
+ +

Result

+ +

{{EmbedLiveSample("Tiling_a_large_image", 340, 340)}}

+ +

Stretching an image

+ +

You can also specify both the horizontal and vertical sizes of the image, like this:

+ +
background-size: 300px 150px;
+
+ +

The result looks like this:

+ +

+ +

Scaling an image up

+ +

On the other end of the spectrum, you can scale an image up in the background. Here we scale a 32x32 pixel favicon to 300x300 pixels:

+ +

+ +
.square2 {
+  background-image: url(favicon.png);
+  background-size: 300px;
+  width: 300px;
+  height: 300px;
+  border: 2px solid;
+  text-shadow: white 0px 0px 2px;
+  font-size: 16px;
+}
+
+ +

As you can see, the CSS is actually essentially identical, save the name of the image file.

+ +

Special values: "contain" and "cover"

+ +

Besides {{cssxref("<length>")}} values, the {{ cssxref("background-size") }} CSS property offers two special size values, contain and cover. Let's take a look at these.

+ +

contain

+ +

The contain value specifies that, regardless of the size of the containing box, the background image should be scaled so that each side is as large as possible while not exceeding the length of the corresponding side of the container. Try resizing the example below to see this in action.

+ +

HTML

+ +
<div class="bgSizeContain">
+  <p>Try resizing this element!</p>
+</div>
+ +

CSS

+ +
.bgSizeContain {
+  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
+  background-size: contain;
+  width: 160px;
+  height: 160px;
+  border: 2px solid;
+  color: pink;
+  resize: both;
+  overflow: scroll;
+}
+ +

Result

+ +

{{ EmbedLiveSample('contain', 250, 250) }}

+ +

cover

+ +

The cover value specifies that the background image should be sized so that it is as small as possible while ensuring that both dimensions are greater than or equal to the corresponding size of the container. Try resizing the example below to see this in action.

+ +

HTML

+ +
<div class="bgSizeCover">
+  <p>Try resizing this element!</p>
+</div>
+ +

CSS

+ +
.bgSizeCover {
+  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
+  background-size: cover;
+  width: 160px;
+  height: 160px;
+  border: 2px solid;
+  color: pink;
+  resize: both;
+  overflow: scroll;
+}
+ +

Result

+ +

{{ EmbedLiveSample('cover', 250, 250) }}

+ +

See also

+ + diff --git a/files/zh-cn/web/css/css_backgrounds_and_borders/scaling_background_images/index.html b/files/zh-cn/web/css/css_backgrounds_and_borders/scaling_background_images/index.html deleted file mode 100644 index 2873b2878c..0000000000 --- a/files/zh-cn/web/css/css_backgrounds_and_borders/scaling_background_images/index.html +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: Scaling background images -slug: Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images -translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images ---- -
{{cssref}}
- -

CSS属性{{ cssxref("background-size") }} 可以用于调整背景图片的宽和高,因背景图片布局的默认行为是根据其原尺寸平铺,所以{{ cssxref("background-size") }}可修改其默认行为。你可以根据需要放大或缩小图片。

- -

Tiling a large image

- -

Let's consider a large image, a 2982x2808 Firefox logo image. We want (for some reason likely involving horrifyingly bad site design) to tile four copies of this image into a 300x300-pixel element. To do this, we can use a fixed background-size value of 150 pixels.

- -

HTML

- -
<div class="tiledBackground">
-</div>
- -

CSS

- -
.tiledBackground {
-  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
-  background-size: 150px;
-  width: 300px;
-  height: 300px;
-  border: 2px solid;
-  color: pink;
-}
-
- -

Result

- -

{{EmbedLiveSample("Tiling_a_large_image", 340, 340)}}

- -

Stretching an image

- -

You can also specify both the horizontal and vertical sizes of the image, like this:

- -
background-size: 300px 150px;
-
- -

The result looks like this:

- -

- -

Scaling an image up

- -

On the other end of the spectrum, you can scale an image up in the background. Here we scale a 32x32 pixel favicon to 300x300 pixels:

- -

- -
.square2 {
-  background-image: url(favicon.png);
-  background-size: 300px;
-  width: 300px;
-  height: 300px;
-  border: 2px solid;
-  text-shadow: white 0px 0px 2px;
-  font-size: 16px;
-}
-
- -

As you can see, the CSS is actually essentially identical, save the name of the image file.

- -

Special values: "contain" and "cover"

- -

Besides {{cssxref("<length>")}} values, the {{ cssxref("background-size") }} CSS property offers two special size values, contain and cover. Let's take a look at these.

- -

contain

- -

The contain value specifies that, regardless of the size of the containing box, the background image should be scaled so that each side is as large as possible while not exceeding the length of the corresponding side of the container. Try resizing the example below to see this in action.

- -

HTML

- -
<div class="bgSizeContain">
-  <p>Try resizing this element!</p>
-</div>
- -

CSS

- -
.bgSizeContain {
-  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
-  background-size: contain;
-  width: 160px;
-  height: 160px;
-  border: 2px solid;
-  color: pink;
-  resize: both;
-  overflow: scroll;
-}
- -

Result

- -

{{ EmbedLiveSample('contain', 250, 250) }}

- -

cover

- -

The cover value specifies that the background image should be sized so that it is as small as possible while ensuring that both dimensions are greater than or equal to the corresponding size of the container. Try resizing the example below to see this in action.

- -

HTML

- -
<div class="bgSizeCover">
-  <p>Try resizing this element!</p>
-</div>
- -

CSS

- -
.bgSizeCover {
-  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
-  background-size: cover;
-  width: 160px;
-  height: 160px;
-  border: 2px solid;
-  color: pink;
-  resize: both;
-  overflow: scroll;
-}
- -

Result

- -

{{ EmbedLiveSample('cover', 250, 250) }}

- -

See also

- - diff --git a/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html b/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html new file mode 100644 index 0000000000..fcde4cecb2 --- /dev/null +++ b/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html @@ -0,0 +1,125 @@ +--- +title: Using URL values for the cursor property +slug: Web/CSS/cursor/url +tags: + - Cursor + - URL +translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property +--- +

Gecko 1.8 (Firefox 1.5,SeaMonkey 1.0) 支持CSS的URL值 {{cssxref("cursor")}} 属性在Windows和Linux。Mac支持是在Gecko 2(Firefox 4)中添加的。这允许将任意图像指定为鼠标光标 - 可以使用Gecko支持的任何图像格式。

+ +

语法

+ +

此属性的基本(CSS 2.1)语法是:

+ +
cursor: [<url>,]* keyword;
+
+ +

这意味着可以指定零个或多个URL(逗号分隔),后面必须跟随CSS规范中定义的一个关键字,例如 auto或 pointer。

+ +

例如,将允许以下值:

+ +
cursor: url(foo.cur), url(http://www.example.com/bar.gif), auto;
+
+ +

首先尝试加载 foo.cur。如果文件不存在或者其它无效原因,bar.gif被尝试加载,如果bar.gif不能被加载,那么使用auto

+ +

在Gecko 1.8beta3 (Deer Park Alpha 2)中加入了对CSS3 语法的指针属性的支持。

+ +
cursor:  [<uri> [<x> <y>]?,]* keyword
+ +

因此,它能在Firefox 1.5中工作。它允许定义指针的热点,加强对指针图橡的边界的控制。如果一个也没有设置,指针的热点会从文件本身读取(适合CUR和XBM文件类型)。否则,设置成图像的左上角。一个CSS3语法的例子:

+ +
.foo  {
+    cursor:  auto;
+    cursor:  url(cursor1.png) 4 12, auto;
+}
+
+.bar  {
+    cursor:  pointer;
+    cursor:  url(cursor2.png) 2 2, pointer;
+}
+
+/*
+fallsback onto 'auto' and 'pointer' in IE,
+but must be set separately
+*/
+ +

第一个数字是X坐标,第二个数字是Y坐标。该示例将热点设置为从左上角(0,0)到(4,12)处的像素。

+ +

局限性

+ +

可以使用任何被Gecko所支持的图像格式。这意味着你可以使用BMP,JPG,CUR,GIF等等。可是,ANI不被支持。还有即使你定义一个GIF动画,指针也不会变成GIF动画。这个局限性可能在以后的版本去掉。

+ +

Gecko它本身不能限制被替换的指针大小。无论如何,你应该自己限制图像的最大值在32x32,以便兼容各种平台的操作系统。尤其是大于这个尺寸的指针不能在Windows 9x (95,98,ME)下工作。

+ +

透明效果的指针在Windows XP以前都不被支持。这是操作系统的一个局限性。透明效果可以在所有平台下工作。

+ +

只 有Windows,OS/2和Linux(使用Gtk+ 2.4及更高版本)的Mozilla版本支持光标属性的URL参数。其它版本可能在以后的版本中加入支持(Mac OS: {{ Bug(286304) }}, QNX Neutrino: {{ Bug(286307) }}, XLib: {{ Bug(286309) }}, Qt: {{ Bug(286310) }}, BeOS: {{ Bug(298184) }}, Gtk 2.0/2.2: {{ Bug(308536) }})。

+ +

关于其它浏览器的兼容性

+ +

Microsoft Internet Explorer 6.0还支持cursor属性的URI值。然而:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BrowserLowest versionformats (e.g.)x-y-coordinates
Internet Explorer6.0.cur | .ani---
Firefox (Gecko), Windows and 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)
Since OS X 10.5 supports Safari (Mac) .curfiles
+ +

它也使用不严格的光标属性语法。例如像这样的参数:

+ +
cursor: url(foo.cur);
+
+ +

或者:

+ +
cursor: url(foo.cur), pointer, url(bar.cur), auto;
+
+ +

可以在MSIE上工作,但是不能在Gecko上面工作。因为Gecko的兼容性与CSS的规范一致,URIs表始终放置在前面,在最后放置正确的关键字。

+ +

 

diff --git a/files/zh-cn/web/css/css_box_model/box-shadow_generator/index.html b/files/zh-cn/web/css/css_box_model/box-shadow_generator/index.html deleted file mode 100644 index 3fb264bc40..0000000000 --- a/files/zh-cn/web/css/css_box_model/box-shadow_generator/index.html +++ /dev/null @@ -1,2880 +0,0 @@ ---- -title: Box-shadow generator -slug: Web/CSS/CSS_Box_Model/Box-shadow_generator -translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator ---- -

这个可视化工具可以帮助你生成一个元素的CSS{{cssxref("box-shadow")}}相关代码,添加box shadow效果到你的CSS对象上。

- -
-

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"> 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"> Class element properties </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 Code </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 = 'shadow ' + 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', '') }}
- -

Related Tool: Box Shadow CSS Generator

diff --git a/files/zh-cn/web/css/css_colors/index.html b/files/zh-cn/web/css/css_colors/index.html deleted file mode 100644 index 60036fea2b..0000000000 --- a/files/zh-cn/web/css/css_colors/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: CSS Colors -slug: Web/CSS/CSS_Colors -tags: - - CSS - - CSS Colors - - NeedsTranslation - - Overview - - Reference - - TopicStub -translation_of: Web/CSS/CSS_Color -translation_of_original: Web/CSS/CSS_Colors ---- -
{{CSSRef}}
- -

CSS Colors 是 CSS 的一个模块,用于处理颜色、颜色类型和透明度。

- -

参考 (Reference)

- -

属性

- -
- -
- -

CSS 数据类型

- -

{{cssxref("<color>")}}

- -

指南 (Guides)

- -

None.

- -

规范 (Specifications)

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Colors')}}{{Spec2('CSS3 Colors')}} 
{{SpecName('CSS2.1', 'colors.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Initial definition
- -

浏览器兼容性 (Browser compatibility)

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatGeckoDesktop("1")}}3.03.51.0
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support1.0{{CompatGeckoMobile("1")}}6.06.01.0
-
- -

另请阅读

- - diff --git a/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html b/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html new file mode 100644 index 0000000000..593e14fd47 --- /dev/null +++ b/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html @@ -0,0 +1,130 @@ +--- +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 属性简写

+ +

多数时候,网页设计者都会使用 {{ 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:8emcolumn-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浏览器是这样的。

+ +

然而,一些情况下,明确设置最大列高也是有用的,这样内容从第一列开始,尽可能多的生成列,甚至会溢出右边沿。因此,如果通过设置{{ 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/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html b/files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html new file mode 100644 index 0000000000..df269a9211 --- /dev/null +++ b/files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html @@ -0,0 +1,121 @@ +--- +title: Flexbox的向下支持 +slug: Web/CSS/CSS_Flexible_Box_Layout/Flexbox_的_向下_支持 +tags: + - '@supports' + - IE + - Safari + - flexbox + - 兼容 + - 弹性盒子 + - 旧版本 + - 浏览器 +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox +--- +

{{CSSRef}}

+ +

虽然弹性盒子被各种现代浏览器很好的支持, 但是你或许还会遇到一些问题。在这个文档中,我们将会了解到浏览器支持弹性盒子的情况和一些潜在的问题, 以及处理它们的资源和方法。

+ +

弹性盒子的历史

+ +

与所有CSS标准一样,弹性盒子标准经历了一系列的改动,直到它成为我们现有的候选推荐版本。作为候选推荐,我们不该着重于当下对于该规范的大量变动,尽管历来弹性盒子的迭代情况有所不同。

+ +

弹性盒子曾在许多浏览器中作为实验功能的方式被实现。当时进行实验性的实现的方式是使用浏览器前缀。这种关于前缀的构思是为了让规范的实现能被测试,并被浏览器工程师和网页开发者等在不和其他实现冲突的情况下浏览。也就是说不再生产代码中使用实验性的实现。然后,前缀最终被用在了生产代码中,结果对实验性规范的不管修改导致了人们需要不断对网站进行对应的修改。

+ +

在2009年时,规则看起来很不一样。当时,要创建一个弹性容器你会用display: box ,会有一大堆 box-* 属性,和现在的弹性盒子显然完全不同。

+ +

曾有一个规范的更新将语法换成了 display: flexbox ——这仍旧是浏览器前缀。

+ +

最后规范被修改成,定义 display: flex 作为创建弹性容器的方式。对于最新版本规范的浏览器支持自此就尽善尽美了。

+ +

有很多老的关于弹性盒子规范旧版本的文章还存着,但他们都容易通过弹性盒子容器创建的方式来辨别。如果你在其中找到任何关于display: box或者display: flexbox的内容,那么它们就是过时的信息。

+ +

浏览器支持情况

+ +

现代浏览器能够很好的支持flexbox,并且大多数浏览器不需要前缀。2015年,Safari9是最后一个移除前缀的主流浏览器。2个需要注意浏览器兼容的浏览器是:

+ + + +

现在,IE11 已经支持display: flex,但是在使用的时候会有一些bug。

+ +

常见问题

+ +

由于经过了发展,flexbox的大多数问题与规范的变更有关,而且事实上我们很多人都试图在生产中环境中使用实验性的规范。 如果您要确保与旧版本的浏览器(尤其是IE10和11)向后兼容,则 Flexbugs 网站是一个有用的资源。 您将看到许多列出的bug都适用于旧的浏览器版本,并且在当前的浏览器中已修复。 每个错误都有列出的解决方法-可以节省许多时间。

+ +

如果你想要支持非常旧的浏览器使用flexbox属性,在CSS中加入:

+ +
.wrapper {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+ +

Autoprefixer Online是查看推荐使用前缀浏览器的有效方式,具体取决于您希望通过浏览器支持返回多少版本。 您还可以从 Can I Use 中以获取浏览器支持的信息,以便在已经支持的浏览器中删除前缀

+ +

有用的向下支持技术

+ +

假设弹性盒子使用 {{cssxref("display")}} 的属性值定义,当我们需要为不支持弹性盒子的旧版本的浏览器提供支持时,向下支持(fallback)技术可以用来覆写布局方式。如果你使用其他布局方法作用于一个元素,随后该元素又成为了弹性盒子的 item,规范定义了会发生什么。

+ +

浮动元素

+ +
+

“浮动和清除浮动不会在 flex item 上触发浮动和清除行为,并且不会脱离当前文档流。” - 3. Flex Containers

+
+ +

在下面的示例中,我将两个块级元素浮动,然后给容器设置了 display: flex。这两个元素现在变成了弹性盒子元素,意味着它们会伸展使得高度相同,并且没有应用任何浮动行为。

+ +

你可以通过移除 display: flex 属性来测试这项向下支持行为。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/browsers/float.html", '100%', 550)}}

+ +

display: inline-block

+ +

一旦一个 inline-block 元素成为了一个弹性盒子元素,那么它将被块级化,因此 display: inline-block 属性的诸如在元素间保留空白符等行为将不会被应用。

+ +

移除 display: flex 属性来查看该向下支持行为,你将会看见这两个元素之间多出的空白符,这是因为使用 display: inine-block 时会把空白符当成其他行内元素对待。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/browsers/inline-block.html", '100%', 550)}}

+ +

display: table-

+ +

CSS 中表格相关的系列属性可能是非常有用的向下支持技术,因为它们允许一些设计模式,例如全高度列和垂直居中等,甚至可以向后兼容至 IE8。

+ +

假如你在 HTML 中对一个元素使用 display: table-cell,它将呈现为表格单元格样式。CSS 会创建一个匿名盒子来呈现这些元素,这样你就不用包裹每一个元素来呈现表格的行(row),以及另外一个元素来呈现这个表格自身。你无法看见或修改这些匿名盒子的样式,它们只是单纯的用来修补文档树。

+ +

如果你在父元素上设置了 display: flex,这些匿名盒子将不会被创建,这样你的元素就保留直接的子元素并成为了一个弹性盒子元素 — 失去所有表格元素的特性。

+ +
+

“注意:display 的某些属性值通常会在初始盒子周围触发匿名盒子的创建行为。如果该盒子是一个弹性盒子元素,那么它会先被块级化,使得匿名盒子不会被创建。例如,两个连续的弹性盒子元素设置了 display: table-cell 后,将会成为两个独立分开的 display: block 弹性盒子元素,而不是被包裹近单独的一个匿名表格中。” - 4. Flex Items

+
+ +

{{EmbedGHLiveSample("css-examples/flexbox/browsers/table-cell.html", '100%', 550)}}

+ +

vertical-align 属性

+ +

下面的示例展示了 {{cssxref("vertical-align")}} 属性与 display: inline-block 结合使用的情况。display: table-cell 和 display: inline-block 都允许使用该属性。使用 vertical-align 可以使垂直排列优先于弹性盒子。这个属性会被弹性盒子忽略,这样你就可以将它与 display: table-cell 或者 display: inline-block 结合使用来作为一个向下支持技巧,然后就可以在弹性盒子中安全地使用盒子排列属性。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/browsers/vertical-align.html", '100%', 550)}}

+ +

特性枚举与弹性盒子

+ +

你可以使用特性枚举(feature queries)来检查弹性盒子的支持情况:

+ +
@supports (display: flex) {
+  // 添加在支持的浏览器中书写的样式代码
+}
+ +

注意 Internet Explorer 11 不支持特性枚举,但是支持弹性盒子。如果你觉得在 IE11 中实现不易并且希望对它使用向下支持布局,那么你可以使用特性枚举只在对弹性盒子支持良好的浏览器中使用弹性盒子属性规则。需要记住的是,如果你想用浏览器厂商前缀的弹性盒子属性来包含某版本的浏览器,你需要在特性枚举中包含该版本浏览器的前缀。下面的特性枚举例子就兼容了 UC 浏览器,它支持特性枚举并且支持旧版弹性盒子语法:

+ +
@supports (display: flex) or (display: -webkit-box) {
+  // code for supporting browsers
+}
+ +

查看更多关于特性枚举的信息请访问:Using Feature Queries in CSS

+ +

结尾

+ +

当我在这个指南中花时间来检查潜在的问题和向下支持技巧时,弹性盒子已经做好了在生产环境中运作的充分准备。该指南可能会在你遇到问题或者需要支持旧版本浏览器时帮到你。

diff --git "a/files/zh-cn/web/css/css_flexible_box_layout/flexbox_\347\232\204_\345\220\221\344\270\213_\346\224\257\346\214\201/index.html" "b/files/zh-cn/web/css/css_flexible_box_layout/flexbox_\347\232\204_\345\220\221\344\270\213_\346\224\257\346\214\201/index.html" deleted file mode 100644 index df269a9211..0000000000 --- "a/files/zh-cn/web/css/css_flexible_box_layout/flexbox_\347\232\204_\345\220\221\344\270\213_\346\224\257\346\214\201/index.html" +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Flexbox的向下支持 -slug: Web/CSS/CSS_Flexible_Box_Layout/Flexbox_的_向下_支持 -tags: - - '@supports' - - IE - - Safari - - flexbox - - 兼容 - - 弹性盒子 - - 旧版本 - - 浏览器 -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox ---- -

{{CSSRef}}

- -

虽然弹性盒子被各种现代浏览器很好的支持, 但是你或许还会遇到一些问题。在这个文档中,我们将会了解到浏览器支持弹性盒子的情况和一些潜在的问题, 以及处理它们的资源和方法。

- -

弹性盒子的历史

- -

与所有CSS标准一样,弹性盒子标准经历了一系列的改动,直到它成为我们现有的候选推荐版本。作为候选推荐,我们不该着重于当下对于该规范的大量变动,尽管历来弹性盒子的迭代情况有所不同。

- -

弹性盒子曾在许多浏览器中作为实验功能的方式被实现。当时进行实验性的实现的方式是使用浏览器前缀。这种关于前缀的构思是为了让规范的实现能被测试,并被浏览器工程师和网页开发者等在不和其他实现冲突的情况下浏览。也就是说不再生产代码中使用实验性的实现。然后,前缀最终被用在了生产代码中,结果对实验性规范的不管修改导致了人们需要不断对网站进行对应的修改。

- -

在2009年时,规则看起来很不一样。当时,要创建一个弹性容器你会用display: box ,会有一大堆 box-* 属性,和现在的弹性盒子显然完全不同。

- -

曾有一个规范的更新将语法换成了 display: flexbox ——这仍旧是浏览器前缀。

- -

最后规范被修改成,定义 display: flex 作为创建弹性容器的方式。对于最新版本规范的浏览器支持自此就尽善尽美了。

- -

有很多老的关于弹性盒子规范旧版本的文章还存着,但他们都容易通过弹性盒子容器创建的方式来辨别。如果你在其中找到任何关于display: box或者display: flexbox的内容,那么它们就是过时的信息。

- -

浏览器支持情况

- -

现代浏览器能够很好的支持flexbox,并且大多数浏览器不需要前缀。2015年,Safari9是最后一个移除前缀的主流浏览器。2个需要注意浏览器兼容的浏览器是:

- - - -

现在,IE11 已经支持display: flex,但是在使用的时候会有一些bug。

- -

常见问题

- -

由于经过了发展,flexbox的大多数问题与规范的变更有关,而且事实上我们很多人都试图在生产中环境中使用实验性的规范。 如果您要确保与旧版本的浏览器(尤其是IE10和11)向后兼容,则 Flexbugs 网站是一个有用的资源。 您将看到许多列出的bug都适用于旧的浏览器版本,并且在当前的浏览器中已修复。 每个错误都有列出的解决方法-可以节省许多时间。

- -

如果你想要支持非常旧的浏览器使用flexbox属性,在CSS中加入:

- -
.wrapper {
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -ms-flexbox;
-  display: flex;
-}
- -

Autoprefixer Online是查看推荐使用前缀浏览器的有效方式,具体取决于您希望通过浏览器支持返回多少版本。 您还可以从 Can I Use 中以获取浏览器支持的信息,以便在已经支持的浏览器中删除前缀

- -

有用的向下支持技术

- -

假设弹性盒子使用 {{cssxref("display")}} 的属性值定义,当我们需要为不支持弹性盒子的旧版本的浏览器提供支持时,向下支持(fallback)技术可以用来覆写布局方式。如果你使用其他布局方法作用于一个元素,随后该元素又成为了弹性盒子的 item,规范定义了会发生什么。

- -

浮动元素

- -
-

“浮动和清除浮动不会在 flex item 上触发浮动和清除行为,并且不会脱离当前文档流。” - 3. Flex Containers

-
- -

在下面的示例中,我将两个块级元素浮动,然后给容器设置了 display: flex。这两个元素现在变成了弹性盒子元素,意味着它们会伸展使得高度相同,并且没有应用任何浮动行为。

- -

你可以通过移除 display: flex 属性来测试这项向下支持行为。

- -

{{EmbedGHLiveSample("css-examples/flexbox/browsers/float.html", '100%', 550)}}

- -

display: inline-block

- -

一旦一个 inline-block 元素成为了一个弹性盒子元素,那么它将被块级化,因此 display: inline-block 属性的诸如在元素间保留空白符等行为将不会被应用。

- -

移除 display: flex 属性来查看该向下支持行为,你将会看见这两个元素之间多出的空白符,这是因为使用 display: inine-block 时会把空白符当成其他行内元素对待。

- -

{{EmbedGHLiveSample("css-examples/flexbox/browsers/inline-block.html", '100%', 550)}}

- -

display: table-

- -

CSS 中表格相关的系列属性可能是非常有用的向下支持技术,因为它们允许一些设计模式,例如全高度列和垂直居中等,甚至可以向后兼容至 IE8。

- -

假如你在 HTML 中对一个元素使用 display: table-cell,它将呈现为表格单元格样式。CSS 会创建一个匿名盒子来呈现这些元素,这样你就不用包裹每一个元素来呈现表格的行(row),以及另外一个元素来呈现这个表格自身。你无法看见或修改这些匿名盒子的样式,它们只是单纯的用来修补文档树。

- -

如果你在父元素上设置了 display: flex,这些匿名盒子将不会被创建,这样你的元素就保留直接的子元素并成为了一个弹性盒子元素 — 失去所有表格元素的特性。

- -
-

“注意:display 的某些属性值通常会在初始盒子周围触发匿名盒子的创建行为。如果该盒子是一个弹性盒子元素,那么它会先被块级化,使得匿名盒子不会被创建。例如,两个连续的弹性盒子元素设置了 display: table-cell 后,将会成为两个独立分开的 display: block 弹性盒子元素,而不是被包裹近单独的一个匿名表格中。” - 4. Flex Items

-
- -

{{EmbedGHLiveSample("css-examples/flexbox/browsers/table-cell.html", '100%', 550)}}

- -

vertical-align 属性

- -

下面的示例展示了 {{cssxref("vertical-align")}} 属性与 display: inline-block 结合使用的情况。display: table-cell 和 display: inline-block 都允许使用该属性。使用 vertical-align 可以使垂直排列优先于弹性盒子。这个属性会被弹性盒子忽略,这样你就可以将它与 display: table-cell 或者 display: inline-block 结合使用来作为一个向下支持技巧,然后就可以在弹性盒子中安全地使用盒子排列属性。

- -

{{EmbedGHLiveSample("css-examples/flexbox/browsers/vertical-align.html", '100%', 550)}}

- -

特性枚举与弹性盒子

- -

你可以使用特性枚举(feature queries)来检查弹性盒子的支持情况:

- -
@supports (display: flex) {
-  // 添加在支持的浏览器中书写的样式代码
-}
- -

注意 Internet Explorer 11 不支持特性枚举,但是支持弹性盒子。如果你觉得在 IE11 中实现不易并且希望对它使用向下支持布局,那么你可以使用特性枚举只在对弹性盒子支持良好的浏览器中使用弹性盒子属性规则。需要记住的是,如果你想用浏览器厂商前缀的弹性盒子属性来包含某版本的浏览器,你需要在特性枚举中包含该版本浏览器的前缀。下面的特性枚举例子就兼容了 UC 浏览器,它支持特性枚举并且支持旧版弹性盒子语法:

- -
@supports (display: flex) or (display: -webkit-box) {
-  // code for supporting browsers
-}
- -

查看更多关于特性枚举的信息请访问:Using Feature Queries in CSS

- -

结尾

- -

当我在这个指南中花时间来检查潜在的问题和向下支持技巧时,弹性盒子已经做好了在生产环境中运作的充分准备。该指南可能会在你遇到问题或者需要支持旧版本浏览器时帮到你。

diff --git a/files/zh-cn/web/css/css_flexible_box_layout/mixins/index.html b/files/zh-cn/web/css/css_flexible_box_layout/mixins/index.html deleted file mode 100644 index d2054bc725..0000000000 --- a/files/zh-cn/web/css/css_flexible_box_layout/mixins/index.html +++ /dev/null @@ -1,408 +0,0 @@ ---- -title: 使用弹性盒子进行高级布局 -slug: Web/CSS/CSS_Flexible_Box_Layout/Mixins -tags: - - CSS3布局模型 - - Flexible_Box - - Flexible_Box_Layout - - Layout - - 弹性盒子 - - 弹性盒子模型 -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Mixins ---- -

使用弹性盒子的意义是在任何尺寸的屏幕上改变其和其子元素的尺寸填充屏幕可用空间。一个弹性框容器将延展它的子元素以填充可用空间,并且缩小它的子元素来避免溢出。

- -

浮动布局的问题

- - - -

弹性盒子如何处理

- - - -

弹性盒子属性

- -

placeholder

- - - -

弹性容器属性

- - - -

弹性元素属性

- - - -

弹性盒子混合

- -

对于希望在现代浏览器原生支持下使用弹性盒子的用户,这里有全部的支撑表格:http://caniuse.com/flexbox

- -

将会使用:

- - - -

启发于:

- - - -

可以从这些地方获取帮助:

- - - -

弹性容器

- -

“flex”值会引起一个元素生成一个盒级的弹性盒子。

- -

“inline-flex”会生成一个行内弹性盒子。

- -

display: flex | inline-flex http://w3.org/tr/css3-flexbox/#flex-containers

- -
-
@mixin flexbox {
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -moz-flex;
-  display: -ms-flexbox;
-  display: flex;
-}
-
-// 使用这样的混合模式
-%flexbox { @include flexbox; }
-
- -
-
@mixin inline-flex {
-  display: -webkit-inline-box;
-  display: -webkit-inline-flex;
-  display: -moz-inline-flex;
-  display: -ms-inline-flexbox;
-  display: inline-flex;
-}
-
-%inline-flex { @include inline-flex; }
-
- -

弹性盒子方向

- -

“flex-direction”属性通过设置容器主轴来定义弹性元素如何在容器内排列。这个属性确定了弹性元素排列的方向。

- -

值:row | row-reverse | column | column-reverse

- -

http://w3.org/tr/css3-flexbox/#flex-direction-property

- -
-
@mixin flex-direction($value: row) {
-  @if $value == row-reverse {
-    -webkit-box-direction: reverse;
-    -webkit-box-orient: horizontal;
-  } @else if $value == column {
-    -webkit-box-direction: normal;
-    -webkit-box-orient: vertical;
-  } @else if $value == column-reverse {
-    -webkit-box-direction: reverse;
-    -webkit-box-orient: vertical;
-  } @else {
-    -webkit-box-direction: normal;
-    -webkit-box-orient: horizontal;
-  }
-  -webkit-flex-direction: $value;
-  -moz-flex-direction: $value;
-  -ms-flex-direction: $value;
-  flex-direction: $value;
-}
-
-// 简短版本:
-@mixin flex-dir($args...) { @include flex-direction($args...); }
-
- -

弹性盒子换行

- -

“flex-wrap”属性控制了容器为单行还是多行。并且定义了侧轴的方向,新行将沿侧轴方向堆砌。

- -

值:nowrap | wrap | wrap-reverse

- -

默认:nowrap

- -

http://w3.org/tr/css3-flexbox/#flex-wrap-property

- -
-
@mixin flex-wrap($value: nowrap) {
-  // No Webkit Box fallback.
-  -webkit-flex-wrap: $value;
-  -moz-flex-wrap: $value;
-  @if $value == nowrap {
-    -ms-flex-wrap: none;
-  } @else {
-    -ms-flex-wrap: $value;
-  }
-  flex-wrap: $value;
-}
-
- -

弹性盒子流(简写)

- -

“flex-flow”属性是设置“flex-direction”和“flex-wrap”的简写,可以同时定义主轴和侧轴。

- -

默认值:row nowrap

- -

http://w3.org/tr/css3-flexbox/#flex-flow-property

- -
-
@mixin flex-flow($values: (row nowrap)) {
-  // No Webkit Box fallback.
-  -webkit-flex-flow: $values;
-  -moz-flex-flow: $values;
-  -ms-flex-flow: $values;
-  flex-flow: $values;
-}
-
- -

弹性盒子顺序

- -

“order”属性通过将这些元素分配到序数分组来控制它们出现的顺序。

- -

默认值:0

- -

http://w3.org/tr/css3-flexbox/#order-property

- -
-
@mixin order($int: 0) {
-  -webkit-box-ordinal-group: $int + 1;
-  -webkit-order: $int;
-  -moz-order: $int;
-  -ms-flex-order: $int;
-  order: $int;
-}
-
- -

弹性盒子增长

- -

“flex-grow”属性设置增长因数,不接受负值。

- -

默认值:0

- -

http://w3.org/tr/css3-flexbox/#flex-grow-property

- -
-
@mixin flex-grow($int: 0) {
-  -webkit-box-flex: $int;
-  -webkit-flex-grow: $int;
-  -moz-flex-grow: $int;
-  -ms-flex-positive: $int;
-  flex-grow: $int;
-}
-
- -

弹性盒子收缩

- -

“flex-shrink”属性设置了收缩因数,不接受负值。

- -

默认值:1

- -

http://w3.org/tr/css3-flexbox/#flex-shrink-property

- -
-
@mixin flex-shrink($int: 1) {
-  -webkit-flex-shrink: $int;
-  -moz-flex-shrink: $int;
-  -ms-flex-negative: $int;
-  flex-shrink: $int;
-}
-
- -

弹性盒子伸缩

- -

“flex-basis”属性设置了弹性框伸缩的基准值,不接受负值。

- -

值:类似“width”,默认值:auto

- -

http://www.w3.org/TR/css3-flexbox/#flex-basis-property

- -
-
@mixin flex-basis($value: auto) {
-  -webkit-flex-basis: $value;
-  -moz-flex-basis: $value;
-  -ms-flex-preferred-size: $value;
-  flex-basis: $value;
-}
-
- -

弹性盒子“Flex”属性(简写)

- -

flex”属性设置了弹性盒子长度的组成,包括增长因数、收缩因数和伸缩基准值。对于一个弹性元素,“flex”属性会被用来设置元素的尺寸,对于一个非弹性元素,该属性无效。

- -

值:none | ||

- -

默认值:见独立属性(1 1 0)

- -

http://w3.org/tr/css3-flexbox/#flex-property

- -
-
@mixin flex($fg: 1, $fs: null, $fb: null) {
-
-  // Set a variable to be used by box-flex properties
-  $fg-boxflex: $fg;
-
-  // Box-Flex only supports a flex-grow value so lets grab the
-  // first item in the list and just return that.
-  @if type-of($fg) == 'list' {
-    $fg-boxflex: nth($fg, 1);
-  }
-
-  -webkit-box-flex: $fg-boxflex;
-  -webkit-flex: $fg $fs $fb;
-  -moz-box-flex: $fg-boxflex;
-  -moz-flex: $fg $fs $fb;
-  -ms-flex: $fg $fs $fb;
-  flex: $fg $fs $fb;
-}
-
- -

弹性盒子对齐方式

- -

“justify-content”属性将弹性元素沿容器主轴方向对齐。当所有弹性元素的长度和边距都设置好之后,布局完成。一般情况下,当行内所有弹性元素尺寸不可变或可变且达到最大尺寸的情况下,该属性会分配剩余可用空间。同时,当元素溢出行的时候,它也会对其排列做出控制。

- -

提示:以前版本的语法不支持“space-*”值。

- -

值:flex-start | flex-end | center | space-between | space-around 默认值:flex-start

- -

http://w3.org/tr/css3-flexbox/#justify-content-property

- -
-
@mixin justify-content($value: flex-start) {
-  @if $value == flex-start {
-    -webkit-box-pack: start;
-    -ms-flex-pack: start;
-  } @else if $value == flex-end {
-    -webkit-box-pack: end;
-    -ms-flex-pack: end;
-  } @else if $value == space-between {
-    -webkit-box-pack: justify;
-    -ms-flex-pack: justify;
-  } @else if $value == space-around {
-    -ms-flex-pack: distribute;
-  } @else {
-    -webkit-box-pack: $value;
-    -ms-flex-pack: $value;
-  }
-  -webkit-justify-content: $value;
-  -moz-justify-content: $value;
-  justify-content: $value;
-}
-  // Shorter version:
-  @mixin flex-just($args...) { @include justify-content($args...); }
-
- -

弹性元素对齐

- -

可以设置弹性元素在容器侧轴上的对齐方式,与“justify-content”功能相似但是方向垂直。“align-items”设置弹性盒子的所有子元素的对齐方式,包括匿名弹性元素。元素可以通过单独设置“align-self”来覆盖该属性。(对于匿名弹性元素,“align-self'”属性总是与“align-items”相同。)

- -

值:flex-start | flex-end | center | baseline | stretch 默认值:stretch

- -

http://w3.org/tr/css3-flexbox/#align-items-property

- -
-
@mixin align-items($value: stretch) {
-  @if $value == flex-start {
-    -webkit-box-align: start;
-    -ms-flex-align: start;
-  } @else if $value == flex-end {
-    -webkit-box-align: end;
-    -ms-flex-align: end;
-  } @else {
-    -webkit-box-align: $value;
-    -ms-flex-align: $value;
-  }
-  -webkit-align-items: $value;
-  -moz-align-items: $value;
-  align-items: $value;
-}
-
- -

弹性元素自对齐

- -

用来单独设置弹性元素在侧轴的对齐方式,功能与“align-items”相同。可以覆盖“align-items”属性。

- -

值:auto | flex-start | flex-end | center | baseline | stretch 默认值:auto

- -
-
@mixin align-self($value: auto) {
-  // No Webkit Box Fallback.
-  -webkit-align-self: $value;
-  -moz-align-self: $value;
-  @if $value == flex-start {
-    -ms-flex-item-align: start;
-  } @else if $value == flex-end {
-    -ms-flex-item-align: end;
-  } @else {
-    -ms-flex-item-align: $value;
-  }
-  align-self: $value;
-}
-
- -

弹性元素内容对齐

- -

“align-content”属性设置了容器内每行沿侧轴的对齐方式。与“justify-content”属性在主轴方向对齐单独元素的方式相似。如果容器内只有一行,该属性无效。

- -

值:flex-start | flex-end | center | space-between | space-around | stretch 默认值:stretch

- -

http://w3.org/tr/css3-flexbox/#align-content-property

- -
-
@mixin align-content($value: stretch) {
-  // No Webkit Box Fallback.
-  -webkit-align-content: $value;
-  -moz-align-content: $value;
-  @if $value == flex-start {
-    -ms-flex-line-pack: start;
-  } @else if $value == flex-end {
-    -ms-flex-line-pack: end;
-  } @else {
-    -ms-flex-line-pack: $value;
-  }
-  align-content: $value;
-}
-
diff --git a/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html b/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html new file mode 100644 index 0000000000..c90b3416a5 --- /dev/null +++ b/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html @@ -0,0 +1,123 @@ +--- +title: 弹性盒子与其他布局方法的联系 +slug: Web/CSS/CSS_Flexible_Box_Layout/弹性盒子与其他布局方法的联系 +tags: + - CSS + - box alignment + - flexbox +translation_of: >- + Web/CSS/CSS_Flexible_Box_Layout/Relationship_of_Flexbox_to_Other_Layout_Methods +--- +
{{CSSRef}}
+ +

在本文中,我们将了解弹性盒子(Flexbox)如何与所有其他CSS模块相适应。如果您想学习flexbox,我们将一起找出需要注意的规范和flexbox与一些其他模块不同的原因。

+ +
+

注意:CSS 1和CSS 2是一个单一的整体规范,其中所有CSS都定义在一个文档中。随着CSS成为一种功能更加丰富的语言,各个部分有不同的发展速度,如何维护一个庞大的规范就成了问题。因此现在的CSS是模块化的,不同的CSS模块有不同的规范,一起构成了现在的CSS。这些模块之间相互关联,并且处于不同的开发阶段。

+
+ +

box alignment 模块

+ +

许多人开始关注flexbox的最初原因是在flex容器中能够很好的对齐其中的元素。flexbox可以设置在其交叉轴以及主轴上的对齐属性。

+ +

这些属性最开始出现在flexbox规范中,现在已经成为Box Alignment规范的一部分。 这个规范详细说明了在所有布局中(不仅仅是flexbox)对齐属性是如何起作用的。 对齐属性用于设置元素对齐方式和沿轴的空间分配。

+ +

之所以在flexbox规范和box alignment模块规范中都有对对齐属性的详细描述,是为了确保flexbox规范的完成不会受box alignment模块规范的影响,因为后者需要详细说明所有的布局类型中的对齐方法。flexbox规范中有一条注释指出将来一旦Box Alignment Level 3完成,它将会取代flexbox规范中的相关定义:

+ +
+

“注意:虽然对齐属性是在CSS Box Alignment [CSS-ALIGN-3]中定义的,但“ Flexible Box Layout”在此处重现了相关属性的定义,以免形成规范性的依赖关系,而这可能会减慢规范的发展。这些属性仅适用于Flex布局,直到CSS Box Alignment Level 3完成并定义其对其他布局模式的效果;此外,在Box Alignment模块中定义的任何新值都将应用于Flexible Box Layout;换句话说,一旦Box Alignment模块完成,其中的相关定义将取代此处的定义。”

+
+ +

在本系列的后续文章(在flex容器中对齐元素)中,我们将彻底研究Box Alignment属性如何应用于flex元素。

+ +

gap属性

+ +

属性{{cssxref("row-gap")}} 和 {{cssxref("column-gap")}},其简写为{{cssxref("gap")}},近期添加到了盒子布局规范中。这些属性(名称为grid-row-gap, grid-column-gap and grid-gap)最初定义在CSS网格布局中。但是他们被重命名并移入盒子布局规范。这样的话,所有的布局方法都可以使用这些属性。不过在浏览器实现Flex的这些属性之前只能通过{{cssxref("margin")}} 来控制元素之间的间隙距离。

+ +

Writing Modes

+ +

In the Basic concepts of flexbox article, I explained that flexbox is writing mode aware. Writing modes are fully detailed in the CSS Writing Modes specification, which details how CSS supports the various different writing modes that exist internationally. We need to be aware of how this will impact our flex layouts as writing mode changes the direction that blocks are laid out in our document. Understanding block and inline directions is key to new layout methods.

+ +

It is worth noting that we might want to change the writing mode of our document for reasons other than publishing content in a language that uses a different writing mode. See this article for a full description of writing modes and ways to use them, both for content in other languages and for creative reasons. 

+ +

The writing modes

+ +

The writing modes specification defines the following values of the {{cssxref("writing-mode")}} property, which serve to change the direction that blocks are laid out on the page, to match the direction that blocks lay out when content is formatted in that particular writing mode. You can change the live example below to these modes in order to see what happens to the flex layout.

+ + + +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/writing-modes.html", '100%', 360)}} 

+ +

Note that sideways-rl and sideways-lr have support only in Firefox currently. There are also some known issues with regard to writing-mode and flexbox. You can see more information on browser support in the MDN documentation for writing-mode. However if you are planning on using writing modes in your layout, carefully testing the results is advisable — not least because it would be easy to make things hard to read!

+ +

Note that you would not normally use CSS and the writing-mode property to change an entire document to another writing mode. This would be done via HTML, by adding a dir and lang attribute to the html element to indicate the document language and default text direction. This would mean that the document would display correctly even if CSS did not load.

+ +

Flexbox and other layout methods

+ +

The flexbox specification contains a definition of what happens if an item uses another layout method and then becomes a flex item. For example, if an item is floated and then its parent becomes a flex container. Or, how a flex container behaves as part of layout.

+ +

An element set to display: flex behaves in most ways like any other block level container that establishes a containing block. Floats will not intrude, and the containers' margins will not collapse.

+ +

With regard to flex items, if an item was floated or cleared and then becomes a flex item due to the parent having display: flex applied, the floating and clearing will no longer happen, and the item will not be taken out of normal flow in the way that floats are. If you have used the {{cssxref("vertical-align")}} property, as used with inline-block or table layout for alignment, this will no longer affect the item and you can use the alignment properties of flexbox instead.

+ +

In this next live example the child elements have been floated, and then their container has had display: flex added. If you remove display: flex, you should see that the .box element collapses as we have no clearing applied. This demonstrates that the float is happening. Re-apply display: flex and the collapsing does not happen. This is because the items no longer have a float applied, as they have been transformed into flex items.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/floats.html", '100%', 430)}}

+ +

Flexbox and Grid Layout

+ +

CSS Grid Layout and Flexbox generally act in the same way with regards to overwriting other methods. You might however want to use flexbox as a fallback for grid layout, as there is better support for flexbox in older browsers. This approach works very well. If a flex item becomes a grid item, then the flex properties that may have been assigned to the child elements will be ignored.

+ +

You can use the Box Alignment properties across both layout methods, so using flexbox as a fallback for grid layout can work very well.

+ +

Flex and grid — what's the difference?

+ +

A common question is to ask what the difference is between Flexbox and CSS Grid Layout — why do we have two specifications that sometimes appear to be doing the same thing?

+ +

The most straightforward answer to this question is defined in the specifications themselves. Flexbox is a one-dimensional layout method whereas Grid Layout is a two-dimensional layout method. The example below has a flex layout. As already described in the Basic concepts article, flex items can be allowed to wrap but, once they do so, each line becomes a flex container of its own. When space is distributed flexbox does not look at the placement of items in other rows and tries to line things up with each other.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/flex-layout.html", '100%', 750)}}

+ +

If we create a very similar layout using Grid, we can control the layout in both rows and columns.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/grid-layout.html", '100%', 700)}}

+ +

These examples point to another key difference between these layout methods. In Grid Layout you do the majority of sizing specification on the container, setting up tracks and then placing items into them. In flexbox, while you create a flex container and set the direction at that level, any control over item sizing needs to happen on the items themselves.

+ +

In some cases you could happily use either layout method, but as you become confident with both you will find each one suiting different layout needs, and you will end up with both methods in your CSS. There is rarely a right or wrong answer.

+ +

As a rule of thumb, if you are adding widths to flex items in order to make items in one row of a wrapped flex container line up with the items above them you really want two-dimensional layout. In this case it is likely that the component would be better laid out using CSS Grid Layout. It isn't the case that you should use flexbox for small components and grid layout for larger ones; a tiny component can be two dimensional, and a large layout can be represented better with layout in one dimension. Try things out — we have a choice in layout method for the first time, so take advantage of it.

+ +

For more comparisons of grid and flexbox see the article Relationship of Grid Layout to other layout methods. This article details many of the ways that Grid Layout differs from flex layout, and demonstrates some of the extra functionality you get when using Grid Layout such as layering of items on the grid. This may also help in your decision as to which layout method to use.

+ +

Flexbox and display: contents

+ +

The contents value of the {{cssxref("display")}} property is a new value that is described in the spec as follows:

+ +
+

“The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.”

+
+ +

This value of display controls box generation, and whether the element should generate a box that we can style and see on the page, or whether instead the box it would normally create should be removed and the child elements essentially moved up to participate in whatever layout method the parent would have been part of. This is much easier to see with an example.

+ +

In the following live example I have a flex container with three child elements. One of these flex items has two elements nested inside it, which would not ordinarily participate in flex layout. Flex layout only applies to the direct children of a flex container.

+ +

By adding display: contents to the wrapper around the nested elements, you can see that that item has disappeared from the layout, allowing the two sub-children to be laid out as if they were direct children of the flex container. You can try removing the display: contents line to see it return.

+ +

Note that this only removes the box from the layout; the sub-children don’t become direct children in any other way. You can see that as I have used a direct child selector to add the background and borders to the flex items, this has not been applied to our nested children. They have been laid out as flex items, but as they are not direct children they do not get the other styling.

+ +
+

Warning: Use of display: contents will also remove the element from the accessibility tree – screen readers will not see what's inside, just the same as if you used display: none. Use of contents should only be for presentational, not content, elements.

+
+ +

Also, having removed the box you cannot then use it to — for example — add a background colour behind the nested sub children. If you remove display: contents in this live example you will see that the direct child we are removing has an orange background colour. This also disappears when the box disappears. 

+ +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/display-contents.html", '100%', 650)}}

+ +

Browser support for display:contents is limited and required for this demo to work. Firefox supports display: contents already, and the value is being implemented in Chrome. Once there is better browser support this feature will be very useful in circumstances where you need the markup for semantic reasons but do not want to display the box that it would generate by default.

diff --git a/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html b/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html new file mode 100644 index 0000000000..1b4c283f36 --- /dev/null +++ b/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html @@ -0,0 +1,131 @@ +--- +title: Flexbox典型用例 +slug: Web/CSS/CSS_Flexible_Box_Layout/典型_用例_的_Flexbox +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox +--- +

{{CSSRef}}

+ +

在这个文档中,我们将看一些常见flexbox的用例—这些都是比其他布局更合理的方法。

+ +

为什么选择flexbox?

+ +

在浏览器完美支持的环境中,你选择使用flexbox的原因是你希望把一堆元素不是放在这个方向就是那个方向。 因为在放置元素过程中,你想控制元素在那个方向的维度,或者控制他们彼此之间的间距。flexbox就是为此设计的。. 又可以阅读Relationship of Flexbox to other layout methods来了解更多关于flexbox和CSS Grid布局的区别, 在这篇文章里面,我们会讨论flexbox如何运用与CSS整体布局。

+ +

在现实中,为了便于对齐,我们通常会选择用Flexbox作为替代品,来完成即使用Grid布局更好的情况。一旦盒子对齐(Box Alignment )被盒模型所实行,这种情况就会得到改善。在这个教程中,我们会介绍一些会在现在使用flexbox的用例。

+ +

导航

+ +

导航的一个常见特征,就是使用水平条的样式去呈现一系列元素。这一模式看起来很简单,但是在 flexbox 出现之前却是很难实现的。 它成为一个最简单的 flexbox 示例,可以被被看成是 flexbox 理想的使用场景。

+ +

当我们有一组元素需要水平排列展示,很可能在末尾会多出一些空间。我们需要决定如何去处理这些额外的空间,通常有多种不同的方案。 我们要么在元素外部展示这些空间即使用间距或包裹的方式来分隔开不同元素,要么将空间吸收至元素内部即需要一个方法来允许元素拉伸以占满额外空间。

+ +

在元素外部处理空间分布

+ +

为了让多余的空间分布在多个元素之间或周围,我们使用 flexbox 中相应的对齐属性以及 {{cssxref("justify-content")}} 属性。你可以通过 Aligning Items in a flex container 来阅读更多关于这个专门用来处理主轴(main axis)对齐的属性。

+ +

在下面的示例中,我们让各元素都展示为其自身的尺寸,通过使用 justify-content: space-between 使元素之间拥有相同的空间。你可以通过 space-around 的值来改变空间分布的方式,在浏览器支持的环境下还可以使用 space-evenly。你也可以使用 flex-start 让空间展示在所有元素末尾。使用 flex-end 让空间展示在所有元素之前,  center 可以剧中所有元素。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation.html", '100%', 550)}}

+ +

让元素自己处理空间分布

+ +

导航的另一个不同模式是让元素自己去决定如何处理额外的空间,而不是将空间分布在它们之间。 在这种情况下,我们使用 {{cssxref("flex")}} 属性来允许各元素彼此成比例的拉伸和收缩,正如 Controlling ratios of flex items along the main axis 所描述。

+ +

如果我想让导航中的所有元素都等宽,会使用 flex: auto,这是 flex: 1 1 auto 的简写形式。所有元素都在它们的 flex-basis 尺寸上进行自动的收缩。这意味着,较长的元素会获得更多的空间。因为 flex-basis 的值被设置为 0,所以所有空间都会被平均分配。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation-flex.html", '100%', 550)}}

+ +

拆分导航

+ +

另一种在主轴上对齐元素的方式就是使用自动边距。 这种方式将创造出一部分元素左对齐而另一部分右对齐的导航栏设计。

+ +

这儿我们使用在 Using auto margins for main axis alignment 这篇文章中介绍的自动边距技术。所有的元素在主轴上按照弹性盒布局的默认设定 flex-start 进行对齐,同时我们给那个需要右对齐的元素添加 margin-left: auto; 样式。你可以尝试将那个类名转移到其它元素上以改变(向右)分割作用的位置。

+ +

在这个例子里我们也为每个元素启用了 margin 属性来控制元素间的间隔,并给容器添加负边距以保证元素与容器的接洽处没有缝隙。在弹性盒布局实现盒式对齐规范中的 gap 属性前,如果我们想要控制元素的间隔就不得不使用使用边距属性。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/split-navigation.html", '100%', 550)}}

+ +

元素居中

+ +

在弹性盒布局到来之前,开发者们曾开玩笑说网页设计中最难的部分是垂直居中。 现在,使用弹性盒布局中的对齐属性,这会变得很简单,如下例所示。

+ +

你可以修改对齐方式,用 flex-start 使元素对齐到交叉轴的开始处或者用 flex-end 使元素对齐到交叉轴的结束处。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/center.html", '100%', 700)}}

+ +

在未来,我们可能不需要为了元素的居中而创建一个弹性盒容器,因为盒对齐属性最终会在块布局中实现。但是现在,假如你想在一个元素中居中另一个,弹性盒布局是一个很好的选择。在上面的例子中,将一个元素放入弹性盒容器里之后,要么在容器中使用 align-items, 要么在元素中使用 align-self 来达到所需的效果。

+ +

绝对底部

+ +

不管你使用的是弹性盒还是网格来进行布局,这些布局方式都只对弹性盒容器或者网格容器的(直接)子元素生效。这也意味着即使你的 content 长度不定,组件在高度上仍会充满整个弹性盒容器或者网格容器。但任何使用常规块布局的方法都会导致 content 内容较少时 footer 上升到 content 下方而不是容器的底部。Two card components showing that the internals of the component do not stretch with the wrapper.

+ +

弹性盒就能解决常规块布局的问题。我们创建一个弹性盒容器, 并启用 {{cssxref("flex-direction")}}: column 。之后我们在 content 部分启用 flex: 1 —— flex: 1 1 0 的缩略形式,这个元素就可以在 flex-basis 为零的基础上伸缩。因为这是唯一一个可以延伸的元素,它会占据所有在弹性盒容器中可以占据的空间,同时将 footer 推至底部。如果你移除例子里的属性 flex 你就会看见 footer 回到 content 底部。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/cards.html", '100%', 800)}}

+ +

媒体对象

+ +

媒体对象是网页设计中的常见模式:这种模式下,一侧具有图片或其他元素,另一侧具有文本。理想情况下,媒体对象应该可以翻转:即把图片从左侧移动到右侧。

+ +

这种模式随处可见,用于评论、以及其他需要显示图片和描述的地方。使用flexbox可以允许包含图片的媒体对象部分从图片中获取其尺寸调整信息,并对媒体对象的主体进行弹性布局,以占用剩余空间。

+ +

在下面的实例中,您可以看到我们的媒体对象。使用对齐属性来将交叉轴上的元素对齐到flex-start,然后为.content flex元素设置为flex: 1。与上面的列布局卡片模式一样,启用flex: 1表示此部分卡片可以延伸。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media.html", '100%', 600)}}

+ +

Some things that you might want to try in this live example relate to the different ways you might want to constrain the media object in your design.

+ +

为避免图片过大,可以在为图片添加{{cssxref("max-width")}}。由于媒体对象那一侧使用的是flexbox的初始值,它可以缩小但不会延伸,且其 flex-basis 值是auto。应用于图片的任何{{cssxref("width")}} 或 max-width将会成为flex-basis。

+ +
.image img {
+  max-width: 100px;
+}
+
+ +

你也可以允许双方按比例延伸和缩小。如果将两边都设置为flex: 1,它们从{{cssxref("flex-basis")}}为0增长和缩小,因此最终会得到两个大小相等的列。你可以将内容作为指南,并将其都设置为 flex: auto,这种情况下,它们将从内容的大小或直接应用于弹性元素的任何大小(例如图片的宽度)延伸和缩小。

+ +
.media .content {
+  flex: 1;
+  padding: 10px;
+}
+
+.image {
+  flex: 1;
+}
+ +

You could also give each side different {{cssxref("flex-grow")}} factors, for example setting the side with the image to flex: 1 and the content side to flex: 3. This will mean they use a flex-basis of auto but distribute that space at different rates according to the flex-grow factor you have assigned. The flex properties we use to do this are described in detail in the guide Controlling ratios of flex items along the main axis.

+ +
.media .content {
+  flex: 3;
+  padding: 10px;
+}
+
+.image {
+  flex: 1;
+}
+ +

Flipping the media object

+ +

To switch the display of the media object so that the image is on the right and the content is on the left we can use the flex-direction property set to row-reverse. The media object now displays the other way around. I have achieved this in the live example by adding a class of flipped alongside the existing .media class. This means you can see how the display changes by removing that class from the html.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media-flipped.html", '100%', 650)}}

+ +

Form controls

+ +

Flexbox is particularly useful when it comes to styling form controls. Forms have lots of markup and lots of small elements that we typically want to align with each other. A common pattern is to have an {{htmlelement("input")}} element paired with a {{htmlelement("button")}}, perhaps for a search form or where you simply want your visitor to enter an email address.

+ +

Flexbox makes this type of layout easy to achieve. I have contained my <button> and <input> field in a wrapper which I have given a border and set to display: flex. I then use the flex properties to allow the <input> field to grow, while the button does not grow. This means we have a pair of fields, with the text field growing and shrinking as the available space changes.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/input-button.html", '100%', 550)}}

+ +

You could add a label or icon to the left as easily as we popped the button onto the right. I have added a label, and other than some styling for background colour I didn’t need to change the layout. The stretchy input field now has a little less space to play with but it uses the space left after the two items are accounted for.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/label-input-button.html", '100%', 550)}}

+ +

Patterns like this can make it much easier to create a library of form elements for your design, which easily accommodate additional elements being added. You are taking advantage of the flexibility of flexbox by mixing items that do not grow with those that do.

+ +

结论

+ +

当了解上面的这些示例时,你已经满怀希望的想象怎么找到最好的方式使用弹性盒子布局实现你想要的结果。大部分情况下,你拥有不止一种选择。将可以变化的内容和不能变化的混合在一起,通过内容来决定他们的大小或者允许弹性布局设置按比例分配空间。要因地制宜,对症下药。

+ +

先考虑一下用什么方法展示你的内容比较好,然后在了解怎么用弹性布局或其他布局方法实现你的想法。

diff --git a/files/zh-cn/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html b/files/zh-cn/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html deleted file mode 100644 index d50cf7582f..0000000000 --- a/files/zh-cn/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html +++ /dev/null @@ -1,408 +0,0 @@ ---- -title: 使用 CSS 弹性盒子 -slug: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes -tags: - - CSS - - CSS Flexible Boxes - - Flex - - Web - - flexbox - - 弹性 - - 弹性容器 - - 弹性盒子 - - 弹性项目 - - 指南 - - 盒子模型 - - 范例 - - 进阶 -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 ---- -
{{CSSRef}}
- -

CSS3 弹性盒子(Flexible BoxFlexbox),是一种用于在页面上布置元素的布局模式使得当页面布局必须适应不同的屏幕尺寸和不同的显示设备时,元素可预测地运行。对于许多应用程序,弹性盒子模型提供了对块模型的改进,因为它不使用浮动,flex容器的边缘也不会与其内容的边缘折叠。

- -

许多设计师会发现弹性盒子模型更易于使用。弹性盒子中的子元素可以在各个方向上进行布局,并且能以弹性尺寸来适应显示空间。由于元素的显示顺序可以与它们在源代码中的顺序无关,定位子元素将变得更容易,并且能够用更简单清晰的代码来完成复杂的布局。这种无关性是仅限制于视觉呈现上的,语言顺序以及基于源代码顺序的导航均不受影响。

- -
注意: 虽然 CSS 弹性盒子布局规范 还处于最终征求意见稿 (Last Call Working Draft)阶段(参见最新编辑草案),并非所有浏览器都实现了弹性盒子的所有功能。但,这么说吧,现在全线产品对弹性盒子都有良好支持。最新的兼容性状况可以查看每个具体属性的兼容性表格获取。
- -

弹性盒布局概念

- -

在定义方面来说,弹性布局是指通过调整其内元素的宽高,从而在任何显示设备上实现对可用显示空间最佳填充的能力。弹性容器扩展其内元素来填充可用空间,或将其收缩来避免溢出。

- -

块级布局更侧重于垂直方向、行内布局更侧重于水平方向,与此相对的,弹性盒子布局算法是方向无关的。虽然块级布局对于单独一个页面来说是行之有效的,但其仍缺乏足够的定义来支持那些必须随用户代理(user agent)不同或设备方向从水平转为垂直等各种变化而变换方向、调整大小、拉伸、收缩的应用程序组件。 弹性盒子布局主要适用于应用程序的组件及小规模的布局,而(新兴的)栅格布局则针对大规模的布局。这二者都是 CSS 工作组为在不同用户代理、不同书写模式和其他灵活性要求下的网页应用程序有更好的互操作性而做出的更广泛的努力的一部分。

- -

弹性盒布局相关词汇

- -

关于弹性盒子的讨论已经从诸如水平/行内轴和垂直/块级轴这些术语中解放出来,与此同时,需要有一套新的术语来正确描述此模型。在学习下面的词汇项目时请对照下图。图中是一个 flex-direction 属性为 row的弹性容器,意味着其内的弹性项目将根据既定书写模式沿主轴水平排列,其方向为元素的文本流方向,在这个例子里,为从左到右。

- -

弹性布局相关名词

- -
-
弹性容器(Flex container)
-
包含着弹性项目的父元素。通过设置 {{Cssxref("display")}} 属性的值为 flexinline-flex 来定义弹性容器。
-
弹性项目(Flex item)
-
-

弹性容器的每个子元素都称为弹性项目。弹性容器直接包含的文本将被包覆成匿名弹性单元。

-
-
轴(Axis)
-
-

每个弹性框布局包含两个轴。弹性项目沿其依次排列的那根轴称为主轴(main axis)。垂直于主轴的那根轴称为侧轴(cross axis)

- -
    -
  • flex-direction 确立主轴。
  • -
  • justify-content 定义了在当前行上,弹性项目沿主轴如何排布。
  • -
  • align-items 定义了在当前行上,弹性项目沿侧轴默认如何排布。
  • -
  • align-self 定义了单个弹性项目在侧轴上应当如何对齐,这个定义会覆盖由 align-items 所确立的默认值。
  • -
-
-
方向(Direction)
-
-

弹性容器的主轴起点(main start)/主轴终点(main end)侧轴起点(cross start)/侧轴终点(cross end)描述了弹性项目排布的起点与终点。它们具体取决于弹性容器的主轴与侧轴中,由 writing-mode 确立的方向(从左到右、从右到左,等等)。

- -
    -
  • order 属性将元素与序号关联起来,以此决定哪些元素先出现。
  • -
  • flex-flow 属性是 flex-directionflex-wrap 属性的简写,决定弹性项目如何排布。
  • -
-
-
行(Line)
-
-

根据 flex-wrap 属性,弹性项目可以排布在单个行或者多个行中。此属性控制侧轴的方向和新行排列的方向。

-
-
尺寸(Dimension)
-
-

根据弹性容器的主轴与侧轴,弹性项目的宽和高中,对应主轴的称为主轴尺寸(main size) ,对应侧轴的称为 侧轴尺寸(cross size)

- - -
-
- -

定义一个弹性盒子

- -

为要使用此样式的元素指派 CSS,需按以下方式设置 display 属性:

- -
display : flex
- -

或者

- -
display : inline-flex
- -

这样做将元素定义为弹性容器,其子元素则成为弹性项目。值 flex 使弹性容器成为块级元素。值 inline-flex 使弹性容器成为单个不可分的行内级元素。

- -
注意:厂商前缀标记会附加给 display 属性值,而不是加给 display 属性本身。例如:display : -webkit-flex
- -

弹性项目须知

- -

弹性容器直接包含的文本将自动包覆成匿名弹性项目。不过,一个只包含一系列空白符(如一堆空格或制表符等)的匿名弹性项目不会被渲染,就如同对其指派 display: none

- -

对于弹性容器的绝对定位子元素来说,其静态位置参照弹性容器的内容框的主起始角确定,而后依此完成此元素的定位。

- -

相邻的弹性元素其外边距不会互相合并。使用 auto 外边距可以吸收掉水平或垂直方向上的额外空间,这可以用于对齐或分隔相邻的弹性项目。更多细节请参考 W3C 弹性框布局模型规范中的 Aligning with 'auto' margins

- -

不像 CSS 中的其他对齐方法,弹性框的对齐属性将进行“真正的”居中对齐。这意味着即使弹性条目溢出了弹性容器,它依然保持居中。不过这在某些时候可能会有问题。如果溢出超过了页面的上边缘或左边缘(在从左到右的语言中,比如英语;在诸如阿拉伯语这样从右到左的语言中这个问题更会出现在右边缘),则虽然那些地方确实有内容,却无法滚动到那些位置。在未来的发布版本里,对齐属性将会有所扩展,使其包含有“安全”选项。目前,如果操心这点,可以改用外边距来达成居中效果,因为外边距会用比较“安全”的方式来响应变化,出现溢出时将停止居中。对这种需要居中的弹性项目,不使用 align- 属性,而使用自动外边距就能解决这个问题。对弹性容器中第一个和最后一个弹性项目的外侧边缘应用,也可以使用自动外边距来替代 justify- 属性。自动外边距会自动伸缩来占满剩余空间,当有剩余空间存在时弹性项目将会居中,如果没有则切换至常规对齐方式。不过很不幸,如果尝试在多行的弹性框中用基于外边距的居中方法来替代 justify-content,就必须对每一行的第一个和最后一个弹性项目应用外边距。此时除非能够事先预测每一行都结束于哪个元素,否则就不能愉快的在主轴方向上用基于外边距的居中方法来替代 justify-content 属性了。

- -

再强调一遍,元素的显示顺序与它们在源代码中的顺序无关,这种无关性只影响视觉呈现,语音顺序以及基于源代码顺序的导航均不受影响。{{cssxref("order")}} 属性并不影响语音和导航的次序。因此开发者们必须小心,合理地安排元素在源代码中的顺序,以免破坏文档的可访问性。

- -

弹性盒子相关属性

- -

不影响弹性盒子的属性

- -

由于弹性盒子使用了不同的布局算法,某些属性用在弹性容器上没有意义:

- - - -

示例

- -

基本的弹性布局示例

- -

这个基本的示例展示了如何对元素应用弹性布局,以及在弹性布局状态下相邻元素的行为方式。

- -
<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <style>
-
-   .flex
-   {
-      /* 基本样式 */
-      width: 350px;
-      height: 200px;
-      border: 1px solid #555;
-      font: 14px Arial;
-
-      /*  建立弹性框 */
-      display: -webkit-flex;
-      -webkit-flex-direction: row;
-
-      display: flex;
-      flex-direction: row;
-   }
-
-   .flex > div
-   {
-      -webkit-flex: 1 1 auto;
-      flex: 1 1 auto;
-
-      width: 30px; /* 让过渡表现良好。(从/到"width:auto"的过渡
-                      至少在 Gecko 和 Webkit 上是有 bug 的。
-                      更多信息参见 http://bugzil.la/731886 ) */
-
-      -webkit-transition: width 0.7s ease-out;
-      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>
- -

圣杯布局示例

- -

此示例展示了弹性盒子根据不同屏幕分辨率动态改变布局的能力。下图说明了这种转换。

- -

HolyGrailLayout.png

- -

这里展示的正是针对浏览器窗口的页面布局必须为智能手机窗口优化的场景。不仅元素的尺寸需要缩减,其呈现顺序也需要改变。弹性盒子让这变得很简单。

- -
<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <style>
-
-  body {
-   font: 24px Helvetica;
-   background: #999999;
-  }
-
-  #main {
-   min-height: 800px;
-   margin: 0px;
-   padding: 0px;
-   display: -webkit-flex;
-   display:         flex;
-   -webkit-flex-flow: row;
-           flex-flow: row;
-   }
-
-  #main > article {
-   margin: 4px;
-   padding: 5px;
-   border: 1px solid #cccc33;
-   border-radius: 7pt;
-   background: #dddd88;
-   -webkit-flex: 3 1 60%;
-           flex: 3 1 60%;
-   -webkit-order: 2;
-           order: 2;
-   }
-
-  #main > nav {
-   margin: 4px;
-   padding: 5px;
-   border: 1px solid #8888bb;
-   border-radius: 7pt;
-   background: #ccccff;
-   -webkit-flex: 1 6 20%;
-           flex: 1 6 20%;
-   -webkit-order: 1;
-           order: 1;
-   }
-
-  #main > aside {
-   margin: 4px;
-   padding: 5px;
-   border: 1px solid #8888bb;
-   border-radius: 7pt;
-   background: #ccccff;
-   -webkit-flex: 1 6 20%;
-           flex: 1 6 20%;
-   -webkit-order: 3;
-           order: 3;
-   }
-
-  header, footer {
-   display: block;
-   margin: 4px;
-   padding: 5px;
-   min-height: 100px;
-   border: 1px solid #eebb55;
-   border-radius: 7pt;
-   background: #ffeebb;
-   }
-
-  /* 窄到已不足以支持三栏 */
-  @media all and (max-width: 640px) {
-
-   #main, #page {
-    -webkit-flex-flow: column;
-            flex-direction: column;
-   }
-
-   #main > article, #main > nav, #main > aside {
-    /* 恢复到文档内的自然顺序 */
-    -webkit-order: 0;
-            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>
- -

试验场地

- -

有几个在线弹性盒子试验场地可供进行各种实验:

- - - -

务必牢记

- -

描述弹性项目如何排布的算法有时会极其棘手。在使用弹性盒子进行设计时,请考虑以下几点,以免碰到不好的意料外状况。

- -

弹性盒子的排布与书写模式是一致的,这意味着排布的主轴起点主轴终点根据的是开始结束的位置。

- -

侧轴起点侧轴终点依赖于开始前面(before)的位置定义,而这个“前面”依赖于 direction 的值。

- -

只要 break- 属性的设置值允许,在弹性框布局中是可以存在分页的。CSS3 中的 break-afterbreak-beforebreak-inside,以及 CSS 2.1 中的 page-break-beforepage-break-afterpage-break-inside 属性在弹性容器上、弹性项目上和弹性项目内均可以使用。

- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
特性Firefox (Gecko)ChromeInternet ExplorerOperaSafari
基础支持(单行弹性框){{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]
多行弹性框{{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]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
特性Firefox Mobile (Gecko)Firefox OSAndroidIE PhoneOpera MobileSafari Mobile
基础支持(单行弹性框){{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]
多行弹性框{{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(以及 iOS 7 上的 Safari)已更新为支持最终版本。

- -

[2] 直到 Firefox 22 为止,用户必须修改 about:config 设置,将 layout.css.flexbox.enabled 改为 true 才能激活对弹性盒子的支持。从 Firefox 22 到 Firefox 27,此设置项默认为 true,而 Firefox 28 中取消了此设置项。

- -

[3] Internet Explorer 10 支持的是规范的一个与现有版本不兼容的旧版草案;Internet Explorer 11 已更新为 支持最终版本。

- -

[4] Android 浏览器直到 4.3 为止支持的是规范的一个与现有版本不兼容的旧版草案。Android 4.4 已更新为支持最终版本。

- -

[5] 在 Opera 12.10 的弹性盒子初始实现中是没有前缀的,但 Opera 版本 15 到 16 和 Opera Mobile 的 15 到 19 需要 {{property_prefix("-webkit")}}. 在 Opera 17 及 Opera Mobile 24 中再次取消了前缀。

- -

[6] 直到 Firefox 29 为止,在弹性项目上指定 visibility: collapse 将使其被视为 display: none 处理,而预期的行为是被视为 visibility: hidden。建议的处理方式是在弹性项目上使用 visibility:hidden,这样其行为应当与指派了 visibility:collapse 一致。更多信息,参考 {{bug(783470)}}.

- -

参见

- - diff --git a/files/zh-cn/web/css/css_flexible_box_layout/using_flexbox_to_lay_out_web_applications/index.html b/files/zh-cn/web/css/css_flexible_box_layout/using_flexbox_to_lay_out_web_applications/index.html deleted file mode 100644 index 9ea8045d96..0000000000 --- a/files/zh-cn/web/css/css_flexible_box_layout/using_flexbox_to_lay_out_web_applications/index.html +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: 使用flexbox来布局web应用 -slug: Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications -tags: - - CSS - - 弹性盒子 -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox -translation_of_original: Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications ---- -

{{CSSRef}}

- -

使用 flexbox 可以帮助你设计出引人注目的布局,并且在pc端或移动端能够很好的缩放。告别使用浮动的 {{HTMLElement("div")}} 元素、绝对定位 和一些JavaScript hacks, 使用仅仅几行 CSS 就可以构建出水平或垂直方向的布局。下面是一些基本的使用案例:

- - - -

这篇文章只囊括了在不使用前缀就可以支持现行标准的浏览器下如何使用 flexbox 的相关信息。 想了解更多关于带有供应商前缀的老版本浏览器的资料,请点击这里 the more general guide to using CSS flexible boxes.

- -

基础

- -

如果你想让元素呈水平或柱状,或如果你想让元素垂直布局,在任何 {{HTMLElement("div")}} 元素中,通过设置 {{cssxref("display")}} 属性为 flex 来使用flexbox,然后设置它任意一行的 {{cssxref("flex-flow")}} 属性, 你就可以在其中尽情的创建元素了。如果你正在使用水平的 flexbox,并想让你的内容垂直换行,只需指定值为wrap。

- -

接下来,只要你想让某个元素使用弹性布局,就为它添加 {{cssxref("flex")}} 属性。一般情况下,你将会使用下列三个值之一:

- - - -

有可能还有使用方法,但是这应该囊括了最基本的使用案例。让我们用几个例子来看看如何使用。

- -

示例 1: 在页面中把一个元素居中

- -

在这个例子中,要做的最简单的事情就是创建两个 flexbox,其中一个在另一个中。每个 flexbox 有三个元素:其中两个当作中间元素的垫子,另一个就是中间元素本身。

- -

CSS 内容

- -
.vertical-box {
-  display: flex;
-  height: 400px;
-  width: 400px;
-  flex-flow: column;
-}
-.horizontal-box {
-  display: flex;
-  flex-flow: row;
-}
-.spacer {
-  flex: auto;
-  background-color: black;
-}
-.centered-element {
-  flex: none;
-  background-color: white;
-}
-
- -

HTML 内容

- -
<div class="vertical-box">
-  <div class="spacer"></div>
-  <div class="centered-element horizontal-box">
-    <div class="spacer"></div>
-    <div class="centered-element">Centered content</div>
-     <div class="spacer"></div>
-  </div>
-  <div class="spacer"></div>
-</div>
-
- -

结果

- -

{{ EmbedLiveSample('示例_1_在页面中把一个元素居中', 500, 500) }}

- -

示例2: 垂直放置一系列的容器

- -

假设你有一个带有头部区域,内容区域,和底部区域的页面。头部和底部应该有一个固定的尺寸,但是内容区域应该根据可以利用的空间来缩放。这可以通过设置内容区域的 {{cssxref("flex")}} 属性,设置头部区域 {{cssxref("flex")}} 属性,底部区域不设置来实现自动扩展功能。

- -

CSS 内容

- -
.vertical-box {
-  display: flex;
-  height: 400px;
-  width: 400px;
-  flex-flow: column;
-}
-.fixed-size {
-  flex: none;
-  height: 30px;
-  background-color: black;
-  text-align: center;
-}
-.flexible-size {
-  flex: auto;
-  background-color: white;
-}
-
- -

HTML 内容

- -
<div id="document" class="vertical-box">
-  <div class="fixed-size"><button id="increase-size">Increase container size</button></div>
-  <div id="flexible-content" class="flexible-size"></div>
-  <div class="fixed-size"><button id="decrease-size">Decrease container size</button></div>
-</div>
-
- -

Javascript 内容

- -
var height = 400;
-document.getElementById('increase-size').onclick=function() {
-  height += 10;
-  if (height > 500) height = 500;
-  document.getElementById('document').style.height = (height + "px");
-}
-
-document.getElementById('decrease-size').onclick=function() {
-  height -= 10;
-  if (height < 300) height = 300;
-  document.getElementById('document').style.height = (height + "px");
-}
- -

结果

- -

{{ EmbedLiveSample('示例2_垂直放置一系列的容器', 500, 500) }}

- -

这个例子已经设定好了,可以通过点击头部来增加尺寸,通过点击底部来减小尺寸。仔细观察在保持头部和底部尺寸不变的情况下,内容区域是如何自动缩放的。

- -

示例3: 创建一个水平折叠的容器

- -

在某些时候,你可能想让一些信息在屏幕尺寸允许的情况下呈水平布局,但是在屏幕不允许的情况下可以水平折叠。这对 flexbox 来讲太容易实现了。你通过设置 {{cssxref("flex-flow")}} 的值为 wrap 来实现。

- -

CSS 内容

- -
.horizontal-container {
-  display: flex;
-  width: 300px;
-  flex-flow: row wrap;
-}
-.fixed-size {
-  flex: none;
-  width: 100px;
-  background-color: black;
-  color: white;
-  text-align: center;
-}
-
- -

HTML 内容

- -
<div id="container" class="horizontal-container">
-  <div class="fixed-size">Element 1</div>
-  <div class="fixed-size">Element 2</div>
-  <div class="fixed-size">Element 3</div>
-</div><button id="increase-size">Increase container size</button><button id="decrease-size">Decrease container size</button>
-
- -

Javascript 内容

- -
var width = 300;
-
-document.getElementById('increase-size').onclick=function() {
-  width += 100;
-  if (width > 300) width = 300;
-  document.getElementById('container').style.width = (width + "px");
-}
-
-document.getElementById('decrease-size').onclick=function() {
-  width -= 100;
-  if (width < 100) width = 100;
-  document.getElementById('container').style.width = (width + "px");
-}
-
- -

结果

- -

{{ EmbedLiveSample('示例3_创建一个水平折叠的容器', 500, 200) }}

- -

参考

- - diff --git "a/files/zh-cn/web/css/css_flexible_box_layout/\345\205\270\345\236\213_\347\224\250\344\276\213_\347\232\204_flexbox/index.html" "b/files/zh-cn/web/css/css_flexible_box_layout/\345\205\270\345\236\213_\347\224\250\344\276\213_\347\232\204_flexbox/index.html" deleted file mode 100644 index 1b4c283f36..0000000000 --- "a/files/zh-cn/web/css/css_flexible_box_layout/\345\205\270\345\236\213_\347\224\250\344\276\213_\347\232\204_flexbox/index.html" +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: Flexbox典型用例 -slug: Web/CSS/CSS_Flexible_Box_Layout/典型_用例_的_Flexbox -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox ---- -

{{CSSRef}}

- -

在这个文档中,我们将看一些常见flexbox的用例—这些都是比其他布局更合理的方法。

- -

为什么选择flexbox?

- -

在浏览器完美支持的环境中,你选择使用flexbox的原因是你希望把一堆元素不是放在这个方向就是那个方向。 因为在放置元素过程中,你想控制元素在那个方向的维度,或者控制他们彼此之间的间距。flexbox就是为此设计的。. 又可以阅读Relationship of Flexbox to other layout methods来了解更多关于flexbox和CSS Grid布局的区别, 在这篇文章里面,我们会讨论flexbox如何运用与CSS整体布局。

- -

在现实中,为了便于对齐,我们通常会选择用Flexbox作为替代品,来完成即使用Grid布局更好的情况。一旦盒子对齐(Box Alignment )被盒模型所实行,这种情况就会得到改善。在这个教程中,我们会介绍一些会在现在使用flexbox的用例。

- -

导航

- -

导航的一个常见特征,就是使用水平条的样式去呈现一系列元素。这一模式看起来很简单,但是在 flexbox 出现之前却是很难实现的。 它成为一个最简单的 flexbox 示例,可以被被看成是 flexbox 理想的使用场景。

- -

当我们有一组元素需要水平排列展示,很可能在末尾会多出一些空间。我们需要决定如何去处理这些额外的空间,通常有多种不同的方案。 我们要么在元素外部展示这些空间即使用间距或包裹的方式来分隔开不同元素,要么将空间吸收至元素内部即需要一个方法来允许元素拉伸以占满额外空间。

- -

在元素外部处理空间分布

- -

为了让多余的空间分布在多个元素之间或周围,我们使用 flexbox 中相应的对齐属性以及 {{cssxref("justify-content")}} 属性。你可以通过 Aligning Items in a flex container 来阅读更多关于这个专门用来处理主轴(main axis)对齐的属性。

- -

在下面的示例中,我们让各元素都展示为其自身的尺寸,通过使用 justify-content: space-between 使元素之间拥有相同的空间。你可以通过 space-around 的值来改变空间分布的方式,在浏览器支持的环境下还可以使用 space-evenly。你也可以使用 flex-start 让空间展示在所有元素末尾。使用 flex-end 让空间展示在所有元素之前,  center 可以剧中所有元素。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation.html", '100%', 550)}}

- -

让元素自己处理空间分布

- -

导航的另一个不同模式是让元素自己去决定如何处理额外的空间,而不是将空间分布在它们之间。 在这种情况下,我们使用 {{cssxref("flex")}} 属性来允许各元素彼此成比例的拉伸和收缩,正如 Controlling ratios of flex items along the main axis 所描述。

- -

如果我想让导航中的所有元素都等宽,会使用 flex: auto,这是 flex: 1 1 auto 的简写形式。所有元素都在它们的 flex-basis 尺寸上进行自动的收缩。这意味着,较长的元素会获得更多的空间。因为 flex-basis 的值被设置为 0,所以所有空间都会被平均分配。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation-flex.html", '100%', 550)}}

- -

拆分导航

- -

另一种在主轴上对齐元素的方式就是使用自动边距。 这种方式将创造出一部分元素左对齐而另一部分右对齐的导航栏设计。

- -

这儿我们使用在 Using auto margins for main axis alignment 这篇文章中介绍的自动边距技术。所有的元素在主轴上按照弹性盒布局的默认设定 flex-start 进行对齐,同时我们给那个需要右对齐的元素添加 margin-left: auto; 样式。你可以尝试将那个类名转移到其它元素上以改变(向右)分割作用的位置。

- -

在这个例子里我们也为每个元素启用了 margin 属性来控制元素间的间隔,并给容器添加负边距以保证元素与容器的接洽处没有缝隙。在弹性盒布局实现盒式对齐规范中的 gap 属性前,如果我们想要控制元素的间隔就不得不使用使用边距属性。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/split-navigation.html", '100%', 550)}}

- -

元素居中

- -

在弹性盒布局到来之前,开发者们曾开玩笑说网页设计中最难的部分是垂直居中。 现在,使用弹性盒布局中的对齐属性,这会变得很简单,如下例所示。

- -

你可以修改对齐方式,用 flex-start 使元素对齐到交叉轴的开始处或者用 flex-end 使元素对齐到交叉轴的结束处。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/center.html", '100%', 700)}}

- -

在未来,我们可能不需要为了元素的居中而创建一个弹性盒容器,因为盒对齐属性最终会在块布局中实现。但是现在,假如你想在一个元素中居中另一个,弹性盒布局是一个很好的选择。在上面的例子中,将一个元素放入弹性盒容器里之后,要么在容器中使用 align-items, 要么在元素中使用 align-self 来达到所需的效果。

- -

绝对底部

- -

不管你使用的是弹性盒还是网格来进行布局,这些布局方式都只对弹性盒容器或者网格容器的(直接)子元素生效。这也意味着即使你的 content 长度不定,组件在高度上仍会充满整个弹性盒容器或者网格容器。但任何使用常规块布局的方法都会导致 content 内容较少时 footer 上升到 content 下方而不是容器的底部。Two card components showing that the internals of the component do not stretch with the wrapper.

- -

弹性盒就能解决常规块布局的问题。我们创建一个弹性盒容器, 并启用 {{cssxref("flex-direction")}}: column 。之后我们在 content 部分启用 flex: 1 —— flex: 1 1 0 的缩略形式,这个元素就可以在 flex-basis 为零的基础上伸缩。因为这是唯一一个可以延伸的元素,它会占据所有在弹性盒容器中可以占据的空间,同时将 footer 推至底部。如果你移除例子里的属性 flex 你就会看见 footer 回到 content 底部。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/cards.html", '100%', 800)}}

- -

媒体对象

- -

媒体对象是网页设计中的常见模式:这种模式下,一侧具有图片或其他元素,另一侧具有文本。理想情况下,媒体对象应该可以翻转:即把图片从左侧移动到右侧。

- -

这种模式随处可见,用于评论、以及其他需要显示图片和描述的地方。使用flexbox可以允许包含图片的媒体对象部分从图片中获取其尺寸调整信息,并对媒体对象的主体进行弹性布局,以占用剩余空间。

- -

在下面的实例中,您可以看到我们的媒体对象。使用对齐属性来将交叉轴上的元素对齐到flex-start,然后为.content flex元素设置为flex: 1。与上面的列布局卡片模式一样,启用flex: 1表示此部分卡片可以延伸。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media.html", '100%', 600)}}

- -

Some things that you might want to try in this live example relate to the different ways you might want to constrain the media object in your design.

- -

为避免图片过大,可以在为图片添加{{cssxref("max-width")}}。由于媒体对象那一侧使用的是flexbox的初始值,它可以缩小但不会延伸,且其 flex-basis 值是auto。应用于图片的任何{{cssxref("width")}} 或 max-width将会成为flex-basis。

- -
.image img {
-  max-width: 100px;
-}
-
- -

你也可以允许双方按比例延伸和缩小。如果将两边都设置为flex: 1,它们从{{cssxref("flex-basis")}}为0增长和缩小,因此最终会得到两个大小相等的列。你可以将内容作为指南,并将其都设置为 flex: auto,这种情况下,它们将从内容的大小或直接应用于弹性元素的任何大小(例如图片的宽度)延伸和缩小。

- -
.media .content {
-  flex: 1;
-  padding: 10px;
-}
-
-.image {
-  flex: 1;
-}
- -

You could also give each side different {{cssxref("flex-grow")}} factors, for example setting the side with the image to flex: 1 and the content side to flex: 3. This will mean they use a flex-basis of auto but distribute that space at different rates according to the flex-grow factor you have assigned. The flex properties we use to do this are described in detail in the guide Controlling ratios of flex items along the main axis.

- -
.media .content {
-  flex: 3;
-  padding: 10px;
-}
-
-.image {
-  flex: 1;
-}
- -

Flipping the media object

- -

To switch the display of the media object so that the image is on the right and the content is on the left we can use the flex-direction property set to row-reverse. The media object now displays the other way around. I have achieved this in the live example by adding a class of flipped alongside the existing .media class. This means you can see how the display changes by removing that class from the html.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media-flipped.html", '100%', 650)}}

- -

Form controls

- -

Flexbox is particularly useful when it comes to styling form controls. Forms have lots of markup and lots of small elements that we typically want to align with each other. A common pattern is to have an {{htmlelement("input")}} element paired with a {{htmlelement("button")}}, perhaps for a search form or where you simply want your visitor to enter an email address.

- -

Flexbox makes this type of layout easy to achieve. I have contained my <button> and <input> field in a wrapper which I have given a border and set to display: flex. I then use the flex properties to allow the <input> field to grow, while the button does not grow. This means we have a pair of fields, with the text field growing and shrinking as the available space changes.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/input-button.html", '100%', 550)}}

- -

You could add a label or icon to the left as easily as we popped the button onto the right. I have added a label, and other than some styling for background colour I didn’t need to change the layout. The stretchy input field now has a little less space to play with but it uses the space left after the two items are accounted for.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/label-input-button.html", '100%', 550)}}

- -

Patterns like this can make it much easier to create a library of form elements for your design, which easily accommodate additional elements being added. You are taking advantage of the flexibility of flexbox by mixing items that do not grow with those that do.

- -

结论

- -

当了解上面的这些示例时,你已经满怀希望的想象怎么找到最好的方式使用弹性盒子布局实现你想要的结果。大部分情况下,你拥有不止一种选择。将可以变化的内容和不能变化的混合在一起,通过内容来决定他们的大小或者允许弹性布局设置按比例分配空间。要因地制宜,对症下药。

- -

先考虑一下用什么方法展示你的内容比较好,然后在了解怎么用弹性布局或其他布局方法实现你的想法。

diff --git "a/files/zh-cn/web/css/css_flexible_box_layout/\345\274\271\346\200\247\347\233\222\345\255\220\344\270\216\345\205\266\344\273\226\345\270\203\345\261\200\346\226\271\346\263\225\347\232\204\350\201\224\347\263\273/index.html" "b/files/zh-cn/web/css/css_flexible_box_layout/\345\274\271\346\200\247\347\233\222\345\255\220\344\270\216\345\205\266\344\273\226\345\270\203\345\261\200\346\226\271\346\263\225\347\232\204\350\201\224\347\263\273/index.html" deleted file mode 100644 index c90b3416a5..0000000000 --- "a/files/zh-cn/web/css/css_flexible_box_layout/\345\274\271\346\200\247\347\233\222\345\255\220\344\270\216\345\205\266\344\273\226\345\270\203\345\261\200\346\226\271\346\263\225\347\232\204\350\201\224\347\263\273/index.html" +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: 弹性盒子与其他布局方法的联系 -slug: Web/CSS/CSS_Flexible_Box_Layout/弹性盒子与其他布局方法的联系 -tags: - - CSS - - box alignment - - flexbox -translation_of: >- - Web/CSS/CSS_Flexible_Box_Layout/Relationship_of_Flexbox_to_Other_Layout_Methods ---- -
{{CSSRef}}
- -

在本文中,我们将了解弹性盒子(Flexbox)如何与所有其他CSS模块相适应。如果您想学习flexbox,我们将一起找出需要注意的规范和flexbox与一些其他模块不同的原因。

- -
-

注意:CSS 1和CSS 2是一个单一的整体规范,其中所有CSS都定义在一个文档中。随着CSS成为一种功能更加丰富的语言,各个部分有不同的发展速度,如何维护一个庞大的规范就成了问题。因此现在的CSS是模块化的,不同的CSS模块有不同的规范,一起构成了现在的CSS。这些模块之间相互关联,并且处于不同的开发阶段。

-
- -

box alignment 模块

- -

许多人开始关注flexbox的最初原因是在flex容器中能够很好的对齐其中的元素。flexbox可以设置在其交叉轴以及主轴上的对齐属性。

- -

这些属性最开始出现在flexbox规范中,现在已经成为Box Alignment规范的一部分。 这个规范详细说明了在所有布局中(不仅仅是flexbox)对齐属性是如何起作用的。 对齐属性用于设置元素对齐方式和沿轴的空间分配。

- -

之所以在flexbox规范和box alignment模块规范中都有对对齐属性的详细描述,是为了确保flexbox规范的完成不会受box alignment模块规范的影响,因为后者需要详细说明所有的布局类型中的对齐方法。flexbox规范中有一条注释指出将来一旦Box Alignment Level 3完成,它将会取代flexbox规范中的相关定义:

- -
-

“注意:虽然对齐属性是在CSS Box Alignment [CSS-ALIGN-3]中定义的,但“ Flexible Box Layout”在此处重现了相关属性的定义,以免形成规范性的依赖关系,而这可能会减慢规范的发展。这些属性仅适用于Flex布局,直到CSS Box Alignment Level 3完成并定义其对其他布局模式的效果;此外,在Box Alignment模块中定义的任何新值都将应用于Flexible Box Layout;换句话说,一旦Box Alignment模块完成,其中的相关定义将取代此处的定义。”

-
- -

在本系列的后续文章(在flex容器中对齐元素)中,我们将彻底研究Box Alignment属性如何应用于flex元素。

- -

gap属性

- -

属性{{cssxref("row-gap")}} 和 {{cssxref("column-gap")}},其简写为{{cssxref("gap")}},近期添加到了盒子布局规范中。这些属性(名称为grid-row-gap, grid-column-gap and grid-gap)最初定义在CSS网格布局中。但是他们被重命名并移入盒子布局规范。这样的话,所有的布局方法都可以使用这些属性。不过在浏览器实现Flex的这些属性之前只能通过{{cssxref("margin")}} 来控制元素之间的间隙距离。

- -

Writing Modes

- -

In the Basic concepts of flexbox article, I explained that flexbox is writing mode aware. Writing modes are fully detailed in the CSS Writing Modes specification, which details how CSS supports the various different writing modes that exist internationally. We need to be aware of how this will impact our flex layouts as writing mode changes the direction that blocks are laid out in our document. Understanding block and inline directions is key to new layout methods.

- -

It is worth noting that we might want to change the writing mode of our document for reasons other than publishing content in a language that uses a different writing mode. See this article for a full description of writing modes and ways to use them, both for content in other languages and for creative reasons. 

- -

The writing modes

- -

The writing modes specification defines the following values of the {{cssxref("writing-mode")}} property, which serve to change the direction that blocks are laid out on the page, to match the direction that blocks lay out when content is formatted in that particular writing mode. You can change the live example below to these modes in order to see what happens to the flex layout.

- - - -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/writing-modes.html", '100%', 360)}} 

- -

Note that sideways-rl and sideways-lr have support only in Firefox currently. There are also some known issues with regard to writing-mode and flexbox. You can see more information on browser support in the MDN documentation for writing-mode. However if you are planning on using writing modes in your layout, carefully testing the results is advisable — not least because it would be easy to make things hard to read!

- -

Note that you would not normally use CSS and the writing-mode property to change an entire document to another writing mode. This would be done via HTML, by adding a dir and lang attribute to the html element to indicate the document language and default text direction. This would mean that the document would display correctly even if CSS did not load.

- -

Flexbox and other layout methods

- -

The flexbox specification contains a definition of what happens if an item uses another layout method and then becomes a flex item. For example, if an item is floated and then its parent becomes a flex container. Or, how a flex container behaves as part of layout.

- -

An element set to display: flex behaves in most ways like any other block level container that establishes a containing block. Floats will not intrude, and the containers' margins will not collapse.

- -

With regard to flex items, if an item was floated or cleared and then becomes a flex item due to the parent having display: flex applied, the floating and clearing will no longer happen, and the item will not be taken out of normal flow in the way that floats are. If you have used the {{cssxref("vertical-align")}} property, as used with inline-block or table layout for alignment, this will no longer affect the item and you can use the alignment properties of flexbox instead.

- -

In this next live example the child elements have been floated, and then their container has had display: flex added. If you remove display: flex, you should see that the .box element collapses as we have no clearing applied. This demonstrates that the float is happening. Re-apply display: flex and the collapsing does not happen. This is because the items no longer have a float applied, as they have been transformed into flex items.

- -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/floats.html", '100%', 430)}}

- -

Flexbox and Grid Layout

- -

CSS Grid Layout and Flexbox generally act in the same way with regards to overwriting other methods. You might however want to use flexbox as a fallback for grid layout, as there is better support for flexbox in older browsers. This approach works very well. If a flex item becomes a grid item, then the flex properties that may have been assigned to the child elements will be ignored.

- -

You can use the Box Alignment properties across both layout methods, so using flexbox as a fallback for grid layout can work very well.

- -

Flex and grid — what's the difference?

- -

A common question is to ask what the difference is between Flexbox and CSS Grid Layout — why do we have two specifications that sometimes appear to be doing the same thing?

- -

The most straightforward answer to this question is defined in the specifications themselves. Flexbox is a one-dimensional layout method whereas Grid Layout is a two-dimensional layout method. The example below has a flex layout. As already described in the Basic concepts article, flex items can be allowed to wrap but, once they do so, each line becomes a flex container of its own. When space is distributed flexbox does not look at the placement of items in other rows and tries to line things up with each other.

- -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/flex-layout.html", '100%', 750)}}

- -

If we create a very similar layout using Grid, we can control the layout in both rows and columns.

- -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/grid-layout.html", '100%', 700)}}

- -

These examples point to another key difference between these layout methods. In Grid Layout you do the majority of sizing specification on the container, setting up tracks and then placing items into them. In flexbox, while you create a flex container and set the direction at that level, any control over item sizing needs to happen on the items themselves.

- -

In some cases you could happily use either layout method, but as you become confident with both you will find each one suiting different layout needs, and you will end up with both methods in your CSS. There is rarely a right or wrong answer.

- -

As a rule of thumb, if you are adding widths to flex items in order to make items in one row of a wrapped flex container line up with the items above them you really want two-dimensional layout. In this case it is likely that the component would be better laid out using CSS Grid Layout. It isn't the case that you should use flexbox for small components and grid layout for larger ones; a tiny component can be two dimensional, and a large layout can be represented better with layout in one dimension. Try things out — we have a choice in layout method for the first time, so take advantage of it.

- -

For more comparisons of grid and flexbox see the article Relationship of Grid Layout to other layout methods. This article details many of the ways that Grid Layout differs from flex layout, and demonstrates some of the extra functionality you get when using Grid Layout such as layering of items on the grid. This may also help in your decision as to which layout method to use.

- -

Flexbox and display: contents

- -

The contents value of the {{cssxref("display")}} property is a new value that is described in the spec as follows:

- -
-

“The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.”

-
- -

This value of display controls box generation, and whether the element should generate a box that we can style and see on the page, or whether instead the box it would normally create should be removed and the child elements essentially moved up to participate in whatever layout method the parent would have been part of. This is much easier to see with an example.

- -

In the following live example I have a flex container with three child elements. One of these flex items has two elements nested inside it, which would not ordinarily participate in flex layout. Flex layout only applies to the direct children of a flex container.

- -

By adding display: contents to the wrapper around the nested elements, you can see that that item has disappeared from the layout, allowing the two sub-children to be laid out as if they were direct children of the flex container. You can try removing the display: contents line to see it return.

- -

Note that this only removes the box from the layout; the sub-children don’t become direct children in any other way. You can see that as I have used a direct child selector to add the background and borders to the flex items, this has not been applied to our nested children. They have been laid out as flex items, but as they are not direct children they do not get the other styling.

- -
-

Warning: Use of display: contents will also remove the element from the accessibility tree – screen readers will not see what's inside, just the same as if you used display: none. Use of contents should only be for presentational, not content, elements.

-
- -

Also, having removed the box you cannot then use it to — for example — add a background colour behind the nested sub children. If you remove display: contents in this live example you will see that the direct child we are removing has an orange background colour. This also disappears when the box disappears. 

- -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/display-contents.html", '100%', 650)}}

- -

Browser support for display:contents is limited and required for this demo to work. Firefox supports display: contents already, and the value is being implemented in Chrome. Once there is better browser support this feature will be very useful in circumstances where you need the markup for semantic reasons but do not want to display the box that it would generate by default.

diff --git a/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html b/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html new file mode 100644 index 0000000000..2c84dc8384 --- /dev/null +++ b/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html @@ -0,0 +1,64 @@ +--- +title: In Flow and Out of Flow +slug: Web/CSS/CSS_Flow_Layout/在Flow中和Flow之外 +translation_of: Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow +--- +
{{CSSRef}}
+ +

在之前的 文档中我解释了常规流中块(block)和行(inline)布局,常规流中的所有元素都会以这种布局方式运作。

+ +

在下面的例子中,我新建了一个标题(h1元素),一个段落(p元素),一个无序列表(ul元素)和一个包含strong元素的段落(p元素),标题和段落都是块级(block level),strong元素为行级(inline)。列表中的项通过弹性盒布局排成一行,但是列表本身仍然处于块和内联布局中 - 他的display属性为block。

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/in-flow.html", '100%', 800)}}

+ +

可以说,示例中的所有元素都属于常规流,按照源代码中的顺序渲染到页面中。

+ +

脱离常规流的元素

+ +

下列元素会脱离常规流:

+ + + +

脱离常规流的元素会创建一个新的块级格式化上下文(Block Formatting Context: BFC)环境,其中包含的所有元素构成了一个小的布局环境,与页面中的其他内容分隔开来。而根元素,作为页面中所有内容的容器,自身脱离常规流,为整个文档创建了一个块级格式化上下文环境。

+ +

Floated Items

+ +

在这个例子中,我有一个div,以及两个段落。我已经为段落添加了背景颜色,然后将div向左浮动。 div现在已经不再处于flow中了。

+ +

作为一个浮动的元素,它首先根据正常flow布局,然后从流动中取出并尽可能地向左移动

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/float.html", '100%', 800)}}

+ +

你可以看到下面段落的背景颜色在下面运行,只是该段落的行框已被缩短以导致在浮动周围包裹内容的效果。我们段落的方框仍然按照正常流程规则显示。这就是为什么要在浮动项目周围留出空间,必须为项目添加边距,以便将线框推离它。您无法对以下内插内容应用任何内容来实现此目的。

+ +

Absolute Positioning

+ +

设置元素属性为 position: absolute 或者 position: fixed 会使此元素脱离文档流, 他本来占据的空间也会被移除. 在下面的例子中,我定义了三个p元素,并且将第二个p元素设置为 position absolute,  top: 30px , right: 30px. 使其脱离文档流。

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/abspos.html", '100%', 700)}}

+ +

设置 position: fixed 也能使元素脱离文档流, 但是偏移量会根据视口而不是父元素来定。

+ +

当通过定位方式使元素脱离文档流,元素内容可能重叠,这需要你自己去处理。脱离文档流意味着页面中的其他元素不知道该元素的存在,故不会对该元素做出响应。

+ +

Relative Positioning and Flow

+ +

如果你给一个元素开启相对定位,那该元素依然会位于文档流中,然而你可以通过设置偏移值的方式来移动他。正如下面的例子所展示的,该元素的原先占据的空间仍然会被保留。

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/relative.html", '100%', 800)}}

+ +

当你移动一个元素或者使元素脱离文档流,为防止重叠,你可能需要对元素内容和元素周围的内容做一些管理,要么清除浮动, 要么保证相对定位不会覆盖其他元素。

+ +

Summary

+ +

In this guide we have covered the ways to take an element out of flow in order to achieve some very specific types of positioning. In the next guide we will look at a related issue, that of creating a Block Formatting Context, in Formatting Contexts Explained.

+ +

See Also

+ + diff --git "a/files/zh-cn/web/css/css_flow_layout/\345\234\250flow\344\270\255\345\222\214flow\344\271\213\345\244\226/index.html" "b/files/zh-cn/web/css/css_flow_layout/\345\234\250flow\344\270\255\345\222\214flow\344\271\213\345\244\226/index.html" deleted file mode 100644 index 2c84dc8384..0000000000 --- "a/files/zh-cn/web/css/css_flow_layout/\345\234\250flow\344\270\255\345\222\214flow\344\271\213\345\244\226/index.html" +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: In Flow and Out of Flow -slug: Web/CSS/CSS_Flow_Layout/在Flow中和Flow之外 -translation_of: Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow ---- -
{{CSSRef}}
- -

在之前的 文档中我解释了常规流中块(block)和行(inline)布局,常规流中的所有元素都会以这种布局方式运作。

- -

在下面的例子中,我新建了一个标题(h1元素),一个段落(p元素),一个无序列表(ul元素)和一个包含strong元素的段落(p元素),标题和段落都是块级(block level),strong元素为行级(inline)。列表中的项通过弹性盒布局排成一行,但是列表本身仍然处于块和内联布局中 - 他的display属性为block。

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/in-flow.html", '100%', 800)}}

- -

可以说,示例中的所有元素都属于常规流,按照源代码中的顺序渲染到页面中。

- -

脱离常规流的元素

- -

下列元素会脱离常规流:

- - - -

脱离常规流的元素会创建一个新的块级格式化上下文(Block Formatting Context: BFC)环境,其中包含的所有元素构成了一个小的布局环境,与页面中的其他内容分隔开来。而根元素,作为页面中所有内容的容器,自身脱离常规流,为整个文档创建了一个块级格式化上下文环境。

- -

Floated Items

- -

在这个例子中,我有一个div,以及两个段落。我已经为段落添加了背景颜色,然后将div向左浮动。 div现在已经不再处于flow中了。

- -

作为一个浮动的元素,它首先根据正常flow布局,然后从流动中取出并尽可能地向左移动

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/float.html", '100%', 800)}}

- -

你可以看到下面段落的背景颜色在下面运行,只是该段落的行框已被缩短以导致在浮动周围包裹内容的效果。我们段落的方框仍然按照正常流程规则显示。这就是为什么要在浮动项目周围留出空间,必须为项目添加边距,以便将线框推离它。您无法对以下内插内容应用任何内容来实现此目的。

- -

Absolute Positioning

- -

设置元素属性为 position: absolute 或者 position: fixed 会使此元素脱离文档流, 他本来占据的空间也会被移除. 在下面的例子中,我定义了三个p元素,并且将第二个p元素设置为 position absolute,  top: 30px , right: 30px. 使其脱离文档流。

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/abspos.html", '100%', 700)}}

- -

设置 position: fixed 也能使元素脱离文档流, 但是偏移量会根据视口而不是父元素来定。

- -

当通过定位方式使元素脱离文档流,元素内容可能重叠,这需要你自己去处理。脱离文档流意味着页面中的其他元素不知道该元素的存在,故不会对该元素做出响应。

- -

Relative Positioning and Flow

- -

如果你给一个元素开启相对定位,那该元素依然会位于文档流中,然而你可以通过设置偏移值的方式来移动他。正如下面的例子所展示的,该元素的原先占据的空间仍然会被保留。

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/relative.html", '100%', 800)}}

- -

当你移动一个元素或者使元素脱离文档流,为防止重叠,你可能需要对元素内容和元素周围的内容做一些管理,要么清除浮动, 要么保证相对定位不会覆盖其他元素。

- -

Summary

- -

In this guide we have covered the ways to take an element out of flow in order to achieve some very specific types of positioning. In the next guide we will look at a related issue, that of creating a Block Formatting Context, in Formatting Contexts Explained.

- -

See Also

- - diff --git a/files/zh-cn/web/css/css_fragmentation/index.html b/files/zh-cn/web/css/css_fragmentation/index.html new file mode 100644 index 0000000000..5b0d8e7a13 --- /dev/null +++ b/files/zh-cn/web/css/css_fragmentation/index.html @@ -0,0 +1,46 @@ +--- +title: CSS分片 +slug: Web/CSS/CSS_分片 +tags: + - CSS + - CSS分片 + - 参考 +translation_of: Web/CSS/CSS_Fragmentation +--- +
{{cssref}}
+ +

CSS FragmentationCSS的模块,它定义了内容在跨多个页面,区域或列中被分割(分段)时如何显示

+ +

当一个内联框包装成多行时会发生碎片。当一个块跨越一个列布局容器内的多个列,或者在打印时跨越一个分页符时,也会发生这种情况。元素的每个渲染片段称为一个片段

+ +

参考

+ +
+ +
+ +

规格

+ + + + + + + + + + + + + + + + +
规格状态评论
{{SpecName('CSS3 Fragmentation')}}{{Spec2('CSS3 Fragmentation')}}初始定义。
diff --git a/files/zh-cn/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html b/files/zh-cn/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html deleted file mode 100644 index 936634c06c..0000000000 --- a/files/zh-cn/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html +++ /dev/null @@ -1,502 +0,0 @@ ---- -title: CSS 网格,逻辑值和书写模式 -slug: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' -tags: - - CSS - - CSS 指南 - - 指南 -translation_of: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' ---- -

在前面的文章中,我们已经接触了网格布局的一个重要特性:被纳入规范的对不同书写模式的支持。本文我们将探讨在网格和其他现代布局方式下的这个特性的表现,以及学习一些关于书写模式和逻辑属性与物理属性的知识。

- -

逻辑属性与物理属性及逻辑值与物理值

- -

CSS 中布满了物理位置的关键字 —— left 和 right,top 和 bottom。当使用绝对位置来定位项目时,就要使项目围绕上用物理关键字描述的偏移量。在下面的代码片断中,项目被定位到距容器顶部 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 设置为 left。在 html 元素上添加 dir="rtl" 声明,就会把书写模式从默认的 ltr (从左到右)的英语切换为 rtl (从右到左)的语言。我们可以看到,第一段仍然是从左到右显示,因为 text-align 的值为 left,但第二段把文字的流动方向切换成了从右到左。

- -

A simple example of text direction.

- -

这只是在使用物理属性和值时引起问题的一个非常简单的例子,它们阻止浏览器切换书写模式,因为这些物理属性和值已经假设文字的流动方向一定是从左到右、从上到下的。

- -

逻辑属性和值

- -

逻辑属性和值不会预设文字方向,这也是为什么在网格布局中要实现对齐到容器的开始位置时使用 start 关键字的原因。对我来说,因为我使用英语工作,所以 start 就是左侧,不过它并不总是代表左侧,并不能根据 start 这个词推断出物理位置。

- -

块和行内

- -

如果我们用逻辑属性而不是物理属性来思考,就不能使用从左到右、从上到下的方式观察世界,我们需要一个新的参考点,也就是在此前的文章中讨论对齐时接触过的块轴行内轴。理解它们是非常重要的,如果开始用块轴与行内轴的方式来看待布局,在网格布局中使用到的术语就变得非常有意义了。

- -

An image showing the default direction of the Block and Inline Axes.

- -

CSS 书写模式

- -

现在我要介绍另一个规范:CSS 书写模式规范,并在下面的例子中给出演示。这个规范详细描述了如何在 CSS 中使用多种不同的书写模式,不仅是支持与英语不同书写模式的语言,而且提供了更富创造性的用途。我将通过使用 {{cssxref("writing-mode")}} 属性来改变网格的书写模式,演示逻辑值是如何工作的。如果你想更深入地探讨书写模式,我推荐你阅读 Jen Simmons 的优秀文章:CSS Writing Modes,这篇文章对标准的讨论比本文要深入得多。

- -

writing-mode

- -

书写模式不仅可以使文字从左到右或从右到左显示,writing-mode 属性还可以设置其他的文字流动方向。{{cssxref("writing-mode")}} 属性有以下可选值:

- - - -

属性值 horizontal-tb 是 web 上显示文本的默认效果,也就是你现在正在阅读的这篇文章的方向,其他的属性值将会改变文字的流动方向,能匹配世界各地不同的书写模式,这些细节你都可以在 Jen 的文章中看到。下面用两个段落展示一个简单的例子,第一个段落使用默认的 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') }}

-
- -

网格布局中的书写模式

- -

现在让我们来做一个网格布局的实验,就可以看到书写模式是如何改变你对块轴和行内轴的看法的。

- -

下面例子是一个二行三列的网格,也就是说有三个沿着块轴方向的轨道。在默认的书写模式下,网格自动定位项目的流向,是从左上开始,向右延伸,填满行内轴方向的三个格子,然后转到下一行,创建一个新的行轨道,继续定位更多的项目:

- -
- - -
.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 属性,就可以看到块轴和行内轴都转到不同的方向了,块轴从左到右地穿过页面,行内轴则从上到下到流动。

- -
- - -
.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 属性,我们将使用对齐属性来对齐项目。startend 属性值仍然像在默认的书写模式下那样保留着它们的逻辑,但却已经不是 left 和 right,top 和 bottom 所能够表示的了。只要我们把网格翻转到一边,就会发生这种情况:

- -
- - -
.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,就能得到一个从右到左的垂直书写模式。

- -

自动定位和书写模式

- -

如上例所示,我们已经看到当书写模式改变了方向时网格是如何定位项目的,项目将被沿着行内轴排列直到下一行,只是行内轴不再总是沿着从左到右的方向罢了。

- -

基于网格线的定位和书写模式

- -

要切记,当用网格线序号来定位项目时,不管在哪种书写模式下,第 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")}} 属性,在第一次使用这个属性时,人们经常会惊讶它的写法没有遵从 margin 的按顺时针的简写顺序:top,right,bottom,left。

- -

但是 grid-area 的简写顺序却是:

- - - -

对于英语书写模式来说,从左到右的顺序应该是:

- - - -

grid-area 的简写顺序是逆时针!与我们常用的 marginpadding 相反。你要意识到 grid-area 是从“块和行内”的角度看世界的,牢记应该先设置两条开始线,再设置两条结束线。这样的顺序才更符合逻辑!

- -

书写模式与网格布局的结合

- -

书写模式除了为特定语言处理提供便利,另外对于文档的显示效果,也可以提供 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') }}

-
- -

物理值和网格布局

- -

在构建网站时经常会遇到物理属性,尽管网格定位和对齐属性及它们的值都遵从书写模式,还是有很多时候即使在网格中也不得不使用物理属性和值。在 网格布局中的盒模型对齐 一文中,演示了在网格区域中如何利用自动边距,而自动边距也是 flexbox 布局的一种技巧,尽管这样又把布局和物理空间纠结到了一起。

- -

如果在网格区域中使用绝对定位,那么你就会使用物理偏移量调整网格区域中的项目的位置。关键是要掌握使用物理属性与逻辑属性的力度,举例来说,要衡量把 ltr 切换到 rtl 时你需要对 CSS 做多少修改。

- -

逻辑属性无处不在!

- -

新的布局方法赋予使用逻辑值定位项目的能力,不过如果和使用物理属性的 marginpadding 属性混用,切记这些物理属性并不会依据书写模式来改变它们的显示效果。

- -

CSS 逻辑属性规范 的目标是改变现状,在未来的 CSS 中,{{cssxref("margin-left")}} 和 {{cssxref("margin-right")}} 将与逻辑属性相同。Firefox 已经实现了,所以你现在就可以在 Firefox 中试上一试。未来如果得到全面支持,那么通过网格学习到的“块和行内”的知识,你也能马上举一反三地用在其他地方了。

- - diff --git a/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html b/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html new file mode 100644 index 0000000000..936634c06c --- /dev/null +++ b/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html @@ -0,0 +1,502 @@ +--- +title: CSS 网格,逻辑值和书写模式 +slug: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' +tags: + - CSS + - CSS 指南 + - 指南 +translation_of: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' +--- +

在前面的文章中,我们已经接触了网格布局的一个重要特性:被纳入规范的对不同书写模式的支持。本文我们将探讨在网格和其他现代布局方式下的这个特性的表现,以及学习一些关于书写模式和逻辑属性与物理属性的知识。

+ +

逻辑属性与物理属性及逻辑值与物理值

+ +

CSS 中布满了物理位置的关键字 —— left 和 right,top 和 bottom。当使用绝对位置来定位项目时,就要使项目围绕上用物理关键字描述的偏移量。在下面的代码片断中,项目被定位到距容器顶部 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 设置为 left。在 html 元素上添加 dir="rtl" 声明,就会把书写模式从默认的 ltr (从左到右)的英语切换为 rtl (从右到左)的语言。我们可以看到,第一段仍然是从左到右显示,因为 text-align 的值为 left,但第二段把文字的流动方向切换成了从右到左。

+ +

A simple example of text direction.

+ +

这只是在使用物理属性和值时引起问题的一个非常简单的例子,它们阻止浏览器切换书写模式,因为这些物理属性和值已经假设文字的流动方向一定是从左到右、从上到下的。

+ +

逻辑属性和值

+ +

逻辑属性和值不会预设文字方向,这也是为什么在网格布局中要实现对齐到容器的开始位置时使用 start 关键字的原因。对我来说,因为我使用英语工作,所以 start 就是左侧,不过它并不总是代表左侧,并不能根据 start 这个词推断出物理位置。

+ +

块和行内

+ +

如果我们用逻辑属性而不是物理属性来思考,就不能使用从左到右、从上到下的方式观察世界,我们需要一个新的参考点,也就是在此前的文章中讨论对齐时接触过的块轴行内轴。理解它们是非常重要的,如果开始用块轴与行内轴的方式来看待布局,在网格布局中使用到的术语就变得非常有意义了。

+ +

An image showing the default direction of the Block and Inline Axes.

+ +

CSS 书写模式

+ +

现在我要介绍另一个规范:CSS 书写模式规范,并在下面的例子中给出演示。这个规范详细描述了如何在 CSS 中使用多种不同的书写模式,不仅是支持与英语不同书写模式的语言,而且提供了更富创造性的用途。我将通过使用 {{cssxref("writing-mode")}} 属性来改变网格的书写模式,演示逻辑值是如何工作的。如果你想更深入地探讨书写模式,我推荐你阅读 Jen Simmons 的优秀文章:CSS Writing Modes,这篇文章对标准的讨论比本文要深入得多。

+ +

writing-mode

+ +

书写模式不仅可以使文字从左到右或从右到左显示,writing-mode 属性还可以设置其他的文字流动方向。{{cssxref("writing-mode")}} 属性有以下可选值:

+ + + +

属性值 horizontal-tb 是 web 上显示文本的默认效果,也就是你现在正在阅读的这篇文章的方向,其他的属性值将会改变文字的流动方向,能匹配世界各地不同的书写模式,这些细节你都可以在 Jen 的文章中看到。下面用两个段落展示一个简单的例子,第一个段落使用默认的 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') }}

+
+ +

网格布局中的书写模式

+ +

现在让我们来做一个网格布局的实验,就可以看到书写模式是如何改变你对块轴和行内轴的看法的。

+ +

下面例子是一个二行三列的网格,也就是说有三个沿着块轴方向的轨道。在默认的书写模式下,网格自动定位项目的流向,是从左上开始,向右延伸,填满行内轴方向的三个格子,然后转到下一行,创建一个新的行轨道,继续定位更多的项目:

+ +
+ + +
.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 属性,就可以看到块轴和行内轴都转到不同的方向了,块轴从左到右地穿过页面,行内轴则从上到下到流动。

+ +
+ + +
.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 属性,我们将使用对齐属性来对齐项目。startend 属性值仍然像在默认的书写模式下那样保留着它们的逻辑,但却已经不是 left 和 right,top 和 bottom 所能够表示的了。只要我们把网格翻转到一边,就会发生这种情况:

+ +
+ + +
.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,就能得到一个从右到左的垂直书写模式。

+ +

自动定位和书写模式

+ +

如上例所示,我们已经看到当书写模式改变了方向时网格是如何定位项目的,项目将被沿着行内轴排列直到下一行,只是行内轴不再总是沿着从左到右的方向罢了。

+ +

基于网格线的定位和书写模式

+ +

要切记,当用网格线序号来定位项目时,不管在哪种书写模式下,第 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")}} 属性,在第一次使用这个属性时,人们经常会惊讶它的写法没有遵从 margin 的按顺时针的简写顺序:top,right,bottom,left。

+ +

但是 grid-area 的简写顺序却是:

+ + + +

对于英语书写模式来说,从左到右的顺序应该是:

+ + + +

grid-area 的简写顺序是逆时针!与我们常用的 marginpadding 相反。你要意识到 grid-area 是从“块和行内”的角度看世界的,牢记应该先设置两条开始线,再设置两条结束线。这样的顺序才更符合逻辑!

+ +

书写模式与网格布局的结合

+ +

书写模式除了为特定语言处理提供便利,另外对于文档的显示效果,也可以提供 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') }}

+
+ +

物理值和网格布局

+ +

在构建网站时经常会遇到物理属性,尽管网格定位和对齐属性及它们的值都遵从书写模式,还是有很多时候即使在网格中也不得不使用物理属性和值。在 网格布局中的盒模型对齐 一文中,演示了在网格区域中如何利用自动边距,而自动边距也是 flexbox 布局的一种技巧,尽管这样又把布局和物理空间纠结到了一起。

+ +

如果在网格区域中使用绝对定位,那么你就会使用物理偏移量调整网格区域中的项目的位置。关键是要掌握使用物理属性与逻辑属性的力度,举例来说,要衡量把 ltr 切换到 rtl 时你需要对 CSS 做多少修改。

+ +

逻辑属性无处不在!

+ +

新的布局方法赋予使用逻辑值定位项目的能力,不过如果和使用物理属性的 marginpadding 属性混用,切记这些物理属性并不会依据书写模式来改变它们的显示效果。

+ +

CSS 逻辑属性规范 的目标是改变现状,在未来的 CSS 中,{{cssxref("margin-left")}} 和 {{cssxref("margin-right")}} 将与逻辑属性相同。Firefox 已经实现了,所以你现在就可以在 Firefox 中试上一试。未来如果得到全面支持,那么通过网格学习到的“块和行内”的知识,你也能马上举一反三地用在其他地方了。

+ + diff --git a/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html b/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html new file mode 100644 index 0000000000..1f19e6933b --- /dev/null +++ b/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html @@ -0,0 +1,593 @@ +--- +title: 利用CSS网格布局实现常用布局 +slug: Web/CSS/CSS_Grid_Layout/利用CSS网格布局实现常用布局 +translation_of: Web/CSS/CSS_Grid_Layout/Realizing_common_layouts_using_CSS_Grid_Layout +--- +

为了完善这组CSS网格布局指南,我将介绍几种不同的布局,它们演示了在使用网格布局进行设计时可以使用的一些不同技术。我们将看到一个使用 grid-template-areas 的示例,一个典型的12列灵活网格系统,以及一个使用自动布局的产品列表。正如您从这组示例中看到的,使用网格布局通常有不止一种方法来实现您想要的结果。选择对您正在解决的问题和需要实现的设计最有帮助的方法。

+ +

使用网格模板区域的响应式布局,包含1到3个流动列

+ +

许多网站都是这种布局的变体,有内容、边栏、页眉和页脚。在响应式设计中,您可能希望将布局显示为单个列,在某个断点添加侧栏,然后为更宽的屏幕引入三列布局。

+ +

Image of the three different layouts created by redefining our grid at two breakpoints.

+ +

我将使用我们在向导网格模板区域中了解到的命名模板区域来创建这个布局。

+ +

我的标记是一个容器,其中包含用于标题、页脚、主要内容、导航、边栏和打算放置广告的块的元素。

+ +
+ + +
<div class="wrapper">
+        <header class="main-head">The header</header>
+        <nav class="main-nav">
+            <ul>
+                <li><a href="">Nav 1</a></li>
+                <li><a href="">Nav 2</a></li>
+                <li><a href="">Nav 3</a></li>
+            </ul>
+        </nav>
+        <article class="content">
+            <h1>Main article area</h1>
+            <p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We go to a two column layout, and then to a three column layout by redefining the grid, and the placement of items on the grid.</p>
+        </article>
+        <aside class="side">Sidebar</aside>
+        <div class="ad">Advertising</div>
+        <footer class="main-footer">The footer</footer>
+</div>
+
+ +

因为我们使用{{cssxref("grid-template-areas")}}来创建布局。在任何媒体查询之外,我需要命名区域。我们使用{{cssxref("grid-area")}} 属性命名区域。

+ +
.main-head {
+  grid-area: header;
+}
+.content {
+  grid-area: content;
+}
+.main-nav {
+  grid-area: nav;
+}
+.side {
+  grid-area: sidebar;
+}
+.ad {
+  grid-area: ad;
+}
+.main-footer {
+  grid-area: footer;
+}
+
+ +

这不会创建任何布局,但是我们的项目现在有了名称,我们可以使用它来创建布局。在任何媒体查询之外,我现在要为移动宽度设置布局。在这里,我保持源文件的顺序,试图避免源文件和显示之间的任何断开,就像向导网格布局和可访问性中描述的那样。我没有定义任何列或行跟踪,但是这种布局规定了单个列,并且将根据需要为隐式网格中的每个项目创建行。

+ +
.wrapper {
+  display: grid;
+  grid-gap: 20px;
+  grid-template-areas:
+    "header"
+    "nav"
+    "content"
+    "sidebar"
+    "ad"
+    "footer";
+}
+
+ +

在设置了移动布局之后,我们将获得所有屏幕大小的这一列,现在我们可以添加一个媒体查询并重新定义布局,以满足屏幕空间足够显示两列的情况。

+ +
@media (min-width: 500px) {
+  .wrapper {
+    grid-template-columns: 1fr 3fr;
+    grid-template-areas:
+      "header  header"
+      "nav     nav"
+      "sidebar content"
+      "ad      footer";
+  }
+  nav ul {
+    display: flex;
+    justify-content: space-between;
+  }
+}
+
+ +

您可以看到布局在{{cssxref("grid-template-areas")}}的值中成形。 header 跨越两个列轨道,就像 nav 一样。在第三行轨道中,我们在 content 旁边有 sidebar 。在第四行轨道,我选择了放置我的广告内容-所以它出现在侧边栏下,然后 footer 旁边的内容。我在导航栏上使用了一个flexbox来显示它。

+ +

现在我可以添加最后一个断点来移动到三列布局。

+ +
@media (min-width: 700px) {
+  .wrapper {
+    grid-template-columns: 1fr 4fr 1fr;
+    grid-template-areas:
+      "header header  header"
+      "nav    content sidebar"
+      "nav    content ad"
+      "footer footer  footer"
+   }
+   nav ul {
+     flex-direction: column;
+   }
+}
+
+ +

三列布局有两个1fr单元侧列和一个中间列,轨道大小为4fr。这意味着容器中的可用空间被划分为6个部分,并按照我们的三个轨道的比例分配—每个轨道的一个部分位于侧列,四个部分位于中心。

+ +

在这个布局中,我在左边的列中显示导航,旁边是内容。在右边栏我们有侧边栏,在它下面是广告。页脚现在横跨布局的底部。然后我使用一个flex xbox将导航显示为一个列。

+ +

{{ EmbedLiveSample('layout_1', '800', '500') }}

+
+ +

这是一个简单的示例,但是演示了如何使用网格布局来为不同的断点重新安排布局。具体来说,我正在更改广告块的位置,这在不同的列设置中是合适的。我发现这种命名区域的方法在原型制作阶段非常有用,很容易处理元素的位置。您可以始终以这种方式开始使用grid进行原型设计,即使由于访问您站点的浏览器的原因,您不能在生产中完全依赖它。

+ +

灵活的12列布局

+ +

如果您使用过许多框架或网格系统之一,那么您可能已经习惯了将站点布置在12或16列的灵活网格上。我们可以使用CSS网格布局创建这种类型的系统。作为一个简单的例子,我正在创建一个12列的灵活网格,它有12个1fr-unit列轨道,它们都有一个名为col-start 的起始行。这意味着我们将拥有12条名为 col-start 的网格线。

+ +
+ + +
.wrapper {
+  display: grid;
+  grid-template-columns: repeat(12, [col-start] 1fr);
+  grid-gap: 20px;
+}
+
+ +

为了演示这个网格系统是如何工作的,我在包装器中包含了4个子元素。

+ +
<div class="wrapper">
+  <div class="item1">Start column line 1, span 3 column tracks.</div>
+  <div class="item2">Start column line 6, span 4 column tracks. 2 row tracks.</div>
+  <div class="item3">Start row 2 column line 2, span 2 column tracks.</div>
+  <div class="item4">Start at column line 3, span to the end of the grid (-1).</div>
+</div>
+
+ +

然后,我可以使用命名行和span关键字将它们放到网格上。

+ +
.item1 {
+  grid-column: col-start / span 3;
+}
+.item2 {
+  grid-column: col-start 6 / span 4 ;
+  grid-row: 1 / 3;
+}
+.item3 {
+  grid-column: col-start 2 / span 2;
+  grid-row: 2;
+}
+.item4 {
+  grid-column: col-start 3 / -1;
+  grid-row: 3;
+}
+
+ +

{{ EmbedLiveSample('layout_2', '800', '400') }}

+
+ +

正如命名行指南中所述,我们使用命名行来放置项目。因为我们有12行名称相同,所以我们使用名称,然后是行索引。如果您喜欢并完全避免使用命名行,也可以使用行索引本身。

+ +

我没有设置结束行号,而是选择使用span关键字表示这个元素应该跨多少个轨道。我喜欢这种方法,因为在使用多列布局系统时,我们通常根据网格的轨迹数量来考虑块,并根据不同的断点进行调整。要查看块如何与轨道对齐,请使用 Firefox Grid Inspector. 。它清楚地展示了我们的项目是如何放置的。

+ +

Showing the items placed on the grid with grid tracks highlighted.

+ +

与您以前可能使用过的网格系统上的网格布局的工作方式有一些关键区别。如您所见,我们不需要添加任何标记来创建行,网格系统需要这样做来阻止元素弹出到上面的行中。使用CSS网格布局,我们可以将内容放入行中,如果行是空的,则它们不会上升到上面的行中。由于这种严格的列和行布局,我们也可以很容易地在布局中留出空白。我们也不需要特殊的类来拉或推东西,将它们缩进网格。我们需要做的就是指定项目的开始和结束行。

+ +

使用12列系统构建布局

+ +

为了了解这种布局方法在实践中是如何工作的,我们可以使用12列网格系统创建与使用{{cssxref("grid-template-areas")}}创建的布局相同的布局。我开始使用与网格模板区域示例相同的标记。

+ +
+ + +
<div class="wrapper">
+        <header class="main-head">The header</header>
+        <nav class="main-nav">
+            <ul>
+                <li><a href="">Nav 1</a></li>
+                <li><a href="">Nav 2</a></li>
+                <li><a href="">Nav 3</a></li>
+            </ul>
+        </nav>
+        <article class="content"><h1>Main article area</h1>
+        <p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We go to a two column layout, and then to a three column layout by redefining the grid, and the placement of items on the grid.</p></article>
+        <aside class="side">Sidebar</aside>
+        <div class="ad">Advertising</div>
+        <footer class="main-footer">The footer</footer>
+    </div>
+
+ +

然后,我可以设置网格,如上面的示例12列布局。

+ +
.wrapper {
+  display: grid;
+  grid-template-columns: repeat(12, [col-start] 1fr);
+  grid-gap: 20px;
+}
+
+ +

我们将再次使其成为响应式布局,不过这次使用的是命名行。每个断点都将使用一个12列的网格,但是,根据屏幕的大小,项目将跨越的轨道数量会发生变化。

+ +

我们首先启动移动设备,对于最窄的屏幕,我们想要的只是保持项目的源顺序,并且所有项目都跨越网格。

+ +
.wrapper > * {
+  grid-column: col-start / span 12;
+}
+
+ +

在下一个断点处,我们希望转移到两列布局。我们的标题和导航仍然跨整个网格,所以我们不需要为它们指定任何位置。侧边栏从第一行colstart开始,共3行。它在第3行之后,因为标题和导航位于前两行轨道中。

+ +

ad面板位于边栏下面,因此从网格行4开始。然后我们有内容和页脚,从colstart 4开始,跨越9个轨道,把它们带到网格的末端。

+ +
@media (min-width: 500px) {
+
+  .side {
+    grid-column: col-start / span 3;
+    grid-row: 3;
+  }
+  .ad {
+    grid-column: col-start / span 3;
+    grid-row: 4;
+  }
+  .content, .main-footer {
+    grid-column: col-start 4 / span 9;
+  }
+  nav ul {
+    display: flex;
+    justify-content: space-between;
+  }
+}
+
+ +

最后,我们转到这个布局的三列版本。标题继续横跨整个网格,但现在导航将向下移动,成为第一个侧边栏,其中包含内容,然后是旁边的侧边栏。页脚现在也跨整个布局。

+ +
@media (min-width: 700px) {
+  .main-nav {
+    grid-column: col-start / span 2;
+    grid-row: 2 / 4;
+  }
+  .content {
+    grid-column: col-start 3 / span 8;
+    grid-row: 2 / 4;
+  }
+  .side {
+    grid-column: col-start 11 / span 2;
+    grid-row: 2;
+  }
+  .ad {
+    grid-column: col-start 11 / span 2;
+    grid-row: 3;
+  }
+  .main-footer {
+    grid-column: col-start / span 12;
+  }
+  nav ul {
+    flex-direction: column;
+  }
+}
+
+ +

{{ EmbedLiveSample('layout_3', '800', '450') }}

+
+ +

网格检查器再次帮助我们了解布局是如何形成的。

+ +

Showing the layout with grid tracks highlighted by the grid inspector.

+ +

在创建这个布局时需要注意的一点是,我们不需要在每个断点显式地定位网格上的每个元素。我们能够继承为早期断点设置的位置——这是移动优先”的优势。我们还可以利用网格自动布局。通过保持元素的逻辑顺序,自动布局为我们将项目放到网格上做了很多工作。在本指南的最后一个示例中,我们将创建完全依赖自动布局的布局。

+ +

自动放置的产品列表

+ +

许多布局基本上是一组“卡片”——产品列表、图像库等等。网格可以使创建这些清单变得非常容易,而且无需添加媒体查询就可以响应。在下一个例子中,我将CSS Grid和flexbox布局相结合,以创建一个简单的产品列表布局。

+ +

我的列表的标记是一个无序的项目列表。每个项目都包含一个标题、一些不同高度的文本和对action链接的调用。

+ +
+
<ul class="listing">
+  <li>
+    <h2>Item One</h2>
+    <div class="body"><p>The content of this listing item goes here.</p></div>
+    <div class="cta"><a href="">Call to action!</a></div>
+  </li>
+   <li>
+     <h2>Item Two</h2>
+     <div class="body"><p>The content of this listing item goes here.</p></div>
+     <div class="cta"><a href="">Call to action!</a></div>
+   </li>
+   <li class="wide">
+     <h2>Item Three</h2>
+     <div class="body"><p>The content of this listing item goes here.</p>
+     <p>This one has more text than the other items.</p>
+     <p>Quite a lot more</p>
+     <p>Perhaps we could do something different with it?</p></div>
+     <div class="cta"><a href="">Call to action!</a></div>
+    </li>
+    <li>
+     <h2>Item Four</h2>
+     <div class="body"><p>The content of this listing item goes here.</p></div>
+     <div class="cta"><a href="">Call to action!</a></div>
+    </li>
+     <li>
+     <h2>Item Five</h2>
+     <div class="body"><p>The content of this listing item goes here.</p></div>
+      <div class="cta"><a href="">Call to action!</a></div>
+    </li>
+</ul>
+
+ + + +

我们将创建一个具有灵活数量的灵活列的网格。我希望它们永远不要小于200像素,然后平等地共享任何可用的剩余空间——所以我们总是得到相同宽度的列轨迹。我们使用minmax()函数实现了这一点,该函数是用于轨道大小的重复表示法。

+ +
.listing {
+  list-style: none;
+  margin: 2em;
+  display: grid;
+  grid-gap: 20px;
+  grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
+}
+
+ +

一旦我添加了这个CSS,项目就开始以网格的形式展开。如果我让窗口变小或变宽,列跟踪的数量就会发生变化,而不需要使用媒体查询添加断点并重新定义网格。

+ +

然后,我就可以使用flex touch来整理这些盒子的内部结构。 我将列表项设置为 display: flex flex-direction 设置为 column。 然后,我可以在 .cta 上使用自动边界将这个工具条推到盒子底部。

+ +
.listing li {
+  border: 1px solid #ffe066;
+  border-radius: 5px;
+  display: flex;
+  flex-direction: column;
+}
+.listing .cta {
+  margin-top: auto;
+  border-top: 1px solid #ffe066;
+  padding: 10px;
+  text-align: center;
+}
+.listing .body {
+  padding: 10px;
+}
+
+ +

这是我使用flexbox而不是grid的一个关键原因,如果我只是在一个维度上调整或发布一些东西,那就是一个flexbox用例。

+ +

{{ EmbedLiveSample('layout_4', '800', '900') }}

+
+ +

这一切现在看起来相当完整,然而我们有时拥有这些卡片,其中包含的内容比其他卡片多得多。让它们跨越两条轨道可能很好,这样它们就不会那么高了。我在较大的项目上有一个wide类,我添加了一个规则{{cssxref("grid-column-end")}},其值为span 2。现在,当grid遇到这个项目时,它将为它分配两个轨道。在某些断点处,这意味着我们将在网格中得到一个缺口——在这个缺口中没有空间放置一个双轨项目。

+ +

The layout has gaps as there is not space to layout a two track item.

+ +

我可以通过设置{{cssxref("grid-auto-flow")}}: dense 在网格容器上设置稠密,从而使网格填充这些空白。但是,在这样做时要小心,因为它会使项目偏离其逻辑源顺序。您应该只在项目没有设置顺序时才这样做——并且要注意源文件后面的选项卡顺序的问题,而不是重新排序的显示。

+ +
+ + +
.listing {
+  list-style: none;
+  margin: 2em;
+  display: grid;
+  grid-gap: 20px;
+  grid-auto-flow: dense;
+  grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
+}
+.listing .wide {
+  grid-column-end: span 2;
+}
+
+ +

{{ EmbedLiveSample('layout_5', '800', '900') }}

+ +

这种技术使用auto-placement一些规则应用于某些物品是非常有用的,并且可以帮助你处理的内容是由CMS例如,输出有重复项,或许可以添加一个类特定的呈现为HTML。

+
+ +

Further exploration

+ +

学习使用网格布局的最佳方法是继续构建我们在这里介绍的示例。选择一些您通常使用选择的框架构建的东西,或者使用浮动构建的东西,看看是否可以使用grid构建它。不要忘记寻找用当前方法无法构建的示例。这可能意味着从杂志或其他非网络资源中获取灵感。网格布局提供了我们以前没有过的可能性,我们不需要绑定到相同的旧布局来使用它。

+ + + + diff --git "a/files/zh-cn/web/css/css_grid_layout/\345\210\251\347\224\250css\347\275\221\346\240\274\345\270\203\345\261\200\345\256\236\347\216\260\345\270\270\347\224\250\345\270\203\345\261\200/index.html" "b/files/zh-cn/web/css/css_grid_layout/\345\210\251\347\224\250css\347\275\221\346\240\274\345\270\203\345\261\200\345\256\236\347\216\260\345\270\270\347\224\250\345\270\203\345\261\200/index.html" deleted file mode 100644 index 1f19e6933b..0000000000 --- "a/files/zh-cn/web/css/css_grid_layout/\345\210\251\347\224\250css\347\275\221\346\240\274\345\270\203\345\261\200\345\256\236\347\216\260\345\270\270\347\224\250\345\270\203\345\261\200/index.html" +++ /dev/null @@ -1,593 +0,0 @@ ---- -title: 利用CSS网格布局实现常用布局 -slug: Web/CSS/CSS_Grid_Layout/利用CSS网格布局实现常用布局 -translation_of: Web/CSS/CSS_Grid_Layout/Realizing_common_layouts_using_CSS_Grid_Layout ---- -

为了完善这组CSS网格布局指南,我将介绍几种不同的布局,它们演示了在使用网格布局进行设计时可以使用的一些不同技术。我们将看到一个使用 grid-template-areas 的示例,一个典型的12列灵活网格系统,以及一个使用自动布局的产品列表。正如您从这组示例中看到的,使用网格布局通常有不止一种方法来实现您想要的结果。选择对您正在解决的问题和需要实现的设计最有帮助的方法。

- -

使用网格模板区域的响应式布局,包含1到3个流动列

- -

许多网站都是这种布局的变体,有内容、边栏、页眉和页脚。在响应式设计中,您可能希望将布局显示为单个列,在某个断点添加侧栏,然后为更宽的屏幕引入三列布局。

- -

Image of the three different layouts created by redefining our grid at two breakpoints.

- -

我将使用我们在向导网格模板区域中了解到的命名模板区域来创建这个布局。

- -

我的标记是一个容器,其中包含用于标题、页脚、主要内容、导航、边栏和打算放置广告的块的元素。

- -
- - -
<div class="wrapper">
-        <header class="main-head">The header</header>
-        <nav class="main-nav">
-            <ul>
-                <li><a href="">Nav 1</a></li>
-                <li><a href="">Nav 2</a></li>
-                <li><a href="">Nav 3</a></li>
-            </ul>
-        </nav>
-        <article class="content">
-            <h1>Main article area</h1>
-            <p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We go to a two column layout, and then to a three column layout by redefining the grid, and the placement of items on the grid.</p>
-        </article>
-        <aside class="side">Sidebar</aside>
-        <div class="ad">Advertising</div>
-        <footer class="main-footer">The footer</footer>
-</div>
-
- -

因为我们使用{{cssxref("grid-template-areas")}}来创建布局。在任何媒体查询之外,我需要命名区域。我们使用{{cssxref("grid-area")}} 属性命名区域。

- -
.main-head {
-  grid-area: header;
-}
-.content {
-  grid-area: content;
-}
-.main-nav {
-  grid-area: nav;
-}
-.side {
-  grid-area: sidebar;
-}
-.ad {
-  grid-area: ad;
-}
-.main-footer {
-  grid-area: footer;
-}
-
- -

这不会创建任何布局,但是我们的项目现在有了名称,我们可以使用它来创建布局。在任何媒体查询之外,我现在要为移动宽度设置布局。在这里,我保持源文件的顺序,试图避免源文件和显示之间的任何断开,就像向导网格布局和可访问性中描述的那样。我没有定义任何列或行跟踪,但是这种布局规定了单个列,并且将根据需要为隐式网格中的每个项目创建行。

- -
.wrapper {
-  display: grid;
-  grid-gap: 20px;
-  grid-template-areas:
-    "header"
-    "nav"
-    "content"
-    "sidebar"
-    "ad"
-    "footer";
-}
-
- -

在设置了移动布局之后,我们将获得所有屏幕大小的这一列,现在我们可以添加一个媒体查询并重新定义布局,以满足屏幕空间足够显示两列的情况。

- -
@media (min-width: 500px) {
-  .wrapper {
-    grid-template-columns: 1fr 3fr;
-    grid-template-areas:
-      "header  header"
-      "nav     nav"
-      "sidebar content"
-      "ad      footer";
-  }
-  nav ul {
-    display: flex;
-    justify-content: space-between;
-  }
-}
-
- -

您可以看到布局在{{cssxref("grid-template-areas")}}的值中成形。 header 跨越两个列轨道,就像 nav 一样。在第三行轨道中,我们在 content 旁边有 sidebar 。在第四行轨道,我选择了放置我的广告内容-所以它出现在侧边栏下,然后 footer 旁边的内容。我在导航栏上使用了一个flexbox来显示它。

- -

现在我可以添加最后一个断点来移动到三列布局。

- -
@media (min-width: 700px) {
-  .wrapper {
-    grid-template-columns: 1fr 4fr 1fr;
-    grid-template-areas:
-      "header header  header"
-      "nav    content sidebar"
-      "nav    content ad"
-      "footer footer  footer"
-   }
-   nav ul {
-     flex-direction: column;
-   }
-}
-
- -

三列布局有两个1fr单元侧列和一个中间列,轨道大小为4fr。这意味着容器中的可用空间被划分为6个部分,并按照我们的三个轨道的比例分配—每个轨道的一个部分位于侧列,四个部分位于中心。

- -

在这个布局中,我在左边的列中显示导航,旁边是内容。在右边栏我们有侧边栏,在它下面是广告。页脚现在横跨布局的底部。然后我使用一个flex xbox将导航显示为一个列。

- -

{{ EmbedLiveSample('layout_1', '800', '500') }}

-
- -

这是一个简单的示例,但是演示了如何使用网格布局来为不同的断点重新安排布局。具体来说,我正在更改广告块的位置,这在不同的列设置中是合适的。我发现这种命名区域的方法在原型制作阶段非常有用,很容易处理元素的位置。您可以始终以这种方式开始使用grid进行原型设计,即使由于访问您站点的浏览器的原因,您不能在生产中完全依赖它。

- -

灵活的12列布局

- -

如果您使用过许多框架或网格系统之一,那么您可能已经习惯了将站点布置在12或16列的灵活网格上。我们可以使用CSS网格布局创建这种类型的系统。作为一个简单的例子,我正在创建一个12列的灵活网格,它有12个1fr-unit列轨道,它们都有一个名为col-start 的起始行。这意味着我们将拥有12条名为 col-start 的网格线。

- -
- - -
.wrapper {
-  display: grid;
-  grid-template-columns: repeat(12, [col-start] 1fr);
-  grid-gap: 20px;
-}
-
- -

为了演示这个网格系统是如何工作的,我在包装器中包含了4个子元素。

- -
<div class="wrapper">
-  <div class="item1">Start column line 1, span 3 column tracks.</div>
-  <div class="item2">Start column line 6, span 4 column tracks. 2 row tracks.</div>
-  <div class="item3">Start row 2 column line 2, span 2 column tracks.</div>
-  <div class="item4">Start at column line 3, span to the end of the grid (-1).</div>
-</div>
-
- -

然后,我可以使用命名行和span关键字将它们放到网格上。

- -
.item1 {
-  grid-column: col-start / span 3;
-}
-.item2 {
-  grid-column: col-start 6 / span 4 ;
-  grid-row: 1 / 3;
-}
-.item3 {
-  grid-column: col-start 2 / span 2;
-  grid-row: 2;
-}
-.item4 {
-  grid-column: col-start 3 / -1;
-  grid-row: 3;
-}
-
- -

{{ EmbedLiveSample('layout_2', '800', '400') }}

-
- -

正如命名行指南中所述,我们使用命名行来放置项目。因为我们有12行名称相同,所以我们使用名称,然后是行索引。如果您喜欢并完全避免使用命名行,也可以使用行索引本身。

- -

我没有设置结束行号,而是选择使用span关键字表示这个元素应该跨多少个轨道。我喜欢这种方法,因为在使用多列布局系统时,我们通常根据网格的轨迹数量来考虑块,并根据不同的断点进行调整。要查看块如何与轨道对齐,请使用 Firefox Grid Inspector. 。它清楚地展示了我们的项目是如何放置的。

- -

Showing the items placed on the grid with grid tracks highlighted.

- -

与您以前可能使用过的网格系统上的网格布局的工作方式有一些关键区别。如您所见,我们不需要添加任何标记来创建行,网格系统需要这样做来阻止元素弹出到上面的行中。使用CSS网格布局,我们可以将内容放入行中,如果行是空的,则它们不会上升到上面的行中。由于这种严格的列和行布局,我们也可以很容易地在布局中留出空白。我们也不需要特殊的类来拉或推东西,将它们缩进网格。我们需要做的就是指定项目的开始和结束行。

- -

使用12列系统构建布局

- -

为了了解这种布局方法在实践中是如何工作的,我们可以使用12列网格系统创建与使用{{cssxref("grid-template-areas")}}创建的布局相同的布局。我开始使用与网格模板区域示例相同的标记。

- -
- - -
<div class="wrapper">
-        <header class="main-head">The header</header>
-        <nav class="main-nav">
-            <ul>
-                <li><a href="">Nav 1</a></li>
-                <li><a href="">Nav 2</a></li>
-                <li><a href="">Nav 3</a></li>
-            </ul>
-        </nav>
-        <article class="content"><h1>Main article area</h1>
-        <p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We go to a two column layout, and then to a three column layout by redefining the grid, and the placement of items on the grid.</p></article>
-        <aside class="side">Sidebar</aside>
-        <div class="ad">Advertising</div>
-        <footer class="main-footer">The footer</footer>
-    </div>
-
- -

然后,我可以设置网格,如上面的示例12列布局。

- -
.wrapper {
-  display: grid;
-  grid-template-columns: repeat(12, [col-start] 1fr);
-  grid-gap: 20px;
-}
-
- -

我们将再次使其成为响应式布局,不过这次使用的是命名行。每个断点都将使用一个12列的网格,但是,根据屏幕的大小,项目将跨越的轨道数量会发生变化。

- -

我们首先启动移动设备,对于最窄的屏幕,我们想要的只是保持项目的源顺序,并且所有项目都跨越网格。

- -
.wrapper > * {
-  grid-column: col-start / span 12;
-}
-
- -

在下一个断点处,我们希望转移到两列布局。我们的标题和导航仍然跨整个网格,所以我们不需要为它们指定任何位置。侧边栏从第一行colstart开始,共3行。它在第3行之后,因为标题和导航位于前两行轨道中。

- -

ad面板位于边栏下面,因此从网格行4开始。然后我们有内容和页脚,从colstart 4开始,跨越9个轨道,把它们带到网格的末端。

- -
@media (min-width: 500px) {
-
-  .side {
-    grid-column: col-start / span 3;
-    grid-row: 3;
-  }
-  .ad {
-    grid-column: col-start / span 3;
-    grid-row: 4;
-  }
-  .content, .main-footer {
-    grid-column: col-start 4 / span 9;
-  }
-  nav ul {
-    display: flex;
-    justify-content: space-between;
-  }
-}
-
- -

最后,我们转到这个布局的三列版本。标题继续横跨整个网格,但现在导航将向下移动,成为第一个侧边栏,其中包含内容,然后是旁边的侧边栏。页脚现在也跨整个布局。

- -
@media (min-width: 700px) {
-  .main-nav {
-    grid-column: col-start / span 2;
-    grid-row: 2 / 4;
-  }
-  .content {
-    grid-column: col-start 3 / span 8;
-    grid-row: 2 / 4;
-  }
-  .side {
-    grid-column: col-start 11 / span 2;
-    grid-row: 2;
-  }
-  .ad {
-    grid-column: col-start 11 / span 2;
-    grid-row: 3;
-  }
-  .main-footer {
-    grid-column: col-start / span 12;
-  }
-  nav ul {
-    flex-direction: column;
-  }
-}
-
- -

{{ EmbedLiveSample('layout_3', '800', '450') }}

-
- -

网格检查器再次帮助我们了解布局是如何形成的。

- -

Showing the layout with grid tracks highlighted by the grid inspector.

- -

在创建这个布局时需要注意的一点是,我们不需要在每个断点显式地定位网格上的每个元素。我们能够继承为早期断点设置的位置——这是移动优先”的优势。我们还可以利用网格自动布局。通过保持元素的逻辑顺序,自动布局为我们将项目放到网格上做了很多工作。在本指南的最后一个示例中,我们将创建完全依赖自动布局的布局。

- -

自动放置的产品列表

- -

许多布局基本上是一组“卡片”——产品列表、图像库等等。网格可以使创建这些清单变得非常容易,而且无需添加媒体查询就可以响应。在下一个例子中,我将CSS Grid和flexbox布局相结合,以创建一个简单的产品列表布局。

- -

我的列表的标记是一个无序的项目列表。每个项目都包含一个标题、一些不同高度的文本和对action链接的调用。

- -
-
<ul class="listing">
-  <li>
-    <h2>Item One</h2>
-    <div class="body"><p>The content of this listing item goes here.</p></div>
-    <div class="cta"><a href="">Call to action!</a></div>
-  </li>
-   <li>
-     <h2>Item Two</h2>
-     <div class="body"><p>The content of this listing item goes here.</p></div>
-     <div class="cta"><a href="">Call to action!</a></div>
-   </li>
-   <li class="wide">
-     <h2>Item Three</h2>
-     <div class="body"><p>The content of this listing item goes here.</p>
-     <p>This one has more text than the other items.</p>
-     <p>Quite a lot more</p>
-     <p>Perhaps we could do something different with it?</p></div>
-     <div class="cta"><a href="">Call to action!</a></div>
-    </li>
-    <li>
-     <h2>Item Four</h2>
-     <div class="body"><p>The content of this listing item goes here.</p></div>
-     <div class="cta"><a href="">Call to action!</a></div>
-    </li>
-     <li>
-     <h2>Item Five</h2>
-     <div class="body"><p>The content of this listing item goes here.</p></div>
-      <div class="cta"><a href="">Call to action!</a></div>
-    </li>
-</ul>
-
- - - -

我们将创建一个具有灵活数量的灵活列的网格。我希望它们永远不要小于200像素,然后平等地共享任何可用的剩余空间——所以我们总是得到相同宽度的列轨迹。我们使用minmax()函数实现了这一点,该函数是用于轨道大小的重复表示法。

- -
.listing {
-  list-style: none;
-  margin: 2em;
-  display: grid;
-  grid-gap: 20px;
-  grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
-}
-
- -

一旦我添加了这个CSS,项目就开始以网格的形式展开。如果我让窗口变小或变宽,列跟踪的数量就会发生变化,而不需要使用媒体查询添加断点并重新定义网格。

- -

然后,我就可以使用flex touch来整理这些盒子的内部结构。 我将列表项设置为 display: flex flex-direction 设置为 column。 然后,我可以在 .cta 上使用自动边界将这个工具条推到盒子底部。

- -
.listing li {
-  border: 1px solid #ffe066;
-  border-radius: 5px;
-  display: flex;
-  flex-direction: column;
-}
-.listing .cta {
-  margin-top: auto;
-  border-top: 1px solid #ffe066;
-  padding: 10px;
-  text-align: center;
-}
-.listing .body {
-  padding: 10px;
-}
-
- -

这是我使用flexbox而不是grid的一个关键原因,如果我只是在一个维度上调整或发布一些东西,那就是一个flexbox用例。

- -

{{ EmbedLiveSample('layout_4', '800', '900') }}

-
- -

这一切现在看起来相当完整,然而我们有时拥有这些卡片,其中包含的内容比其他卡片多得多。让它们跨越两条轨道可能很好,这样它们就不会那么高了。我在较大的项目上有一个wide类,我添加了一个规则{{cssxref("grid-column-end")}},其值为span 2。现在,当grid遇到这个项目时,它将为它分配两个轨道。在某些断点处,这意味着我们将在网格中得到一个缺口——在这个缺口中没有空间放置一个双轨项目。

- -

The layout has gaps as there is not space to layout a two track item.

- -

我可以通过设置{{cssxref("grid-auto-flow")}}: dense 在网格容器上设置稠密,从而使网格填充这些空白。但是,在这样做时要小心,因为它会使项目偏离其逻辑源顺序。您应该只在项目没有设置顺序时才这样做——并且要注意源文件后面的选项卡顺序的问题,而不是重新排序的显示。

- -
- - -
.listing {
-  list-style: none;
-  margin: 2em;
-  display: grid;
-  grid-gap: 20px;
-  grid-auto-flow: dense;
-  grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
-}
-.listing .wide {
-  grid-column-end: span 2;
-}
-
- -

{{ EmbedLiveSample('layout_5', '800', '900') }}

- -

这种技术使用auto-placement一些规则应用于某些物品是非常有用的,并且可以帮助你处理的内容是由CMS例如,输出有重复项,或许可以添加一个类特定的呈现为HTML。

-
- -

Further exploration

- -

学习使用网格布局的最佳方法是继续构建我们在这里介绍的示例。选择一些您通常使用选择的框架构建的东西,或者使用浮动构建的东西,看看是否可以使用grid构建它。不要忘记寻找用当前方法无法构建的示例。这可能意味着从杂志或其他非网络资源中获取灵感。网格布局提供了我们以前没有过的可能性,我们不需要绑定到相同的旧布局来使用它。

- - - - diff --git a/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html b/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html new file mode 100644 index 0000000000..4a3e2bb7c9 --- /dev/null +++ b/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html @@ -0,0 +1,49 @@ +--- +title: 在 CSS 中实现图像合并 +slug: Web/Guide/CSS/CSS_Image_Sprites +tags: + - CSS + - CSS Image + - Graphics + - Guide + - Web +translation_of: Web/CSS/CSS_Images/Implementing_image_sprites_in_CSS +--- +
{{cssRef}}
+ +

CSS 图像合并Image sprites) 技术,亦作 CSS 贴图定位、图像精灵(sprite,意为精灵),被运用于众多使用大量小图标的网页应用之上。它可取图像的一部分来使用,使得使用一个图像文件替代多个小文件成为可能。相较于一个小图标一个图像文件,单独一张图片所需的 HTTP 请求更少,对内存和带宽更加友好。

+ +
+

备注: 当使用 HTTP/2 时,使用多个小流量请求实际上可能更为带宽友好。

+
+ +

实现

+ +

若要为所有类名为 toolbtn 的元素附加上一张图片:

+ +
.toolbtn {
+  background: url(myfile.png);
+  display: inline-block;
+  height: 20px;
+  width: 20px;
+}
+
+ +

为设置 background-position 以使每个按钮得到合并后图片中的正确部分,可以在 background 属性中的 {{cssxref("url()")}} 后添加 x, y 两个坐标值,或直接使用 {{cssxref("background-position")}} 属性。例如:

+ +
#btn1 {background-position: -20px 0px}
+#btn2 {background-position: -40px 0px}
+
+ +

这会将 ID 为 btn1 的元素的背景向左移 20px,ID 为 btn2 的元素的背景向左移40px(假设这两个元素都带有 toolbtn 这个类且应用了上面 background 属性中定义的图片背景)

+ +

类似的,你也可以使用下面的代码添加悬停效果:

+ +
#btn:hover {
+  background-position: <pixels shifted right>px <pixels shifted down>px;
+}
+
+ +

深入阅读

+ +

CSS Tricks 上的完整 Demo:http://css-tricks.com/snippets/css/perfect-css-sprite-sliding-doors-button/

diff --git a/files/zh-cn/web/css/css_images/using_css_gradients/index.html b/files/zh-cn/web/css/css_images/using_css_gradients/index.html new file mode 100644 index 0000000000..21460cd820 --- /dev/null +++ b/files/zh-cn/web/css/css_images/using_css_gradients/index.html @@ -0,0 +1,717 @@ +--- +title: 使用 CSS 渐变 +slug: Web/Guide/CSS/Using_CSS_gradients +translation_of: Web/CSS/CSS_Images/Using_CSS_gradients +--- +
{{CSSRef}}
+ +

CSS 渐变 {{cssxref("<image>")}} 类型的一种特殊类型 {{cssxref("<gradient>")}} 表示,由两种或多种颜色之间的渐进过渡组成。您可以选择三种类型的渐变:线性 (由 {{cssxref("linear-gradient")}} 函数创建),径向(由 {{cssxref("radial-gradient")}} 函数创建) 和圆锥 (由 {{cssxref("conic-gradient")}} 函数创建)。您还可以使用 {{cssxref("repeating-linear-gradient")}} 和 {{cssxref("repeating-radial-gradient")}} 函数创建重复渐变。

+ +

渐变可以在任何使用 <image> 的地方使用,例如在背景中。 由于渐变是动态生成的,因此它们可以消除对传统用于实现类似效果的栅格图像文件的需求。 此外,由于渐变是由浏览器生成的,因此在放大时它们看起来比栅格图像更好,并且可以动态调整大小。

+ +

我们将从线性渐变开始介绍,然后以线性渐变为例介绍所有渐变类型支持的功能,然后继续介绍径向渐变,圆锥渐变和重复渐变。

+ +

使用线性渐变

+ +

线性渐变创建了一条沿直线前进的颜色带。

+ +
+

基础线性渐变

+ +

要创建最基本的渐变类型,您只需指定两种颜色即可。 这些被称为色标。 至少指定两个色标,也可以指定任意数量。

+ + + +
.simple-linear {
+  background: linear-gradient(blue, pink);
+}
+ +

{{ EmbedLiveSample('A_basic_linear_gradient', 120, 120) }}

+
+ +
+

改变渐变方向

+ +

默认情况下,线性渐变的方向是从上到下, 你可以指定一个值来改变渐变的方向。

+ + + +
.horizontal-gradient {
+  background: linear-gradient(to right, blue, pink);
+}
+
+ +

{{ EmbedLiveSample('Changing_the_direction', 120, 120) }}

+
+ +
+

对角线渐变

+ +

你甚至可以设置渐变方向为从一个对角到另一个对角。

+ + + +
.diagonal-gradient {
+  background: linear-gradient(to bottom right, blue, pink);
+}
+
+ +

{{ EmbedLiveSample('Diagonal_gradients', 200, 100) }}

+
+ +
+

设置渐变角度

+ +

如果你想要更精确地控制渐变的方向,你可以给渐变设置一个具体的角度。

+ + + +
.angled-gradient {
+  background: linear-gradient(70deg, blue, pink);
+}
+
+ +

{{ EmbedLiveSample('Using_angles', 120, 120) }}

+ +

在使用角度的时候, 0deg 代表渐变方向为从下到上, 90deg 代表渐变方向为从左到右,诸如此类正角度都属于顺时针方向。 而负角度意味着逆时针方向。

+ +

linear_redangles.png

+
+ +

声明颜色和创建效果

+ +

所有的CSS渐变类型都是一个位置依赖的颜色范围。CSS渐变产生的颜色可以随位置不断变化,从而产生平滑的颜色过渡。也可以创建纯色带和两种颜色之间的硬过渡。以下内容适用于所有渐变函数:

+ +
+

使用多种颜色

+ +

无需局限于使用两种颜色,你想使用多少种颜色都可以! 默认情况下,所设置颜色会均匀分布在渐变路径中。

+ + + +
.auto-spaced-linear-gradient {
+  background: linear-gradient(red, yellow, blue, orange);
+}
+
+ +

{{ EmbedLiveSample('Using_more_than_two_colors', 120, 120) }}

+
+ +
+

颜色终止位置

+ +

你不需要让你设置的颜色在默认位置终止。 你可以通过给每个颜色设置0,1%或者2%或者其他的绝对数值来调整它们的位置。如果你将位置设置为百分数, 0% 表示起始点, 而100%表示终点,但是如果需要的话你也可以设置这个范围之外的其他值来达到你想要的效果。如果有些位置你没有明确设置,那么它将会被自动计算,第一种颜色会在0%处停止,而最后一种颜色是100%,至于其他颜色则是在它邻近的两种颜色的中间停止。 

+ + + +
.multicolor-linear {
+   background: linear-gradient(to left, lime 28px, red 77%, cyan);
+}
+
+ +

{{ EmbedLiveSample('Positioning_color_stops', 120, 120) }}

+
+ +
+

创建实线

+ +

要在两种颜色之间创建一条硬线,即创建一个条纹而不是逐渐过渡,可以将相邻的颜色停止设置为相同的位置。在此示例中,两种颜色在50%标记处共享一个颜色停止点,即渐变的一半:

+ + + +
.striped {
+   background: linear-gradient(to bottom left, cyan 50%, palegoldenrod 50%);
+}
+ +

{{ EmbedLiveSample('Creating_hard_lines', 120, 120) }}

+
+ +
+

渐变提示

+ +

默认情况下,渐变会平滑地从一种颜色过渡到另一种颜色。你可以通过设置一个值来将渐变的中心点移动到指定位置。 在如下示例中, 我们将渐变的中心点由50%设为10%。

+ + + +
.color-hint {
+  background: linear-gradient(blue, 10%, pink);
+}
+.simple-linear {
+  background: linear-gradient(blue, pink);
+}
+ +

{{ EmbedLiveSample('Gradient_hints', 120, 120) }}

+
+ +
+

创建色带和条纹

+ +

要在渐变中包含一个实心的非过渡颜色区域,请包含颜色起止点的两个位置。颜色起止点可以有两个位置,这相当于两个连续颜色在不同位置具有相同的颜色起止点。颜色将在第一个颜色起止点时达到完全饱和,保持该饱和度到第二个颜色起止点,并通过相邻颜色起止点的第一个位置过渡到相邻颜色起止点的颜色。

+ + + +
.multiposition-stops {
+   background: linear-gradient(to left,
+       lime 20%, red 30%, red 45%, cyan 55%, cyan 70%, yellow 80% );
+   background: linear-gradient(to left,
+       lime 20%, red 30% 45%, cyan 55% 70%, yellow 80% );
+}
+.multiposition-stop2 {
+   background: linear-gradient(to left,
+      lime 25%, red 25%, red 50%, cyan 50%, cyan 75%, yellow 75% );
+   background: linear-gradient(to left,
+      lime 25%, red 25% 50%, cyan 50% 75%, yellow 75% );
+}
+
+ +

{{ EmbedLiveSample('Creating_color_bands_stripes', 120, 120) }}

+ +

In the first example above, the lime goes from the 0% mark, which is implied, to the 20% mark, transitions from lime to red over the next 10% of the width of the gradient, reach solid red at the 30% mark, and staying solid red up until 45% through the gradient, where it fades to cyan, being fully cyan for 15% of the gradient, and so on.

+ +

In the second example, the second color stop for each color is at the same location as the first color stop for the adjacent color, creating a striped effect.

+ +

In both examples, the gradient is written twice: the first is the CSS Images Level 3 method of repeating the color for each stop and the second example is the CSS Images Level 4 multiple color stop method of including two color-stop-lengths in a linear-color-stop declaration.

+
+ +
+

Controlling the progression of a gradient

+ +

By default, a gradient evenly progresses between the colors of two adjacent color stops, with the midpoint between those two color stops being the midpoint color value. You can control the interpolation, or progression, between two color stops by including a color hint location. In this example, the color reaches the midpoint between lime and cyan 20% of the way through the gradient rather than 50% of the way through. The second example does not contain the hint to hilight the difference the color hint can make:

+ + + +
.colorhint-gradient {
+  background: linear-gradient(to top, black, 20%, cyan);
+}
+.regular-progression {
+  background: linear-gradient(to top, black, cyan);
+}
+
+ +

{{ EmbedLiveSample('Controlling_the_progression_of_a_gradient', 120, 120) }}

+
+ +

Overlaying gradients

+ +

Gradients support transparency, so you can stack multiple backgrounds to achieve some pretty fancy effects. The backgrounds are stacked from top to bottom, with the first specified being on top.

+ + + +
.layered-image {
+  background: linear-gradient(to right, transparent, mistyrose),
+      url("https://mdn.mozillademos.org/files/15525/critters.png");
+}
+
+ +

{{ EmbedLiveSample('Overlaying_gradients', 300, 150) }}

+ +

Stacked gradients

+ +

You can even stack gradients with other gradients. As long as the top gradients aren't entirely opaque, the gradients below will still be visible.

+ + + +
.stacked-linear {
+  background:
+      linear-gradient(217deg, rgba(255,0,0,.8), rgba(255,0,0,0) 70.71%),
+      linear-gradient(127deg, rgba(0,255,0,.8), rgba(0,255,0,0) 70.71%),
+      linear-gradient(336deg, rgba(0,0,255,.8), rgba(0,0,255,0) 70.71%);
+}
+
+ +

{{ EmbedLiveSample('Stacked_gradients', 200, 200) }}

+ +

Using radial gradients

+ +

Radial gradients are similar to linear gradients, except that they radiate out from a central point. You can dictate where that central point is. You can also make them circular or elliptical.

+ +

A basic radial gradient

+ +

As with linear gradients, all you need to create a radial gradient are two colors. By default, the center of the gradient is at the 50% 50% mark, and the gradient is elliptical matching the aspect ratio of it's box:

+ + + +
.simple-radial {
+  background: radial-gradient(red, blue);
+}
+
+ +

{{ EmbedLiveSample('A_basic_radial_gradient', 120, 120) }}

+ +

Positioning radial color stops

+ +

Again like linear gradients, you can position each radial color stop with a percentage or absolute length.

+ + + +
.radial-gradient {
+  background: radial-gradient(red 10px, yellow 30%, #1e90ff 50%);
+}
+
+ +

{{ EmbedLiveSample('Positioning_radial_color_stops', 120, 120) }}

+ +

Positioning the center of the gradient

+ +

You can position the center of the gradient with keyterms, percentage, or absolute lengths, length and percentage values repeating if only one is present, otherwise in the order of position from the left and position from the top.

+ + + +
.radial-gradient {
+  background: radial-gradient(at 0% 30%, red 10px, yellow 30%, #1e90ff 50%);
+}
+
+ +

{{ EmbedLiveSample('Positioning_the_center_of_the_gradient', 120, 120) }}

+ +

Sizing radial gradients

+ +

Unlike linear gradients, you can specify the size of radial gradients. Possible values include closest-corner, closest-side, farthest-corner, and farthest-side, with farthest-corner being the default.

+ +

Example: closest-side for ellipses

+ +

This example uses the closest-side size value, which means the size is set by the distance from the starting point (the center) to the closest side of the enclosing box.

+ + + +
.radial-ellipse-side {
+  background: radial-gradient(ellipse closest-side,
+      red, yellow 10%, #1e90ff 50%, beige);
+}
+
+ +

{{ EmbedLiveSample('Example_closest-side_for_ellipses', 240, 100) }}

+ +

Example: farthest-corner for ellipses

+ +

This example is similar to the previous one, except that its size is specified as farthest-corner, which sets the size of the gradient by the distance from the starting point to the farthest corner of the enclosing box from the starting point.

+ + + +
.radial-ellipse-far {
+  background: radial-gradient(ellipse farthest-corner at 90% 90%,
+      red, yellow 10%, #1e90ff 50%, beige);
+}
+
+ +

{{ EmbedLiveSample('Example_farthest-corner_for_ellipses', 240, 100) }}

+ +

Example: closest-side for circles

+ +

This example uses closest-side, which makes the circle's size to be the distance between the starting point (the center) and the closest side. The circle's radius is the distance between the center of the gradient and the closest edge, which due to the positioning of the 25% from the top and 25% from the bottom, is closest to the bottom, since the height in this case is narrower than the width.

+ + + +
.radial-circle-close {
+  background: radial-gradient(circle closest-side at 25% 75%,
+      red, yellow 10%, #1e90ff 50%, beige);
+}
+
+ +

{{ EmbedLiveSample('Example_closest-side_for_circles', 240, 120) }}

+ +

Stacked radial gradients

+ +

Just like linear gradients, you can also stack radial gradients. The first specified is on top, the last on the bottom.

+ + + +
.stacked-radial {
+  background:
+      radial-gradient(circle at 50% 0,
+        rgba(255,0,0,.5),
+        rgba(255,0,0,0) 70.71%),
+      radial-gradient(circle at 6.7% 75%,
+        rgba(0,0,255,.5),
+        rgba(0,0,255,0) 70.71%),
+      radial-gradient(circle at 93.3% 75%,
+        rgba(0,255,0,.5),
+        rgba(0,255,0,0) 70.71%) beige;
+  border-radius: 50%;
+}
+
+ +

{{ EmbedLiveSample('Stacked_radial_gradients', 200, 200) }}

+ +

Using repeating gradients

+ +

The {{cssxref("linear-gradient")}} and {{cssxref("radial-gradient")}} properties don't support automatically repeated color stops. However, the {{cssxref("repeating-linear-gradient")}} and {{cssxref("repeating-radial-gradient")}} properties are available to offer this functionality.

+ +

The size of the gradient line that repeats is the length between the first color stop value and the last color stop length value. If the last color stop has just a color and no color stop length, the value defaults to 0, meaning the linear gradient will not repeat and the radial gradient will only repeat if the radius of the gradient is smaller than the length between the center of the gradient and the farthest corner.

+ +
+

Repeating linear gradients

+ +

This example uses {{cssxref("repeating-linear-gradient")}} to create a gradient that progresses repeatedly in a straight line. The colors get cycled over again as the gradient repeats. In this case the gradient line is 10px long.

+ + + +
.repeating-linear {
+  background: repeating-linear-gradient(-45deg, red, red 5px, blue 5px, blue 10px);
+}
+
+ +

{{ EmbedLiveSample('Repeating_linear_gradients', 120, 120) }}

+
+ +
+

Multiple repeating linear gradients

+ +

Similar to regular linear and radial gradients, you can include multiple gradients, one on top of the other. This only makes sense if the gradients are partially transparent allowing subsequent gradients to show through the transparent areas, or if you include different background-sizes, optionally with different background-position property values, for each gradient image. We are using transparency.

+ +

In this case the gradient lines are 300px, 230px, and 300px long.

+ + + +
.multi-repeating-linear {
+  background:
+      repeating-linear-gradient(190deg, rgba(255, 0, 0, 0.5) 40px,
+        rgba(255, 153, 0, 0.5) 80px, rgba(255, 255, 0, 0.5) 120px,
+        rgba(0, 255, 0, 0.5) 160px, rgba(0, 0, 255, 0.5) 200px,
+        rgba(75, 0, 130, 0.5) 240px, rgba(238, 130, 238, 0.5) 280px,
+        rgba(255, 0, 0, 0.5) 300px),
+      repeating-linear-gradient(-190deg, rgba(255, 0, 0, 0.5) 30px,
+        rgba(255, 153, 0, 0.5) 60px, rgba(255, 255, 0, 0.5) 90px,
+        rgba(0, 255, 0, 0.5) 120px, rgba(0, 0, 255, 0.5) 150px,
+        rgba(75, 0, 130, 0.5) 180px, rgba(238, 130, 238, 0.5) 210px,
+        rgba(255, 0, 0, 0.5) 230px),
+      repeating-linear-gradient(23deg, red 50px, orange 100px,
+        yellow 150px, green 200px, blue 250px,
+        indigo 300px, violet 350px, red 370px);
+}
+
+ +

{{ EmbedLiveSample('Multiple_repeating_linear_gradients', 600, 400) }}

+
+ +

Plaid gradient

+ +

To create plaid we include several overlapping gradients with transparency. In the first background declaration we listed every color stop separately. The second background property declaration using the multiple position color stop syntax:

+ + + +
.plaid-gradient {
+  background:
+      repeating-linear-gradient(90deg, transparent, transparent 50px,
+        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
+        transparent 56px, transparent 63px,
+        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
+        transparent 69px, transparent 116px,
+        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
+      repeating-linear-gradient(0deg, transparent, transparent 50px,
+        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
+        transparent 56px, transparent 63px,
+        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
+        transparent 69px, transparent 116px,
+        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
+      repeating-linear-gradient(-45deg, transparent, transparent 5px,
+        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px),
+      repeating-linear-gradient(45deg, transparent, transparent 5px,
+        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px);
+
+  background:
+      repeating-linear-gradient(90deg, transparent 0 50px,
+        rgba(255, 127, 0, 0.25) 50px 56px,
+        transparent 56px 63px,
+        rgba(255, 127, 0, 0.25) 63px 69px,
+        transparent 69px 116px,
+        rgba(255, 206, 0, 0.25) 116px 166px),
+      repeating-linear-gradient(0deg, transparent 0 50px,
+        rgba(255, 127, 0, 0.25) 50px 56px,
+        transparent 56px 63px,
+        rgba(255, 127, 0, 0.25) 63px 69px,
+        transparent 69px 116px,
+        rgba(255, 206, 0, 0.25) 116px 166px),
+      repeating-linear-gradient(-45deg, transparent 0 5px,
+        rgba(143, 77, 63, 0.25) 5px 10px),
+      repeating-linear-gradient(45deg, transparent 0 5px,
+        rgba(143, 77, 63, 0.25) 5px 10px);
+}
+
+ +

{{ EmbedLiveSample('Plaid_gradient', 200, 200) }}

+ +

Repeating radial gradients

+ +

This example uses {{cssxref("repeating-radial-gradient")}} to create a gradient that radiates repeatedly from a central point. The colors get cycled over and over as the gradient repeats.

+ + + +
.repeating-radial {
+  background: repeating-radial-gradient(black, black 5px, white 5px, white 10px);
+}
+
+ +

{{ EmbedLiveSample('Repeating_radial_gradients', 120, 120) }}

+ +

Multiple repeating radial gradients

+ + + +
.multi-target {
+  background:
+      repeating-radial-gradient(ellipse at 80% 50%,rgba(0,0,0,0.5),
+        rgba(0,0,0,0.5) 15px, rgba(255,255,255,0.5) 15px,
+        rgba(255,255,255,0.5) 30px) top left no-repeat,
+      repeating-radial-gradient(ellipse at 20% 50%,rgba(0,0,0,0.5),
+        rgba(0,0,0,0.5) 10px, rgba(255,255,255,0.5) 10px,
+        rgba(255,255,255,0.5) 20px) top left no-repeat yellow;
+  background-size: 200px 200px, 150px 150px;
+}
+
+ +

{{ EmbedLiveSample('Multiple_repeating_radial_gradients', 250, 150) }}

+ +

Plaid gradient

+ +

To create plaid we include several overlapping gradients with transparency. In the first background declaration we listed every color stop separately. The second background property declaration using the multiple position color stop syntax:

+ +
<div class="plaid-gradient"></div>
+ +
div {
+  width: 200px;
+  height: 200px;
+}
+ +
.plaid-gradient {
+  background:
+      repeating-linear-gradient(90deg, transparent, transparent 50px,
+        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
+        transparent 56px, transparent 63px,
+        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
+        transparent 69px, transparent 116px,
+        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
+      repeating-linear-gradient(0deg, transparent, transparent 50px,
+        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
+        transparent 56px, transparent 63px,
+        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
+        transparent 69px, transparent 116px,
+        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
+      repeating-linear-gradient(-45deg, transparent, transparent 5px,
+        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px),
+      repeating-linear-gradient(45deg, transparent, transparent 5px,
+        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px);
+
+  background:
+      repeating-linear-gradient(90deg, transparent 0 50px,
+        rgba(255, 127, 0, 0.25) 50px 56px,
+        transparent 56px 63px,
+        rgba(255, 127, 0, 0.25) 63px 69px,
+        transparent 69px 116px,
+        rgba(255, 206, 0, 0.25) 116px 166px),
+      repeating-linear-gradient(0deg, transparent 0 50px,
+        rgba(255, 127, 0, 0.25) 50px 56px,
+        transparent 56px 63px,
+        rgba(255, 127, 0, 0.25) 63px 69px,
+        transparent 69px 116px,
+        rgba(255, 206, 0, 0.25) 116px 166px),
+      repeating-linear-gradient(-45deg, transparent 0 5px,
+        rgba(143, 77, 63, 0.25) 5px 10px),
+      repeating-linear-gradient(45deg, transparent 0 5px,
+        rgba(143, 77, 63, 0.25) 5px 10px);
+}
+
+ +

{{ EmbedLiveSample('Plaid_gradient', 200, 200) }}

+ +

See also

+ + diff --git a/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html b/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html new file mode 100644 index 0000000000..1426940c48 --- /dev/null +++ b/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html @@ -0,0 +1,106 @@ +--- +title: 调整列表缩进 +slug: Web/Guide/CSS/Consistent_list_indentation +tags: + - CSS + - Guide + - NeedsUpdate + - Web + - 列表 + - 缩进 +translation_of: Web/CSS/CSS_Lists_and_Counters/Consistent_list_indentation +--- +

对列表最常见的样式修改之一是改变缩进距离,即列表项向右侧移动的距离。令人沮丧的是,缩进在一个浏览器中的表现常常与其他浏览器中的效果不尽相同。例如,如果声明列表的左边距为0,在IE浏览器中生效,但是在基于Gecko引擎的浏览器中却不起作用。本文将帮助你理解这些可能发生的问题,以及如何避免这些问题的产生。

+ +

为了弄明白这是为什么,以及如何避免这些问题发生,有必要研究一下列表结构的具体细节。

+ +

创建一个列表

+ +

首先,来看一个简单,单独的列表项目。该列表项目没有标记符号(或称之为“着重号”),并且没有被列表包裹起来。如下图图1所示,单独的列表项是无效的,简单且没有任何装饰。

+ +

Figure 1

+ +

红色的虚线边框代表列表项目内容区域的外边界。记住,从这一点上看,这个列表项目没有内边距和边框。如果我们再添加两个列表项目,我们得到下面的结果,如图2所示。

+ +

Figure 2

+ +

现在我们在外面加上父元素;这个例子中,我们使用一个无序列表(i.e., <ul>)。根据 CSS 盒子模型,列表项目的盒子必须显示在其父元素的内容区域里。因为这里的父元素既没有 padding 也没有 margin,所以我们得到下面的结果,如图3所示。

+ +

Figure 3

+ +

这里,蓝色的虚线边框表示 <ul> 元素内容区域的边缘。因为我们没有给 <ul> 元素添加内边距,  所以它的内容的包裹层紧贴在三个列表项外。

+ +

现在我们来添加列表项目标记,由于这是一个无序列表,我们添加传统的实心圆“着重标记”,如下图图4所示。

+ +

Figure 4

+ +

可以看到,这些标记符号在<ul>内容区域的外面,但这无关紧要。重要的是,这些标记被放到主要的<li>元素盒子外面了。它们有点像列表项目的附件,在<li>的内容区域外游荡,但依然依附于<li>。

+ +

这就是为什么在除了IE浏览器以外的所有浏览器上,标记符号都被放在<li>元素的边框外,假设列表项位置的值为外部"outside"。如果该值被改为内部"inside",则标记符号会被放到<li>的内容区域里面,像是放在<li>最开头的内联盒子一样。

+ +

二次缩进

+ +

So how will all this appear in a document? At the moment, we have a situation analogous to these styles:

+ +
ul, li {margin-left: 0; padding-left: 0;}
+ +

If we dropped this list into a document as-is, there would be no apparent indentation and the markers would be in danger of falling off the left edge of the browser window.

+ +

In order to avoid this and get some indentation, there are really only three options available to browser implementors.

+ +
    +
  1. Give each <li> element a left margin.
  2. +
  3. Give the <ul> element a left margin.
  4. +
  5. Give the <ul> element some left padding.
  6. +
+ +

As it turns out, nobody seems to have used the first option. The second option was taken by Internet Explorer for Windows and Macintosh, and Opera. The third was adopted by Gecko, and by extension all the browsers that embed it.

+ +

Let's look at the two approaches for a moment. In Internet Explorer and Opera, the lists are indented by setting a left margin of 40 pixels on the <ul> element. If we apply a background color to the <ul> element and leave the list item and <ul> borders in place, we get the result shown in Figure 5.

+ +

Figure 5

+ +

Gecko, on the other hand, sets a left padding of 40 pixels for the <ul> element, so given the exact same styles as were used to produce Figure 5, loading the example into a Gecko-based browser gives us Figure 6.

+ +

Figure 6

+ +

As we can see, the markers remain attached to the <li> elements, no matter where they are. The difference is entirely in how the <ul> is styled. We can only see the difference if we try to set a background or border on the <ul> element.

+ +

Finding Consistency

+ +

Boil it all down, and what we're left with is this: if you want consistent rendering of lists between Gecko, Internet Explorer, and Opera, you need to set both the left margin and left padding of the <ul> element. We can ignore <li> altogether for these purposes. If you want to reproduce the default display in Netscape 6.x, you write:

+ +
ul {margin-left: 0; padding-left: 40px;}
+ +

If you're more interested in following the Internet Explorer/Opera model, then:

+ +
ul {margin-left: 40px; padding-left: 0;}
+ +

Of course, you can fill in your own preferred values. Set both to 1.25em, if you like -- there's no reason why you have to stick with pixel-based indentation. If you want to reset lists to have no indentation, then you still have to zero out both padding and margin:

+ +
ul {margin-left: 0; padding-left: 0;}
+ +

Remember, though, that in so doing, you'll have the bullets hanging outside the list and its parent element. If the parent is the body, there's a strong chance your bullets will be completely outside the browser window, and thus will not be visible.

+ +

结论

+ +

In the end, we can see that none of the browsers mentioned in this article is right or wrong about how they lay out lists. They use different default styles, and that's where the problems creep in. By making sure you style both the left padding and left margin of lists, you can find much greater cross-browser consistency in your list indentation.

+ +

建议

+ + + +
+

原始文档信息

+ + +
+ +

{{ languages( { "fr": "fr/Indentation_homog\u00e8ne_des_listes" } ) }}

diff --git a/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html b/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html new file mode 100644 index 0000000000..4a8fa17797 --- /dev/null +++ b/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html @@ -0,0 +1,120 @@ +--- +title: 使用CSS计数器 +slug: Web/Guide/CSS/Counters +tags: + - CSS + - CSS List + - Web + - counter + - 教程 +translation_of: Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters +--- +
{{CSSRef}}
+ +

本质上CSS计数器是由CSS维护的变量,这些变量可能根据CSS规则增加以跟踪使用次数。这允许你根据文档位置来调整内容表现。 CSS计数器是CSS2.1中自动计数编号部分的实现。

+ +

计数器的值通过使用{{cssxref("counter-reset")}} 和 {{cssxref("counter-increment")}} 操作,在 content 上应用 counter()counters()函数来显示在页面上。

+ +

使用计数器

+ +

使用CSS计数器之前,必须重置一个值,默认是0。使用{{cssxref("counter()")}}函数来给元素增加计数器。 下面的CSS给每个h3元素的前面增加了 "Section <计算器值>:"。

+ +
body {
+  counter-reset: section;           /* 重置计数器成0 */
+}
+h3:before {
+  counter-increment: section;      /* 增加计数器值 */
+  content: "Section " counter(section) ": "; /* 显示计数器 */
+}
+
+ +

例如:

+ +
<h3>Introduction</h3>
+<h3>Body</h3>
+<h3>Conclusion</h3>
+ +

{{ EmbedLiveSample('使用计数器', 300,200) }}

+ +

计数器嵌套

+ +

CSS计数器对创建有序列表特别有用,因为在子元素中会自动创建一个CSS计数器的实例。使用 counters() 函数,在不同级别的嵌套计数器之间可以插入字符串。比如这个CSS例子:

+ +
ol {
+  counter-reset: section;                /* 为每个ol元素创建新的计数器实例 */
+  list-style-type: none;
+}
+li:before {
+  counter-increment: section;            /* 只增加计数器的当前实例 */
+  content: counters(section, ".") " ";   /* 为所有计数器实例增加以“.”分隔的值 */
+}
+
+ +

结合下面的HTML:

+ +
<ol>
+  <li>item</li>          <!-- 1     -->
+  <li>item               <!-- 2     -->
+    <ol>
+      <li>item</li>      <!-- 2.1   -->
+      <li>item</li>      <!-- 2.2   -->
+      <li>item           <!-- 2.3   -->
+        <ol>
+          <li>item</li>  <!-- 2.3.1 -->
+          <li>item</li>  <!-- 2.3.2 -->
+        </ol>
+        <ol>
+          <li>item</li>  <!-- 2.3.1 -->
+          <li>item</li>  <!-- 2.3.2 -->
+          <li>item</li>  <!-- 2.3.3 -->
+        </ol>
+      </li>
+      <li>item</li>      <!-- 2.4   -->
+    </ol>
+  </li>
+  <li>item</li>          <!-- 3     -->
+  <li>item</li>          <!-- 4     -->
+</ol>
+<ol>
+  <li>item</li>          <!-- 1     -->
+  <li>item</li>          <!-- 2     -->
+</ol>
+ +

结果为:

+ +

{{ EmbedLiveSample('计数器嵌套') }}

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName("CSS3 Lists", "#auto-numbering", "CSS Counters")}}{{Spec2("CSS3 Lists")}}无变化
{{SpecName('CSS2.1', 'generate.html#generate.html#counters', 'counter-reset')}}{{Spec2('CSS2.1')}}初始定义
+ +

其它

+ + + +

另一个可用的示例在 http://www.mezzoblue.com/archives/20.../counter_intu/。这篇博客 发布于2006年11月1日,但是看上去写得还是准确的。

+ +
 
diff --git a/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html b/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html new file mode 100644 index 0000000000..cfce90ff34 --- /dev/null +++ b/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html @@ -0,0 +1,71 @@ +--- +title: 逻辑属性的和值的基本概念 +slug: Web/CSS/CSS_Logical_Properties/Basic_conceptsjie +translation_of: Web/CSS/CSS_Logical_Properties/Basic_concepts +--- +
{{CSSRef}}
+ +

逻辑属性与值详述中为CSS中许多属性和值引入相对浮动功能。本文介绍了详述,同时对浮动相关的属性和值做出了解释。

+ +

我们为什么需要逻辑属性?

+ +

传统CSS根据屏幕的物理大小定义了 traditionally has sized things according to the physical dimensions of the screen. Therefore we describe boxes as having a {{CSSxRef("width")}} and {{CSSxRef("height")}}, position items from the top and left, float things left, assign borders, margin, and padding to the top, right, bottom, left, etc. The Logical Properties and Values specification defines mappings for these physical values to their logical, or flow relative, counterparts — e.g. start and end as opposed to left and right/top and bottom.

+ +

An example of why these mappings might be needed is as follows. I have a Layout using CSS Grid, the grid container has a width applied and I am using the {{CSSxRef("align-self")}} and {{CSSxRef("justify-self")}} properties to align the items. These properties are flow relative — justify-self: start aligns the item to the start on the inline dimension, align-self: start does the same on the block dimension.

+ +

A grid in a horizontal writing mode

+ +

If I now change the writing mode of this component to vertical-rl using the {{CSSxRef("writing-mode")}} property, the alignment continues to work in the same way. The inline dimension is now running vertically and the block dimension horizontally. The grid doesn't look the same however, as the width assigned to the container is a horizontal measure, a measure tied to the physical and not the logical or flow relative running of the text.

+ +

A grid in vertical writing mode.

+ +

If instead of the width property we use the logical property {{CSSxRef("inline-size")}}, the component now works the same way no matter which writing mode it is displayed using.

+ +

A grid layout in vertical writing mode

+ +

You can try this out in the live example below. Change writing-mode from vertical-rl to horizontal-tb on .box to see how the different properties change the layout.

+ +

{{EmbedGHLiveSample("css-examples/logical/intro-grid-example.html", '100%', 700)}}

+ +

When working with a site in a writing mode other than a horizontal, top to bottom one, or when using writing modes for creative reasons, being able to relate to the flow of the content makes a lot of sense.

+ +

Block and inline dimensions

+ +

A key concept of working with flow relative properties and values is the two dimensions of block and inline. As we saw above, newer CSS layout methods such as Flexbox and Grid Layout use the concepts of block and inline rather than right and left/top and bottom when aligning items.

+ +

The inline dimension is the dimension along which a line of text runs in the writing mode in use. Therefore, in an English document with the text running horizontally left to right, or an Arabic document with the text running horizontally right to left, the inline dimension is horizontal. Switch to a vertical writing mode (e.g. a Japanese document) and the inline dimension is now vertical, as lines in that writing mode run vertically.

+ +

The block dimension is the other dimension, and the direction in which blocks — such as paragraphs — display one after the other. In English and Arabic these run vertically, whereas in any vertical writing mode these run horizontally.

+ +

The below diagram shows the inline and block directions in a horizontal writing mode:

+ +

diagram showing the inline axis running horizontally, block axis vertically.

+ +

This diagram shows block and inline in a vertical writing mode:

+ +

Diagram showing the block axis running horizontally the inline axis vertically.

+ +

Browser support

+ +

Logical Properties and Values can be thought of as a couple of groups in terms of current browser support. Some of the properties are essentially mappings from the physical versions, for example {{CSSxRef("inline-size")}} for {{CSSxRef("width")}} or {{CSSxRef("margin-inline-start")}} rather than {{CSSxRef("margin-left")}}. These mapped properties are starting to see good browser support, and if you look at the individual pages for the properties in the reference here on MDN you will see that Edge is the only modern browser currently missing these.

+ +

There are then a group of properties which do not have a direct mapping in terms of existing physical properties. These are shorthands made possible by the fact that we can refer to both edges of the block or inline dimension at once. An example would be {{CSSxRef("margin-block")}}, which is a shorthand setting for {{CSSxRef("margin-block-start")}} and {{CSSxRef("margin-block-end")}}. These currently have no browser support.

+ +
+

Note: The CSS Working Group are currently trying to decide what to do about the four-value shorthands for logical properties, for example the equivalents to setting four physical properties at once, like margins with the {{CSSxRef("margin")}} property. We would need some kind of modifier if we were to reuse margin for flow-relative properties. If you would like to read the suggestions or comment on them the relevant GitHub issue is #1282.

+
+ +

Testing for browser support

+ +

You can test for support of logical properties and values using feature queries. For example you could set a {{CSSxRef("width")}}, test for {{CSSxRef("inline-size")}} and, if it is supported, set the width to auto and the inline-size to the original width value.

+ +

{{EmbedGHLiveSample("css-examples/logical/intro-feature-queries.html", "100%", 700)}}

+ +

See also

+ + diff --git a/files/zh-cn/web/css/css_logical_properties/basic_conceptsjie/index.html b/files/zh-cn/web/css/css_logical_properties/basic_conceptsjie/index.html deleted file mode 100644 index cfce90ff34..0000000000 --- a/files/zh-cn/web/css/css_logical_properties/basic_conceptsjie/index.html +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: 逻辑属性的和值的基本概念 -slug: Web/CSS/CSS_Logical_Properties/Basic_conceptsjie -translation_of: Web/CSS/CSS_Logical_Properties/Basic_concepts ---- -
{{CSSRef}}
- -

逻辑属性与值详述中为CSS中许多属性和值引入相对浮动功能。本文介绍了详述,同时对浮动相关的属性和值做出了解释。

- -

我们为什么需要逻辑属性?

- -

传统CSS根据屏幕的物理大小定义了 traditionally has sized things according to the physical dimensions of the screen. Therefore we describe boxes as having a {{CSSxRef("width")}} and {{CSSxRef("height")}}, position items from the top and left, float things left, assign borders, margin, and padding to the top, right, bottom, left, etc. The Logical Properties and Values specification defines mappings for these physical values to their logical, or flow relative, counterparts — e.g. start and end as opposed to left and right/top and bottom.

- -

An example of why these mappings might be needed is as follows. I have a Layout using CSS Grid, the grid container has a width applied and I am using the {{CSSxRef("align-self")}} and {{CSSxRef("justify-self")}} properties to align the items. These properties are flow relative — justify-self: start aligns the item to the start on the inline dimension, align-self: start does the same on the block dimension.

- -

A grid in a horizontal writing mode

- -

If I now change the writing mode of this component to vertical-rl using the {{CSSxRef("writing-mode")}} property, the alignment continues to work in the same way. The inline dimension is now running vertically and the block dimension horizontally. The grid doesn't look the same however, as the width assigned to the container is a horizontal measure, a measure tied to the physical and not the logical or flow relative running of the text.

- -

A grid in vertical writing mode.

- -

If instead of the width property we use the logical property {{CSSxRef("inline-size")}}, the component now works the same way no matter which writing mode it is displayed using.

- -

A grid layout in vertical writing mode

- -

You can try this out in the live example below. Change writing-mode from vertical-rl to horizontal-tb on .box to see how the different properties change the layout.

- -

{{EmbedGHLiveSample("css-examples/logical/intro-grid-example.html", '100%', 700)}}

- -

When working with a site in a writing mode other than a horizontal, top to bottom one, or when using writing modes for creative reasons, being able to relate to the flow of the content makes a lot of sense.

- -

Block and inline dimensions

- -

A key concept of working with flow relative properties and values is the two dimensions of block and inline. As we saw above, newer CSS layout methods such as Flexbox and Grid Layout use the concepts of block and inline rather than right and left/top and bottom when aligning items.

- -

The inline dimension is the dimension along which a line of text runs in the writing mode in use. Therefore, in an English document with the text running horizontally left to right, or an Arabic document with the text running horizontally right to left, the inline dimension is horizontal. Switch to a vertical writing mode (e.g. a Japanese document) and the inline dimension is now vertical, as lines in that writing mode run vertically.

- -

The block dimension is the other dimension, and the direction in which blocks — such as paragraphs — display one after the other. In English and Arabic these run vertically, whereas in any vertical writing mode these run horizontally.

- -

The below diagram shows the inline and block directions in a horizontal writing mode:

- -

diagram showing the inline axis running horizontally, block axis vertically.

- -

This diagram shows block and inline in a vertical writing mode:

- -

Diagram showing the block axis running horizontally the inline axis vertically.

- -

Browser support

- -

Logical Properties and Values can be thought of as a couple of groups in terms of current browser support. Some of the properties are essentially mappings from the physical versions, for example {{CSSxRef("inline-size")}} for {{CSSxRef("width")}} or {{CSSxRef("margin-inline-start")}} rather than {{CSSxRef("margin-left")}}. These mapped properties are starting to see good browser support, and if you look at the individual pages for the properties in the reference here on MDN you will see that Edge is the only modern browser currently missing these.

- -

There are then a group of properties which do not have a direct mapping in terms of existing physical properties. These are shorthands made possible by the fact that we can refer to both edges of the block or inline dimension at once. An example would be {{CSSxRef("margin-block")}}, which is a shorthand setting for {{CSSxRef("margin-block-start")}} and {{CSSxRef("margin-block-end")}}. These currently have no browser support.

- -
-

Note: The CSS Working Group are currently trying to decide what to do about the four-value shorthands for logical properties, for example the equivalents to setting four physical properties at once, like margins with the {{CSSxRef("margin")}} property. We would need some kind of modifier if we were to reuse margin for flow-relative properties. If you would like to read the suggestions or comment on them the relevant GitHub issue is #1282.

-
- -

Testing for browser support

- -

You can test for support of logical properties and values using feature queries. For example you could set a {{CSSxRef("width")}}, test for {{CSSxRef("inline-size")}} and, if it is supported, set the width to auto and the inline-size to the original width value.

- -

{{EmbedGHLiveSample("css-examples/logical/intro-feature-queries.html", "100%", 700)}}

- -

See also

- - diff --git a/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html b/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html new file mode 100644 index 0000000000..b96f3f6c88 --- /dev/null +++ b/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html @@ -0,0 +1,132 @@ +--- +title: 浮动和定位的逻辑属性 +slug: Web/CSS/CSS_Logical_Properties/浮动和定位 +translation_of: Web/CSS/CSS_Logical_Properties/Floating_and_positioning +--- +
{{CSSRef}}
+ +

逻辑属性和值指南 包含了 {{cssxref("float")}} 和{{cssxref("clear")}}逻辑属性到物理属性的映射, 以及与定位布局一起使用的定位属性. 通过本文,我们来看看如何使用它们。

+ +

Mapped properties and values

+ +

The table below details the properties and values discussed in this guide along with their physical mappings. They assume a horizontal {{cssxref("writing-mode")}}, with a left-to-right direction.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Logical property or valuePhysical property or value
{{cssxref("float")}}: inline-start{{cssxref("float")}}: left
{{cssxref("float")}}: inline-end{{cssxref("float")}}: right
{{cssxref("clear")}}: inline-start{{cssxref("clear")}}: left
{{cssxref("clear")}}: inline-end{{cssxref("clear")}}: right
{{cssxref("inset-inline-start")}}{{cssxref("left")}}
{{cssxref("inset-inline-end")}}{{cssxref("right")}}
{{cssxref("inset-block-start")}}{{cssxref("top")}}
{{cssxref("inset-block-end")}}{{cssxref("bottom")}}
{{cssxref("text-align")}}: start{{cssxref("text-align")}}: left
{{cssxref("text-align")}}: end{{cssxref("text-align")}}: right
+ +

In addition to these mapped properties there are some additional shorthand properties made possible by being able to address block and inline dimensions. These have no mapping to physical properties, aside from the {{cssxref("inset")}} property.

+ + + + + + + + + + + + + + + + + + + + + + +
Logical propertyPurpose
{{cssxref("inset-inline")}}Sets both of the above inset values for the inline dimension simultaneously.
{{cssxref("inset-block")}}Sets both of the above inset values for the block dimension simultaneously.
{{cssxref("inset")}}Sets all four inset values simultaneously with physical mapping of multi-value.
+ +

Float and clear example

+ +

The physical values used with the {{cssxref("float")}} and {{cssxref("clear")}} properties are left, right and both. The Logical Properties specification defines the values inline-start and inline-end as mappings for left and right.

+ +

In the example below I have two boxes — the first has the box floated with float: left, the second with float: inline-start. If you change the writing-mode to vertical-rl or the direction to rtl you will see that the left-floated box always sticks to the left, whereas the inline-start-floated item follows the direction and writing-mode.

+ +

{{EmbedGHLiveSample("css-examples/logical/float.html", '100%', 700)}}

+ +

Example: Inset properties for positioned layout

+ +

Positioning generally allows us to position an element in a manner relative to its containing block — we essentially inset the item relative to where it would fall based on normal flow. To do this we have historically used the physical properties {{cssxref("top")}}, {{cssxref("right")}}, {{cssxref("bottom")}} and {{cssxref("left")}}.

+ +

These properties take a length or a percentage as a value, and relate to the user's screen dimensions.

+ +

New properties have been created in the Logical Properties specification for when you want the positioning to relate to the flow of text in your writing mode. These are as follows: {{cssxref("inset-block-start")}}, {{cssxref("inset-block-end")}}, {{cssxref("inset-inline-start")}} and {{cssxref("inset-inline-end")}}.

+ +

In the below example I have used the inset-block-start and inset-inline-end properties to position the blue box using absolute positioning inside the area with the grey dotted border, which has position: relative. Change the writing-mode property to vertical-rl, or add direction: rtl, and see how the flow relative box stays with the text direction.

+ +

{{EmbedGHLiveSample("css-examples/logical/positioning-inset.html", '100%', 700)}}

+ +

New two- and four-value shorthands

+ +

As with other properties in the specification we have some new shorthand properties, which give the ability to set two or four values at once.

+ + + +
+

Note: The browsers that have implemented the Logical Properties specification have so far implemented the direct mappings and not the new shorthands. Look to the browser compatibility data section on each property page reference for more details.

+
+ +

Example: Logical values for text-align

+ +

The {{cssxref("text-align")}} property has logical values that relate to text direction — rather than using left and right we can use start and end. In the below example I have set text-align: right in the first block and text-align: end in the second.

+ +

If you change the value of direction to rtl you will see that the alignment stays to the right for the first block, but goes to the logical end on the left in the second.

+ +

{{EmbedGHLiveSample("css-examples/logical/text-align.html", '100%', 700)}}

+ +

This works in a more consistent way when using box alignment that uses start and end rather than physical directions for alignment.

diff --git "a/files/zh-cn/web/css/css_logical_properties/\346\265\256\345\212\250\345\222\214\345\256\232\344\275\215/index.html" "b/files/zh-cn/web/css/css_logical_properties/\346\265\256\345\212\250\345\222\214\345\256\232\344\275\215/index.html" deleted file mode 100644 index b96f3f6c88..0000000000 --- "a/files/zh-cn/web/css/css_logical_properties/\346\265\256\345\212\250\345\222\214\345\256\232\344\275\215/index.html" +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: 浮动和定位的逻辑属性 -slug: Web/CSS/CSS_Logical_Properties/浮动和定位 -translation_of: Web/CSS/CSS_Logical_Properties/Floating_and_positioning ---- -
{{CSSRef}}
- -

逻辑属性和值指南 包含了 {{cssxref("float")}} 和{{cssxref("clear")}}逻辑属性到物理属性的映射, 以及与定位布局一起使用的定位属性. 通过本文,我们来看看如何使用它们。

- -

Mapped properties and values

- -

The table below details the properties and values discussed in this guide along with their physical mappings. They assume a horizontal {{cssxref("writing-mode")}}, with a left-to-right direction.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Logical property or valuePhysical property or value
{{cssxref("float")}}: inline-start{{cssxref("float")}}: left
{{cssxref("float")}}: inline-end{{cssxref("float")}}: right
{{cssxref("clear")}}: inline-start{{cssxref("clear")}}: left
{{cssxref("clear")}}: inline-end{{cssxref("clear")}}: right
{{cssxref("inset-inline-start")}}{{cssxref("left")}}
{{cssxref("inset-inline-end")}}{{cssxref("right")}}
{{cssxref("inset-block-start")}}{{cssxref("top")}}
{{cssxref("inset-block-end")}}{{cssxref("bottom")}}
{{cssxref("text-align")}}: start{{cssxref("text-align")}}: left
{{cssxref("text-align")}}: end{{cssxref("text-align")}}: right
- -

In addition to these mapped properties there are some additional shorthand properties made possible by being able to address block and inline dimensions. These have no mapping to physical properties, aside from the {{cssxref("inset")}} property.

- - - - - - - - - - - - - - - - - - - - - - -
Logical propertyPurpose
{{cssxref("inset-inline")}}Sets both of the above inset values for the inline dimension simultaneously.
{{cssxref("inset-block")}}Sets both of the above inset values for the block dimension simultaneously.
{{cssxref("inset")}}Sets all four inset values simultaneously with physical mapping of multi-value.
- -

Float and clear example

- -

The physical values used with the {{cssxref("float")}} and {{cssxref("clear")}} properties are left, right and both. The Logical Properties specification defines the values inline-start and inline-end as mappings for left and right.

- -

In the example below I have two boxes — the first has the box floated with float: left, the second with float: inline-start. If you change the writing-mode to vertical-rl or the direction to rtl you will see that the left-floated box always sticks to the left, whereas the inline-start-floated item follows the direction and writing-mode.

- -

{{EmbedGHLiveSample("css-examples/logical/float.html", '100%', 700)}}

- -

Example: Inset properties for positioned layout

- -

Positioning generally allows us to position an element in a manner relative to its containing block — we essentially inset the item relative to where it would fall based on normal flow. To do this we have historically used the physical properties {{cssxref("top")}}, {{cssxref("right")}}, {{cssxref("bottom")}} and {{cssxref("left")}}.

- -

These properties take a length or a percentage as a value, and relate to the user's screen dimensions.

- -

New properties have been created in the Logical Properties specification for when you want the positioning to relate to the flow of text in your writing mode. These are as follows: {{cssxref("inset-block-start")}}, {{cssxref("inset-block-end")}}, {{cssxref("inset-inline-start")}} and {{cssxref("inset-inline-end")}}.

- -

In the below example I have used the inset-block-start and inset-inline-end properties to position the blue box using absolute positioning inside the area with the grey dotted border, which has position: relative. Change the writing-mode property to vertical-rl, or add direction: rtl, and see how the flow relative box stays with the text direction.

- -

{{EmbedGHLiveSample("css-examples/logical/positioning-inset.html", '100%', 700)}}

- -

New two- and four-value shorthands

- -

As with other properties in the specification we have some new shorthand properties, which give the ability to set two or four values at once.

- - - -
-

Note: The browsers that have implemented the Logical Properties specification have so far implemented the direct mappings and not the new shorthands. Look to the browser compatibility data section on each property page reference for more details.

-
- -

Example: Logical values for text-align

- -

The {{cssxref("text-align")}} property has logical values that relate to text direction — rather than using left and right we can use start and end. In the below example I have set text-align: right in the first block and text-align: end in the second.

- -

If you change the value of direction to rtl you will see that the alignment stays to the right for the first block, but goes to the logical end on the left in the second.

- -

{{EmbedGHLiveSample("css-examples/logical/text-align.html", '100%', 700)}}

- -

This works in a more consistent way when using box alignment that uses start and end rather than physical directions for alignment.

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html new file mode 100644 index 0000000000..acd3b034ce --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html @@ -0,0 +1,158 @@ +--- +title: Adding z-index +slug: Web/Guide/CSS/Understanding_z_index/Adding_z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index +--- +

« CSS «理解z-index

+

使用 {{ cssxref("z-index") }}

+

在第一个例子 Stacking without z-index中, 我们描述了默认的摆放顺序。 当你需要指定不同的排列顺序时, 只要给元素指定一个z-index的数值就可以了。 

+

 

+

该属性必须是整数(正负均可), 它体现了元素在z轴的位置。 如果你对z轴体系不了解, 你也可以把它理解成“层叠”, 每个层都有一个顺序数, 顺序数大的层在上面, 小的在下面。 

+

注意!z-index只对指定了 positioned属性的元素有效。

+ +
+

注释:

+ +
+

在下一个例子中, 所有的层都是用z-index进行排序的。 元素div#5 的z-index无效, 因为他没有被指定position属性。 

+

Example of stacking rules modified using z-index

+

Example source code

+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head><style type="text/css">
+
+div {
+   opacity: 0.7;
+   font: 12px Arial;
+}
+
+span.bold { font-weight: bold; }
+
+#normdiv {
+   z-index: 8;
+   height: 70px;
+   border: 1px dashed #999966;
+   background-color: #ffffcc;
+   margin: 0px 50px 0px 50px;
+   text-align: center;
+}
+
+#reldiv1 {
+   z-index: 3;
+   height: 100px;
+   position: relative;
+   top: 30px;
+   border: 1px dashed #669966;
+   background-color: #ccffcc;
+   margin: 0px 50px 0px 50px;
+   text-align: center;
+}
+
+#reldiv2 {
+   z-index: 2;
+   height: 100px;
+   position: relative;
+   top: 15px;
+   left: 20px;
+   border: 1px dashed #669966;
+   background-color: #ccffcc;
+   margin: 0px 50px 0px 50px;
+   text-align: center;
+}
+
+#absdiv1 {
+   z-index: 5;
+   position: absolute;
+   width: 150px;
+   height: 350px;
+   top: 10px;
+   left: 10px;
+   border: 1px dashed #990000;
+   background-color: #ffdddd;
+   text-align: center;
+}
+
+#absdiv2 {
+   z-index: 1;
+   position: absolute;
+   width: 150px;
+   height: 350px;
+   top: 10px;
+   right: 10px;
+   border: 1px dashed #990000;
+   background-color: #ffdddd;
+   text-align: center;
+}
+
+</style></head>
+
+<body>
+
+<br /><br />
+
+<div id="absdiv1">
+   <br /><span class="bold">DIV #1</span>
+   <br />position: absolute;
+   <br />z-index: 5;
+</div>
+
+<div id="reldiv1">
+   <br /><span class="bold">DIV #2</span>
+   <br />position: relative;
+   <br />z-index: 3;
+</div>
+
+<div id="reldiv2">
+   <br /><span class="bold">DIV #3</span>
+   <br />position: relative;
+   <br />z-index: 2;
+</div>
+
+<div id="absdiv2">
+   <br /><span class="bold">DIV #4</span>
+   <br />position: absolute;
+   <br />z-index: 1;
+</div>
+
+<div id="normdiv">
+   <br /><span class="bold">DIV #5</span>
+   <br />no positioning
+   <br />z-index: 8;
+</div>
+
+</body></html>
+
+

See also

+ +
+

Original Document Information

+ +
+

{{ languages( { "fr": "fr/CSS/Comprendre_z-index/Ajout_de_z-index" } ) }}

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html new file mode 100644 index 0000000000..19f49650d1 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html @@ -0,0 +1,47 @@ +--- +title: 理解CSS的 z-index属性 +slug: Web/Guide/CSS/Understanding_z_index +tags: + - CSS + - Guide +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index +--- +

{{cssref}}

+ +

通常情况下,HTML页面可以被认为是二维的,因为文本,图像和其他元素被排列在页面上而不重叠。在这种情况下,只有一个渲染进程,所有元素都知道其他元素所占用的空间。 {{cssxref("z-index")}}属性可让你在渲染内容时调整对象分层的顺序。

+ +
+

在 CSS 2.1 中, 所有的盒模型元素都处于三维坐标系中。 除了我们常用的横坐标和纵坐标, 盒模型元素还可以沿着“z 轴”层叠摆放, 当他们相互覆盖时, z 轴顺序就变得十分重要。

+
+ +

(参见 CSS 2.1 Section 9.9.1 - Layered presentation)

+ +

这意味着其实 CSS 允许你在现有的渲染引擎上层叠的摆放盒模型元素。 所有的层都可以用一个整数( z 轴顺序)来表明当前层在 z 轴的位置。 数字越大, 元素越接近观察者。Z 轴顺序用 CSS 的 {{ cssxref("z-index") }} 属性来指定。

+ +

使用 z-index 很简单: 给它指定一个整数值即可。 然而,在层叠比较复杂的 HTML 元素上使用 z-index 时,结果可能让人觉得困惑,甚至不可思议。 这是由复杂的元素排布规则导致的。  更多细节请参见  CSS-2.1 Appendix E 。

+ +

本文将通过一些简单的例子来解释这些规则。

+ +
    +
  1. Stacking without z-index : 默认的摆放规则,即不含有 z-index 属性时
  2. +
  3. Stacking and float : 浮动元素的处理方式
  4. +
  5. Adding z-index : 使用 z-index 来改变堆放顺序
  6. +
  7. The stacking context : 内容堆放注意事项
  8. +
  9. Stacking context example 1 : 在两层元素的第二层上使用 z-index
  10. +
  11. Stacking context example 2 : 在两层元素的所有层上使用 z-index
  12. +
  13. Stacking context example 3 : 在三层元素的第二层上使用 z-index
  14. +
+ +
+

 

+ +

原始文档信息

+ +

 

+ + +
diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html new file mode 100644 index 0000000000..9312c1759d --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html @@ -0,0 +1,158 @@ +--- +title: 层叠与浮动 +slug: Web/Guide/CSS/Understanding_z_index/Stacking_and_float +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float +--- +

« CSS « 理解 CSS 中的 z-index

+ +

层叠与浮动

+ +

对于浮动的块元素来说,层叠顺序变得有些不同。浮动块元素被放置于非定位块元素与定位块元素之间:

+ +
    +
  1. 根元素的背景与边框
  2. +
  3. 位于普通流中的后代块元素按照它们在 HTML 中出现的顺序层叠
  4. +
  5. 浮动块元素
  6. +
  7. 后代中的定位元素按照它们在 HTML 中出现的顺序层叠
  8. +
+ +

实际上,在接下来的例子中你会看到,非定位块元素(DIV #4)的背景与边框丝毫不会受到浮动块元素的影响,但内容却恰恰相反。出现这种情况是由于 CSS 的标准浮动行为引起的。

+ +

这种行为可以通过前一章列表的改进版本来解释:

+ +
    +
  1. 根元素的背景与边框
  2. +
  3. 位于普通流中的后代块元素按照它们在 HTML 中出现的顺序层叠
  4. +
  5. 浮动块元素
  6. +
  7. 常规流中的后代行内元素
  8. +
  9. 后代中的定位元素按照它们在 HTML 中出现的顺序层叠
  10. +
+ +
注意: 在下面的例子中,除了非定位的那个块元素外,所有的块元素都是半透明的,以便来显示层叠顺序。如果减少非定位元素(DIV #4)的透明度,会发生很诡异的事情:该元素的背景和边框会出现在浮动块元素上方,但是仍然处于定位元素的下方。我不能确定这是规范的 bug 或是怪异的解析。(设置透明度会隐式的创建一个层叠上下文。)
+ +

{{ EmbedLiveSample('该示例的源码', '563', '255', '', 'Web/Guide/CSS/Understanding_z_index/Stacking_and_float') }}

+ +

该示例的源码

+ +
<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>Stacking and float</title>
+    <style type="text/css">
+
+    div {
+        font: 12px Arial;
+    }
+
+    span.bold { font-weight: bold; }
+
+    #absdiv1 {
+        position: absolute;
+        width: 150px;
+        height: 200px;
+        top: 10px;
+        right: 140px;
+        border: 1px dashed #990000;
+        background-color: #ffdddd;
+        text-align: center;
+    }
+
+    #normdiv {
+        /* opacity: 0.7; */
+        height: 100px;
+        border: 1px dashed #999966;
+        background-color: #ffffcc;
+        margin: 0px 10px 0px 10px;
+        text-align: left;
+    }
+
+    #flodiv1 {
+        margin: 0px 10px 0px 20px;
+        float: left;
+        width: 150px;
+        height: 200px;
+        border: 1px dashed #009900;
+        background-color: #ccffcc;
+        text-align: center;
+    }
+
+    #flodiv2 {
+        margin: 0px 20px 0px 10px;
+        float: right;
+        width: 150px;
+        height: 200px;
+        border: 1px dashed #009900;
+        background-color: #ccffcc;
+        text-align: center;
+    }
+
+    #absdiv2 {
+        position: absolute;
+        width: 150px;
+        height: 100px;
+        top: 130px;
+        left: 100px;
+        border: 1px dashed #990000;
+        background-color: #ffdddd;
+        text-align: center;
+    }
+
+</style>
+</head>
+
+<body>
+    <br /><br />
+
+    <div id="absdiv1">
+        <br /><span class="bold">DIV #1</span>
+        <br />position: absolute;
+    </div>
+
+    <div id="flodiv1">
+        <br /><span class="bold">DIV #2</span>
+        <br />float: left;
+    </div>
+
+    <div id="flodiv2">
+        <br /><span class="bold">DIV #3</span>
+        <br />float: right;
+    </div>
+
+    <br />
+
+    <div id="normdiv">
+        <br /><span class="bold">DIV #4</span>
+        <br />no positioning
+    </div>
+
+    <div id="absdiv2">
+        <br /><span class="bold">DIV #5</span>
+        <br />position: absolute;
+    </div>
+</body>
+</html>
+
+ +

相关链接

+ + + +
+

原始文档信息

+ + +
+ +

 

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html new file mode 100644 index 0000000000..59f298d269 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html @@ -0,0 +1,133 @@ +--- +title: Stacking context example 1 +slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_1 +tags: + - 理解_CSS_z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1 +--- +

« CSS « Understanding CSS z-index

+ +

Stacking context 层叠上下文 例子 1

+ +

先看一个基础的例子。在根元素的层叠上下文中,有两个都是相对定位且没有设置 z-index 属性的 DIV(DIV #1 和 DIV #3)。在 DIV #1 中有一个绝对定位的 DIV #2,而在 DIV #3 中有一个绝对定位的 DIV #4,DIV #2 和 DIV #4 也都没有设置 z-index 属性。

+ +

现在唯一的层叠上下文就是根元素的上下文。因为没有 z-index 值,所有的元素按照出现(在 HTML 中)的顺序层叠。

+ +

Stacking context example 1

+ +

如果给 DIV #2 设置一个正的 z-index  值 (不能是 0 或 auto) ,那么 DIV #2 会渲染在其他所有 DIV 之上。

+ +

Stacking context example 1

+ +

然后如果给 DIV #4 也设置一个正的 z-index  值,且这个值比给的 DIV #2 设置的值要大,则 DIV #4  会渲染在其他所有 DIV(包括 DIV #2)之上。

+ +

Stacking context example 1

+ +

在这个列子中,DIV #2 和 DIV #4 不是兄弟关系(因为它们的父元素不同)。即便如此,我们也可以通过 z-index 来控制 DIV #4 和 DIV #2 的层叠关系。这是因为,DIV #1 和 DIV #3 没有设置 z-index 的值,所以它们不会创建层叠上下文。这就意味着 DIV #1 和 DIV #3 的所有内容(包括 DIV #2 和 DIV #4)都属于同一个层叠上下文(即根元素的层叠上下文)。

+ +

就层叠上下文而言,DIV #1 和 DIV #3 隶属于根元素,因此层次结构如下所示:

+ + + +
注意: DIV #1 和 DIV #3 不是透明的。记住所有设置了 opacity 小于 1 的定位元素都会隐式地生成一个层叠上下文(和给元素增加一个 z-index 值的效果相同)。上述的例子是为了说明,当父元素没有生成一个层叠上下文环境的时候,各元素是怎么层叠的。
+ +

Example

+ +

HTML

+ +
<div id="div1">
+<br /><span class="bold">DIV #1</span>
+<br />position: relative;
+   <div id="div2">
+   <br /><span class="bold">DIV #2</span>
+   <br />position: absolute;
+   <br />z-index: 1;
+   </div>
+</div>
+
+<br />
+
+<div id="div3">
+<br /><span class="bold">DIV #3</span>
+<br />position: relative;
+   <div id="div4">
+   <br /><span class="bold">DIV #4</span>
+   <br />position: absolute;
+   <br />z-index: 2;
+   </div>
+</div>
+
+</body></html>
+
+ +

CSS

+ +
.bold {
+    font-weight: bold;
+    font: 12px Arial;
+}
+#div1,
+#div3 {
+    height: 80px;
+    position: relative;
+    border: 1px dashed #669966;
+    background-color: #ccffcc;
+    padding-left: 5px;
+}
+#div2 {
+    opacity: 0.8;
+    z-index: 1;
+    position: absolute;
+    width: 150px;
+    height: 200px;
+    top: 20px;
+    left: 170px;
+    border: 1px dashed #990000;
+    background-color: #ffdddd;
+    text-align: center;
+}
+#div4 {
+    opacity: 0.8;
+    z-index: 2;
+    position: absolute;
+    width: 200px;
+    height: 70px;
+    top: 65px;
+    left: 50px;
+    border: 1px dashed #000099;
+    background-color: #ddddff;
+    text-align: left;
+    padding-left: 10px;
+}
+ +

Result

+ +

{{ EmbedLiveSample('Example', '', '', '', 'Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1') }}

+ +

See also

+ + + +
+

Original Document Information

+ + +
diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html new file mode 100644 index 0000000000..3c21bef062 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html @@ -0,0 +1,142 @@ +--- +title: Stacking context example 2 +slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2 +tags: + - CSS + - 理解css的index属性 + - 高级 +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_2 +--- +

« CSS « 理解CSS z-index

+ +

层叠上下文示例 2

+ +

这是一个非常简单的例子, 但它是理解层叠上下文这个概念的关键。还是和之前的例子中一样的四个DIV,不过现在z-index属性被分配在两个水平的层次结构中。

+ +

{{ EmbedLiveSample('Example_source_code', '352', '270', '', 'Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2') }}

+ +

可以看到现在DIV #2 (z-index: 2)在DIV #3 (z-index: 1)的上面,因为他们都属于同一个层叠上下文(根元素创建的层叠上下文),所以z-index的值决定了元素如何叠放。

+ +

奇怪的是DIV #2 (z-index: 2)在DIV #4 (z-index: 10)的上面,尽管DIV #2的z-index值小于DIV #4。原因在于它们不属于同一个层叠上下文。DIV #4处于DIV #3所创建的层叠上下文中,而整个DIV #3(包含其后代元素)是在DIV #2下面的。

+ +

为了更好的理解这种情况, 这里列出了层叠上下文的层次结构:

+ + + +
Note: 值得记住的是,通常HTML的层次结构和层叠上下文的层次结构是不同的。在层叠上下文的层次结构中,没有创建层叠上下文的元素同其父级处于一个层叠上下文。
+ +

示例源码

+ +
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head><style type="text/css">
+
+div { font: 12px Arial; }
+
+span.bold { font-weight: bold; }
+
+#div2 { z-index: 2; }
+#div3 { z-index: 1; }
+#div4 { z-index: 10; }
+
+#div1,#div3 {
+   height: 80px;
+   position: relative;
+   border: 1px dashed #669966;
+   background-color: #ccffcc;
+   padding-left: 5px;
+}
+
+#div2 {
+   opacity: 0.8;
+   position: absolute;
+   width: 150px;
+   height: 200px;
+   top: 20px;
+   left: 170px;
+   border: 1px dashed #990000;
+   background-color: #ffdddd;
+   text-align: center;
+}
+
+#div4 {
+   opacity: 0.8;
+   position: absolute;
+   width: 200px;
+   height: 70px;
+   top: 65px;
+   left: 50px;
+   border: 1px dashed #000099;
+   background-color: #ddddff;
+   text-align: left;
+   padding-left: 10px;
+}
+
+
+</style></head>
+
+<body>
+
+    <br />
+
+    <div id="div1"><br />
+        <span class="bold">DIV #1</span><br />
+        position: relative;
+        <div id="div2"><br />
+            <span class="bold">DIV #2</span><br />
+            position: absolute;<br />
+            z-index: 2;
+        </div>
+    </div>
+
+    <br />
+
+    <div id="div3"><br />
+        <span class="bold">DIV #3</span><br />
+        position: relative;<br />
+        z-index: 1;
+        <div id="div4"><br />
+            <span class="bold">DIV #4</span><br />
+            position: absolute;<br />
+            z-index: 10;
+        </div>
+    </div>
+
+</body>
+</html>
+
+ +

相关文章

+ + + +
+

原文信息

+ + +
+ +

 

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html new file mode 100644 index 0000000000..f7d2972c7c --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html @@ -0,0 +1,190 @@ +--- +title: Stacking context example 3 +slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3 +tags: + - CSS + - 层叠上下文 + - 理解css的z-index属性 +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_3 +--- +

« CSS « Understanding CSS z-index

+ +

层叠上下文示例 3

+ +

最后一个例子展示了,在多层级的HTML结构中混合了多个定位元素且使用类选择器设置z-index属性时出现的问题。

+ +

我们来看一个用多个定位的div实现的三级菜单的例子,二级菜单和三级菜单在鼠标悬停或点击其父元素时才出现,通常这样的菜单在客户端和服务端都是由脚本生成的,所以样式规则不是通过ID选择器设置而是通过类选择器设置。

+ +

如果这个三级菜单有部分区域重叠,管理层叠顺序就会成为一个问题。

+ +

{{ EmbedLiveSample('Example_source_code', '320', '330', '', 'Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3') }}

+ + + +

一级菜单仅仅是相对定位,所以没有创建层叠上下文。

+ +

二级菜单相对其父元素(一级菜单)绝对定位,要使二级菜单在所有一级菜单的上方,则需要使用z-index。此时每个二级菜单都创建了一个层叠上下文,而三级菜单也处于其父元素(二级菜单)创建的上下文中。

+ +

这样一来,在HTML结构中处于三级菜单后面的二级菜单,则会显示在三级菜单的上方,因为所有的二级菜单都使用了同样的z-index值,所以处于同一个层叠上下文中。

+ +

为了能更好地理解这种情况,这里列出了层叠上下文的层次结构:

+ + + +

可以通过移除不同级别的菜单之间的重叠,或者使用ID选择器指定独立的(不同的)z-index值,或者减少HTML的层级来解决这个问题。

+ +
Note: 在源码中你会看到三级菜单和二级菜单是由一个绝对定位元素包含很多div来实现的,这种方式在需要同时定位一组元素时很有用。
+ +

示例源码

+ +
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head><style type="text/css">
+
+div { font: 12px Arial; }
+
+span.bold { font-weight: bold; }
+
+div.lev1 {
+   width: 250px;
+   height: 70px;
+   position: relative;
+   border: 2px outset #669966;
+   background-color: #ccffcc;
+   padding-left: 5px;
+}
+
+#container1 {
+   z-index: 1;
+   position: absolute;
+   top: 30px;
+   left: 75px;
+}
+
+div.lev2 {
+   opacity: 0.9;
+   width: 200px;
+   height: 60px;
+   position: relative;
+   border: 2px outset #990000;
+   background-color: #ffdddd;
+   padding-left: 5px;
+}
+
+#container2 {
+   z-index: 1;
+   position: absolute;
+   top: 20px;
+   left: 110px;
+}
+
+div.lev3 {
+   z-index: 10;
+   width: 100px;
+   position: relative;
+   border: 2px outset #000099;
+   background-color: #ddddff;
+   padding-left: 5px;
+}
+
+</style></head>
+
+<body>
+
+<br />
+
+<div class="lev1">
+<span class="bold">LEVEL #1</span>
+
+   <div id="container1">
+
+      <div class="lev2">
+      <br /><span class="bold">LEVEL #2</span>
+      <br />z-index: 1;
+
+         <div id="container2">
+
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+
+         </div>
+
+      </div>
+
+      <div class="lev2">
+      <br /><span class="bold">LEVEL #2</span>
+      <br />z-index: 1;
+      </div>
+
+   </div>
+</div>
+
+<div class="lev1">
+<span class="bold">LEVEL #1</span>
+</div>
+
+<div class="lev1">
+<span class="bold">LEVEL #1</span>
+</div>
+
+<div class="lev1">
+<span class="bold">LEVEL #1</span>
+</div>
+
+</body></html>
+
+ +

相关文章

+ + + +
+

原文信息

+ + +
+ +

Note: the reason the sample image looks wrong - with the second level 2 overlapping the level 3 menus - is because level 2 has opacity, which creates a new stacking context. Basically, this whole sample page is incorrect and misleading.

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html new file mode 100644 index 0000000000..a5aaebdc95 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html @@ -0,0 +1,161 @@ +--- +title: Stacking without z-index +slug: Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index +--- +

« CSS « 理解 CSS z-index

+ +

不含z-index的堆叠

+ +

当没有元素包含z-index属性时,元素按照如下顺序堆叠(从底到顶顺序):

+ +
    +
  1. 根元素的背景和边界
  2. +
  3. 普通流(无定位)里的块元素(没有position或者position:static;)按HTML中的出现顺序堆叠
  4. +
  5. 定位元素按HTML中的出现顺序堆叠
  6. +
+ +

在接下来的例子中,相对和绝对定位的块元素的大小和位置刚好说明上述堆叠规则。

+ +
+

Notes:

+ + +
+ +

understanding_zindex_01.png

+ +

 

+ +

示例

+ +
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head><style type="text/css">
+
+div {
+   font: 12px Arial;
+}
+
+span.bold { font-weight: bold; }
+
+#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;
+}
+
+</style></head>
+
+<body>
+
+<br /><br />
+
+<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>
+
+</body></html>
+
+
+ +

See also

+ + + +

 

+ +
+

Original Document Information

+ + +
+ +

{{ languages( { "fr": "fr/CSS/Comprendre_z-index/Empilement_sans_z-index" } ) }}

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html new file mode 100644 index 0000000000..6d96e3e198 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html @@ -0,0 +1,240 @@ +--- +title: 层叠上下文 +slug: Web/Guide/CSS/Understanding_z_index/The_stacking_context +tags: + - Advanced + - CSS + - CSS层叠上下文 + - z-index + - 教程 +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context +--- +
{{cssref}}
+ +

我们假定用户正面向(浏览器)视窗或网页,而 HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。

+ +

层叠上下文

+ +

在本篇之前的部分——运用 z-index,(我们认识到)某些元素的渲染顺序是由其 z-index 的值影响的。这是因为这些元素具有能够使他们形成一个层叠上下文的特殊属性

+ +

文档中的层叠上下文由满足以下任意一个条件的元素形成:

+ + + +

在层叠上下文中,子元素同样也按照上面解释的规则进行层叠。 重要的是,其子级层叠上下文的 z-index 值只在父级中才有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。

+ +

总结:

+ + + +
Note: 层叠上下文的层级是 HTML 元素层级的一个子级,因为只有某些元素才会创建层叠上下文。可以这样说,没有创建自己的层叠上下文的元素会被父层叠上下文同化
+ +

示例

+ +

Example of stacking rules modified using z-index

+ +

在这个例子中,每个被定位的元素都创建了独自的层叠上下文,因为他们被指定了定位属性和 z-index 值。我们把层叠上下文的层级列在下面:

+ + + +

请一定要注意 DIV #4,DIV #5 和 DIV #6 是 DIV #3 的子元素,所以它们的层叠完全在 DIV #3 中被处理。一旦 DIV #3 中的层叠和渲染处理完成,DIV #3 元素就被作为一个整体传递与兄弟元素的 DIV 在 root(根)元素进行层叠。

+ +
+

注意:

+ + +
+ +

示例源码

+ +

HTML

+ +
<div id="div1">
+  <h1>Division Element #1</h1>
+  <code>position: relative;<br/>
+  z-index: 5;</code>
+</div>
+
+<div id="div2">
+  <h1>Division Element #2</h1>
+  <code>position: relative;<br/>
+  z-index: 2;</code>
+</div>
+
+<div id="div3">
+  <div id="div4">
+    <h1>Division Element #4</h1>
+    <code>position: relative;<br/>
+    z-index: 6;</code>
+  </div>
+
+  <h1>Division Element #3</h1>
+  <code>position: absolute;<br/>
+  z-index: 4;</code>
+
+  <div id="div5">
+    <h1>Division Element #5</h1>
+    <code>position: relative;<br/>
+    z-index: 1;</code>
+  </div>
+
+  <div id="div6">
+    <h1>Division Element #6</h1>
+    <code>position: absolute;<br/>
+    z-index: 3;</code>
+  </div>
+</div>
+ +

CSS

+ +
* {
+    margin: 0;
+}
+html {
+    padding: 20px;
+    font: 12px/20px Arial, sans-serif;
+}
+div {
+    opacity: 0.7;
+    position: relative;
+}
+h1 {
+    font: inherit;
+    font-weight: bold;
+}
+#div1,
+#div2 {
+    border: 1px dashed #696;
+    padding: 10px;
+    background-color: #cfc;
+}
+#div1 {
+    z-index: 5;
+    margin-bottom: 190px;
+}
+#div2 {
+    z-index: 2;
+}
+#div3 {
+    z-index: 4;
+    opacity: 1;
+    position: absolute;
+    top: 40px;
+    left: 180px;
+    width: 330px;
+    border: 1px dashed #900;
+    background-color: #fdd;
+    padding: 40px 20px 20px;
+}
+#div4,
+#div5 {
+    border: 1px dashed #996;
+    background-color: #ffc;
+}
+#div4 {
+    z-index: 6;
+    margin-bottom: 15px;
+    padding: 25px 10px 5px;
+}
+#div5 {
+    z-index: 1;
+    margin-top: 15px;
+    padding: 5px 10px;
+}
+#div6 {
+    z-index: 3;
+    position: absolute;
+    top: 20px;
+    left: 180px;
+    width: 150px;
+    height: 125px;
+    border: 1px dashed #009;
+    padding-top: 125px;
+    background-color: #ddf;
+    text-align: center;
+}
+ +

Result

+ +

{{EmbedLiveSample('示例源码', '100%', '396') }}

+ +

参考

+ + + +
+

原始文档信息

+ + +
diff --git a/files/zh-cn/web/css/css_selectors/comparison_with_xpath/index.html b/files/zh-cn/web/css/css_selectors/comparison_with_xpath/index.html deleted file mode 100644 index c196e077e6..0000000000 --- a/files/zh-cn/web/css/css_selectors/comparison_with_xpath/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Comparison of CSS Selectors and XPath -slug: Web/CSS/CSS_Selectors/Comparison_with_XPath -translation_of: Web/XPath/Comparison_with_CSS_selectors ---- -
{{CSSRef("Selectors")}}{{QuickLinksWithSubpages("/en-US/docs/Web/XPath")}}{{Draft}}
- -

本文旨在记录CSS选择器和XPath之间的区别,以便Web开发人员能够更好地为正确的工作选择合适的工具。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XPath featureCSS equivalent
ancestor, parent or preceding-sibling axis{{CSSxRef(":has",":has()")}} selector {{experimental_inline}}
attribute axisAttribute selectors
child axisChild combinator
descendant axisDescendant combinator
following-sibling axisGeneral sibling combinator or adjacent sibling combinator
self axis{{CSSxRef(":scope")}} or {{CSSxRef(":host")}} selector
diff --git a/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html b/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html new file mode 100644 index 0000000000..65883df437 --- /dev/null +++ b/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html @@ -0,0 +1,68 @@ +--- +title: '在选择器中使用 :target 伪类' +slug: 'Web/Guide/CSS/Using_the_:target_selector' +tags: + - CSS + - CSS_3 + - Selectors +translation_of: 'Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors' +--- +

{{CSSRef}}

+ +

为了辅助标识那些指向文档特定部分链接的目标, CSS3 选择器 引入了 {{ Cssxref(":target") }} 伪类. Netscape 7.1 已经在 Netscape 系列中加入了这个伪类的支持, 这一新的举措让页面作者能够辅助用户在较大的页面中定位。 

+ +

选择一个目标

+ +

{{ Cssxref(":target") }} 伪类用来指定那些包含片段标识符的 URI 的目标元素样式。 例如, http://developer.mozilla.org/en/docs/Using_the_:target_selector#Example 这个 URI 包含了 #Example 片段标识符。 在HTML中, 标识符是元素的id或者name属性,。由于这两者位于相同的命名空间, 因此, 这个示例 URI 指向的是文档顶层的 "Example" 。

+ +

假设你想修改 URI 指向的任何 h2 元素,但是又不想把样式应用到任何其它同类型的元素,那么以下示例足够简单有用:

+ +
h2:target {font-weight: bold;}
+ +

同样的,将样式应用于特定的文档片段也是可行的。这是通过使用 URI 中相同的标识符实现的。例如,要在 #Example 文档片段中加入边框,我们可以通过如下代码实现: 

+ +
#Example:target {border: 1px solid black;}
+ +

定位所有元素

+ +

如果想要创建应用于所有目标元素的样式,那么可以使用通用选择器:

+ +
:target {color: red;}
+
+ +

示例

+ +

在以下示例中, 5个链接指向了同一文档中的元素。例如,选择 "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>
+
+ +

结论

+ +

在片段标识符指向部分文档的情况下,读者可能会对到底应该阅读文档的哪一部分感到疑惑。通过对不同的目标元素的样式进行修饰, 读者的相关疑惑会减少或者消除。

+ + + + + +
+

Original Document Information

+ + +
diff --git "a/files/zh-cn/web/css/css_\345\210\206\347\211\207/index.html" "b/files/zh-cn/web/css/css_\345\210\206\347\211\207/index.html" deleted file mode 100644 index 5b0d8e7a13..0000000000 --- "a/files/zh-cn/web/css/css_\345\210\206\347\211\207/index.html" +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: CSS分片 -slug: Web/CSS/CSS_分片 -tags: - - CSS - - CSS分片 - - 参考 -translation_of: Web/CSS/CSS_Fragmentation ---- -
{{cssref}}
- -

CSS FragmentationCSS的模块,它定义了内容在跨多个页面,区域或列中被分割(分段)时如何显示

- -

当一个内联框包装成多行时会发生碎片。当一个块跨越一个列布局容器内的多个列,或者在打印时跨越一个分页符时,也会发生这种情况。元素的每个渲染片段称为一个片段

- -

参考

- -
- -
- -

规格

- - - - - - - - - - - - - - - - -
规格状态评论
{{SpecName('CSS3 Fragmentation')}}{{Spec2('CSS3 Fragmentation')}}初始定义。
diff --git a/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html b/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html new file mode 100644 index 0000000000..d6ea967a43 --- /dev/null +++ b/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html @@ -0,0 +1,178 @@ +--- +title: 坐标系 +slug: Web/CSS/CSSOM_View/坐标系 +translation_of: Web/CSS/CSSOM_View/Coordinate_systems +--- +
{{cssref}}
+ +

当我们需要在图形上指定一点的坐标{{interwiki("wikipedia", "algebra")}}),这个坐标需要先对于某一个固定点. 这个固定点我们称为原点{{interwiki("wikipedia", "Origin_(mathematics)", "origin")}}. 这个指定点的坐标即为包含在各个维度上相对于远点的距离值。

+ +

下面我将谈谈基于CSS对象模型的坐标系系统。大体上来讲这些坐标系唯一的不同就是坐标原点不一样。

+ +

Dimensions坐标维度

+ +

在网页技术里,通常来讲,相对于坐标原点,x轴指向右为正值,向左为负值;y轴向下为正值,向上为负值。

+ +

On the web, the default origin is the top-left corner of a given context (with positive y-coordinate values being below the origin). Note that this is unlike most mathematical models, where the origin is at the bottom-left corner, with positive y-coordinate values being above the origin.

+ +

When drawing 3D graphics, or using a third dimension to layer objects from front to back, the z-coordinate is also used. This specifies the distance away from the viewer if positive and toward the viewer if negative.

+ +
+

It's actually possible to change the definitions and orientations of these coordinate systems using CSS properties such as {{cssxref("transform")}}. However, we'll only talk about the standard coordinate system for now.

+
+ +

Standard CSSOM coordinate systems

+ +

There are four standard coordinate systems used by the CSS object model, as described below.

+ +

Offset

+ +

Coordinates specified using the "offset" model use the top-left corner of the element being examined, or on which an event has occurred.

+ +

For example, when a {{domxref("MouseEvent", "mouse event", "", 1)}} occurs, the position of the mouse as specified in the event's {{domxref("MouseEvent.offsetX", "offsetX")}} and {{domxref("MouseEvent.offsetY", "offsetY")}} properties are given relative to the top-left corner of the node to which the event has been delivered. The origin is inset by the distances specified by {{cssxref("padding-left")}} and {{cssxref("padding-top")}}.

+ +

Client

+ +

The "client" coordinate system uses as its origin the top-left corner of the viewport or browsing context in which the event occurred. This is the entire viewing area in which the document is presented. Scrolling is not a factor.

+ +

On a desktop computer, for example, the {{domxref("MouseEvent.clientX")}} and {{domxref("MouseEvent.clientY")}} properties indicate the position of the mouse cursor at the moment the event occurred, relative to the top-left corner of the browser window. The top-left corner of the window is always (0, 0), regardless of the content of the document or any scrolling that may have been done. In other words, scrolling the document will change the client coordinates of a given position within the document.

+ +

Page

+ +

The "page" coordinate system gives the position of a pixel relative to the top-left corner of the entire {{domxref("Document")}} in which the pixel is located. That means that a given point in an element within the document will keep the same coordinates in the page model unless the element moves (either directly by changing its position or indirectly by adding or resizing other content).

+ +

Mouse events' {{domxref("MouseEvent.pageX", "pageX")}} and {{domxref("MouseEvent.pageY", "pageY")}} properties provide the position of the mouse at the time the event was generated, given relative to the top-left corner of the document.

+ +

Screen

+ +

Finally, we come to the "screen" model. It's probably fairly obvious what this is: it's the coordinate system where the origin is located at the top-left corner of the user's entire screen space. This means that the position of a given point within a document will change if the containing window is moved, for example, or if the user's screen geometry changes (by changing display resolution or by adding or removing monitors to their system).

+ +

The {{domxref("MouseEvent.screenX")}} and {{domxref("MouseEvent.screenY")}} properties give the coordinates of a mouse event's position relative to the screen's origin.

+ +

Example

+ +

Let's take a look at an example. This simple example creates a set of nested boxes. Whenever the mouse enters, moves around inside, or exits the inner box, the corresponding event is handled by updating a set of informational messages within the box, listing out the current mouse coordinates in each of the four available coordinate systems.

+ +

JavaScript

+ +

Let's look at the script in two sections. First, the code that logs the coordinates to the screen. This code will be called by the event handler for the various mouse events we watch.

+ +

Displaying the coordinates

+ +

As we'll see in the HTML, the inner box (the one we're watching for events on) contains several paragraphs; one for each of the four coordinate systems we'll be reporting on.

+ +
let inner = document.querySelector(".inner");
+let log = document.querySelector(".log");
+
+function setCoords(e, type) {
+  let idX = type + "X";
+  let idY = type + "Y";
+
+  document.getElementById(idX).innerText = e[idX];
+  document.getElementById(idY).innerText = e[idY];
+}
+
+ +

A reference to the {{HTMLElement("div")}} inside the inner box which contains the paragraphs that will show the coordinate information is fetched into log.

+ +

The setCoords() function is designed to accept as input a {{domxref("MouseEvent")}} and the name of the origin to use when obtaining the coordinates. The implementation is then quite simple. The variables idX and idY are set to strings with the names of the properties corresponding to the coordinates in the given coordinate system. For example, if the value of type is "page", then idX is "pageX" and idY is "pageY".

+ +

Handling the mouse events

+ +

setCoords() is called by the event handler for the various mouse events, named update(); this is shown below.

+ +
function update(e) {
+  setCoords(e, "offset");
+  setCoords(e, "client");
+  setCoords(e, "page");
+  setCoords(e, "screen");
+}
+
+inner.addEventListener("mouseenter", update, false);
+inner.addEventListener("mousemove", update, false);
+inner.addEventListener("mouseleave", update, false);
+ +

The event handler is in the update() method. It simply calls setCoords() once for each coordinate system, passing in the event that occurred.

+ +

Our main code sets up the event handlers on the inner box by calling {{domxref("EventTarget.addEventListener", "addEventListener()")}} for each of the types {{event("mouseenter")}}, {{event("mousemove")}}, and {{event("mouseleave")}}.

+ +

HTML

+ +

The HTML for our example is below. Note that within the <div> with the ID "log", we have a paragraph for each coordinate system, with {{domxref("span")}} used for each of the elements to receive and display the coordinates in each model.

+ +
<div class="outer">
+  <div class="inner">
+    <div class="log">
+      <p>
+        Offset-relative: <span id="offsetX">0</span>,
+        <span id="offsetY">0</span>
+      </p>
+      <p>
+        Client-relative: <span id="clientX">0</span>,
+        <span id="clientY">0</span>
+      </p>
+      <p>
+        Page-relative: <span id="pageX">0</span>,
+        <span id="pageY">0</span>
+      </p>
+      <p>
+        Screen-relative: <span id="screenX">0</span>,
+        <span id="screenY">0</span>
+      </p>
+    </div>
+  </div>
+</div>
+ +
+

CSS

+
+ +

The CSS is pretty much just for appearances here. The class "outer" is used for the containing box, which is intentionally too wide to show in the MDN window, to allow you to scroll it horizontally. The "inner" box is the one that we track events in and in which we show the mouse coordinates.

+ +
.outer {
+  width: 1000px;
+  height: 200px;
+  background-color: red;
+}
+
+.inner {
+  position: relative;
+  width: 500px;
+  height: 150px;
+  top: 25px;
+  left: 100px;
+  background-color: blue;
+  color: white;
+  cursor: crosshair;
+  user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  -webkit-user-select: none;
+}
+
+.log {
+  position: relative;
+  width: 100%;
+  text-align: center;
+}
+
+ +

Result

+ +

Here you can see the results in action. As you mouse in and around the blue box, watch the values of the mouse's X and Y coordinates change in the various coordinate systems in which you can obtain the values. Note also the effect of scrolling the example horizontally upon the values returned and how the value of clientX doesn't change.

+ +

{{EmbedLiveSample("Example", 600, 250)}}

+ +

See also

+ + diff --git "a/files/zh-cn/web/css/cssom_view/\345\235\220\346\240\207\347\263\273/index.html" "b/files/zh-cn/web/css/cssom_view/\345\235\220\346\240\207\347\263\273/index.html" deleted file mode 100644 index d6ea967a43..0000000000 --- "a/files/zh-cn/web/css/cssom_view/\345\235\220\346\240\207\347\263\273/index.html" +++ /dev/null @@ -1,178 +0,0 @@ ---- -title: 坐标系 -slug: Web/CSS/CSSOM_View/坐标系 -translation_of: Web/CSS/CSSOM_View/Coordinate_systems ---- -
{{cssref}}
- -

当我们需要在图形上指定一点的坐标{{interwiki("wikipedia", "algebra")}}),这个坐标需要先对于某一个固定点. 这个固定点我们称为原点{{interwiki("wikipedia", "Origin_(mathematics)", "origin")}}. 这个指定点的坐标即为包含在各个维度上相对于远点的距离值。

- -

下面我将谈谈基于CSS对象模型的坐标系系统。大体上来讲这些坐标系唯一的不同就是坐标原点不一样。

- -

Dimensions坐标维度

- -

在网页技术里,通常来讲,相对于坐标原点,x轴指向右为正值,向左为负值;y轴向下为正值,向上为负值。

- -

On the web, the default origin is the top-left corner of a given context (with positive y-coordinate values being below the origin). Note that this is unlike most mathematical models, where the origin is at the bottom-left corner, with positive y-coordinate values being above the origin.

- -

When drawing 3D graphics, or using a third dimension to layer objects from front to back, the z-coordinate is also used. This specifies the distance away from the viewer if positive and toward the viewer if negative.

- -
-

It's actually possible to change the definitions and orientations of these coordinate systems using CSS properties such as {{cssxref("transform")}}. However, we'll only talk about the standard coordinate system for now.

-
- -

Standard CSSOM coordinate systems

- -

There are four standard coordinate systems used by the CSS object model, as described below.

- -

Offset

- -

Coordinates specified using the "offset" model use the top-left corner of the element being examined, or on which an event has occurred.

- -

For example, when a {{domxref("MouseEvent", "mouse event", "", 1)}} occurs, the position of the mouse as specified in the event's {{domxref("MouseEvent.offsetX", "offsetX")}} and {{domxref("MouseEvent.offsetY", "offsetY")}} properties are given relative to the top-left corner of the node to which the event has been delivered. The origin is inset by the distances specified by {{cssxref("padding-left")}} and {{cssxref("padding-top")}}.

- -

Client

- -

The "client" coordinate system uses as its origin the top-left corner of the viewport or browsing context in which the event occurred. This is the entire viewing area in which the document is presented. Scrolling is not a factor.

- -

On a desktop computer, for example, the {{domxref("MouseEvent.clientX")}} and {{domxref("MouseEvent.clientY")}} properties indicate the position of the mouse cursor at the moment the event occurred, relative to the top-left corner of the browser window. The top-left corner of the window is always (0, 0), regardless of the content of the document or any scrolling that may have been done. In other words, scrolling the document will change the client coordinates of a given position within the document.

- -

Page

- -

The "page" coordinate system gives the position of a pixel relative to the top-left corner of the entire {{domxref("Document")}} in which the pixel is located. That means that a given point in an element within the document will keep the same coordinates in the page model unless the element moves (either directly by changing its position or indirectly by adding or resizing other content).

- -

Mouse events' {{domxref("MouseEvent.pageX", "pageX")}} and {{domxref("MouseEvent.pageY", "pageY")}} properties provide the position of the mouse at the time the event was generated, given relative to the top-left corner of the document.

- -

Screen

- -

Finally, we come to the "screen" model. It's probably fairly obvious what this is: it's the coordinate system where the origin is located at the top-left corner of the user's entire screen space. This means that the position of a given point within a document will change if the containing window is moved, for example, or if the user's screen geometry changes (by changing display resolution or by adding or removing monitors to their system).

- -

The {{domxref("MouseEvent.screenX")}} and {{domxref("MouseEvent.screenY")}} properties give the coordinates of a mouse event's position relative to the screen's origin.

- -

Example

- -

Let's take a look at an example. This simple example creates a set of nested boxes. Whenever the mouse enters, moves around inside, or exits the inner box, the corresponding event is handled by updating a set of informational messages within the box, listing out the current mouse coordinates in each of the four available coordinate systems.

- -

JavaScript

- -

Let's look at the script in two sections. First, the code that logs the coordinates to the screen. This code will be called by the event handler for the various mouse events we watch.

- -

Displaying the coordinates

- -

As we'll see in the HTML, the inner box (the one we're watching for events on) contains several paragraphs; one for each of the four coordinate systems we'll be reporting on.

- -
let inner = document.querySelector(".inner");
-let log = document.querySelector(".log");
-
-function setCoords(e, type) {
-  let idX = type + "X";
-  let idY = type + "Y";
-
-  document.getElementById(idX).innerText = e[idX];
-  document.getElementById(idY).innerText = e[idY];
-}
-
- -

A reference to the {{HTMLElement("div")}} inside the inner box which contains the paragraphs that will show the coordinate information is fetched into log.

- -

The setCoords() function is designed to accept as input a {{domxref("MouseEvent")}} and the name of the origin to use when obtaining the coordinates. The implementation is then quite simple. The variables idX and idY are set to strings with the names of the properties corresponding to the coordinates in the given coordinate system. For example, if the value of type is "page", then idX is "pageX" and idY is "pageY".

- -

Handling the mouse events

- -

setCoords() is called by the event handler for the various mouse events, named update(); this is shown below.

- -
function update(e) {
-  setCoords(e, "offset");
-  setCoords(e, "client");
-  setCoords(e, "page");
-  setCoords(e, "screen");
-}
-
-inner.addEventListener("mouseenter", update, false);
-inner.addEventListener("mousemove", update, false);
-inner.addEventListener("mouseleave", update, false);
- -

The event handler is in the update() method. It simply calls setCoords() once for each coordinate system, passing in the event that occurred.

- -

Our main code sets up the event handlers on the inner box by calling {{domxref("EventTarget.addEventListener", "addEventListener()")}} for each of the types {{event("mouseenter")}}, {{event("mousemove")}}, and {{event("mouseleave")}}.

- -

HTML

- -

The HTML for our example is below. Note that within the <div> with the ID "log", we have a paragraph for each coordinate system, with {{domxref("span")}} used for each of the elements to receive and display the coordinates in each model.

- -
<div class="outer">
-  <div class="inner">
-    <div class="log">
-      <p>
-        Offset-relative: <span id="offsetX">0</span>,
-        <span id="offsetY">0</span>
-      </p>
-      <p>
-        Client-relative: <span id="clientX">0</span>,
-        <span id="clientY">0</span>
-      </p>
-      <p>
-        Page-relative: <span id="pageX">0</span>,
-        <span id="pageY">0</span>
-      </p>
-      <p>
-        Screen-relative: <span id="screenX">0</span>,
-        <span id="screenY">0</span>
-      </p>
-    </div>
-  </div>
-</div>
- -
-

CSS

-
- -

The CSS is pretty much just for appearances here. The class "outer" is used for the containing box, which is intentionally too wide to show in the MDN window, to allow you to scroll it horizontally. The "inner" box is the one that we track events in and in which we show the mouse coordinates.

- -
.outer {
-  width: 1000px;
-  height: 200px;
-  background-color: red;
-}
-
-.inner {
-  position: relative;
-  width: 500px;
-  height: 150px;
-  top: 25px;
-  left: 100px;
-  background-color: blue;
-  color: white;
-  cursor: crosshair;
-  user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  -webkit-user-select: none;
-}
-
-.log {
-  position: relative;
-  width: 100%;
-  text-align: center;
-}
-
- -

Result

- -

Here you can see the results in action. As you mouse in and around the blue box, watch the values of the mouse's X and Y coordinates change in the various coordinate systems in which you can obtain the values. Note also the effect of scrolling the example horizontally upon the values returned and how the value of clientX doesn't change.

- -

{{EmbedLiveSample("Example", 600, 250)}}

- -

See also

- - diff --git a/files/zh-cn/web/css/cursor/url/index.html b/files/zh-cn/web/css/cursor/url/index.html deleted file mode 100644 index fcde4cecb2..0000000000 --- a/files/zh-cn/web/css/cursor/url/index.html +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Using URL values for the cursor property -slug: Web/CSS/cursor/url -tags: - - Cursor - - URL -translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property ---- -

Gecko 1.8 (Firefox 1.5,SeaMonkey 1.0) 支持CSS的URL值 {{cssxref("cursor")}} 属性在Windows和Linux。Mac支持是在Gecko 2(Firefox 4)中添加的。这允许将任意图像指定为鼠标光标 - 可以使用Gecko支持的任何图像格式。

- -

语法

- -

此属性的基本(CSS 2.1)语法是:

- -
cursor: [<url>,]* keyword;
-
- -

这意味着可以指定零个或多个URL(逗号分隔),后面必须跟随CSS规范中定义的一个关键字,例如 auto或 pointer。

- -

例如,将允许以下值:

- -
cursor: url(foo.cur), url(http://www.example.com/bar.gif), auto;
-
- -

首先尝试加载 foo.cur。如果文件不存在或者其它无效原因,bar.gif被尝试加载,如果bar.gif不能被加载,那么使用auto

- -

在Gecko 1.8beta3 (Deer Park Alpha 2)中加入了对CSS3 语法的指针属性的支持。

- -
cursor:  [<uri> [<x> <y>]?,]* keyword
- -

因此,它能在Firefox 1.5中工作。它允许定义指针的热点,加强对指针图橡的边界的控制。如果一个也没有设置,指针的热点会从文件本身读取(适合CUR和XBM文件类型)。否则,设置成图像的左上角。一个CSS3语法的例子:

- -
.foo  {
-    cursor:  auto;
-    cursor:  url(cursor1.png) 4 12, auto;
-}
-
-.bar  {
-    cursor:  pointer;
-    cursor:  url(cursor2.png) 2 2, pointer;
-}
-
-/*
-fallsback onto 'auto' and 'pointer' in IE,
-but must be set separately
-*/
- -

第一个数字是X坐标,第二个数字是Y坐标。该示例将热点设置为从左上角(0,0)到(4,12)处的像素。

- -

局限性

- -

可以使用任何被Gecko所支持的图像格式。这意味着你可以使用BMP,JPG,CUR,GIF等等。可是,ANI不被支持。还有即使你定义一个GIF动画,指针也不会变成GIF动画。这个局限性可能在以后的版本去掉。

- -

Gecko它本身不能限制被替换的指针大小。无论如何,你应该自己限制图像的最大值在32x32,以便兼容各种平台的操作系统。尤其是大于这个尺寸的指针不能在Windows 9x (95,98,ME)下工作。

- -

透明效果的指针在Windows XP以前都不被支持。这是操作系统的一个局限性。透明效果可以在所有平台下工作。

- -

只 有Windows,OS/2和Linux(使用Gtk+ 2.4及更高版本)的Mozilla版本支持光标属性的URL参数。其它版本可能在以后的版本中加入支持(Mac OS: {{ Bug(286304) }}, QNX Neutrino: {{ Bug(286307) }}, XLib: {{ Bug(286309) }}, Qt: {{ Bug(286310) }}, BeOS: {{ Bug(298184) }}, Gtk 2.0/2.2: {{ Bug(308536) }})。

- -

关于其它浏览器的兼容性

- -

Microsoft Internet Explorer 6.0还支持cursor属性的URI值。然而:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BrowserLowest versionformats (e.g.)x-y-coordinates
Internet Explorer6.0.cur | .ani---
Firefox (Gecko), Windows and 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)
Since OS X 10.5 supports Safari (Mac) .curfiles
- -

它也使用不严格的光标属性语法。例如像这样的参数:

- -
cursor: url(foo.cur);
-
- -

或者:

- -
cursor: url(foo.cur), pointer, url(bar.cur), auto;
-
- -

可以在MSIE上工作,但是不能在Gecko上面工作。因为Gecko的兼容性与CSS的规范一致,URIs表始终放置在前面,在最后放置正确的关键字。

- -

 

diff --git a/files/zh-cn/web/css/float/index.html b/files/zh-cn/web/css/float/index.html new file mode 100644 index 0000000000..30f9928c0b --- /dev/null +++ b/files/zh-cn/web/css/float/index.html @@ -0,0 +1,247 @@ +--- +title: float +slug: CSS/float +tags: + - CSS + - CSS Positioning + - CSS Property + - CSS 定位 + - CSS 属性 + - 参考 +translation_of: Web/CSS/float +--- +
{{CSSRef}}
+ +

float CSS属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性(与绝对定位相反)。

+ +
{{EmbedInteractiveExample("pages/css/float.html")}}
+ + + +

浮动元素float 的计算值非 none 的元素。

+ +

由于float意味着使用块布局,它在某些情况下修改{{cssxref("display")}} 值的计算值:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指定值计算值
inlineblock
inline-blockblock
inline-tabletable
table-rowblock
table-row-groupblock
table-columnblock
table-column-groupblock
table-cellblock
table-captionblock
table-header-groupblock
table-footer-groupblock
flexflex, 但是float对这样的元素不起作用
inline-flexinline-flex, 但是float对这样的元素不起作用
otherunchanged
+ +
备注:如果要在 JavaScript 中把float属性当作{{domxref("element.style")}}对象的一个成员来操作,那么在Firefox 34 和更老的版本中,你必须拼写成cssFloat。另外还要注意到在 Internet Explorer 8 和更老的IE当中,要使用styleFloat属性。这是DOM驼峰命名和CSS所用的连字符分隔命名法对应关系中的一个特例(这是因为在 JavaScript 中"float"是一个保留字,因为同样的原因,"class"被改成了"className" 、"for"被改成了"htmlFor")。
+ +

语法

+ +
/* Keyword values */
+float: left;
+float: right;
+float: none;
+float: inline-start;
+float: inline-end;
+
+/* Global values */
+float: inherit;
+float: initial;
+float: unset;
+ +

float 属性的值被指定为单一的关键字,值从下面的值列表中选择。

+ +

+ +
+
left
+
表明元素必须浮动在其所在的块容器左侧的关键字。
+
right
+
表明元素必须浮动在其所在的块容器右侧的关键字。
+
none
+
表明元素不进行浮动的关键字。
+
inline-start
+
关键字,表明元素必须浮动在其所在块容器的开始一侧,在ltr脚本中是左侧,在rtl脚本中是右侧。
+
inline-end
+
关键字,表明元素必须浮动在其所在块容器的结束一侧,在ltr脚本中是右侧,在rtl脚本中是左侧。
+
+ +

形式化语法

+ +
{{csssyntax("float")}}
+ +

例子

+ +

浮动元素是如何定位的

+ +

正如我们前面提到的那样,当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素

+ +

在下面的图片中,有三个红色的正方形。其中有两个向左浮动,一个向右浮动。要注意到第二个向左浮动的正方形被放在第一个向左浮动的正方形的右边。如果还有更多的正方形这样浮动,它们会继续向右堆放,直到填满容器一整行,之后换行至下一行。

+ + + +

HTML

+ +
<section>
+  <div class="left">1</div>
+  <div class="left">2</div>
+  <div class="right">3</div>
+  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+     Morbi tristique sapien ac erat tincidunt, sit amet dignissim
+     lectus vulputate. Donec id iaculis velit. Aliquam vel
+     malesuada erat. Praesent non magna ac massa aliquet tincidunt
+     vel in massa. Phasellus feugiat est vel leo finibus congue.</p>
+</section>
+
+ +

CSS

+ +
section {
+  border: 1px solid blue;
+}
+
+div {
+  margin: 5px;
+  width: 50px;
+  height: 50px;
+}
+
+.left {
+  float: left;
+  background: pink;
+}
+
+.right {
+  float: right;
+  background: cyan;
+}
+ +

结果

+ +

{{EmbedLiveSample('How_floated_elements_are_positioned','400','180')}}

+ +

清除浮动

+ +

有时,你可能想要强制元素移至任何浮动元素下方。比如说,你可能希望某个段落与浮动元素保持相邻的位置,但又希望这个段落从头开始强制独占一行。请参考 {{cssxref("clear")}} 以获取例子等。

+ +
+
+

译者注:以下直至“规范”部分,皆为英文原文中已剔除的过时内容。

+
+
+ +

在前面的例子当中,浮动的元素的高度比它们所在的容器元素(是块元素)的高度小。然而如果块元素内的文本太短,不足以把块元素的大小撑到高度大于所有浮动元素的高度,我们可能会看到意想不到的效果。例如,如果上面图片中的文字只有"Lorem ipsum dolor sit amet,",并且接下来是另外一个和"Floats Example"这个标题一样风格的标题元素,那么第二个标题元素会出现在红色的正方形之间。然而在大多数这种情况下,我们希望这个标题元素是靠左对齐的。为了实现这个效果,我们需要清除浮动。

+ +

这个例子中,最简单的清除浮动方式就是给我们想要确保左对齐的新标题元素添加{{Cssxref("clear")}}属性:

+ +
h2.secondHeading { clear: both; }
+
+ +

然而这个方法只是在同一块级格式化上下文(block formatting context)中没有其他元素的时候才是有效的。如果我们的 H2 有兄弟元素是向左浮动和向右浮动的边栏,那么使用clear 会导致这个标题元素出现在边栏的下方,这显然不是我们期望的结果。

+ +

如果不能使用清除浮动,另一种做法是浮动容器的限制块级格式化上下文。再次列举上面的例子,有三个红色的正方形和一个P元素。我们可以设置P元素的{{Cssxref("overflow")}}属性值变成hidden 或者auto,因为这样可以让容器元素伸展到能够包含红色正方形,而不是让他们超出块元素的底部。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('CSS Logical Properties', '#float-clear', 'float and clear')}}{{Spec2('CSS Logical Properties')}}添加了 inline-start 和 inline-end
{{SpecName('CSS3 Box', '#float', 'float')}}{{Spec2('CSS3 Box')}}大量新属性值,但目前还没完全定义清楚。任何与新特性无关的浏览器差异应该是无意中造成的,需要报告。
{{SpecName('CSS2.1', 'visuren.html#float-position', 'float')}}{{Spec2('CSS2.1')}}没有改变。
{{SpecName('CSS1', '#float', 'float')}}{{Spec2('CSS1')}}初始定义。
+ +

{{cssinfo}}

+ +

浏览器兼容性

+ + + +

{{Compat("css.properties.float")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/css/grid-template-rows/index.html b/files/zh-cn/web/css/grid-template-rows/index.html new file mode 100644 index 0000000000..0dcd6b29d5 --- /dev/null +++ b/files/zh-cn/web/css/grid-template-rows/index.html @@ -0,0 +1,209 @@ +--- +title: grid-template-rows +slug: Web/CSS/网格-模板-列 +tags: + - grid-template-rows +translation_of: Web/CSS/grid-template-rows +--- +

grid-template-rows 该属性是基于 {{glossary("grid rows", "网格行")}} 的维度,去定义网格线的名称和网格轨道的尺寸大小。

+ +
{{EmbedInteractiveExample("pages/css/grid-template-rows.html")}}
+ + + +

语法

+ +
/* Keyword value */
+grid-template-rows: none;
+
+/* <track-list> values */
+grid-template-rows: 100px 1fr;
+grid-template-rows: [linename] 100px;
+grid-template-rows: [linename1] 100px [linename2 linename3];
+grid-template-rows: minmax(100px, 1fr);
+grid-template-rows: fit-content(40%);
+grid-template-rows: repeat(3, 200px);
+
+/* <auto-track-list> values */
+grid-template-rows: 200px repeat(auto-fill, 100px) 300px;
+grid-template-rows: minmax(100px, max-content)
+                       repeat(auto-fill, 200px) 20%;
+grid-template-rows: [linename1] 100px [linename2]
+                       repeat(auto-fit, [linename3 linename4] 300px)
+                       100px;
+grid-template-rows: [linename1 linename2] 100px
+                       repeat(auto-fit, [linename1] 300px) [linename3];
+
+/* Global values */
+grid-template-rows: inherit;
+grid-template-rows: initial;
+grid-template-rows: unset;
+
+ +

该属性可能包含如下值:

+ + + +

+ +
+
none
+
这个关键字表示不明确的网格。所有的行和其大小都将由{{cssxref("grid-auto-rows")}} 属性隐式的指定。
+
{{cssxref("<length>")}}
+
非负值的长度大小。
+
{{cssxref("<percentage>")}}
+
非负值且相对于网格容器的 {{cssxref("percentage", "<百分比>")}}。 如果网格容器的尺寸大小依赖网格轨道的大小(比如 inline-grid ),则百分比值将被视为auto
+
为了遵守网格的百分比,网格轨道本身定义的大小,将自动被调整为相对网格容器大小,并且是以最小量将网格轨道调整到最终的大小。
+
{{cssxref("<flex_value>","<flex>")}}
+
非负值,用单位 fr 来定义网格轨道大小的弹性系数。 每个定义了 <flex> 的网格轨道会按比例分配剩余的可用空间。当外层用一个 minmax() 表示时,它将是一个自动最小值(即 minmax(auto, <flex>) ) 。
+
max-content
+
是一个用来表示以网格项的最大的内容来占据网格轨道的关键字。
+
min-content
+
是一个用来表示以网格项的最大的最小内容来占据网格轨道的关键字。
+
{{cssxref("minmax", "minmax(min, max)")}}
+
是一个来定义大小范围的属性,大于等于min值,并且小于等于max值。如果max值小于min值,则该值会被视为min值。最大值可以设置为网格轨道系数值<flex> ,但最小值则不行。 
+
+

Note:  该规范在将来可能会允许设置最小值为 flex ,也会调整网格轨道算法(track sizing algorithm) 计算出正确的大小。

+
+
auto
+
如果该网格轨道为最大时,该属性等同于 <max-content> ,为最小时,则等同于 <min-content> 。
+
+

Note: 网格轨道大小为 auto (且只有为 auto ) 时,才可以被属性{{cssxref("align-content")}} 和 {{cssxref("justify-content")}} 拉伸 。

+
+
{{cssxref("fit-content", "fit-content( [ <length> | <percentage> ] )")}}
+
相当于公式 min(max-content, max(auto, argument)),类似于auto 的计算(即 minmax(auto, max-content)),除了网格轨道大小值是确定下来的,否则该值都大于 auto 的最小值。
+
{{cssxref("repeat", "repeat( [ <positive-integer> | auto-fill | auto-fit ] , <track-list> )")}}
+
表示网格轨道的重复部分,以一种更简洁的方式去表示大量而且重复行的表达式。
+
+ +

正式语法

+ +
{{csssyntax}}
+ +

示例

+ +

CSS

+ +
#grid {
+  display: grid;
+  height: 100px;
+  grid-template-rows: 30px 1fr;
+}
+
+#areaA {
+  background-color: lime;
+}
+
+#areaB {
+  background-color: yellow;
+}
+ +

HTML

+ +
<div id="grid">
+  <div id="areaA">A</div>
+  <div id="areaB">B</div>
+</div>
+ +

结果

+ +

{{EmbedLiveSample("示例", "40px", "100px")}}

+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName("CSS3 Grid", "#propdef-grid-template-rows", "grid-template-rows")}}{{Spec2("CSS3 Grid")}}初步定义
+ +

{{cssinfo}}

+ +

浏览器兼容性

+ +

 

+ + + +

{{Compat("css.properties.grid-template-rows")}}

+ +

 

+ +

参见

+ + + + diff --git a/files/zh-cn/web/css/layout_cookbook/card/index.html b/files/zh-cn/web/css/layout_cookbook/card/index.html new file mode 100644 index 0000000000..260ef3ba54 --- /dev/null +++ b/files/zh-cn/web/css/layout_cookbook/card/index.html @@ -0,0 +1,82 @@ +--- +title: 卡片 +slug: Web/CSS/Layout_cookbook/卡片 +translation_of: Web/CSS/Layout_cookbook/Card +--- +

{{CSSRef}}

+ +

这个模式是带有页脚选项的卡片组件列表。

+ +

+ +

Three card components in a row

+ +

要求

+ +

卡片组件可以包含各种内容,包括一个头部(heading),图片,内容和一个页脚(footer)

+ +

每个卡片组件应有相同的高度,并且页脚应该在卡片组件的底部

+ +

当添加到卡片组中时,卡片上下应对齐。

+ +

使用指南

+ +

{{EmbedGHLiveSample("css-examples/css-cookbook/card.html", '100%', 1720)}}

+ +
+

Download this example

+
+ +

所选方案

+ +

卡片布局使用 CSS 网格布局(CSS Grid Layout) despite being a single dimensional layout, as it enables the use of content sizing for the grid tracks. When setting up the single column grid I use the following:

+ +
.card {
+  display: grid;
+  grid-template-rows: max-content 200px 1fr;
+}
+ +

The heading track is set to {{cssxref("max-content")}}, which prevents it from stretching. I have decided that I want my image to live within a track that is 200 pixels tall. I then set the next track — which is where the content lives — to 1fr. This means it will take up any additional space. 

+ +

If the track does have a footer it will be auto-sized, as rows created in the implicit grid are auto-sized by default. Therefore this will fit the content added to it.

+ +
+

Note: The various elements in separate cards do not align with each other, as each card is an independent grid. The proposed subgrid feature of Grid Level 2 would give a solution to this issue.

+
+ +

Useful fallbacks or alternative methods

+ +

Flexbox could be used to lay out the card, in which case you should make the content area grow, and other items not grow. This would be a reasonable way to lay out the card, although I have a slight preference for being able to control the tracks from the container rather than needing to add rules to the items.

+ +

For the overall layout you could use flexbox, however this will result in cards stretching over the final flex row where there are fewer than can fit in the rows above. Alternatively you could use CSS multi-col — this would cause the cards to lay out down the columns, which may or may not be a problem.

+ +

See the columns recipe for demonstrations of each of these layout methods.

+ +

Accessibility concerns

+ +

Depending on the content of your card there may be things you could, or should do to enhance accessibility. See Inclusive Components: Card by Heydon Pickering, for a very detailed explanation of these issues.

+ +

Browser compatibility

+ +

The various layout methods have different browser support. See the charts below for details on basic support for the properties used.

+ + + +

grid-template-columns

+ +

{{Compat("css.properties.grid-template-columns")}}

+ +

grid-template-rows

+ +

{{Compat("css.properties.grid-template-rows")}}

+ + + +

See also

+ + diff --git a/files/zh-cn/web/css/layout_cookbook/media_objects/index.html b/files/zh-cn/web/css/layout_cookbook/media_objects/index.html new file mode 100644 index 0000000000..382e4bacce --- /dev/null +++ b/files/zh-cn/web/css/layout_cookbook/media_objects/index.html @@ -0,0 +1,86 @@ +--- +title: '指南: 媒体对象' +slug: Web/CSS/Layout_cookbook/媒体对象 +tags: + - 媒体对象 + - 布局 + - 指南 + - 浮动 + - 网格 +translation_of: Web/CSS/Layout_cookbook/Media_objects +--- +
{{CSSRef}}
+ +

媒体对象是web上随处可见的一种模式。它由Nicole Sullivan命名,表示一种一侧是图片并且另一侧是描述性的文字的两列盒子,比如一篇facebook帖子或者tweet。

+ +

+ +

要求

+ +

媒体对象模式需要以下特性的一些或者全部:

+ + + +

使用指南

+ +

{{EmbedGHLiveSample("css-examples/css-cookbook/media-objects.html", '100%', 1200)}}

+ +
+

Download this example

+
+ +

做出选择

+ +

我选择使用Grid Layout实现媒体对象,因为它可以让我在我需要的时候控制两个维度的布局。这意味着当我们有一个页脚(footer)的时候,上面的内容很短,页脚可以被推到媒体对象的底部。

+ +

另一个使用网格布局(Grid Layout)的原因是为了可以使用{{cssxref("fit-content")}}图片的追踪(track)大小。通过使用 最大尺寸是200像素的fit-content ,当我们有一个小图片比如icon的时候,track仅仅得到和image的尺寸一样的大小(max-content 大小)。如果图片更大,track在200像素的时候停止增长,因为图片应用了{{cssxref("max-width ")}}为100%。同样,它会缩小以适应列内部的尺寸。

+ +

通过使用{{cssxref("grid-template-areas")}} 来实现布局,我可以看到CSS中的这个模式。我定义我的网格,其并且设置最大宽度(max-width)为500像素,因此在较小的设备上媒体对象会被堆叠起来。

+ +

模式的一个选项是翻转它将图片切换到另一边——这通过添加media-flip 类来实现,它定义了一个翻转的网格模板所以布局被镜像了。

+ +

当我们在另一个媒体对象之中嵌套一个媒体对象,我么你需要将它放到常规布局的第二个track中,当翻转时放到第一个track中

+ +

回退方案

+ +

对于这种模式有很多种可能的回退方案,取决于你希望支持的浏览器。一个比较号的方案是将图片浮动到左边,并且为盒子添加clearfix来确保它包含浮动元素。

+ +

{{EmbedGHLiveSample("css-examples/css-cookbook/media-objects-fallback.html", '100%', 1200)}}

+ +
+

Download this example

+
+ +

一旦浮动元素成为网格项,浮动将不再被应用到网格上,因此你不需要做任何特殊的事情来清楚浮动。

+ +

你需要做的事情是移除应用到这些items的任何边界,以及我们在一个网格上下文中不需要的任何宽度(在网格中我们有{{cssxref("gap")}}属性来控制它,并且track控制了尺寸)。

+ +

MDN上相关的资源

+ + + +

浏览器兼容性

+ +

.各种各样的布局方法有不同的浏览器支持。查看下面的图表得到属性的基本支持的细节。

+ +

这个页面中的兼容性表格由结构数据生成。如果你想对数据做贡献,请查看 https://github.com/mdn/browser-compat-data 并且给我们发送一个pull request。

+ +

grid-template-areas

+ +

{{Compat("css.properties.grid-template-areas")}}

+ +

float

+ +

{{Compat("css.properties.float")}}

diff --git "a/files/zh-cn/web/css/layout_cookbook/\345\215\241\347\211\207/index.html" "b/files/zh-cn/web/css/layout_cookbook/\345\215\241\347\211\207/index.html" deleted file mode 100644 index 260ef3ba54..0000000000 --- "a/files/zh-cn/web/css/layout_cookbook/\345\215\241\347\211\207/index.html" +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: 卡片 -slug: Web/CSS/Layout_cookbook/卡片 -translation_of: Web/CSS/Layout_cookbook/Card ---- -

{{CSSRef}}

- -

这个模式是带有页脚选项的卡片组件列表。

- -

- -

Three card components in a row

- -

要求

- -

卡片组件可以包含各种内容,包括一个头部(heading),图片,内容和一个页脚(footer)

- -

每个卡片组件应有相同的高度,并且页脚应该在卡片组件的底部

- -

当添加到卡片组中时,卡片上下应对齐。

- -

使用指南

- -

{{EmbedGHLiveSample("css-examples/css-cookbook/card.html", '100%', 1720)}}

- -
-

Download this example

-
- -

所选方案

- -

卡片布局使用 CSS 网格布局(CSS Grid Layout) despite being a single dimensional layout, as it enables the use of content sizing for the grid tracks. When setting up the single column grid I use the following:

- -
.card {
-  display: grid;
-  grid-template-rows: max-content 200px 1fr;
-}
- -

The heading track is set to {{cssxref("max-content")}}, which prevents it from stretching. I have decided that I want my image to live within a track that is 200 pixels tall. I then set the next track — which is where the content lives — to 1fr. This means it will take up any additional space. 

- -

If the track does have a footer it will be auto-sized, as rows created in the implicit grid are auto-sized by default. Therefore this will fit the content added to it.

- -
-

Note: The various elements in separate cards do not align with each other, as each card is an independent grid. The proposed subgrid feature of Grid Level 2 would give a solution to this issue.

-
- -

Useful fallbacks or alternative methods

- -

Flexbox could be used to lay out the card, in which case you should make the content area grow, and other items not grow. This would be a reasonable way to lay out the card, although I have a slight preference for being able to control the tracks from the container rather than needing to add rules to the items.

- -

For the overall layout you could use flexbox, however this will result in cards stretching over the final flex row where there are fewer than can fit in the rows above. Alternatively you could use CSS multi-col — this would cause the cards to lay out down the columns, which may or may not be a problem.

- -

See the columns recipe for demonstrations of each of these layout methods.

- -

Accessibility concerns

- -

Depending on the content of your card there may be things you could, or should do to enhance accessibility. See Inclusive Components: Card by Heydon Pickering, for a very detailed explanation of these issues.

- -

Browser compatibility

- -

The various layout methods have different browser support. See the charts below for details on basic support for the properties used.

- - - -

grid-template-columns

- -

{{Compat("css.properties.grid-template-columns")}}

- -

grid-template-rows

- -

{{Compat("css.properties.grid-template-rows")}}

- - - -

See also

- - diff --git "a/files/zh-cn/web/css/layout_cookbook/\345\252\222\344\275\223\345\257\271\350\261\241/index.html" "b/files/zh-cn/web/css/layout_cookbook/\345\252\222\344\275\223\345\257\271\350\261\241/index.html" deleted file mode 100644 index 382e4bacce..0000000000 --- "a/files/zh-cn/web/css/layout_cookbook/\345\252\222\344\275\223\345\257\271\350\261\241/index.html" +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: '指南: 媒体对象' -slug: Web/CSS/Layout_cookbook/媒体对象 -tags: - - 媒体对象 - - 布局 - - 指南 - - 浮动 - - 网格 -translation_of: Web/CSS/Layout_cookbook/Media_objects ---- -
{{CSSRef}}
- -

媒体对象是web上随处可见的一种模式。它由Nicole Sullivan命名,表示一种一侧是图片并且另一侧是描述性的文字的两列盒子,比如一篇facebook帖子或者tweet。

- -

- -

要求

- -

媒体对象模式需要以下特性的一些或者全部:

- - - -

使用指南

- -

{{EmbedGHLiveSample("css-examples/css-cookbook/media-objects.html", '100%', 1200)}}

- -
-

Download this example

-
- -

做出选择

- -

我选择使用Grid Layout实现媒体对象,因为它可以让我在我需要的时候控制两个维度的布局。这意味着当我们有一个页脚(footer)的时候,上面的内容很短,页脚可以被推到媒体对象的底部。

- -

另一个使用网格布局(Grid Layout)的原因是为了可以使用{{cssxref("fit-content")}}图片的追踪(track)大小。通过使用 最大尺寸是200像素的fit-content ,当我们有一个小图片比如icon的时候,track仅仅得到和image的尺寸一样的大小(max-content 大小)。如果图片更大,track在200像素的时候停止增长,因为图片应用了{{cssxref("max-width ")}}为100%。同样,它会缩小以适应列内部的尺寸。

- -

通过使用{{cssxref("grid-template-areas")}} 来实现布局,我可以看到CSS中的这个模式。我定义我的网格,其并且设置最大宽度(max-width)为500像素,因此在较小的设备上媒体对象会被堆叠起来。

- -

模式的一个选项是翻转它将图片切换到另一边——这通过添加media-flip 类来实现,它定义了一个翻转的网格模板所以布局被镜像了。

- -

当我们在另一个媒体对象之中嵌套一个媒体对象,我么你需要将它放到常规布局的第二个track中,当翻转时放到第一个track中

- -

回退方案

- -

对于这种模式有很多种可能的回退方案,取决于你希望支持的浏览器。一个比较号的方案是将图片浮动到左边,并且为盒子添加clearfix来确保它包含浮动元素。

- -

{{EmbedGHLiveSample("css-examples/css-cookbook/media-objects-fallback.html", '100%', 1200)}}

- -
-

Download this example

-
- -

一旦浮动元素成为网格项,浮动将不再被应用到网格上,因此你不需要做任何特殊的事情来清楚浮动。

- -

你需要做的事情是移除应用到这些items的任何边界,以及我们在一个网格上下文中不需要的任何宽度(在网格中我们有{{cssxref("gap")}}属性来控制它,并且track控制了尺寸)。

- -

MDN上相关的资源

- - - -

浏览器兼容性

- -

.各种各样的布局方法有不同的浏览器支持。查看下面的图表得到属性的基本支持的细节。

- -

这个页面中的兼容性表格由结构数据生成。如果你想对数据做贡献,请查看 https://github.com/mdn/browser-compat-data 并且给我们发送一个pull request。

- -

grid-template-areas

- -

{{Compat("css.properties.grid-template-areas")}}

- -

float

- -

{{Compat("css.properties.float")}}

diff --git a/files/zh-cn/web/css/media_queries/index.html b/files/zh-cn/web/css/media_queries/index.html new file mode 100644 index 0000000000..9936c531f1 --- /dev/null +++ b/files/zh-cn/web/css/media_queries/index.html @@ -0,0 +1,109 @@ +--- +title: 媒体查询 +slug: Web/CSS/媒体查询 +tags: + - CSS + - 参考 + - 响应式设计 + - 媒体查询 + - 总览 +translation_of: Web/CSS/Media_Queries +--- +
{{CSSRef}}
+ +

通过媒体查询Media queries),您可以根据各种设备特征和参数的值或者是否存在来调整您的网站或应用。

+ +

它们是响应式设计的关键组成部分。 例如,媒体查询可以缩小小型设备上的字体大小,在纵向模式下查看页面时增加段落之间的填充,或者增加触摸屏上按钮的大小。

+ +

在 CSS 中,使用 {{cssxref("@media")}} at-rule 根据媒体查询的结果有条件地应用样式表的一部分。 使用 {{cssxref("@import")}} 有条件地应用整个样式表。

+ +

在 HTML 中使用媒体查询

+ +

HTML 中,媒体查询可以应用于各种元素:

+ + + +

在 JavaScript 中使用媒体查询

+ +

JavaScript中,您可以使用 {{domxref("Window.matchMedia()")}} 方法根据媒体查询测试窗口。 您还可以使用{{domxref("MediaQueryList.addListener()")}}在查询状态发生变化时收到通知。 借助此功能,您的站点或应用可以响应设备配置,方向或状态的更改。

+ +

您可以学习更多以编程方式使用媒体查询在测试媒体查询中。

+ +

参考

+ +

At-rules

+ +
+ +
+ +

指南

+ +
+
使用媒体查询
+
介绍媒体查询和媒体查询的的语法以及用于构造媒体查询表达式的运算符和媒体功能。
+
编程方式使用媒体查询
+
描述如何在 JavaScript 代码中使用媒体查询来确定设备的状态,以及设置在媒体查询结果发生更改时(例如,当用户旋转屏幕或调整浏览器大小时)通知代码的监听器。
+
使用媒体查询增强网站的可访问性
+
了解媒体查询如何帮助用户更好地了解您的网站。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('CSS5 Media Queries')}}{{Spec2('CSS5 Media Queries')}}
{{SpecName('CSS3 Conditional')}}{{Spec2('CSS3 Conditional')}}
{{SpecName('CSS4 Media Queries')}}{{Spec2('CSS4 Media Queries')}}
{{SpecName('CSS3 Media Queries')}}{{Spec2('CSS3 Media Queries')}}
{{SpecName('CSS2.1', 'media.html')}}{{Spec2('CSS2.1')}}Initial definition
+ +

浏览器兼容性

+ +

@media rule

+ + + +

{{Compat("css.at-rules.media")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/css/media_queries/testing_media_queries/index.html b/files/zh-cn/web/css/media_queries/testing_media_queries/index.html new file mode 100644 index 0000000000..0d33436410 --- /dev/null +++ b/files/zh-cn/web/css/media_queries/testing_media_queries/index.html @@ -0,0 +1,90 @@ +--- +title: 使用编程方法测试媒体查询 +slug: Web/Guide/CSS/Testing_media_queries +tags: + - CSS + - DOM + - Event + - Media Queries + - Web +translation_of: Web/CSS/Media_Queries/Testing_media_queries +--- +
{{cssref}}
+ +

{{Glossary("DOM")}} 提供了通过编程方法来获得媒体查询结果的特性。这是通过 {{domxref("MediaQueryList")}} 接口和它的方法来实现的。创建了 MediaQueryList 对象之后,就可以通过它来检查查询结果,或者设置事件监听器,在查询结果发生变化时自动接收到通知。

+ +

创建媒体查询列表

+ +

在获取查询结果前,首先要创建查询列表,也就是 MediaQueryList 对象来存放媒体查询。为了实现这个目的,可以使用 {{domxref("window.matchMedia")}} 方法。

+ +

举个例子,设置一个用来判断设备的旋转方向(横屏还是竖屏)的查询列表:

+ +
var mediaQueryList = window.matchMedia("(orientation: portrait)");
+
+ +

检查查询结果

+ +

一旦创建了媒体查询列表,你就可以通过检查它的 matches 属性来获取相应的查询结果,上述属性会直接返回查询结果:

+ +
if (mediaQueryList.matches) {
+  /* 设备的旋转方向为纵向 portrait */
+} else {
+  /* 设备的旋转方向不是纵向,也就是横向 landscape */
+}
+
+ +

接收查询提醒

+ +

如果你需要持续观察查询结果值的变化情况,那么,注册一个监听器比手动检查查询结果要高效很多。要注册监听器,只要在 {{domxref("MediaQueryList")}} 对象上使用 addListener() 方法,并使用一个回调函数作为其参数。这样,就通过实现 {{domxref("MediaQueryListListener")}} 接口指定了一个监听器。每当查询结果发生变化,比如从 true 变为 false 时,就会调用一遍传入的回调函数。

+ +
// 创建查询列表
+const mediaQueryList = window.matchMedia("(orientation: portrait)");
+
+// 定义回调函数
+function handleOrientationChange(mql) {
+  // ...
+}
+
+// 先运行一次回调函数
+handleOrientationChange(mediaQueryList);
+
+// 为查询列表注册监听器,同时将回调函数传给监听器
+mediaQueryList.addListener(handleOrientationChange);
+
+ +

上述代码创建了一个屏幕方向的测试查询列表 mediaQueryList,并且添加了事件监听器。需要注意的是,当我们添加监听后,我们其实直接调用了一次监听。这会让我们的监听器以目前设备的屏幕方向来初始化判定代码。换句话说,如果我们代码中设定设备处于竖屏模式,而实际上它在启动时处于横屏模式,那么我们在后面的判定就会出现矛盾。

+ +

然后,我们就能在 handleOrientationChange() 方法中检查查询结果,比如,可以设置屏幕方向变化后的逻辑处理代码:

+ +
function handleOrientationChange(evt) {
+  if (evt.matches) {
+    /* The viewport is currently in portrait orientation */
+  } else {
+    /* The viewport is currently in landscape orientation */
+  }
+}
+
+ +

终止查询通知

+ +

如果不再需要再接收媒体查询值变化的相关通知,那么,只要调用 MediaQueryListremoveListener() 方法,就可以方便地移除监听:

+ +
mediaQueryList.removeListener(handleOrientationChange);
+
+ +

浏览器兼容性

+ +

MediaQueryList 接口

+ + + +

{{Compat("api.MediaQueryList")}}

+ +

另见

+ + diff --git a/files/zh-cn/web/css/media_queries/using_media_queries/index.html b/files/zh-cn/web/css/media_queries/using_media_queries/index.html new file mode 100644 index 0000000000..bfb15efa67 --- /dev/null +++ b/files/zh-cn/web/css/media_queries/using_media_queries/index.html @@ -0,0 +1,412 @@ +--- +title: 使用媒体查询 +slug: Web/Guide/CSS/Media_queries +tags: + - CSS + - CSS媒体查询 + - Media + - Web + - 媒体 + - 媒体查询 + - 指南 +translation_of: Web/CSS/Media_Queries/Using_media_queries +--- +
{{cssref}}
+ +

媒体查询Media queries)非常实用,尤其是当你想要根据设备的大致类型(如打印设备与带屏幕的设备)或者特定的特征和设备参数(例如屏幕分辨率和浏览器{{glossary("viewport", "视窗")}}宽度)来修改网站或应用程序时。

+ +

媒体查询常被用于以下目的:

+ + + +
<link rel="stylesheet" src="styles.css" media="screen" />
+<link rel="stylesheet" src="styles.css" media="print" />
+
+ + + +
+

注意:本页的例子使用CSS @media 的方式来说明目的,但是对于所有类型的媒体查询,基本语法均相同。

+
+ +

语法

+ +

每条媒体查询语句都由一个可选的媒体类型和任意数量的媒体特性表达式构成。可以使用多种逻辑操作符合并多条媒体查询语句。媒体查询语句不区分大小写。

+ +

当媒体类型(如果指定)与在其上显示文档的设备匹配并且所有媒体功能表达式都计算为true时,媒体查询将计算为true。 涉及未知媒体类型的查询始终为false。

+ +
+

注意: 即使媒体查询返回false,带有媒体查询附加到其{{HTMLElement("link")}}标记的样式表仍将下载。 但是,除非查询结果变为true,否则其内容将不适用。

+
+ +

媒体类型

+ +

媒体类型Media types)描述设备的一般类别。除非使用 notonly 逻辑操作符,媒体类型是可选的,并且会(隐式地)应用 all 类型。

+ +
+
all
+
适用于所有设备。
+
print
+
适用于在打印预览模式下在屏幕上查看的分页材料和文档。 (有关特定于这些格式的格式问题的信息,请参阅分页媒体。)
+
screen
+
主要用于屏幕。
+
speech
+
主要用于语音合成器。
+
+ +
被废弃的媒体类型: CSS2.1 和  Media Queries 3 定义了一些额外的媒体类型(tty, tv, projection, handheld, braille, embossed, 以及 aural),但是他们在Media Queries 4 中已经被废弃,并且不应该被使用。aural类型被替换为具有相似效果的speech
+ +

媒体特性

+ +

媒体特性Media features)描述了 {{glossary("user agent")}}、输出设备,或是浏览环境的具体特征。媒体特性表达式是完全可选的,它负责测试这些特性或特征是否存在、值为多少。每条媒体特性表达式都必须用括号括起来。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称简介备注
{{cssxref("@media/any-hover", "any-hover")}}是否有任何可用的输入机制允许用户(将鼠标等)悬停在元素上?在 Media Queries Level 4 中被添加。
{{cssxref("@media/any-pointer", "any-pointer")}}可用的输入机制中是否有任何指针设备,如果有,它的精度如何?在 Media Queries Level 4 中被添加。
{{cssxref("@media/aspect-ratio", "aspect-ratio")}}视窗(viewport)的宽高比
{{cssxref("@media/color", "color")}}输出设备每个像素的比特值,常见的有 8、16、32 位。如果设备不支持输出彩色,则该值为 0
{{cssxref("@media/color-gamut", "color-gamut")}}用户代理和输出设备大致程度上支持的色域在 Media Queries Level 4 中被添加。
{{cssxref("@media/color-index", "color-index")}}输出设备的颜色查询表(color lookup table)中的条目数量,如果设备不使用颜色查询表,则该值为 0
{{cssxref("@media/device-aspect-ratio", "device-aspect-ratio")}} {{obsolete_inline}}输出设备的宽高比已在 Media Queries Level 4 中被弃用。
{{cssxref("@media/device-height", "device-height")}} {{obsolete_inline}}输出设备渲染表面(如屏幕)的高度已在 Media Queries Level 4 中被弃用。
{{cssxref("@media/device-width", "device-width")}} {{obsolete_inline}}输出设备渲染表面(如屏幕)的宽度已在 Media Queries Level 4 中被弃用。
{{cssxref("@media/display-mode", "display-mode")}} +

应用程序的显示模式,如web app的manifest中的display 成员所指定

+
在 Web App Manifest spec被定义.
{{cssxref("@media/forced-colors", "forced-colors")}}检测是user agent否限制调色板在 Media Queries Level 5 中被添加。
{{cssxref("@media/grid", "grid")}}输出设备使用网格屏幕还是点阵屏幕?
{{cssxref("@media/height", "height")}}视窗(viewport)的高度
{{cssxref("@media/hover", "hover")}} +

主要输入模式是否允许用户在元素上悬停

+
在 Media Queries Level 4 中被添加。
{{cssxref("@media/inverted-colors", "inverted-colors")}}user agent或者底层操作系统是否反转了颜色在 Media Queries Level 5 中被添加。
{{cssxref("@media/light-level", "light-level")}}环境光亮度在 Media Queries Level 5 中被添加。
{{cssxref("@media/monochrome", "monochrome")}} +

输出设备单色帧缓冲区中每个像素的位深度。如果设备并非黑白屏幕,则该值为 0

+
{{cssxref("@media/orientation", "orientation")}}视窗(viewport)的旋转方向
{{cssxref("@media/overflow-block", "overflow-block")}} +

输出设备如何处理沿块轴溢出视窗(viewport)的内容

+
在 Media Queries Level 4 中被添加。
{{cssxref("@media/overflow-inline", "overflow-inline")}} +

沿内联轴溢出视窗(viewport)的内容是否可以滚动?

+
在 Media Queries Level 4 中被添加。
{{cssxref("@media/pointer", "pointer")}} +

主要输入机制是一个指针设备吗?如果是,它的精度如何?

+
在 Media Queries Level 4 中被添加。
{{cssxref("@media/prefers-color-scheme", "prefers-color-scheme")}}探测用户倾向于选择亮色还是暗色的配色方案在 Media Queries Level 5 中被添加。
{{cssxref("@media/prefers-contrast", "prefers-contrast")}}探测用户是否有向系统要求提高或降低相近颜色之间的对比度在 Media Queries Level 5 中被添加。
{{cssxref("@media/prefers-reduced-motion", "prefers-reduced-motion")}}用户是否希望页面上出现更少的动态效果在 Media Queries Level 5 中被添加。
{{cssxref("@media/prefers-reduced-transparency", "prefers-reduced-transparency")}}用户是否倾向于选择更低的透明度在 Media Queries Level 5 中被添加。
{{cssxref("@media/resolution", "resolution")}}输出设备的像素密度(分辨率)
{{cssxref("@media/scan", "scan")}}输出设备的扫描过程(适用于电视等)
{{cssxref("@media/scripting", "scripting")}}探测脚本(例如 JavaScript)是否可用在 Media Queries Level 5 中被添加。
{{cssxref("@media/update-frequency", "update")}}输出设备更新内容的渲染结果的频率在 Media Queries Level 4 中被添加。
{{cssxref("@media/width", "width")}}视窗(viewport)的宽度,包括纵向滚动条的宽度
+ +

逻辑操作符

+ +

逻辑操作符logical operatorsnot, and, 和 only 可用于联合构造复杂的媒体查询,您还可以通过用逗号分隔多个媒体查询,将它们组合为一个规则。

+ +

and

+ +

 and 操作符用于将多个媒体查询规则组合成单条媒体查询,当每个查询规则都为真时则该条媒体查询为真,它还用于将媒体功能与媒体类型结合在一起。

+ +

not

+ +

not运算符用于否定媒体查询,如果不满足这个条件则返回true,否则返回false。 如果出现在以逗号分隔的查询列表中,它将仅否定应用了该查询的特定查询。 如果使用not运算符,则还必须指定媒体类型。

+ +
+

注意:在Level 3中,not关键字不能用于否定单个媒体功能表达式,而只能用于否定整个媒体查询。

+
+ +

only

+ +

only运算符仅在整个查询匹配时才用于应用样式,并且对于防止较早的浏览器应用所选样式很有用。 当不使用only时,旧版本的浏览器会将screen and (max-width: 500px)简单地解释为screen,忽略查询的其余部分,并将其样式应用于所有屏幕。 如果使用only运算符,则还必须指定媒体类型。

+ +

, (逗号)

+ +

逗号用于将多个媒体查询合并为一个规则。 逗号分隔列表中的每个查询都与其他查询分开处理。 因此,如果列表中的任何查询为true,则整个media语句均返回true。 换句话说,列表的行为类似于逻辑或or运算符。

+ +

定位媒体类型

+ +

媒体类型描述了给定设备的一般类别。 尽管通常在设计网站时会考虑屏幕,但您可能希望创建针对特殊设备(例如打印机或基于音频的屏幕阅读器)的样式。 例如,此CSS针对打印机:

+ +
@media print { ... }
+
+ +

您还可以定位多个设备。 例如,此@media规则使用两个媒体查询来同时定位屏幕和打印设备

+ +
@media screen, print { ... }
+
+ +

有关所有媒体类型的列表,请参见Media types。 由于它们仅以非常广泛的术语描述设备,因此只有少数几种可用。 要定位更具体的属性,请改用媒体功能

+ +

定位媒体特性

+ +

媒体功能描述了给定的{{glossary("user agent")}}的输出设备或环境的特定特征。 例如,您可以将特定样式应用于宽屏显示器,使用鼠标的计算机,或应用于在弱光条件下使用的设备。 当用户的主要输入机制(例如鼠标)可以悬停在元素上时,如下为一个示例:

+ +
@media (hover: hover) { ... }
+
+ +

许多媒体功能都是范围功能,这意味着可以在它们前面加上“最小”或“最大”来表示“最小条件”或“最大条件”约束。 例如,仅当您的浏览器的{{glossary("viewport")}}宽度等于或小于12450px时,此CSS才会应用样式:

+ +
@media (max-width: 12450px) { ... }
+
+ +

如果您在未指定值的情况下创建媒体功能查询,则该样式将全部被应用,只要该查询的值不为零(或在Level 4中为none)即可。 例如,此CSS将适用于任何带有彩色屏幕的设备:

+ +
@media (color) { ... }
+
+ +

如果某个功能不适用于运行浏览器的设备,则涉及该媒体功能的表达式始终为false。 例如,将不会使用嵌套在以下查询中的样式,因为没有语音专用设备具有屏幕长宽比:

+ +
@media speech and (aspect-ratio: 11/5) { ... }
+
+ +

有关更多媒体功能media feature示例,请参阅每个特定功能的参考页。

+ +

创建复杂查询

+ +

有时您可能想创建一个取决于多个条件的媒体查询。 这就是逻辑运算符使用的场景:notand,和 only。 此外,您可以将多个媒体查询合并到一个逗号分隔的列表中。 这使您可以在不同情况下应用相同的样式。

+ +

在前面的示例中,我们已经看到and运算符用于将媒体类型与媒体功能分组。 and运算符还可以将多个媒体功能组合到单个媒体查询中。 同时,not运算符会否定媒体查询,从而基本上颠倒了它的正常含义。 唯一的运算符可防止较早的浏览器应用样式。

+ +
+

注意: 在大多数情况下,默认情况下,如果未指定其他类型,则使用all媒体类型。 但是,如果使用notonly运算符,则必须显式指定媒体类型。

+
+ +

结合多种类型和特性

+ +

and关键字将媒体功能与媒体类型或其他媒体功能组合在一起。 此示例结合了两种媒体功能,以将样式限制为宽度至少为30 em的横向的设备:

+ +
@media (min-width: 30em) and (orientation: landscape) { ... }
+
+ +

要将样式限制为带有屏幕的设备,可以将媒体功能链接到screen媒体类型:

+ +
@media screen and (min-width: 30em) and (orientation: landscape) { ... }
+ +

测试多重查询

+ +

当用户的设备与各种媒体类型,功能或状态中的任何一种匹配时,可以使用逗号分隔的列表来应用样式。 例如,如果用户设备的最小高度为680px或为纵向模式的屏幕设备,则以下规则将应用其样式:

+ +
@media (min-height: 680px), screen and (orientation: portrait) { ... }
+
+ +

以上面的示例为例,如果用户使用的打印机的页面高度为800像素,则media语句将返回true,因为将应用第一个查询。 同样,如果用户使用的是纵向模式的智能手机,并且视口高度为480px,则将应用第二个查询,并且media语句仍将返回true。

+ +

反转查询的含义

+ +

not关键字会反转整个媒体查询的含义。 它只会否定要应用的特定媒体查询。 (因此,它不会应用于以逗号分隔的媒体查询列表中的每个媒体查询。)not关键字不能用于否定单个功能查询,只能用于否定整个媒体查询。 看看以下not关键字的例子:

+ +
@media not all and (monochrome) { ... }
+
+ +

所以上述查询等价于:

+ +
@media not (all and (monochrome)) { ... }
+
+ +

而不是:

+ +
@media (not all) and (monochrome) { ... }
+ +

再看另一个例子,如下媒体查询:

+ +
@media not screen and (color), print and (color) { ... }
+
+ +

等价于:

+ +
@media (not (screen and (color))), print and (color) { ... }
+ +

提升老版本浏览器兼容性

+ +

only关键字可防止不支持带有媒体功能的媒体查询的旧版浏览器应用给定的样式。 它对现代浏览器没有影响。

+ +
@media only screen and (color) { ... }
+
+ +

版本 4 中的语法改进

+ +

媒体查询4级规范对语法进行了一些改进,以使用具有“范围”类型(例如宽度或高度,减少冗余)的功能进行媒体查询。 级别4添加了用于编写此类的查询范围上下文。 例如,使用最大宽度max- 功能,我们可以编写以下代码:

+ +
+

Note: 媒体查询4级规范在现代浏览器中具有合理的支持,但某些媒体功能并未得到很好的支持。 有关更多详细信息,请参见 @media browser compatibility table

+
+ +
@media (max-width: 30em) { ... }
+ +

在媒体查询4级规范可以这样写:

+ +
@media (width <= 30em) { ... }
+
+ +

使用min-max-可以测试一个在两个值之间的宽度

+ +
@media (min-width: 30em) and (max-width: 50em) { ... }
+ +

用4级语法书写如下

+ +
@media (30em <= width <= 50em ) { ... }
+
+
+ +

媒体查询4级规范还添加了用and, not, 和 or实现的完整的布尔运算来合并媒体查询的方法。

+ +

使用 not否定一个特性

+ +

在媒体功能周围使用not()会否定查询中的该特性。 例如,如果设备没有悬停功能,则not(hover)将被匹配:

+ +
@media (not(hover)) { ... }
+ +

用 or测试多个特性

+ +

您可以使用or测试多个功能之间的匹配,如果任何功能为true,则解析为true。 例如,以下查询测试具有单色显示或悬停功能的设备:

+ +
@media (not (color)) or (hover) { ... }
+ +

参见

+ + diff --git a/files/zh-cn/web/css/offset/index.html b/files/zh-cn/web/css/offset/index.html new file mode 100644 index 0000000000..e61a0ffd7a --- /dev/null +++ b/files/zh-cn/web/css/offset/index.html @@ -0,0 +1,97 @@ +--- +title: offset +slug: Web/CSS/偏移 +translation_of: Web/CSS/offset +--- +
{{SeeCompatTable}}{{CSSRef}}{{draft}}
+ +

这个 offset 是CSS属性的快速属性动画元素沿着定义的路径。

+ +
+

早期版本 规格 属性叫做 motion.

+
+ +

{{cssinfo}}

+ +

Syntax

+ +
/* 偏移位置 */
+offset: auto
+offset: 10px 30px;
+offset: none;
+
+/* 偏移路径 */
+offset: ray(45deg closest-side);
+offset: path(M 100 100 L 300 100 L 200 300 z);
+offset: url(arc.svg);
+
+/*  偏移路径的距离和/或旋转  */
+offset: url(circle.svg) 100px;
+offset: url(circle.svg) 40%;
+offset: url(circle.svg) 30deg;
+offset: url(circle.svg) 50px 20deg;
+
+/*  包括锚偏移  */
+offset: ray(45deg closest-side) / 40px 20px;
+offset: url(arc.svg) 2cm / 0.5cm 3cm;
+offset: url(arc.svg) 30deg / 50px 100px;
+
+ +

语法形式

+ +
{{csssyntax}}
+ +

举例

+ +

HTML

+ +
<div id="offsetElement"></div>
+
+ +

CSS

+ +
@keyframes move {
+  from {
+    offset-distance: 0%;
+  }
+
+  to {
+    offset-distance: 100%;
+  }
+}
+
+#offsetElement {
+  width: 50px;
+  height: 50px;
+  background-color: blue;
+  offset: path("M 100 100 L 300 100 L 200 300 z") auto;
+  animation: move 3s linear infinite;
+}
+
+ +

Result

+ +

{{EmbedLiveSample("Example", 350, 350)}}

+ +

规格

+ + + + + + + + + + + + + + +
规格使用状态注释
{{SpecName('Motion Path Level 1', '#offset-shorthand', 'offset')}}{{Spec2('Motion Path Level 1')}}Initial definition
+ +

浏览器兼容性

+ +

该兼容性表生成从该网页的结构化数据。如果你愿意,请查看https://github.com/mdn/browser-compat-数据,并发送一个引入请求。

+ +

{{Compat("css.properties.offset")}}

diff --git a/files/zh-cn/web/css/overflow-wrap/index.html b/files/zh-cn/web/css/overflow-wrap/index.html new file mode 100644 index 0000000000..5c2c0c687d --- /dev/null +++ b/files/zh-cn/web/css/overflow-wrap/index.html @@ -0,0 +1,147 @@ +--- +title: overflow-wrap +slug: Web/CSS/word-wrap +tags: + - CSS Text Module Level 3 + - CSS3 + - W3C + - overflow-wrap + - word-wrap +translation_of: Web/CSS/overflow-wrap +--- +
{{CSSRef}}
+ +
+ +

{{EmbedInteractiveExample("pages/css/overflow-wrap.html")}}

+ + + +

CSS 属性 overflow-wrap 是用来说明当一个不能被分开的字符串太长而不能填充其包裹盒时,为防止其溢出,浏览器是否允许这样的单词中断换行。

+ +
+

与{{cssxref("word-break")}}相比,overflow-wrap仅在无法将整个单词放在自己的行而不会溢出的情况下才会产生中断。

+
+ +
注:word-wrap 属性原本属于微软的一个私有属性,在 CSS3 现在的文本规范草案中已经被重名为 {{cssxref("overflow-wrap")}} 。 word-wrap 现在被当作 overflow-wrap 的 “别名”。 稳定的谷歌 Chrome 和 Opera 浏览器版本支持这种新语法。
+ +

语法

+ +
/* Keyword values */
+overflow-wrap: normal;
+overflow-wrap: break-word;
+
+/* Global values */
+overflow-wrap: inherit;
+overflow-wrap: initial;
+overflow-wrap: unset;
+
+
+ +

overflow-wrap 属性指定为从下面的值列表中选择的单个关键字。

+ +

+ +
+
normal
+
行只能在正常的单词断点处中断。(例如两个单词之间的空格)。
+
break-word
+
表示如果行内没有多余的地方容纳该单词到结尾,则那些正常的不能被分割的单词会被强制分割换行。
+
+ +

形式语法

+ +
{{csssyntax}}
+ +

示例

+ +

比较 overflow-wrap、word-break 和 hyphens

+ +

本示例比较分解长单词时,overflow-wrapword-break,  hyphens 的结果。

+ +

HTML

+ +
<p>They say the fishing is excellent at
+  Lake <em class="normal">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>normal</code>)</p>
+<p>They say the fishing is excellent at
+  Lake <em class="ow-anywhere">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>overflow-wrap: anywhere</code>)</p>
+<p>They say the fishing is excellent at
+  Lake <em class="ow-break-word">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>overflow-wrap: break-word</code>)</p>
+<p>They say the fishing is excellent at
+  Lake <em class="word-break">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>word-break</code>)</p>
+<p>They say the fishing is excellent at
+  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>hyphens</code>, without <code>lang</code> attribute)</p>
+<p lang="en">They say the fishing is excellent at
+  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>hyphens</code>, English rules)</p>
+<p class="hyphens" lang="de">They say the fishing is excellent at
+  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>hyphens</code>, German rules)</p>
+ +

CSS

+ +
p {
+   width: 13em;
+   margin: 2px;
+   background: gold;
+}
+
+.ow-anywhere {
+   overflow-wrap: anywhere;
+}
+
+.ow-break-word {
+   overflow-wrap: break-word;
+}
+
+.word-break {
+   word-break: break-all;
+}
+
+.hyphens {
+   hyphens: auto;
+}
+ +

结果

+ +

{{ EmbedLiveSample('Comparing_overflow-wrap_word-break_and_hyphens', '100%', 260) }}

+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('CSS3 Text', '#propdef-overflow-wrap', 'overflow-wrap') }}{{ Spec2('CSS3 Text') }}Initial definition
+ +

{{cssinfo}}

+ +

浏览器兼容性

+ +

{{Compat("css.properties.overflow-wrap")}}

+ +

另参见

+ + diff --git a/files/zh-cn/web/css/text-decoration-thickness/index.html b/files/zh-cn/web/css/text-decoration-thickness/index.html new file mode 100644 index 0000000000..cdffd6eced --- /dev/null +++ b/files/zh-cn/web/css/text-decoration-thickness/index.html @@ -0,0 +1,119 @@ +--- +title: 文本装饰线厚度(粗细) +slug: Web/CSS/文本装饰线厚度(粗细) +tags: + - 装饰线粗细 装饰线厚度 +translation_of: Web/CSS/text-decoration-thickness +--- +
{{CSSRef}}
+ +
CSS 属性 text-decoration-thickness 用于设置元素中文本所使用的装饰线(如 line-through、underline 或 overline)的笔触厚度。
+ +

语法

+ +
/* Single keyword */
+text-decoration-thickness: auto;
+text-decoration-thickness: from-font;
+
+/* length */
+text-decoration-thickness: 0.1em;
+text-decoration-thickness: 3px;
+
+/* percentage */
+text-decoration-thickness: 10%;
+
+/* Global values */
+text-decoration-thickness: inherit;
+text-decoration-thickness: initial;
+text-decoration-thickness: unset;
+ +

+ +
+
auto
+
由浏览器为文本装饰线选择合适的厚度。
+
from-font
+
如果字体文件中包含了首选的厚度值,则使用字体文件的厚度值。如果字体文件中没有包含首选的厚度值,则效果和设置为 auto 一样,由浏览器选择合适的厚度值。
+
<length>
+
将文本装饰线的厚度设置为一个 {{cssxref('length')}} 类型的值,覆盖掉字体文件建议的值或浏览器默认的值。
+
<percentage>
+
Specifies the thickness of the text decoration line as a {{cssxref('percentage')}} of 1em in the current font. A percentage inherits as a relative value, and so therefore scales with changes in the font. The browser must use a minimum of 1 device pixel. For a given application of this property, the thickness is constant across the whole box it is applied to, even if there are child elements with a different font size.
+
+ +

Formal definition

+ +

{{CSSInfo}}

+ +

Formal syntax

+ +
{{csssyntax}}
+ +

示例

+ +

Varying thickness

+ +

HTML

+ +
<p class="thin">Here's some text with a 1px red underline.</p>
+<p class="thick">This one has a 5px red underline.</p>
+<p class="shorthand">This uses the equivalent shorthand.</p>
+ +

CSS

+ +
.thin {
+  text-decoration-line: underline;
+  text-decoration-style: solid;
+  text-decoration-color: red;
+  text-decoration-thickness: 1px;
+}
+
+.thick {
+  text-decoration-line: underline;
+  text-decoration-style: solid;
+  text-decoration-color: red;
+  text-decoration-thickness: 5px;
+}
+
+.shorthand {
+  text-decoration: underline solid red 5px;
+}
+ +

Results

+ +

{{ EmbedLiveSample('Varying_thickness', '', '', '') }}

+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS4 Text Decoration', '#text-decoration-width-property', 'text-decoration-width')}}{{Spec2('CSS4 Text Decoration')}}Initial definition.
+ +
+

Note: The property used to be called text-decoration-width, but was updated in 2019 to text-decoration-thickness.

+
+ +

浏览器兼容性

+ + + +

{{Compat("css.properties.text-decoration-thickness")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/css/timing-function/index.html b/files/zh-cn/web/css/timing-function/index.html deleted file mode 100644 index aef640fdd3..0000000000 --- a/files/zh-cn/web/css/timing-function/index.html +++ /dev/null @@ -1,266 +0,0 @@ ---- -title: -slug: Web/CSS/timing-function -tags: - - CSS - - timing-function -translation_of: Web/CSS/easing-function -translation_of_original: Web/CSS/timing-function ---- -

{{ CSSRef() }}

- -

<timing-function> CSS 数据类型表示一个数学函数,它描述了在一个过渡或动画中一维数值的改变速度。这实质上让你可以自己定义一个加速度曲线,以便动画的速度在动画的过程中可以进行改变。这些函数通常被称为缓动函数。

- -

这是一个表示时间输出比率的函数,表示为{{cssxref("<number>")}},0, 0 代表初始状态,1, 1 代表终止状态。

- -

输出比可以大于1.0(或者小于0.0)。这是因为在一种反弹效果中,动画是可以比最后的状态走的更远的,然后再回到最终状态。

- -

不过,如果输出值超过了它允许的范围,比如组成一个颜色的值大于了255或者小于了0,这个值会被修改为允许范围内的最接近的值(在颜色值这个例子中分别为255和0)。一些贝塞尔曲线展示了这些性质。

- -

定时函数

- -
-

CSS 支持两种定时函数:立方贝塞尔曲线的子集和阶梯函数。这些函数中最有用的是一个关键字,可以很容易地引用它们。

- -

cubic-bezier() 定时函数

- - - - - - - - -
-

-
-

cubic-bezier() 定义了一条 立方贝塞尔曲线(cubic Bézier curve)。这些曲线是连续的,一般用于动画的平滑变换,也被称为缓动函数(easing functions)。

- -

一条立方贝塞尔曲线需要四个点来定义,P0 、P1 、P2 和 P3。P0 和 P3 是起点和终点,这两个点被作为比例固定在坐标系上,横轴为时间比例,纵轴为完成状态。P0 是 (0, 0),表示初始时间和初始状态。P3 是 (1, 1) ,表示终止时间和终止状态。

- -

并非所有的三次贝塞尔曲线都适合作为计时函数,也并非所有的曲线都是数学函数,即给定横坐标为0或1的曲线。在CSS定义的P0和P3固定的情况下,三次贝塞尔曲线是一个函数,因此,当且仅当P1和P2的横坐标都在[0,1]范围内时,三次贝塞尔曲线是有效的。

- -

三次贝塞尔曲线的 P1或 P2坐标超出[0, 1] 范围可能会产生弹跳效果。

- -

当指定的三次贝塞尔曲线无效时,CSS将忽略整个属性。

-
-
- -

语法

- -
cubic-bezier(x1, y1, x2, y2)
-
- -

其中,

- -
-
x1, y1, x2, y2是<number>类型的值,它们代表当前定义立方贝塞尔曲线中的P1 和 P2点的横坐标和纵坐标,X1和X2必须在[0,1]范围内,否则当前值无效。
-
Are {{cssxref("<number>")}} values representing the abscissas and ordinates of the P1 and P2 points defining the cubic Bézier curve. x1 and x2 must be in the range [0, 1] or the value is invalid.
-
- -

示例

- -

CSS 中允许使用这些贝塞尔曲线:

- -
cubic-bezier(0.1, 0.7, 1.0, 0.1)   The canonical Bézier curve with four <number> in the [0,1] range.
-cubic-bezier(0, 0, 1, 1)           Using <integer> is valid as any <integer> is also a <number>.
-cubic-bezier(0.3, -1.9, 2.1, -0.2) Negative values for ordinates are valid, leading to bouncing effects.
-cubic-bezier(0.1, 4, 0.6, 2.45)    Values > 1.0 for ordinates are also valid.
- -

像这些贝塞尔曲线的定义是无效的:

- -
cubic-bezier(0.1, red, 1.0, green) Though the animated output type may be a color, Bézier curves work w/ numerical ratios.
-cubic-bezier(-0.2, 0.6, -0.1, 0)   Abscissas must be in the [0, 1] range or the curve is not a function of time.
-cubic-bezier(0.3, 2.1)             The two points must be defined, there is no default value.
-cubic-bezier(1.1, 0, 4, 0)         Abscissas must be in the [0, 1] range or the curve is not a function of time.
-
- -

The steps() class of timing-functions

- - - - - - - - - - - - - -
- - - - - - - -
-

steps() 定义了一个以等距步长划分值域的步长函数。这个阶跃函数的子类有时也称为阶梯函数。

-
-
steps(2, start)steps(4, end)
- -

Syntax

- -
steps(number_of_steps, direction)
-
- -

where :

- -
-
number_of_steps
-
Is a strictly positive {{cssxref("<integer>")}} representing the amount of equidistant treads composing the stepping function.
-
direction
-
Is a keyword indicating if it the function is left- or right-continuous: -
    -
  • start denotes a left-continuous function, so that the first step happens when the animation begins;
  • -
  • end denotes a right-continuous function, so that the last step happens when the animation ends.
  • -
-
-
- -

Examples

- -

These timing functions are valid :

- -
steps(5, end)          There is 5 treads, the last one happens right before the end of the animation.
-steps(2, start)        A two-step staircase, the first one happening at the start of the animation.
-
- -

These timing function are invalid :

- -
steps(2.0, end)        The first parameter must be an <integer> and cannot be a real value, even if it is equal to one.
-steps(-3, start)       The amount of steps must be non-negative.
-steps(0, end)          There must be at least one step.
-steps(2)               The second parameter is not optional.
-steps(start, 3)        Though of different types, the order of parameter is important.
-step(1, end)           Even if there is one step, the function name is steps, with the plural 's'
-steps(3 end)           The two parameters must be separated with a comma; one or several spaces is not enough.
-
- -

常用定时函数关键字

- -

linear

- - - - - - - - -
-

此关键字表示定时函数cubic-bezier(0.0, 0.0, 1.0, 1.0)。使用这个定时函数,动画会以恒定的速度从初始状态过渡到结束状态。

-
- -

ease

- - - - - - - - -
此关键字表示定时函数 cubic-bezier(0.25, 0.1, 0.25, 1.0)。 这个函数类似于 ease-in-out, 尽管它在开始时加速地更快,但在接近中间中,加速已经开始变慢了。
- -

ease-in

- - - - - - - - -
-

此关键字表示定时函数cubic-bezier(0.42, 0.0, 1.0, 1.0)。动画开始时缓慢,然后逐步加速,知道达到最后状态,动画突然停止。

-
- -

ease-in-out

- - - - - - - - -
-

此关键字表示定时函数 cubic-bezier(0.42, 0.0, 0.58, 1.0)。使用这个定时函数,动画开始的行为类似于 ease-in 函数,动画结束时的行为类似于 ease-out函数。

-
- -

ease-out

- - - - - - - - -
-

此关键字表示定时函数 cubic-bezier(0.0, 0.0, 0.58, 1.0)。动画开始很快,然后逐渐减慢,直到最终状态。

-
- -

step-start

- - - - - - - - -
此关键字表示定时函数 steps(1, start)。使用这个定时函数,动画会立刻跳转到结束状态,并一直停留在结束状态直到动画结束。
- -

step-end

- - - - - - - - -
-

此关键字表示定时函数 steps(1, end)。使用这个定时函数,动画会一直保持初始状态直到动画结束,然后立刻跳转到结束状态。

-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('CSS3 Transitions', '#transition-timing-function', '<timing-function>') }}{{ Spec2('CSS3 Transitions') }}Defined anonymously
{{ SpecName('CSS3 Animations', '#animation-timing-function', '<timing-function>') }}{{ Spec2('CSS3 Animations') }}Defined anonymously, says to see definition in the CSS Transitions Module
- -

浏览器兼容性

- -

{{Compat("css.types.timing-function", 2)}}

- -

相关链接

- - diff --git a/files/zh-cn/web/css/url()/index.html b/files/zh-cn/web/css/url()/index.html new file mode 100644 index 0000000000..3ba85545e4 --- /dev/null +++ b/files/zh-cn/web/css/url()/index.html @@ -0,0 +1,127 @@ +--- +title: +slug: Web/CSS/url +translation_of: Web/CSS/url() +translation_of_original: Web/CSS/url +--- +

{{ CssRef() }}

+ +

概述

+ +

CSS 数据类型 <url> 指向一个资源。它没有独有的表达形式,只能通过 url() 函数定义。

+ +
URI 和 URL?
+
+URI(统一资源标识符) 与 URL(统一资源定位符) 不同。URL 描述资源的位置,而 URI 描述资源的 id。URI 可以是一个资源的 URL(地址)、或 URN(统一资源名称)。
+
+在 CSS Level 1 中,url() 函数被引入并用于描述 URL,即地址(虽然没有明确定义,但指一个 CSS 数据类型 <url>
+
+在 CSS Level 2 中,url() 函数被扩展为可以描述任何一个 URI,即 URL 或 URN。这一定义导致  url() 函数被用于创建一个  <uri> 数据类型。这一行为使人迷惑,且在 CSS 中几乎从不使用 URN。
+
+为了解决这一问题,在 CSS Level 3 中恢复了它的初始定义, url() 函数被明确定义为指代 <url> CSS 数据类型,且 <uri> CSS 数据类型不再存在。
+
+注意,这些语义信息并不会影响 Web 开发者的开发和对此数据类型的具体实现。
+ +

许多 CSS 属性 将 URL 作为属性值,例如 {{ Cssxref("background-image") }}、{{ Cssxref("cursor") }}、{{ Cssxref("@font-face") }}、{{ cssxref("list-style") }} 等。

+ +

url() 函数

+ +

URL 可以使用单引号或双引号包含,也可以直接书写。可以在此函数中使用相对地址。相对地址相对于 CSS 样式表的 URL(而不是网页的 URL)。

+ +

语法

+ +
 <CSS 属性>:  url("http://mysite.example.com/mycursor.png")
+
+ <CSS 属性>:  url(http://mysite.example.com/mycursor.png)
+
+ +
+

注意: 从 Firefox 15 开始,不再允许在未用引号包含的 url() 中使用大于 0x7e 的控制字符。详情请查看 {{Bug(752230)}}。

+
+ +

示例

+ +
.topbanner { background: url("topbanner.png") #00D no-repeat fixed; }
+
+ +
ul { list-style: square url(http://www.example.com/redball.png) }
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{ SpecName('CSS3 Values', '#urls', '<url>') }}{{ Spec2('CSS3 Values') }}自 CSS Level 2 (Revision 1) 以来没有显著更改
{{ Specname('CSS2.1', 'syndata.html#uri', '<uri>') }}{{ Spec2('CSS2.1') }}自 CSS Level 1 以来没有显著更改
{{ SpecName('CSS1', '#url', '<url>') }}{{ Spec2('CSS1') }} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
基本支持1.01.0 (1.0)3.03.51.0 (85)
+
+ +
+ + + + + + + + + + + + + + + + + + + +
特性AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
基本支持1.01.0 (3.5)yesyes1.0
+
diff --git a/files/zh-cn/web/css/url/index.html b/files/zh-cn/web/css/url/index.html deleted file mode 100644 index 3ba85545e4..0000000000 --- a/files/zh-cn/web/css/url/index.html +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: -slug: Web/CSS/url -translation_of: Web/CSS/url() -translation_of_original: Web/CSS/url ---- -

{{ CssRef() }}

- -

概述

- -

CSS 数据类型 <url> 指向一个资源。它没有独有的表达形式,只能通过 url() 函数定义。

- -
URI 和 URL?
-
-URI(统一资源标识符) 与 URL(统一资源定位符) 不同。URL 描述资源的位置,而 URI 描述资源的 id。URI 可以是一个资源的 URL(地址)、或 URN(统一资源名称)。
-
-在 CSS Level 1 中,url() 函数被引入并用于描述 URL,即地址(虽然没有明确定义,但指一个 CSS 数据类型 <url>
-
-在 CSS Level 2 中,url() 函数被扩展为可以描述任何一个 URI,即 URL 或 URN。这一定义导致  url() 函数被用于创建一个  <uri> 数据类型。这一行为使人迷惑,且在 CSS 中几乎从不使用 URN。
-
-为了解决这一问题,在 CSS Level 3 中恢复了它的初始定义, url() 函数被明确定义为指代 <url> CSS 数据类型,且 <uri> CSS 数据类型不再存在。
-
-注意,这些语义信息并不会影响 Web 开发者的开发和对此数据类型的具体实现。
- -

许多 CSS 属性 将 URL 作为属性值,例如 {{ Cssxref("background-image") }}、{{ Cssxref("cursor") }}、{{ Cssxref("@font-face") }}、{{ cssxref("list-style") }} 等。

- -

url() 函数

- -

URL 可以使用单引号或双引号包含,也可以直接书写。可以在此函数中使用相对地址。相对地址相对于 CSS 样式表的 URL(而不是网页的 URL)。

- -

语法

- -
 <CSS 属性>:  url("http://mysite.example.com/mycursor.png")
-
- <CSS 属性>:  url(http://mysite.example.com/mycursor.png)
-
- -
-

注意: 从 Firefox 15 开始,不再允许在未用引号包含的 url() 中使用大于 0x7e 的控制字符。详情请查看 {{Bug(752230)}}。

-
- -

示例

- -
.topbanner { background: url("topbanner.png") #00D no-repeat fixed; }
-
- -
ul { list-style: square url(http://www.example.com/redball.png) }
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - -
规范状态说明
{{ SpecName('CSS3 Values', '#urls', '<url>') }}{{ Spec2('CSS3 Values') }}自 CSS Level 2 (Revision 1) 以来没有显著更改
{{ Specname('CSS2.1', 'syndata.html#uri', '<uri>') }}{{ Spec2('CSS2.1') }}自 CSS Level 1 以来没有显著更改
{{ SpecName('CSS1', '#url', '<url>') }}{{ Spec2('CSS1') }} 
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
基本支持1.01.0 (1.0)3.03.51.0 (85)
-
- -
- - - - - - - - - - - - - - - - - - - -
特性AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
基本支持1.01.0 (3.5)yesyes1.0
-
diff --git a/files/zh-cn/web/css/visual_formatting_model/index.html b/files/zh-cn/web/css/visual_formatting_model/index.html new file mode 100644 index 0000000000..640f3abbc9 --- /dev/null +++ b/files/zh-cn/web/css/visual_formatting_model/index.html @@ -0,0 +1,282 @@ +--- +title: 视觉格式化模型 +slug: Web/Guide/CSS/Visual_formatting_model +tags: + - CSS + - CSS盒模型 + - 参考 +translation_of: Web/CSS/Visual_formatting_model +--- +

{{CSSRef}}

+ +

CSS 视觉格式化模型(visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。该模型是 CSS 的基础概念之一。

+ + + +

视觉格式化模型会根据CSS盒子模型将文档中的元素转换为一个个盒子,每个盒子的布局由以下因素决定:

+ +
    +
  • 盒子的尺寸:精确指定、由约束条件指定或没有指定
  • +
  • 盒子的类型:行内盒子(inline)、行内级盒子(inline-level)、原子行内级盒子(atomic inline-level)、块盒子(block)
  • +
  • 定位方案(positioning scheme):普通流定位、浮动定位或绝对定位
  • +
  • 文档树中的其它元素:即当前盒子的子元素或兄弟元素
  • +
  • {{glossary("viewport", "视口")}}尺寸与位置
  • +
  • 所包含的图片的尺寸
  • +
  • 其他的某些外部因素
  • +
+ +

该模型会根据盒子的包含块(containing block)的边界来渲染盒子。通常,盒子会创建一个包含其后代元素的包含块,但是盒子并不由包含块所限制,当盒子的布局跑到包含块的外面时称为溢出(overflow)

+ +
+

译注:本文有很多相近的术语,阅读时需仔细,否则容易造成误解。为了方便读者,这里我将其整理一下。

+ +

 

+ +
    +
  • :block,一个抽象的概念,一个块在文档流上占据一个独立的区域,块与块之间在垂直方向上按照顺序依次堆叠。
  • +
  • 包含块:containing block,包含其他盒子的块称为包含块。
  • +
  • 盒子:box,一个抽象的概念,由CSS引擎根据文档中的内容所创建,主要用于文档元素的定位、布局和格式化等用途。盒子与元素并不是一一对应的,有时多个元素会合并生成一个盒子,有时一个元素会生成多个盒子(如匿名盒子)。
  • +
  • 块级元素:block-level element,元素的 displayblocklist-itemtable 时,该元素将成为块级元素。元素是否是块级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
  • +
  • 块级盒子:block-level box,由块级元素生成。一个块级元素至少会生成一个块级盒子,但也有可能生成多个(例如列表项元素)。
  • +
  • 块盒子:block box,如果一个块级盒子同时也是一个块容器盒子(见下),则称其为块盒子。除具名块盒子之外,还有一类块盒子是匿名的,称为匿名块盒子(Anonymous block box),匿名盒子无法被CSS选择符选中。
  • +
  • 块容器盒子:block container box或block containing box,块容器盒子侧重于当前盒子作为“容器”的这一角色,它不参与当前块的布局和定位,它所描述的仅仅是当前盒子与其后代之间的关系。换句话说,块容器盒子主要用于确定其子元素的定位、布局等。
  • +
+ +

注意:盒子分为“块盒子”和“块级盒子”两种,但元素只有“块级元素”,而没有“块元素”。下面的“行内级元素”也是一样。

+ +
    +
  • 行内级元素:inline-level element,displayinlineinline-blockinline-table 的元素称为行内级元素。与块级元素一样,元素是否是行内级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
  • +
  • 行内级盒子:inline-level box,由行内级元素生成。行内级盒子包括行内盒子和原子行内级盒子两种,区别在于该盒子是否参与行内格式化上下文的创建。
  • +
  • 行内盒子:inline box,参与行内格式化上下文创建的行内级盒子称为行内盒子。与块盒子类似,行内盒子也分为具名行内盒子和匿名行内盒子(anonymous inline box)两种。
  • +
  • 原子行内级盒子:atomic inline-level box,不参与行内格式化上下文创建的行内级盒子。原子行内级盒子一开始叫做原子行内盒子(atomic inline box),后被修正。原子行内级盒子的内容不会拆分成多行显示。
  • +
+ +

另外,本文的英文原文仍未最后定稿,因此部分内容并不完整。待英文原文更新后应及时更新译文。

+
+ +

盒子的生成

+ +

盒子的生成是 CSS 视觉格式化模型的一部分,用于从文档元素生成盒子。盒子有不同的类型,不同类型的盒子的格式化方法也有所不同。盒子的类型取决于 CSS {{ cssxref("display") }} 属性。

+ +

块级元素与块盒子

+ +

当元素的 {{ cssxref("display") }} 为 blocklist-item 或 table 时,该元素将成为块级元素。一个块级元素会被格式化成一个块(例如文章的一个段落),默认按照垂直方向依次排列。

+ +

每个块级盒子都会参与块格式化上下文(block formatting context)的创建,而每个块级元素都会至少生成一个块级盒子,即主块级盒子(principal block-level box)。有一些元素,比如列表项会生成额外的盒子来放置项目符号,而那些会生成列表项的元素可能会生成更多的盒子。不过,多数元素只生成一个主块级盒子。 

+ +

主块级盒子包含由后代元素生成的盒子以及内容,同时它也会参与定位方案

+ +

venn_blocks.png一个块级盒子可能也是一个块容器盒子。块容器盒子(block container box)要么只包含其它块级盒子,要么只包含行内盒子并同时创建一个行内格式化上下文(inline formatting context)

+ +

能够注意到块级盒子与块容器盒子是不同的这一点很重要。前者描述了元素与其父元素和兄弟元素之间的行为,而后者描述了元素跟其后代之间的行为。有些块级盒子并不是块容器盒子,比如表格;而有些块容器盒子也不是块级盒子,比如非替换行内块和非替换表格单元格。

+ +

一个同时是块容器盒子的块级盒子称为块盒子(block box)。

+ +

匿名块盒子

+ +

在某些情况下进行视觉格式化时,需要添加一些增补性的盒子,这些盒子不能用CSS选择符选中,因此称为匿名盒子(anonymous boxes)

+ +

CSS选择器不能作用于匿名盒子(anonymous boxes),所以它不能被样式表赋予样式。也就是说,此时所有可继承的 CSS 属性值都为 inherit ,而所有不可继承的 CSS 属性值都为 initial

+ +

块包含盒子可能只包含行内级盒子,也可能只包含块级盒子,但通常的文档都会同时包含两者,在这种情况下,就会在相邻的行内级盒子外创建匿名块盒子。

+ +

示例

+ +

考虑下面的HTML代码,假设 {{ HTMLElement("div") }} 和 {{ HTMLElement("p") }} 都保持默认的样式(即它们的 display 为 block):

+ +
<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>
+
+ +

此时会产生两个匿名块盒子:一个是 <p> 元素前面的那些文本(Some inline text),另一个是 <p> 元素后面的文本(followed by more inline text.)。此时会生成下面的块结构:

+ +

+ +

显示为:

+ +
Some inline text
+followed by a paragraph
+followed by more inline text.
+
+ +

对这两个匿名盒子来说,程序员无法像 {{ HTMLElement("p") }} 元素那样控制它们的样式,因此它们会从 {{ HTMLElement("div") }} 那里继承那些可继承的属性,如 {{ cssxref("color") }}。其他不可继承的属性则会设置为 initial,比如,因为没有为它们指定 {{ cssxref("background-color") }},因此其具有默认的透明背景,而 <p> 元素的盒子则能够用CSS指定背景颜色。类似地,两个匿名盒子的文本颜色总是一样的。

+ +

另一种会创建匿名块盒子的情况是一个行内盒子中包含一或多个块盒子。此时,包含块盒子的盒子会拆分为两个行内盒子,分别位于块盒子的前面和后面。块盒子前面的所有行内盒子会被一个匿名块盒子包裹,块盒子后面的行内盒子也是一样。因此,块盒子将成为这两个匿名块盒子的兄弟盒子。

+ +

如果有多个块盒子,而它们中间又没有行内元素,则会在这些盒子的前面和后面创建两个匿名块盒子。

+ +

示例

+ +

考虑下面的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.
+
+ +

行内级元素和行内盒子

+ +

如果一个元素的 {{ cssxref("display") }} 属性为 inlineinline-blockinline-table,则称该元素为行内级元素。显示时,它不会生成内容块,但是可以与其他行内级内容一起显示为多行。一个典型的例子是包含多种格式内容(如强调文本、图片等)的段落,就可以由行内级元素组成。

+ +

+ +
+

该图使用了过时的术语,见下面的“注意”(译注:指图中的 “Atomic inline boxes”)。除此之外该图还有一个错误,右边的黄色部分应该完全包含左侧的椭圆(类似于数学上的超集),因为标准所说的是“如果行内级元素生成的盒子参与行内格式化上下文的创建,则该盒子为一个行内级盒子”,见“CSS 2.2标准的9.2.2节”。

+
+ +

行内级元素会生成行内级盒子,该盒子同时会参与行内格式化上下文(inline formatting context)的创建。行内盒子既是行内级盒子,也是一个其内容会参与创建其容器的行内格式化上下文的盒子,比如所有具有 display:inline 样式的非替换盒子。如果一个行内级盒子的内容不参与行内格式化上下文的创建,则称其为原子行内级盒子。而通过替换行内级元素或 display 值为 inline-blockinline-table 的元素创建的盒子不会像行内盒子一样可以被拆分为多个盒子。

+ +
+

注意:开始的时候,原子行内级盒子叫做原子行内盒子,这并不准确,因为它们并不是行内盒子。后来在一次勘误时修正了这一问题。不过,当你见到某些文章中使用了“原子行内盒子”的时候,你尽可以将其理解为“原子行内级盒子”,因为这仅仅是一个名字的修改。

+
+ +
+

在同一个行内格式化上下文中,原子行内级盒子不能拆分成多行:

+ +
<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>
+
+ +

可能会显示为:

+ +

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>
+
+ +

则可能显示为:

+ +

The text in the span 
+ cannot be split into several lines as it is an
+ inline-block box.

+ +

其中的“cannot be split into several lines as it”永远不会换行。

+
+ +

匿名行内盒子

+ +
类似于块盒子,CSS引擎有时候也会自动创建一些行内盒子。这些行内盒子无法被选择符选中,因此是匿名的,它们从父元素那里继承那些可继承的属性,其他属性保持默认值 initial
+ +
 
+ +
一种常见的情况是CSS引擎会自动为直接包含在块盒子中的文本创建一个行内格式化上下文,在这种情况下,这些文本会被一个足够大的匿名行内盒子所包含。但是如果仅包含空格则有可能不会生成匿名行内盒子,因为空格有可能会由于 {{ cssxref("white-space") }} 的设置而被移除,从而导致最终的实际内容为空。
+ +
 
+ +
示例 TBD
+ +

其他类型的盒子

+ +

行盒子

+ +

行盒子由行内格式化上下文创建,用来显示一行文本。在块盒子内部,行盒子总是从块盒子的一边延伸到另一边(译注:即占据整个块盒子的宽度)。当有浮动元素时,行盒子会从向左浮动的元素的右边缘延伸到向右浮动的元素的左边缘。

+ +
行盒子更多是以技术性目的而存在的,Web开发者通常不需要关心。
+ +

Run-in 盒子

+ +
Run-in 盒子通过 display:run-in 来定义,它可以是块盒子,也可以是行内盒子,这取决于紧随其后的盒子的类型。Run-in 盒子可以用来在可能的情况下将标题嵌入文章的第一个段落中。
+ +
 
+ +
+

注意:Run-in 盒子已经在CSS 2.1的标准中移除了,但可能会在CSS 3中作为一个实验性的内容再次加入。因此最好不要将其用于正式项目。

+
+ +

由其他模型引入的盒子

+ +
除了行内格式化上下文和块格式化上下文之外,CSS还定义了几种内容模型,这些模型同样可以应用于元素。这些模型一般用来描述布局,它们可能会定义一些额外的盒子类型:
+ +
 
+ +
    +
  • 表格内容模型可能会创建一个表格包装器盒子和一个表格盒子,以及多个其他盒子如表格标题盒子等
  • +
  • 多列内容模型可能会在容器盒子和内容之间创建多个列盒子
  • +
  • 实验性的网格内容模型或flex-box内容模型同样会创建一些其他种类的盒子
  • +
+ +

定位规则

+ +

一旦生成了盒子以后,CSS引擎就需要定位它们以完成布局。下面是定位盒子时所使用的规则:

+ +
    +
  • 普通流:按照次序依次定位每个盒子
  • +
  • 浮动:将盒子从普通流中单独拎出来,将其放到外层盒子的某一边
  • +
  • 绝对定位:按照绝对位置来定位盒子,其位置根据盒子的包含元素所建立的绝对坐标系来计算,因此绝对定位元素有可能会覆盖其他元素
  • +
+ +

普通流

+ +
在普通流中,盒子会依次放置。在块格式化上下文中,盒子在垂直方向依次排列;而在行内格式化上下文中,盒子则水平排列。当CSS的 {{ cssxref("position") }} 属性为 static 或 relative,并且 {{ cssxref("float") }} 为 none 时,其布局方式为普通流。
+ +

示例

+ +
+

在普通流的块格式化上下文中,盒子会垂直依次排列:

+ +

[TODO 图片]

+ +

在普通流的行内格式化上下文中,盒子会水平依次排列:

+ +

[TODO 图片]

+
+ +
+

普通流又有两种情况:静态定位和相对定位:

+ +

{{ cssxref("position") }} 为 static 时为静态定位,此时每个盒子根据普通流所计算出的确切位置来定位。

+ +

[TODO 图片]

+ +

当 {{ cssxref("position") }} 为 relative 时为相对定位,此时每个盒子还会根据 {{ cssxref("top") }}、{{ cssxref("bottom") }}、{{ cssxref("left") }} 和 {{ cssxref("right") }} 属性的值在其原本所在的位置上产生指定大小的偏移。

+
+ +

浮动

+ +

在浮动定位中,浮动盒子会浮动到当前行的开始或尾部位置。这会导致普通流中的文本及其他内容会“流”到浮动盒子的边缘处,除非元素通过 {{ cssxref("clear") }} 清除了前面的浮动。

+ +

一个盒子的 {{ cssxref("float") }} 值不为 none,并且其 {{ cssxref("position") }} 为 static 或 relative 时,该盒子为浮动定位。如果将 {{ cssxref("float") }} 设置为 left,浮动盒子会定位到当前行盒子的开始位置(左侧),如果设置为 right,浮动盒子会定位到当前行盒子的尾部位置(右侧)。不管是左浮动还是右浮动,行盒子都会伸缩以适应浮动盒子的大小。

+ +

[TODO 图片]

+ +

绝对定位

+ +

在绝对定位中,盒子会完全从当前流中移除,并且不会再与其有任何联系(译注:此处仅指定位和位置计算,而绝对定位的元素在文档树中仍然与其他元素有父子或兄弟等关系),其位置会使用 {{ cssxref("top") }}、{{ cssxref("bottom") }}、{{ cssxref("left") }} 和 {{ cssxref("right") }} 相对其包含块进行计算。

+ +

如果元素的 {{ cssxref("position") }} 为 absolute 或 fixed,该元素为绝对定位。

+ +

对固定位置的元素来说,其包含块为整个视口,该元素相对视口进行绝对定位,因此滚动时元素的位置并不会改变。

+ +

参见

+ +
    +
  • {{css_key_concepts}}
  • +
diff --git a/files/zh-cn/web/css/word-wrap/index.html b/files/zh-cn/web/css/word-wrap/index.html deleted file mode 100644 index 5c2c0c687d..0000000000 --- a/files/zh-cn/web/css/word-wrap/index.html +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: overflow-wrap -slug: Web/CSS/word-wrap -tags: - - CSS Text Module Level 3 - - CSS3 - - W3C - - overflow-wrap - - word-wrap -translation_of: Web/CSS/overflow-wrap ---- -
{{CSSRef}}
- -
- -

{{EmbedInteractiveExample("pages/css/overflow-wrap.html")}}

- - - -

CSS 属性 overflow-wrap 是用来说明当一个不能被分开的字符串太长而不能填充其包裹盒时,为防止其溢出,浏览器是否允许这样的单词中断换行。

- -
-

与{{cssxref("word-break")}}相比,overflow-wrap仅在无法将整个单词放在自己的行而不会溢出的情况下才会产生中断。

-
- -
注:word-wrap 属性原本属于微软的一个私有属性,在 CSS3 现在的文本规范草案中已经被重名为 {{cssxref("overflow-wrap")}} 。 word-wrap 现在被当作 overflow-wrap 的 “别名”。 稳定的谷歌 Chrome 和 Opera 浏览器版本支持这种新语法。
- -

语法

- -
/* Keyword values */
-overflow-wrap: normal;
-overflow-wrap: break-word;
-
-/* Global values */
-overflow-wrap: inherit;
-overflow-wrap: initial;
-overflow-wrap: unset;
-
-
- -

overflow-wrap 属性指定为从下面的值列表中选择的单个关键字。

- -

- -
-
normal
-
行只能在正常的单词断点处中断。(例如两个单词之间的空格)。
-
break-word
-
表示如果行内没有多余的地方容纳该单词到结尾,则那些正常的不能被分割的单词会被强制分割换行。
-
- -

形式语法

- -
{{csssyntax}}
- -

示例

- -

比较 overflow-wrap、word-break 和 hyphens

- -

本示例比较分解长单词时,overflow-wrapword-break,  hyphens 的结果。

- -

HTML

- -
<p>They say the fishing is excellent at
-  Lake <em class="normal">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>normal</code>)</p>
-<p>They say the fishing is excellent at
-  Lake <em class="ow-anywhere">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>overflow-wrap: anywhere</code>)</p>
-<p>They say the fishing is excellent at
-  Lake <em class="ow-break-word">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>overflow-wrap: break-word</code>)</p>
-<p>They say the fishing is excellent at
-  Lake <em class="word-break">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>word-break</code>)</p>
-<p>They say the fishing is excellent at
-  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>hyphens</code>, without <code>lang</code> attribute)</p>
-<p lang="en">They say the fishing is excellent at
-  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>hyphens</code>, English rules)</p>
-<p class="hyphens" lang="de">They say the fishing is excellent at
-  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>hyphens</code>, German rules)</p>
- -

CSS

- -
p {
-   width: 13em;
-   margin: 2px;
-   background: gold;
-}
-
-.ow-anywhere {
-   overflow-wrap: anywhere;
-}
-
-.ow-break-word {
-   overflow-wrap: break-word;
-}
-
-.word-break {
-   word-break: break-all;
-}
-
-.hyphens {
-   hyphens: auto;
-}
- -

结果

- -

{{ EmbedLiveSample('Comparing_overflow-wrap_word-break_and_hyphens', '100%', 260) }}

- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('CSS3 Text', '#propdef-overflow-wrap', 'overflow-wrap') }}{{ Spec2('CSS3 Text') }}Initial definition
- -

{{cssinfo}}

- -

浏览器兼容性

- -

{{Compat("css.properties.overflow-wrap")}}

- -

另参见

- -
    -
  • {{cssxref("word-break")}}
  • -
  • {{cssxref("hyphens")}}
  • -
  • {{cssxref("text-overflow")}}
  • -
diff --git "a/files/zh-cn/web/css/\345\201\217\347\247\273/index.html" "b/files/zh-cn/web/css/\345\201\217\347\247\273/index.html" deleted file mode 100644 index e61a0ffd7a..0000000000 --- "a/files/zh-cn/web/css/\345\201\217\347\247\273/index.html" +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: offset -slug: Web/CSS/偏移 -translation_of: Web/CSS/offset ---- -
{{SeeCompatTable}}{{CSSRef}}{{draft}}
- -

这个 offset 是CSS属性的快速属性动画元素沿着定义的路径。

- -
-

早期版本 规格 属性叫做 motion.

-
- -

{{cssinfo}}

- -

Syntax

- -
/* 偏移位置 */
-offset: auto
-offset: 10px 30px;
-offset: none;
-
-/* 偏移路径 */
-offset: ray(45deg closest-side);
-offset: path(M 100 100 L 300 100 L 200 300 z);
-offset: url(arc.svg);
-
-/*  偏移路径的距离和/或旋转  */
-offset: url(circle.svg) 100px;
-offset: url(circle.svg) 40%;
-offset: url(circle.svg) 30deg;
-offset: url(circle.svg) 50px 20deg;
-
-/*  包括锚偏移  */
-offset: ray(45deg closest-side) / 40px 20px;
-offset: url(arc.svg) 2cm / 0.5cm 3cm;
-offset: url(arc.svg) 30deg / 50px 100px;
-
- -

语法形式

- -
{{csssyntax}}
- -

举例

- -

HTML

- -
<div id="offsetElement"></div>
-
- -

CSS

- -
@keyframes move {
-  from {
-    offset-distance: 0%;
-  }
-
-  to {
-    offset-distance: 100%;
-  }
-}
-
-#offsetElement {
-  width: 50px;
-  height: 50px;
-  background-color: blue;
-  offset: path("M 100 100 L 300 100 L 200 300 z") auto;
-  animation: move 3s linear infinite;
-}
-
- -

Result

- -

{{EmbedLiveSample("Example", 350, 350)}}

- -

规格

- - - - - - - - - - - - - - -
规格使用状态注释
{{SpecName('Motion Path Level 1', '#offset-shorthand', 'offset')}}{{Spec2('Motion Path Level 1')}}Initial definition
- -

浏览器兼容性

- -

该兼容性表生成从该网页的结构化数据。如果你愿意,请查看https://github.com/mdn/browser-compat-数据,并发送一个引入请求。

- -

{{Compat("css.properties.offset")}}

diff --git "a/files/zh-cn/web/css/\345\252\222\344\275\223\346\237\245\350\257\242/index.html" "b/files/zh-cn/web/css/\345\252\222\344\275\223\346\237\245\350\257\242/index.html" deleted file mode 100644 index 9936c531f1..0000000000 --- "a/files/zh-cn/web/css/\345\252\222\344\275\223\346\237\245\350\257\242/index.html" +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: 媒体查询 -slug: Web/CSS/媒体查询 -tags: - - CSS - - 参考 - - 响应式设计 - - 媒体查询 - - 总览 -translation_of: Web/CSS/Media_Queries ---- -
{{CSSRef}}
- -

通过媒体查询Media queries),您可以根据各种设备特征和参数的值或者是否存在来调整您的网站或应用。

- -

它们是响应式设计的关键组成部分。 例如,媒体查询可以缩小小型设备上的字体大小,在纵向模式下查看页面时增加段落之间的填充,或者增加触摸屏上按钮的大小。

- -

在 CSS 中,使用 {{cssxref("@media")}} at-rule 根据媒体查询的结果有条件地应用样式表的一部分。 使用 {{cssxref("@import")}} 有条件地应用整个样式表。

- -

在 HTML 中使用媒体查询

- -

HTML 中,媒体查询可以应用于各种元素:

- -
    -
  • 在{{HTMLElement("link")}}元素的{{htmlattrxref("media", "link")}}属性中,它们定义了待应用链接资源(通常是CSS)的媒体。
  • -
  • 在{{HTMLElement("source")}}元素的{{htmlattrxref("media", "source")}}属性中,它们定义待应用源的媒体。 (这仅在{{HTMLElement("picture")}}元素内有效。)
  • -
  • 在{{HTMLElement("style")}}元素的{{htmlattrxref("media", "style")}}属性中,它们定义待应用样式的媒体。
  • -
- -

在 JavaScript 中使用媒体查询

- -

JavaScript中,您可以使用 {{domxref("Window.matchMedia()")}} 方法根据媒体查询测试窗口。 您还可以使用{{domxref("MediaQueryList.addListener()")}}在查询状态发生变化时收到通知。 借助此功能,您的站点或应用可以响应设备配置,方向或状态的更改。

- -

您可以学习更多以编程方式使用媒体查询在测试媒体查询中。

- -

参考

- -

At-rules

- -
-
    -
  • {{cssxref("@import")}}
  • -
  • {{cssxref("@media")}}
  • -
-
- -

指南

- -
-
使用媒体查询
-
介绍媒体查询和媒体查询的的语法以及用于构造媒体查询表达式的运算符和媒体功能。
-
编程方式使用媒体查询
-
描述如何在 JavaScript 代码中使用媒体查询来确定设备的状态,以及设置在媒体查询结果发生更改时(例如,当用户旋转屏幕或调整浏览器大小时)通知代码的监听器。
-
使用媒体查询增强网站的可访问性
-
了解媒体查询如何帮助用户更好地了解您的网站。
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('CSS5 Media Queries')}}{{Spec2('CSS5 Media Queries')}}
{{SpecName('CSS3 Conditional')}}{{Spec2('CSS3 Conditional')}}
{{SpecName('CSS4 Media Queries')}}{{Spec2('CSS4 Media Queries')}}
{{SpecName('CSS3 Media Queries')}}{{Spec2('CSS3 Media Queries')}}
{{SpecName('CSS2.1', 'media.html')}}{{Spec2('CSS2.1')}}Initial definition
- -

浏览器兼容性

- -

@media rule

- - - -

{{Compat("css.at-rules.media")}}

- -

参见

- -
    -
  • Use {{cssxref("@supports")}} to apply styles that depend on browser support for various CSS technologies.
  • -
diff --git "a/files/zh-cn/web/css/\346\226\207\346\234\254\350\243\205\351\245\260\347\272\277\345\216\232\345\272\246(\347\262\227\347\273\206)/index.html" "b/files/zh-cn/web/css/\346\226\207\346\234\254\350\243\205\351\245\260\347\272\277\345\216\232\345\272\246(\347\262\227\347\273\206)/index.html" deleted file mode 100644 index cdffd6eced..0000000000 --- "a/files/zh-cn/web/css/\346\226\207\346\234\254\350\243\205\351\245\260\347\272\277\345\216\232\345\272\246(\347\262\227\347\273\206)/index.html" +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: 文本装饰线厚度(粗细) -slug: Web/CSS/文本装饰线厚度(粗细) -tags: - - 装饰线粗细 装饰线厚度 -translation_of: Web/CSS/text-decoration-thickness ---- -
{{CSSRef}}
- -
CSS 属性 text-decoration-thickness 用于设置元素中文本所使用的装饰线(如 line-through、underline 或 overline)的笔触厚度。
- -

语法

- -
/* Single keyword */
-text-decoration-thickness: auto;
-text-decoration-thickness: from-font;
-
-/* length */
-text-decoration-thickness: 0.1em;
-text-decoration-thickness: 3px;
-
-/* percentage */
-text-decoration-thickness: 10%;
-
-/* Global values */
-text-decoration-thickness: inherit;
-text-decoration-thickness: initial;
-text-decoration-thickness: unset;
- -

- -
-
auto
-
由浏览器为文本装饰线选择合适的厚度。
-
from-font
-
如果字体文件中包含了首选的厚度值,则使用字体文件的厚度值。如果字体文件中没有包含首选的厚度值,则效果和设置为 auto 一样,由浏览器选择合适的厚度值。
-
<length>
-
将文本装饰线的厚度设置为一个 {{cssxref('length')}} 类型的值,覆盖掉字体文件建议的值或浏览器默认的值。
-
<percentage>
-
Specifies the thickness of the text decoration line as a {{cssxref('percentage')}} of 1em in the current font. A percentage inherits as a relative value, and so therefore scales with changes in the font. The browser must use a minimum of 1 device pixel. For a given application of this property, the thickness is constant across the whole box it is applied to, even if there are child elements with a different font size.
-
- -

Formal definition

- -

{{CSSInfo}}

- -

Formal syntax

- -
{{csssyntax}}
- -

示例

- -

Varying thickness

- -

HTML

- -
<p class="thin">Here's some text with a 1px red underline.</p>
-<p class="thick">This one has a 5px red underline.</p>
-<p class="shorthand">This uses the equivalent shorthand.</p>
- -

CSS

- -
.thin {
-  text-decoration-line: underline;
-  text-decoration-style: solid;
-  text-decoration-color: red;
-  text-decoration-thickness: 1px;
-}
-
-.thick {
-  text-decoration-line: underline;
-  text-decoration-style: solid;
-  text-decoration-color: red;
-  text-decoration-thickness: 5px;
-}
-
-.shorthand {
-  text-decoration: underline solid red 5px;
-}
- -

Results

- -

{{ EmbedLiveSample('Varying_thickness', '', '', '') }}

- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS4 Text Decoration', '#text-decoration-width-property', 'text-decoration-width')}}{{Spec2('CSS4 Text Decoration')}}Initial definition.
- -
-

Note: The property used to be called text-decoration-width, but was updated in 2019 to text-decoration-thickness.

-
- -

浏览器兼容性

- - - -

{{Compat("css.properties.text-decoration-thickness")}}

- -

相关链接

- -
    -
  • {{cssxref("text-decoration")}}
  • -
  • {{cssxref("text-underline-offset")}}
  • -
diff --git "a/files/zh-cn/web/css/\347\275\221\346\240\274-\346\250\241\346\235\277-\345\210\227/index.html" "b/files/zh-cn/web/css/\347\275\221\346\240\274-\346\250\241\346\235\277-\345\210\227/index.html" deleted file mode 100644 index 0dcd6b29d5..0000000000 --- "a/files/zh-cn/web/css/\347\275\221\346\240\274-\346\250\241\346\235\277-\345\210\227/index.html" +++ /dev/null @@ -1,209 +0,0 @@ ---- -title: grid-template-rows -slug: Web/CSS/网格-模板-列 -tags: - - grid-template-rows -translation_of: Web/CSS/grid-template-rows ---- -

grid-template-rows 该属性是基于 {{glossary("grid rows", "网格行")}} 的维度,去定义网格线的名称和网格轨道的尺寸大小。

- -
{{EmbedInteractiveExample("pages/css/grid-template-rows.html")}}
- - - -

语法

- -
/* Keyword value */
-grid-template-rows: none;
-
-/* <track-list> values */
-grid-template-rows: 100px 1fr;
-grid-template-rows: [linename] 100px;
-grid-template-rows: [linename1] 100px [linename2 linename3];
-grid-template-rows: minmax(100px, 1fr);
-grid-template-rows: fit-content(40%);
-grid-template-rows: repeat(3, 200px);
-
-/* <auto-track-list> values */
-grid-template-rows: 200px repeat(auto-fill, 100px) 300px;
-grid-template-rows: minmax(100px, max-content)
-                       repeat(auto-fill, 200px) 20%;
-grid-template-rows: [linename1] 100px [linename2]
-                       repeat(auto-fit, [linename3 linename4] 300px)
-                       100px;
-grid-template-rows: [linename1 linename2] 100px
-                       repeat(auto-fit, [linename1] 300px) [linename3];
-
-/* Global values */
-grid-template-rows: inherit;
-grid-template-rows: initial;
-grid-template-rows: unset;
-
- -

该属性可能包含如下值:

- -
    -
  • 关键字 none
  • -
  • 或者 <track-list> 值
  • -
  • 或者 <auto-track-list> 值。
  • -
- -

- -
-
none
-
这个关键字表示不明确的网格。所有的行和其大小都将由{{cssxref("grid-auto-rows")}} 属性隐式的指定。
-
{{cssxref("<length>")}}
-
非负值的长度大小。
-
{{cssxref("<percentage>")}}
-
非负值且相对于网格容器的 {{cssxref("percentage", "<百分比>")}}。 如果网格容器的尺寸大小依赖网格轨道的大小(比如 inline-grid ),则百分比值将被视为auto
-
为了遵守网格的百分比,网格轨道本身定义的大小,将自动被调整为相对网格容器大小,并且是以最小量将网格轨道调整到最终的大小。
-
{{cssxref("<flex_value>","<flex>")}}
-
非负值,用单位 fr 来定义网格轨道大小的弹性系数。 每个定义了 <flex> 的网格轨道会按比例分配剩余的可用空间。当外层用一个 minmax() 表示时,它将是一个自动最小值(即 minmax(auto, <flex>) ) 。
-
max-content
-
是一个用来表示以网格项的最大的内容来占据网格轨道的关键字。
-
min-content
-
是一个用来表示以网格项的最大的最小内容来占据网格轨道的关键字。
-
{{cssxref("minmax", "minmax(min, max)")}}
-
是一个来定义大小范围的属性,大于等于min值,并且小于等于max值。如果max值小于min值,则该值会被视为min值。最大值可以设置为网格轨道系数值<flex> ,但最小值则不行。 
-
-

Note:  该规范在将来可能会允许设置最小值为 flex ,也会调整网格轨道算法(track sizing algorithm) 计算出正确的大小。

-
-
auto
-
如果该网格轨道为最大时,该属性等同于 <max-content> ,为最小时,则等同于 <min-content> 。
-
-

Note: 网格轨道大小为 auto (且只有为 auto ) 时,才可以被属性{{cssxref("align-content")}} 和 {{cssxref("justify-content")}} 拉伸 。

-
-
{{cssxref("fit-content", "fit-content( [ <length> | <percentage> ] )")}}
-
相当于公式 min(max-content, max(auto, argument)),类似于auto 的计算(即 minmax(auto, max-content)),除了网格轨道大小值是确定下来的,否则该值都大于 auto 的最小值。
-
{{cssxref("repeat", "repeat( [ <positive-integer> | auto-fill | auto-fit ] , <track-list> )")}}
-
表示网格轨道的重复部分,以一种更简洁的方式去表示大量而且重复行的表达式。
-
- -

正式语法

- -
{{csssyntax}}
- -

示例

- -

CSS

- -
#grid {
-  display: grid;
-  height: 100px;
-  grid-template-rows: 30px 1fr;
-}
-
-#areaA {
-  background-color: lime;
-}
-
-#areaB {
-  background-color: yellow;
-}
- -

HTML

- -
<div id="grid">
-  <div id="areaA">A</div>
-  <div id="areaB">B</div>
-</div>
- -

结果

- -

{{EmbedLiveSample("示例", "40px", "100px")}}

- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName("CSS3 Grid", "#propdef-grid-template-rows", "grid-template-rows")}}{{Spec2("CSS3 Grid")}}初步定义
- -

{{cssinfo}}

- -

浏览器兼容性

- -

 

- - - -

{{Compat("css.properties.grid-template-rows")}}

- -

 

- -

参见

- - - - -- cgit v1.2.3-54-g00ecf